[WUSTCTF2020]funnyre
有花指令 瞎搞一通后得到main
进行了超长的变换
最后与已知的数组比较结果
这里重点是要理解到:这些变换都是限制在BYTE范围内的
也就是说 这些变换都可以等价为0~256的某个数的一次变换
所以两种变换(取反也可以等价为xor)分别枚举0~256的一次变换即可
这里最好判断一下是不是16进制数
dt = [0xd9, 0x2c, 0x27, 0xd6, 0xd8, 0x2a, 0xda, 0x2d, 0xd7, 0x2c, 0xdc, 0xe1, 0xdb, 0x2c, 0xd9, 0xdd, 0x27, 0x2d, 0x2a, 0xdc, 0xdb, 0x2c, 0xe1, 0x29, 0xda, 0xda, 0x2c, 0xda, 0x2a, 0xd9, 0x29, 0x2a]
def move(xx, kk):
return [(x+kk) & 0xFF for x in xx]
def xor(xx, kk):
return [x ^ kk for x in xx]
def check(xx): # 16进制
for x in xx:
if x < ord('0') or (x > ord('9') and x < ord('a')) or x > ord('f'):
return False
return True
if __name__ == '__main__':
for k1 in range(0x100):
tt = move(dt, k1)
for k2 in range(0x100):
tt2 = xor(tt, k2)
if check(tt2):
print(bytes(tt2))
print(k1, k2)
当然这种题目肯定可以用angr库暴力求解
exp:
import angr
import claripy
p=angr.Project('./attachment',load_options={"auto_load_libs": False})
f=p.factory
state = f.entry_state(addr=0x400605)#设置state开始运行时的地址
flag = claripy.BVS('flag',8*32)#要求的内容有32个,用BVS转成二进制给flag变量
state.memory.store(0x603055+0x300+5,flag)#因为程序没有输入,所以直接把字符串设置到内存
state.regs.rdx=0x603055+0x300
state.regs.rdi=0x603055+0x300+5#然后设置两个寄存器
sm = p.factory.simulation_manager(state)#准备从state开始遍历路径
print("ready")
sm.explore(find=0x401DAE)#遍历到成功的地址
if sm.found:
print("sucess")
x=sm.found[0].solver.eval(flag,cast_to=bytes)
print(x)
else:
print('error')