[SWPUCTF 2021 新生赛]简简单单的逻辑

查看源代码,大概意思就是已知result反推flag

flag = 'xxxxxxxxxxxxxxxxxx'
list = [47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25]
result = ''
for i in range(len(list)):
    key = (list[i]>>4)+((list[i] & 0xf)<<4)
    result += str(hex(ord(flag[i])^key))[2:].zfill(2)
print(result)
# result=bcfba4d0038d48bd4b00f82796d393dfec

观察代码可以发现,在每一轮循环中keyresult所对应的字符都是已知的但是flag的字符是未知的,而且对于每一个i,都有flag[i]^key=result[i]

注:若A、C已知,B未知且A^B=C,则B=A^C,即flag[i]=key^result[i]

for循环中

遍历 list 的每个元素。

  • key = (list[i]>>4)+((list[i] & 0xf)<<4):这行代码对 list[i] 进行了位操作。
    • list[i]>>4:将 list[i] 右移 4 位。
    • list[i] & 0xf:将 list[i] 与 15(二进制中的 00001111)进行按位与操作,从而得到 list[i] 的低 4 位。
    • ((list[i] & 0xf)<<4):将上一步得到的低 4 位左移 4 位。
    • 将两部分相加,得到 key
  • result += str(hex(ord(flag[i])^key))[2:].zfill(2):这行代码执行了几个操作。
    • ord(flag[i]):获取 flag 字符串中第 i 个字符的 ASCII 值。
    • ord(flag[i])^key:将上述 ASCII 值与 key 进行按位异或操作。
    • hex(...):将异或结果转换为十六进制字符串。
    • str(hex(...))[2:]:从十六进制字符串中去除开头的 '0x'
    • .zfill(2):如果结果字符串长度小于 2,则在前面填充 '0' 以确保长度为 2。
    • 将结果添加到 result 字符串中。

构造payload

result='bcfba4d0038d48bd4b00f82796d393dfec'
list = [47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25]
list2=[]
flag=[]
for i in range(0,34,2):   #i的步长为2
    list2.append(result[i:i+2])    #将result两两分为一组依次放入list2中
print(list2)            #打印list2
for i in range(17):
    if list2[i].startswith('0'):      #判断list2中的每个元素是否是以0开头,如果是则说明这个0是之前补上的
        list2[i]=list2[i][1:]         #选择字符串第一个字符及其后面的部分,在这里去掉即为去掉开头的0
print(list2)
for i in range(17):
    list2[i]=bin(int(list2[i],16))[2:]       #转换为16进制
    list2[i]=list2[i].zfill(8)               #不足8位的在前面补0,补足8位
print(list2)
for i in range(17):
    key = bin((list[i] >> 4) + ((list[i] & 0xf) << 4))[2:]     #这里的key与源代码中的key相同
    key=key.zfill(8)                                           #不足8位的在前面补0,补足8位
    flag.append(format(int(key, 2) ^ int(list2[i], 2), '08b'))   #异或求得flag中的每一个字符的ascii码对应的二进制数值
    print(flag[i],end=",")

print('\n')
for i in range(17):
    flag[i]=int(flag[i],2)   #将flag中的每个元素(二进制字符串)转换为整数
finall_flag= ''.join([chr(i) for i in flag])        #将flag中的每个整数转换为对应的ASCII字符
print(finall_flag)                                  #输出flag

得到flag

['bc', 'fb', 'a4', 'd0', '03', '8d', '48', 'bd', '4b', '00', 'f8', '27', '96', 'd3', '93', 'df', 'ec']
['bc', 'fb', 'a4', 'd0', '3', '8d', '48', 'bd', '4b', '0', 'f8', '27', '96', 'd3', '93', 'df', 'ec']
['10111100', '11111011', '10100100', '11010000', '00000011', '10001101', '01001000', '10111101', '01001011', '00000000', '11111000', '00100111', '10010110', '11010011', '10010011', '11011111', '11101100']
01001110,01010011,01010011,01000011,01010100,01000110,01111011,01000101,01011010,01000101,01011010,01011111,01010010,01000101,01010010,01000101,01111101,

NSSCTF{EZEZ_RERE}
posted @   Zonda_R  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示