题目
文件
IDA
解题
答案
flag{reversing_is_not_that_hard!}
查看Writeup
题目描述
听说运行就能拿到Flag,不过菜鸡运行的结果不知道为什么是乱码
运行
代码逻辑
- 复制409B10中的数据到申请的堆空间中
- 检测是否反调试
- 没有则将堆空间的数据作为MessageBoxA的第二个参数(显示的内容,即上图的中文乱码部分)弹框:
此时传入MessageBoxA的参数2数据是乱码:
通过交叉引用可以看到,该堆空间还有在函数401000中进行异或解密处理:
异或处理的数据为409B10和409B38:
分别为密文和密钥,数据为:
listPass = [ 0xBB, 0xCC, 0xA0, 0xBC, 0xDC, 0xD1, 0xBE, 0xB8, 0xCD, 0xCF, 0xBE, 0xAE, 0xD2, 0xC4, 0xAB, 0x82, 0xD2, 0xD9, 0x93, 0xB3, 0xD4, 0xDE, 0x93, 0xA9, 0xD3, 0xCB, 0xB8, 0x82, 0xD3, 0xCB, 0xBE, 0xB9, 0x9A, 0xD7, 0xCC, 0xDD ]
listKey = [ 0xBB, 0xAA, 0xCC, 0xDD ]
解题方式
1️⃣动态运行 - 反反调试
同上面的代码逻辑部分已经推理出了,在运行到反调试检测时,要修改跳转去执行401000。此处的跳转指令是JE,对应ZF标志位:
执行到401000时可以看到,传入的寄存器为EDX,此处地址对应数据是乱码:
运行过401000后,该地址的数据已解密:
还可以通过修改/跳过JMP或修改EIP, 运行到弹框代码将Flag弹出,不过不是很有必要:
2️⃣Python脚本 - 异或解密
由于解密代码比较简单,就是异或,数据也比较容易获取。在比较难调的情况,可以通过Python等代码解密:
listPass = [ 0xBB, 0xCC, 0xA0, 0xBC, 0xDC, 0xD1, 0xBE, 0xB8, 0xCD, 0xCF, 0xBE, 0xAE, 0xD2, 0xC4, 0xAB, 0x82, 0xD2, 0xD9, 0x93, 0xB3, 0xD4, 0xDE, 0x93, 0xA9, 0xD3, 0xCB, 0xB8, 0x82, 0xD3, 0xCB, 0xBE, 0xB9, 0x9A, 0xD7, 0xCC, 0xDD ]
listKey = [ 0xBB, 0xAA, 0xCC, 0xDD ]
def Xor(strPass, key):
strXOR = ""
for i in range(len(strPass)):
strXOR += (chr(strPass[i] ^ key[i % len(key)]))
return strXOR
print("Flag是:", Xor(listPass,listKey))