记录一次学校实验Bomb Lab

技术30-11-2023

前言

这是学校的某课程的最终实验课。其实也就是大名鼎鼎的CS:APP Bomb Lab,即阅读汇编拆炸弹。
这也是我为什么要进行记录的原因。
实验预计耗时:学校给了20天的时间。
我的耗时约6小时:当天实验课+晚上睡前2小时+今天早上一小时(11.29-11.30)
使用工具:objdump+gdb(使用了插件pwndbg进行高亮)

建议:不借助任何高级的逆向工具,使用原生的objdump+gdb,这样才能达到本次实验的训练效果。

经验

本次实验有很多快速破题技巧,我在做到后面的时候,才开始觉悟。

一、炸弹一:字符串比较

通过读给出的C源代码,可以知道交互逻辑为读取、调用解析判断。
反编译定位main。
1.png找到第一个函数的地址,进入查看他的代码。
2.png
我们找到了比较的地址。接着就是去调试查看地址里面的内容。
3.png
输入验证,答案正确。
4.png

二、炸弹二:循环

继续上面的代码跟进,查看第二个实验的代码逻辑。
5.png
显然是读取6个数,然后循环判断,我们要过了这个炸弹,目标即绕过即可。重点关注比较的逻辑上下文,大体是,不能小于0,后面的话后一个元素等于前一个元素加索引。
于是构造数列:0, 1, 3, 6, 10, 15
验证!通过。
6.png

三、炸弹三:条件分支

继续审计代码。
7.png
这回代码的意思是条件分支,所以我们可以大体猜测他的逻辑就是:输入,匹配,通过。
所以我们可以从结果导向,从汇编出口开始,逆向追回整个可选分支链。
8.png
最终发现,最终的目标就是让分支赋值的变量,和我们的第二个参数一样,而第一个参数选择,分支。这样简单。我们随便选择构造一个即可。这里我选择0 464,验证通过。
9.png

四、炸弹四:递归

这题是递归,我的猜想是,显然是根据有一个回溯,然后根据返回结果来判断是否通过。我们审计汇编代码,也发现确实是如此。
11.png
这里调用了func4函数,要求返回结果为27,输入参数的话,要求第一个不能大于14,且第二个要。为27。那么我们来看一下func4函数的逻辑。
12.png
显然,他是一个双分支的回溯调用。因为对着猜数列太难了。所以直接写代码!
13.png
所以可行解为9 27,验证成功!
14.png

五、炸弹五:指针

听到这个标题,我的想法是考我们地址和地址里面的内容的区别,不知道是不是,看一下汇编。
15.png
看开头可以知道,参数限制长度为6.输入内容为字符串。
16.png
后面半段,主要是对字符串进行循环处理,然后比较判断。最终是一个值,这里用类ASCII编码的知识。最终绕过条件为值55。所以我们要构造。他对输出的处理如下:*arry++ & 0xF,而对值加的内容,是又另外一个数组。我们通过gdb去看这个数组内容。
17.png
我们选择0,1,2,4,5,6。接着就是什么字符0xf为这些索引了。直接写脚本吧。
18.png
最终验证成功!
19.png

六、炸弹六:链表/指针/结构体

还是老套路,直接看汇编代码。发现这次有点长,那就分段来看。
首先是第一个循环:
20.png
他的意思为:所有数不大于6,且两两不相等。
21.png
接着往下面看,可以发现,依旧是一个循环。
22.png
23.png
结合上面情况,可以知道是结合node在进行操作。
24.png
总结上面循环的作为为:根据输入数字的索引,取node里面取值存入新的数组中。然后下面的循环就是对节点进行链化操作。
25.png
最后是对链表进行检测,进行5次,每个小于后面即可绕过。故可解为6 3 1 5 4 2。验证通过。
26.png

七、炸弹七:彩蛋

在做上面那题过程中,其实我已经注意到了彩蛋。
1.png
且吸取上面的一些操作,下面解决非常快。我们快速溯源谁调用了他。发现是输出成功函数。
2.png
这里有一系列参数移动操作,我们定位看一下内容。发现就是炸弹4的输入嘛。
3.png
溯源触发条件。
4.png
是这样一个字符串。
1.png
目前,破解全部完成,接着就是常规老套路的读函数汇编了。
2.png
熟悉的感觉,一眼就是二叉树?为啥,因为我看到0xfffffffff,写算法题我经常这样操作。思路差不多这样。
3.png
观察到是一个二叉树。看树的内容。
1.png
画出图来观察,应该是下面这种情况。
2.png
因为如果找到n,返回0。递归左子树为2result,递归右子树为2result+1。而绕过条件如下:
3.png
所以遍历顺序的可选方式为右。即0x32.(50).验证通过。
1.png

感慨

6e2858b0bbaf943f2158cb95f0fbfe0.jpg

拍摄于我的另外一个实验室(学校有两个,这个比较少来)

现在是11月30日,11月的最后一天,而我的桌面日历是9月。这学期累爆了,周末也要上课,很多时候都在做一些无意义的事情,加上星期比赛忘记请假被记录旷课,内心对课内学习的压抑上到了极点。但有时候觉得自己这样其实也算好的,很多人为课内花费了比我更多的精力。我写实验是比较快的,这学期的实验我基本都是当天发实验,当堂就能结束。现在所有实验室课的作业都完成了,就差一个每天都要早八去打卡的Java实验,以及期末最后的课程实训。
可能过去我会把实验写得认真一些,但是自从我上学期写的代码,老师就只是简单跑一下输入输出之后,我便不在想花心思在课程实验。美其名曰课程设计,但是完全无视我在代码中运用的设计模式,无视我在程序中提升的鲁棒性。我觉得我花时间做一个完美的程序,也和其他同学一样。所以这学期我把大部分精力用来做自己的事情。去参加技术交流会。听了一些逆天发言,深感这种产学的脱轨。
不过有时候,想了想,其实当个纯朴的人也挺好的,你懂得多,能力大,你的烦恼就会更多。我挺希望自己比较无知,可以选择的东西少一些,这样我就不会太烦了。当一个纯朴的人,不在乎那么多,其实开开心心的,也过得不会那么差。对于我这种单核单线程的人来说,只能专注于一件事。大二我已经不想希望多自由了,希望大三的时候,不会卡我太多规划吧。

Author's photo

HuanXin-Chen

A tech enthusiast and avid sharer, this dream chaser firmly believes that great things will happen!

See other articles: