xctf-simple-check-100

水题一枚

这道题有点坑,给了三个平台的程序文件,可惜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,会抽时间把以前写的一些有价值的东西迁移上去,应该很少吧!


给自己的忠告:多写代码,多睡觉!^_^

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章