首页
社区
课程
招聘
[原创]阿里2015第二届安全挑战赛第三题题解
发表于: 2020-7-5 19:06 13960

[原创]阿里2015第二届安全挑战赛第三题题解

2020-7-5 19:06
13960

这里有这题的解答,这位大佬通过分析IDA Trace分析出算法逻辑,然后写出逆向算法,求得答案。实在强大。不过这解法太考验耐性了,我的想法还是尽可能的过掉混淆,还原出代码真实面目,然后分析算法。所以,我的解法就是先去除混淆,然后通过动态分析,定位到关键代码后,再还原算法。

接下来的内容分两部分,反混淆,包括机器代码和ollvm的反混淆和算法分析。

后端混淆包含一个后端实现的控制流平坦混淆(CFF)和几组隐藏函数调用,无条件跳转,全局变量,常量引用的花指令。

不了解控制流程平坦混淆反混淆的朋友可以先自行研究下ollvm的反混淆。后端实现的CFF反混淆做法和ir实现的是通用的,
我们都需要先获取块编号到真实块地址的映射关系,然后将跳转到分发器的边修改为真实代码的块。

先看下外层CFF混淆。

任意混淆后的函数都有类似下面的入口:

最后一行跳转,最终走到下面的代码片段

为了弄清这个代码片段的作用,我使用miasm进行符号执行

可以看到,执行该代码片段之后,会恢复R0, R1, LR,平衡栈,并跳转到

这其实就是把 LR_init + 4作为跳转表基址, R0为索引的switch-case实现。把

代入,可计算得跳转目标0xF738 + @32[0x10BE4] = 0xF738 + 0x97DC = 0x18F14

在这块代码最后,设置R0后又跳转回函数入口。计算0x5AA的目标块地址为0x00019B68

经过上面简单分析,我们知道这个crackme的最外层有如下结构

这是个典型的CFF混淆。我们只需要遍历跳转表,将各case最后的跳转指令定向到真实的块,就完成了外层的CFF反混淆。要遍历跳转表,我们还得知道跳转表的大小。
我是通过第一个case的地址计算的

即第一个((case的偏移地址 - 4) / 4)就是跳转表大小。
处理完之后,我们尝试在0x0000F72C创建新函数(快捷键p),发现部分代码已经恢复,但是反编译出来的代码还不完整。

发现有如下代码干扰的IDA的分析:

使用miasm辅助分析00001F80

现在可以知道000199A2-000199A8的作用是加载一个常量到R0,然后跳转到LR_init + 4继续执行。
直接使用movw, movt拼接这个常量到r0就可以去除该混淆。清理后的代码:

crackme里面还有几组类似的混淆,通过前面的CFF反混淆,我们已经知道各case块的起始地址,进而可以计算出case块的大小,遍历case块中的所有指令,使用简单的模式匹配就可以去除所有的后端混淆。

感兴趣的朋友可以自行分析。附件包含我清除后端混淆后的二进制和完整的ida脚本。

后端混淆清理完之后,就可以IDA反编译所有函数了。

反混淆前的代码:
反混淆前的代码
反混淆后的效果:
反混淆后的效果

在IDA中随意反编译一个函数,发现这crackme还有ollvm的混淆等着我们,控制流平坦,指令替换,假分支一个都不少。
网上关于ollvm反混淆的研究已经很多了,相信大家都有自己反混淆方案,或Unicorn,或符号执行。下面简单介绍我使用的方法。

我之前的方案是使用Binary Ninja进行控制流平坦反混淆,但只支持arm64,而这里的crackme是32位,用不上。
使用IDA的微码进行反流程平坦混淆应该是一种通用的,跟体系无关的方案。我也尝试过使用IDA微码进行反混淆,在经历无数次修改微码IDA崩溃后,我崩溃了,彻底放弃修改微码这条路。
考虑到以后分析虚拟机保护的代码,我觉得还有必要维护自己的一个反编译器,看比较高级控制流结构的伪码总比看汇编效率高,所以决定自己实现反编译器。

这次的控制流平坦的反混淆就是用的我自己的反编译器进行的。反混淆的流程如下

之前不好处理的case,现在自己的IR上就很好办了。

难以处理case

我的做法是使用指令和代码块复制,把他们转换成下面样子:
处理好之后

经过处理之后,就可以统一的把跳转到BB_0012的指令修改为r0_10对应的代码块了。

当然还是有无法处理的case
无法处理

这里使用变量对state进行更新。

