盒子
盒子
文章目录
  1. 前言:
  2. 解析:
    1. 第一个函数:
    2. 第二个函数:
    3. 第三个函数:

2018CISCN_Re_06

前言:

这道是今年国赛上的逆向题,题目难度怎么说呢..如果想通了的话还是蛮简单的,但是你没想通的话,我估计头皮想破了也想不出来阿..还是怪自己太菜了..哎,大佬们撸一眼就能看出来,而我..不说了,继续学习去了。(这里后来又看了看别人的wp,发现了一个神器,是PEID的插件krypto analyzer,这个神器可以帮你判断所用的加密类型,是不是很无敌..)

解析:

先看看反汇编的代码:
1

开始先将开头字符串和CISCN{作对比

2

然后申请一段32大小的内存

3

再将输入的字符串按照’_’分为三段,分别进行判断

第一个函数:

4

大佬一眼就看出来这是md5加密了,我也不知道大佬们是怎么知道的..我这样的菜鸡当时做的时候居然是一个一个函数全都看过去了,然后还是没弄明白,大佬直接就知道这是MD5加密方式了..前两个函数貌似是初始化向量,用了两步是为了怕直接被看出来,只是简单的xor亦或了一下,没什么用,但是最后一个函数被修改过了,将hex转ascii输出32位。我也完全没有看出来这是hex转ascii,只看出来输出32位T T。

往下看:

5

前面得到的字符串之后再经过所圈出来的函数与v7字符串对比是否相同。
不过这里我不太明白圈中的函数的具体含义,单从函数上面来讲的话是原字符串ASCII码小于‘F’则需要变换,否则不用变,但是看别人的wp的结果是数字不变,字母变。这里不明白,很奇怪。所以这里我们可以直接写出逆算法来解出:

1
2
3
4
5
6
7
8
9
str = '5BH8170528842F510K70EGH31F44M24B'
md5 = ''
for i in range(0,len(str)) :
if ord(str[i]) >= 65 :
s = ord(str[i]) - (i%10)
md5 += chr(s)
else :
md5 += str[i]
print md5

解出来的md5去网上解就可以解得:tima

这里我们再来看看之前所说的上面的md5的第四个函数,为什么是hex转为ASCII码呢,我们可以直接在网上看见decode(‘hex’)的代码实现:

6

来看看反汇编的:

7

简直一毛一样好吗,不过这里我在实践的时候又注意到一个问题,那就是python输出的格式问题:

8

这里所打印出的s是不是和我们想的有些不一样?因为0x5a不是应该打印出‘Z’对吗?为什么没打印出来?这我也不知道,我开始还以为是decode函数的问题,但是当我看见打印出的有p和D的时候,我就消除了这个疑虑了。

第二个函数:

第二个函数和第一个函数其实一样,就是第二个函数多了一个亦或的处理而已:

9

所以我们在第一个解密函数的基础上再加上一个亦或处理函数就可以了,在这之前还有一个ASCII码转换,所以我们要先ASCII转换再进行亦或,再decode(‘hex’),但是其实顺序都可以,因为ASCII转换再亦或的时候还要再变回十六进制。所以可以写解密脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cipher1 = "5BH8170528842F510K70EGH31F44M24B"
get1 = []
for i in xrange(len(cipher1)):
if ord(cipher1[i]) <= 0x39:
get1.append(cipher1[i])
else:
get1.append(chr(ord(cipher1[i]) - i % 10))
cipher2 = ''.join(get1).decode('hex')
print cipher2,len(cipher2)
print ''.join(get1)
xor = "92 84 3D A7 14 F2 FB 4B EE 8A C2 C3 76 68 13 1E".replace(' ', '').decode('hex')
get2 = []
for i in xrange(len(cipher2)):
get2.append(hex(ord(cipher2[i]) ^ ord(xor[i])))
print ''.join(map(lambda x: x[2:], get2))

第三个函数:

这个函数前半部分还是和第一第二函数一样的,多了一个输出flag文件的函数:

10

如果仍然用先前的方式去逆向解md5值的话,是解不出来的,所以应该是思路错了,往下看会发现多出来的函数是一个写flag文件的函数,flag文件内容的生成过程也可以看到,其实只取决于第三部分flag的第四、第五个字节,两个可见字符完全可以爆破了,生成一堆文件,并用python的filetype库进行文件格式识别。
别人的wp上说直接根据jpg格式的文件头(0xff 0xd8 0xff 0xe0)猜测出是jpg文件,然后得到一张jpg图片,发现是第三部分的flag。

dalao们还有一种思路是:
看见生成的原始flag文件

11

根据多年做misc的经验,感觉不会是txt文件,应该是二进制文件,具体是什么不好说。而且这还不是最后的文件,还未处理,但是有的值引起了我的注意。特别是9n这个值。如果是二进制文件的话,正常情况下不会有9n这种值重复多遍,有可能是00、ff这种或者其他的值。一开始分析了很久,后来突然想起来,这种xor的文件是有方法可以快速解的。很久以前用过python的xortool库,可以自动分析xor的密钥值和密钥长度。然后我就试了试。

·····接下来的就不细说了,因为这种方法没有成功

还有一种方式是这样的:
可以直接动态调试,然后动态patch,过掉hash匹配那步,然后就可以得到flag文件。(惊了!)
三段结合起来就是真正的flag。

支持一下
扫一扫,支持v1nke
  • 微信扫一扫
  • 支付宝扫一扫