首页
学习
活动
专区
工具
TVP
发布

“红帽杯”其一逆向题分析

还记得五月份的“红帽杯”吗?

今天小编给大家细细讲解其中一道题目。

RE-CCM

题目

题目给出一个CCM.exe文件。

解题

①拿到 exe,扔进PEiD看看。

②加了nSPack 壳,先找个工具脱壳。脱壳后的文件拖进IDA,按 F5 看伪代码。

main函数逻辑很简单,就是确认输入的flag长度为42,再经过函数sub_401380处理,如果返回 1 就打印Right!,表示输入的flag正确。

③进入sub_401380分析。

这里一上来是一个反调试,总共三句GetTickCount(),因为只会影响到动态调试,不会影响静态分析,所以不用管。

比较重要的是几个函数调用,以及标签LABEL_15后的代码。先看第33行调用的sub_401320。

这个函数作用是以0x99为异或密钥检验输入flag的前五位是否为 flag{,并直接比对第14192429位是否为 -,以及最后一位是否为 }。

换句话说,输入的flag格式必须是 :

flag{????????-????-????-????-????????????}

其中 ? 是待确定字符。

⑤回到上一个函数,按程序流程走到第35行,进入sub_401280分析。

这个函数作用是用随机数种子0x556AAF49生成84个伪随机数,每个数模26映射到a-z 26个小写字母,再存到全局数组byte_403370中,作为后面加密替换的密码表之一。因为随机数种子固定,所以生成的伪随机数和密码表也是固定的,密码表为:

sxcunsbjptdunaaxklcvxsikxiewcmpwdngfqtfvomgkbwjrmccntqlratukzoafmngbyykjtabnhrnmweln

⑥回到上一个函数继续走,动态分配了两个数组,并在第41行将其中一个数组flag_hex_ary作为参数传入sub_4012C0,跟进去分析。

简单来说,这个函数作用是把输入的flag转换成十六进制字符串,例如字符串abc会转换成字符串616263616263abc三个字符的十六进制ASCII码)。转换后的字符串(严格来说没有结束符)存到传进来的数组中。注意,转换后的字符串长度是原来的两倍,即42*2=84字节;而且转换后字符串中字母全小写。

⑦回到上一个函数继续走,第48行以两个局部数组为参数调用了sub_401000,进入分析。

这个函数有两部分,功能一样,只是一个针对小写字母,一个针对大写字母,这里只截取了小写字母部分,后面的分析将会表明大写字母的部分是没用的。

这个函数的作用是生成两张维吉尼亚密码表,一张小写,一张大写,长这样(要用到的是小写的):

小写密码表会存到传入的局部数组subst_table_low,以备后面加密替换。

⑧回到上一个函数继续走,第49行调用了sub_401170,参数是转换过的十六进制字符串、两张维吉尼亚密码表、一个空数组,进入分析。

只截取了重要部分代码。这个函数对传进来的十六进制字符串加密,根据每个字符是数字还是字母分别处理:数字0123456789分别转换成GHIJKLMNOP,字母则调用函数sub_4010E0决定要替换成什么字符。加密后的字符串存到new_pass_table。限于篇幅,这里就不展开了,字母替换的规则简单来说就是在小写维吉尼亚密码表(由于前面生成十六进制字符串的算法中只会生成小写字母,所以大写维吉尼亚密码表其实没用到)第一行找到待替换字符所在列,再在第一列找到byte_403370[v7 % v9]这个字符所在行,行列交叉处的字符就是要替换成的字符。

⑨回到上一个函数,按流程走到第72行:

一开始while循环不会执行,先看到很长的那句,作用是比对全局数组dword_402160中的每个字节和v12 % 256与new_pass_table中每个字节的异或是否相等,不相等就返回-1,全部相等就跳到标签LABEL_17。我们的目的是使程序最后打印出Right!,从而确定正确的flag,所以要求if语句必须满足,即二者必须相等。

注意到异或运算的一个性质:如果A ^ B = C,那么A ^ C = B。现在已知dword_402160数组的内容和v12 % 256的值,可以反推出输入正确的flag时,new_pass_table中应该有的内容。再结合前面分析的加密算法,可以从new_pass_table再解密还原出正确的flag

⑩写了一段 C 代码,得到正确flag对应的new_pass_table内容是(都是十六进制数):

4d 4d 4d 75 4d 48 4d d3 4e 79 4a 4c 4a 4b 4d 4d 4a 50 4a 4b 4a 4d 4d e3 4a 4c 49 66 4d 4d 4a 50 4a 4c 4d 48 49 78 4a f3 4d 48 4a 47 4d 48 49 71 4d 49 4d 48 4a 4a 4a 03 49 76 4a 4e 4d 49 4a 48 4a 4e 4a 48 4d 48 4a 13 4d 4c 4d 4a 4d 48 4a 4f 4a 49 4e 65

看成ASCII码转成字符是:

MMMuMHM?NyJLJKMMJPJKJMM?JLIfMMJPJLMHIxJ?MHJGMHIqMIMHJJJ?IvJNMIJHJNJHMHJ?MLMJMHJOJINe

⑪其中问号是不可显示字符,是题目故意设置的障碍,要在标签LABEL_17中才能解出。先不管问号,把已知的部分按刚才分析的加密算法反过来做,大写字母还原回数字,小写字母还原回字母,就能得到:

66 6c 61 6? 7b 35 34 66 39 34 36 6? 35 2d 66 39 35 61 2d 3? 61 30 61 2d 62 61 33 3? 2d 37 62 31 37 31 61 3? 65 63 61 38 32 7d

看成ASCII码转成字符是:

fla?

由于已知 flag 前四位,第四位问号可以补出。剩下四位未知字符需要在标签LABEL_17中确定,据说是一个 CRC32 算法。但因为只有四位字符,运算量不大,我就直接爆破了。

⑫最后的 flag:

flag

总结

这道题其实比较走运,一是加的是著名的nSPack 壳,有通用脱壳工具可以脱,否则后面的分析都进行不下去;二是最后的四位字符可以爆破出来,不用去看复杂的 CRC32 算法。

逆向的题大概就是查壳脱壳,扔到IDA里分析,必要时OD辅助。刚开始接触逆向难免会因为代码太多、加密混淆太复杂而无所适从,是正常的,还是要多做题,积累经验。最后给大家推荐一个工具叫Signsrch,可以扫描 PE 和 ELF 文件,识别其中的加密或者编码算法,方便分析。

END

文案:黄翔

排版:黄浚杰

责编:许乐炜

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180611G1U3XM00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券