指令替换在我自己的IR上进行,IDA已经帮我做好表达式传播,我只需进行简单的模式匹配就可以对表达式进行化简。如

我当前实现的反编译器还只具备非常有限的优化能力,为了使用IDA的优化能力,假分支的反混淆是用Binary ninja进行分析和patch,然后把结果导入IDA。
假分支的识别在Binary Ninja MLIL的SSA形式上进行。
如对于下面指令序列,x为全局变量

判断c & 1是否是不透明的谓词的步骤

附件包含反混淆前后的两个关键,反混淆的效果我还是很满意的,当然还有巨大的改进空间。

之前一些关于这个crackme的分析都是基于IDA trace, 而我则是试水我的内存trace工具,测试他是否能处理现实中程序。
逆向的时候有两个非常常见的需求,找到数据在哪被使用和相关数据的来源。对于这个crackme就是找到我们输入的座位编号在哪被处理,处理过程中用到的数据来源。

为了解决两问题,我实现了自己的内存读写trace工具,这个工具可以记录每条指令对内存读写的地址和内容。

打开附件libcrackme-clean-memory-trace.txt,输入座位号"zzzzzzzzszzzzzzz",马上定位到关键函数sub_F72C。

搜索地址0xb4b39400,它有如下引用

打开附件sub_F72C_check-deobfuscated.c,0x0001877d位于一个循环内,循环256次

每次循环读取的地址和内容,都可以在trace找到:

一次迭代对输入的处理过程:

人肉化简anonymous2

最后在0x00014a28写入结果,首次写入的地址和内容

这个循环对应Python伪码

同样,在trace文件过滤出0xbea4aca0就可以找到对他的处理过程。

依次分析对这个地址的写入内容,就可以弄清整个算法处理过程。

这个crackme使用的算法是应该是rc4,sbox使用0xf6f8开始代码构建,使用sbox解密0x2d01c,256字节大小的密文即可得到座位号,与标准rc4差异是,
在跟sbox异或前后多了对数据进行循环位移或者加密的操作。

可以看到,通过内存trace,我们可以很快就定位到关键代码,再结合反混淆后的伪码,这道压轴题已经变成送分题了。

对算法细节有兴趣的朋友可以结合附件trace,伪码里面关键点注释和solve.py,自行分析。

附件内容:

以上内容均可从我的github仓库获取:msc2-crackme3

 
 

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 10
支持
分享
最新回复 (15)
雪    币: 2141
活跃值: (7226)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
2
表哥牛比
2020-7-5 20:42
0
雪    币: 4005
活跃值: (2183)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
niu bi
2020-7-5 22:24
0
雪    币: 4883
活跃值: (18890)
能力值: ( LV13,RANK:317 )
在线值:
发帖
回帖
粉丝
4
学习了
2020-7-6 07:22
0
雪    币: 1237
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
大佬,我的so文件分析几乎一窍不通啊。有没有好的由浅入深的学习方案和教材啊
2020-7-6 09:47
0
雪    币: 2335
活跃值: (1319)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
6
大佬的内存trace工具和反编译器呢 
2020-7-6 10:05
0
雪    币: 8447
活跃值: (5041)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
7
我什么时候才能像你一样强啊
2020-7-6 10:48
0
雪    币: 3358
活跃值: (3383)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
8
厉害啊
2020-7-6 15:31
0
雪    币: 3818
活跃值: (4228)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
9
dumBball 大佬,我的so文件分析几乎一窍不通啊。有没有好的由浅入深的学习方案和教材啊
我是在工作中慢慢积累的,没有系统看过什么逆向教材。
2020-7-6 19:56
0
雪    币: 3818
活跃值: (4228)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
10
FraMeQ 大佬的内存trace工具和反编译器呢 [em_6]
不开源
2020-7-6 19:57
0
雪    币: 210
活跃值: (631)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
11
收藏+评论=学会了
2020-7-7 09:30
0
雪    币: 977
活跃值: (435)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
12
我什么时候才能像你一样强啊
2020-7-7 10:06
0
雪    币: 268
活跃值: (630)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
13
这也太强了吧
2020-7-13 18:10
0
雪    币: 2231
活跃值: (1078)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
我什么时候才能像你一样强啊
2021-5-24 10:49
0
雪    币: 44
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
大哥能不能简单说一下你那个内存trace的原理
2022-3-22 11:28
0
雪    币: 10
活跃值: (774)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16

很有启发

最后于 2022-6-20 19:58 被Runope编辑 ,原因: 已解决
2022-6-20 19:32
0
游客
登录 | 注册 方可回帖
返回
//