前言
作为刚入门没多久的新手,分享一下自己在学习过程中的经验吧,图片有水印是因为我先发在CSDN上面了,不过那上面可交流的人很少,感兴趣的朋友可以去xctf社区找找这道题来做一下体验一下,不过这应该算是入门级别的题目了吧。
水题一枚
这道题有点坑,给了三个平台的程序文件,可惜win上面的是错的。考察的也仅仅只是一个逻辑修改,不过为了能从这道题学点东西,我把静态情况下分析的结果利用py写了个脚本来跑flag,算是对IDA中的算法逆向有了更深一步的理解吧。
算法描述
程序一开始会初始化一个数组,这里我把它叫做key_data数组,ida自动分析出来的数值不好看把它转为16进制的:
然后就是输出字符提示让输入key:
进入check_key函数判断key是否正确,正确则进入interesting_function函数解码flag:
check_key函数是一个计算校验和与正确的校验和对比的一个函数,ida自动分析出来是这样:
经过简单的修改参数类型之后如下,看起来更为清晰,input_key作为一个DWORD数组,有5个元素,也就是20个字节的长度:
算法就是将input_key看做一个DWORD数组将其每一项相加得到校验和,而这个值要为0xDEADBEEF
才是正确的,根据这个本来想爆破得到key的,可惜耗时太大不行。
再来看interesting_function函数,其参数即为上面说到的key_data数组v7:
ida自动分析的结果如下:
稍加修改后如下:
这个函数就是解码flag的过程,可以看出,解码的数组都和输入的key没有关系,所以我们可以写出解码的脚本来得到flag,这就是我学习到的地方了。
同上面key_data的赋值来看,为7个DWORD值,而interesting_function中通过两层循环先将key_data的值与校验和0xDEADBEEF
(死牛肉,hhh)相异或,然后再将异或后的值一个一个字节与flag_data异或得到flag值,这里需要注意异或后的值是从高地址处的字节开始异或的,又由于小端存放的原因,所以写脚本的时候逐字节异或时按照结果从左到右,不要被内层循环的--j
给迷惑了。
脚本
#!/usr/bin python
"""
xctf:simple-check-100
"""
key_data = [0xE37EC854,0x9A16C764,0x326511CD,0x43D3E32D,0xD29DA992,0xD32C6DE6,0x6AFEBDB6]
flag_data = [0xDC, 0x17, 0xBF, 0x5B, 0xD4, 0x0A, 0xD2, 0x1B, 0x7D, 0xDA, 0xA7, 0x95, 0xB5, 0x32, 0x10, 0xF6, 0x1C, 0x65, 0x53, 0x53, 0x67, 0xBA, 0xEA, 0x6E, 0x78, 0x22, 0x72, 0xD3]
def decode():
flag = ""
for i in range(7):
tmp = hex(key_data[i] ^ 0xDEADBEEF)
if len(tmp)<10:
tmp = '0x'+'0'*(10-len(tmp))+tmp[2:]
print "The XOR value:"+tmp
for j in range(4):
flag += chr(int('0x'+tmp[2*j+2:2*j+4],16)^flag_data[4*i+(3-j)])
print "flag:"+flag
if __name__ == "__main__":
decode()
# output
'''
The XOR value:0x3dd376bb
The XOR value:0x44bb798b
The XOR value:0xecc8af22
The XOR value:0x9d7e5dc2
The XOR value:0x0c30177d
The XOR value:0x0d81d309
The XOR value:0xb4530359
flag:flag_is_you_know_cracking!!!
'''
总结
好水的题,关键是菜,用OD分析时一直不得结果,原因是win上的程序有问题,在key_data赋值那一段是错误的,导致你绕过check_key之后也得不到正确的结果,换成elf
文件来看才是正确的。
最后一篇csdn blog了,在github上搭了新的blog,会抽时间把以前写的一些有价值的东西迁移上去,应该很少吧!
给自己的忠告:多写代码,多睡觉!^_^