RE:
题目文件:链接:点击打开链接 密码:hyzy
这题当时做的时候陷入了出题人的陷阱,上来找到了“关键部分”就开始逆,但是遇到了很多问题,因为有很多函数,而且篇幅都不小,而且每个函数还要调用其他一大堆函数,这就大大增加了工作量,后面实在看不下去了,就放弃了。
后面找到一些大佬的writeup看了看,原来是思路的问题:
总结一下:
逆向赛题一般工作量不会大到让你逆不了,一下锁定了十七八个函数肯定是有问题的,换思路
在这里就记录一下自己的学习历程,偏基础一点,适用于刚入门的,比如我。
看题目:
首先用IDA分析:
第一部分逆向脚本:
def check1(str0):
flagmd5 = ''
for i in range(len(str0)):
temp = ord(str0[i])-i%10
if temp <= ord('A') + 5 and temp >= ord('A'):
flagmd5 += chr(temp)
else:
flagmd5 += str0[i]
return flagmd5
得到的结果拿去在线解密 : yubu
def change2(str0):
byte_603860 = [0xd7,0xdb,0xb4,0x0e,0x1e,0x17,0x2b,0x76,0x34,0xcc,0x00,0x81,0xef,0x67,0x29,0xb3]
flag_byte = ""
for i in range(0,32,2):
v5 = str0[i]
v7 = str0[i+1]
if ord(v5)>=0x41 and ord(v5)<=0x46:
tmp = ord(v5)-0x41+10
elif ord(v5)>=0x30 and ord(v5)<=0x39:
tmp = ord(v5)-0x30
else:
print "Error"
if ord(v7)>=0x41 and ord(v7)<=0x46:
tmp1 = ord(v7)-0x41+10
elif ord(v7)>=0x30 and ord(v7)<=0x39:
tmp1 = ord(v7)-0x30
else:
print "Error"
byte = str(bin(tmp)[2:]).rjust(4,"0")+str(bin(tmp1)[2:]).rjust(4,"0")
flag_byte += hex(int(byte,2))[2:].rjust(2,"0")
flagmd5 = ""
for i in range(0,16,):
flagmd5 += str( hex(int(flag_byte[2*i]+flag_byte[2*i+1],16) ^ byte_603860[i]).rjust(2,"0")[2:] )
return flagmd5
得到的结果拿去在线解密 : kulo
发现最下面将最后的结果写入了一个文件“flag”,前面未知量较多,不适合逆向尝试爆破,脚本如下:
这里我们从写入文件的一步开始倒着看,上面是一个循环,奇偶不同异或的值也不同,但只有v15,v16两个值。这里我们不管他之前的值是什么,只有两个字节我们可以爆破。
爆破脚本:
def get_data():
f2 = open("result",'wb')
for i in range(256):
for j in range(256):
f1 = open("data",'rb')
for k in range(6047):
ori_byte = f1.read(1)
if k&1 ==0:
f2.write(chr(ord(ori_byte)^i))
else:
f2.write(chr(ord(ori_byte)^j))
f1.close()
f2.write('\n')
f2.close()
get_data()
写脚本的思路就是,因为v15、v16我们不知道,但是我们知道他们每个都是一个“char”类型的数,一个字节,那么范围就是从0到255,每一个v15,尝试256个v16,这时候每一种v15、v16的组合和一个大的数组byte_6020E0,做上述操作。一共会生成256*256*6047个字节的数据,这256*256次中一定有一次组合是正确的,是我们需要的数据。
我跑了大约有七八分钟的样子,得到了数据快400M
用HxD打开,这时候就需要我们脑洞了,这里出题人放的是一张 jpg,文件头为“FF D8 FF E0 00 10 4A 46 49 46 00 01”,搜索发现有头,再搜索“FF D9”文件尾,把这一部分数据截取出来单独保存成jpg后缀的文件。
打开图片就可以看到一个字符串,得到了第三部分数据。
我们将三部分的数据组合得到flag:
CISCN{yubu_kulo_JipCC%6&goFunMz}
前两段完整代码:
def change1(str0):
str00 = ''
for i in range(len(str0)):
temp = ord(str0[i])-i%10
if temp <= ord('A') + 5 and temp >= ord('A'):
str00 += chr(temp)
else:
str00 += str0[i]
return str00
def change2(str0):
byte_603860 = [0xd7,0xdb,0xb4,0x0e,0x1e,0x17,0x2b,0x76,0x34,0xcc,0x00,0x81,0xef,0x67,0x29,0xb3]
flag_byte = ""
for i in range(0,32,2):
v5 = str0[i]
v7 = str0[i+1]
if ord(v5)>=0x41 and ord(v5)<=0x46:
tmp = ord(v5)-0x41+10
elif ord(v5)>=0x30 and ord(v5)<=0x39:
tmp = ord(v5)-0x30
else:
print "Error"
if ord(v7)>=0x41 and ord(v7)<=0x46:
tmp1 = ord(v7)-0x41+10
elif ord(v7)>=0x30 and ord(v7)<=0x39:
tmp1 = ord(v7)-0x30
else:
print "Error"
byte = str(bin(tmp)[2:]).rjust(4,"0")+str(bin(tmp1)[2:]).rjust(4,"0")
flag_byte += hex(int(byte,2))[2:].rjust(2,"0")
flagmd5 = ""
for i in range(0,16,):
flagmd5 += str( hex(int(flag_byte[2*i]+flag_byte[2*i+1],16) ^ byte_603860[i]).rjust(2,"0")[2:] )
return flagmd5
flag1 = ""
flag2 = ""
flag1_check = "762306GI890905GKL6887E5D75776382"
flag2_check = "762306GI890905GKL6887E5D75776382"
flag1 = change1(flag1_check)
print "flag1",flag1
flag2 = change2(change1(flag2_check))
print "flag2",flag2
flag1 762306AB890905CFF6887D5A75776382 在线解密之后为 : yubu
flag2 a1f8b2a5971e2eb9c2447ddb9a104a31 在线解密之后为 : kulo