首页
社区
课程
招聘
[原创]【2019看雪CTF】Q3赛季 第十题:传家之宝 WP
发表于: 2019-9-25 00:53 5745

[原创]【2019看雪CTF】Q3赛季 第十题:传家之宝 WP

2019-9-25 00:53
5745

程序存在大量SMC,且嵌套多层,除最后一层外,每层功能包括四个功能:一是真实原指令功能;一是清除上层解码;一是对下层进行解码(范围为下层代码入口至全部代码结束);一是进行代码段及栈的迁移(数据及栈都在程序的代码段,紧接代码后)。每层代码中都有花指令,个别层还有反调试和反虚拟机。程序的输入在SMC代码外,输入后到程序输出校验结果不能随意停下。

开始看到代码有点蒙,对于每层代码结构不是很了解。手工调试了一段时间,摸索到了一点规律。
因为有代码段和栈的迁移,所以代码中不能硬编码绝对地址,都是相对当前EIP的相对偏移,所以取解码开始地址、取全局变量地址、EBP地址都是大多是根据当前EIP计算出来的,如下:

同时我们注意到只有计算解码地址和全局变量地址时,才用到ESI寄存器存储地址,而局部变量是根据EBP寻址的,代码段和栈迁移时都会计算出相应的EBP。最重要的一点是:解码代码不受解码前运行时寄存器及栈的影响

因为代码模式相对比较固定,结合上面的分析信息,对于解码就有了思路了,可以模拟运行或动态调试,跳过其它代码,只执行解码部分代码,解出全部指令。虽然代码有小调整,修正两次代码就OK了。用unicorn模拟运行,速度太慢,而后换了ida+windbg的debug方式。代码如下:

反调试就一种:rdtsc,发现调试修改局部变量值,还有两种反虚拟机的代码。
解码后将无用代码nop掉了。发现SMC部分开始到到校验前都在一个函数中:

直接创建函数,调整后,可以F5,伪代码形如:

本想弄出个去除编码与无用代码且运行正常的程序,对原程序进行patch,发现计算结果不正确,折腾了两天也没找出是哪patch多了或少了。于是放弃。继续任务主线,解题。

在解代码前,测试过。输入的只要改动一个bit都会致使最后计算结果大相径庭,当时怀疑有对称加密。从伪代码可以很容易得出加密算法是AES。主要特征有计算过程中用到的256字节表及替换操作,最明显的是有限域的乘法代码。

再将伪代码与AES算法进行对照,确定为AES算法无疑,只是作了修改。地址0x55E613开始的256字节表及后面的11组16字节表应该就是inv_sbox和round_key了。
很明显,add_round_key这部分被改了,行变换则没改。列混合变换一下一眼看不出来。调整了下伪代码,列出混合变换向量,发现列混合变换也没改。

找了份AES的加解密代码,按照伪代码修改出解密过程,测试计算结果正确,直接复制解密过程代码,行逆序,修改+-号,sbox就OK了。

对于此题有两点要说的:
1.2880层解码,有以量取胜的嫌疑,通常情况下做题者不喜。
2.只要模式较固定,脚本解码就有了可能。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
最新回复 (3)
雪    币: 8209
活跃值: (4518)
能力值: ( LV15,RANK:2473 )
在线值:
发帖
回帖
粉丝
2
关于smc解码,既然能写出恢复脚本,应该也不算以量取胜了
2019-9-25 10:25
0
雪    币: 10845
活跃值: (1054)
能力值: (RANK:190 )
在线值:
发帖
回帖
粉丝
3
此题原意是想通过2880层来迫使破解者写脚本破解(这应该不算违规吧)。
但实际上,有更令人惊奇的方法,连脚本都不要,就直接提取核心aes代码了
最后于 2019-9-25 12:31 被看场雪编辑 ,原因:
2019-9-25 12:31
0
雪    币: 13713
活跃值: (2851)
能力值: ( LV15,RANK:2663 )
在线值:
发帖
回帖
粉丝
4
看场雪 此题原意是想通过2880层来迫使破解者写脚本破解(这应该不算违规吧)。但实际上,有更令人惊奇的方法,连脚本都不要,就直接提取核心aes代码了
没说违规。我是说开始面对题目时的感觉。
2019-9-25 13:16
0
游客
登录 | 注册 方可回帖
返回
//