首页
社区
课程
招聘
[原创]叹息之墙 writeup
发表于: 2018-10-1 23:12 5951

[原创]叹息之墙 writeup

2018-10-1 23:12
5951

拿到程序之后拖进ida,发现是一个控制流平坦化的混淆,而且其中夹杂了大量的辣鸡代码。

于是考虑跑一个trace,来分析程序的流程。

首先利用deflat.py,可以获得控制流平坦化中每一个基本块对应的地址。

获得地址之后,使用odscript来记录程序的执行流程,这里我程序的base是0x12B0000

拿到trace之后可以开始分析一些比较可疑的地方,首先是这里:

在trace记录中搜索,这个基本块也是只执行了一次,所以这里应该是获取用户输入的地方。

可以对这里下断点进行验证:

之后继续对trace进行分析,发现从12BD5A8

开始是一个循环,一共执行了6遍,于是猜测这里是对输入的字符串进行了一定的处理

而这个循环中包含了另一个可疑的区块:

这里使用了%d%n对输入的字符串进行了处理,于是猜测之后可能是直接使用%d录入的输入数字,于是对%d对应的内存区域下内存访问断点。后面会在这里断下来:

同样在trace里面查看,这里同样也执行了6次,这个基本块大致功能就是用snprintf(猜测)打印输入的字符串到另一个区域,相当于复制了一份输入,但是对那一片内存区域下访问断点之后没有断下来,所以猜测这里是一个没有任何作用的拷贝操作。

同样断下来的还有几个地方,但是经过分析之后都是一些没有任何作用的操作。

最后终于发现了一个有意义的操作:

在这里0x93fe40是输入的数字转成int之后储存的地址,这里把这个数作为索引到0x93f000取了一个数,并且以64位的大小累加到了[esi+0x3024]这个内存区域,于是对这个地方下一个内存访问断点。

最后可以在这里断下来:

在trace中查看发现这个基本块只执行了一次,并且在格式错误的情况下不会执行到,所以这里极有可能是验证的位置。这里调用了一个函数,并且把返回值与0x93f580这个地址进行了比较,于是这里尝试手动让这个条件成立:

可以发现程序成功输出了答案正确的提示,所以是验证函数没跑了。

于是我们需要分析的就是8A1020这个函数,直接看没法看出这个函数直接的作用。

分析引用后可以发现这个函数调用了aullrem这个函数,经过查询,这是一个64位取模的函数。所以对这个函数下断点,分析其调用方式。

发现8A1020调用了这个取模函数很多次,并且行为非常像快速幂算法。于是手动提取出模数进行验证,可以发现这个函数的功能就是pow(x,y,4288794511)。

到此为止,整个程序的算法就基本还原完成了,大致流程就是取输入的每一个数进行索引,并将索引到的元素求和,最后带入方程1702197298 ^ x mod 4288794511 = 1851878196进行验证。

反解的第一步就是求出1702197298 ^ x mod 4288794511 = 1851878196的解。

直接用sage解出方程

得到通解: x = 4288794510k + 1427250197

最后需要从351个数中选出不超过9个数让他们的和等于通解

所以这里直接用比较经典的背包问题思路去做:

最后就可以得到7个数:2144397255, 2450739720, 2859196340, 3027384360, 3958887240, 553392840, 1171109940, 1559561640, 857758902

按照索引从小到大排序就是17, 27, 60, 97, 133, 161, 243, 292, 309,按照格式输入即可。


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

收藏
免费 3
支持
分享
最新回复 (3)
雪    币: 14
活跃值: (60)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
tql
2018-12-5 11:36
0
雪    币: 8447
活跃值: (5041)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
3
牛逼 
2019-9-8 10:45
0
雪    币: 256
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
w.
4
tql
2019-9-19 15:20
0
游客
登录 | 注册 方可回帖
返回
//