打开题目首先拖入IDA
看见茫茫多的函数,无从下手。正常。这个时候需要利用一个针对MVC的工具了 XSPY
将拖到按钮处,记住这里的id 0x9e。
再次拖到主框处继续查看,看到check按钮的出发事件在偏移0x2420处。OK,这下我们获取了关键信息。
返回IDA查看偏移地址0x2420处的函数
这里看到很像成功与失败的判断。为了检验正确性。我们使用OD去检测。
打开OD,首先同样在偏移0x2420处下断点
成功断在这里后,往下找if分支
修改分支条件,使它为正确。可以看到程序走向correct
接下来回到IDA继续查看,既然已经知道这里是分支正确与错误的地方,那if里的值必然是类似于checkflag的地方了。
跟进查看
来到偏移为2600的函数。这里仍然有一个if判断。
跟进条件很容易看到flag输入的长度应该为38.
接下来看静态可能看不懂了。这就是花指令的作用。不会去花,无奈之下,只能选择动态调试。但是已经知道了2600是check的地方并且flag长度为38。所以输入38个字符,满足第一个if长度要求,进入if内部,F7跟进陌生的2CA0函数。
这里的F7跟进我的心得是: 遇到提取字符串的循环,cmp比较,xor等常用的加密处理字符停下来观察。
在这里,遇到第一个循环,并且跟随所填充的地址可以发现在不断往一个内存填充数据。最终填满为256个字符,熟悉密码学的知道这里是RC4加密,但是不知道的也不影响。F4跳出这个循环外,继续F7跟进。后续遇到的每一个循环都仔细看一看,大概知道是干什么的了就跳出。
跟进到这里,发现输入的数据正在进行异或。记录下来参与异或的数据。继续跟进会发现CMP
在这里将两个数据对比,记录下两组参与对比的数据,会发现一个是异或产生后的数据,一个是固定数据。
接下来就是使用python脚本解答案了。
a=[0x3D,0xE4,0xE5 ,0x16 ,0xAD ,0xEE ,0x7D ,0x49 ,0x5B ,0x6 ,0xF9 ,0x26 ,0xA9 ,0x49 ,0xC8 ,0xCB,0xE9 ,0x44 ,0x53 ,0xD6 ,0xC4 ,0x84 ,0xEF ,0x66 ,0xB3,0xFE ,0x3B,0x38 ,0xAD ,0xE3 ,0x72,0xC3]
b=[0x5b,0xd6,0xd0,0x26,0xc8,0xdd,0x19,0x7e,0x6e,0x3e,0xcb,0x16,0x9a,0x7d,0xff,0xaf,0xdd,0x76,0x64,0xb0,0xf7,0xe5,0x89,0x57,0x82,0x9f,0xc,0x0,0x9e,0xd0,0x45,0xfa]
for i in range(0,len(b)):
print(chr(b[i]^a[i]),end='')
但是结果尝试仍然不对,本来测试用的字母是38个a,这里却只有32位字符,改用0123abcd…输入,可以发现省略检查了一些字符,并且是逆序异或。由此将上述脚本获得的字符逆序一下即可获得正确的flag
其中正确的格式只要被xxxxx32位字符x。即可