二进制炸弹的拆除——张渣渣_的学习记录(1)

张渣渣_的学习记录(1)之二进制炸弹的拆除

二进制炸弹闯关
我们学校计算机系统基础课程的大作业,现在我把自己做实验的整个过程贴在下面,希望大家对不足的地方加以指正。
(因为自己在学习的过程中还是有很多的不足,所以在之后的博客中,我会有一篇专门对这篇文章中不足的地方进行补充。

话不多说,我们直接开始!!!!!!

【大作业要求】
该大作业为闯关实验,共需破解7关。下载压缩文件,在Debian系统里进行解压缩,通过对可执行文件bomb反汇编,分析汇编代码并获取相关线索,从而破解每一关的输入内容,完成闯关。

【闯关结果】
1、闯关情况
在这里插入图片描述
2、破解运行结果
在这里插入图片描述图1 破解运行结果

【代码分析】
对成功破解阶段的代码给出分析说明。

阶段0
phase_0
在这里插入图片描述图2 phase_0源代码及分析

使用objdump生成bomb程序的汇编代码,下图将汇编代码定位在给出了第一关字符串对比的地方<phase_0>。可以看出在调用<string_not_equal>函数前,现将要参与对比的两个字符串压入栈中,push $0x804a1d7就是存放内置字符串的首地址,pushl 0x8(%ebp)是用户输入字符串的首地址。
在这里插入图片描述图3 phase_0 gdb调试

gdb进行调试,断点设置在b 72。这时根据汇编语句中发现的内置字符串首地址0x804a1d7,使用examine指令显示这个字符串为”Simplicity favors regularity.”。

在这里插入图片描述图4 phase_0通过
单步或继续执行后续的代码时输入这个字符串,结果显示成功过关。
第零关(phase_0)已破解!!!

阶段1
phase_1
在这里插入图片描述图5 phase_1源代码及分析

在这里插入图片描述图6 phase_1源代码及分析

先使用gdb查看第二关所需要输入的类型:
在这里插入图片描述图7 phase_1gdb查看输入格式

由gdb调试得知,在第二关需要输入的是两个整数。由于计算浮点数时出现计算问题,所以,在这一关采用查看寄存器内容的方法来解决。
此次需要使用的指令分别是:si;finish;disas;info registers
两次查看地址分别为0x080494f1和0x08049504

整个的过程如下:
先设置断点,然后在断点之前是要进行输入第零关和第一关的结果,因为两关之间无关联,所以节省时间第零关随便输入即可,到了第一关要根据gdb得到的格式输入。
第二步,再用si进行跳转,当出现80494ca这一行的调用函数语句的时候,用finifh指令。
第三步,调用完finish之后,先用空格使得整个的代码能完整的呈现出来,然后在左侧你可以通过一个小箭头看到当前代码执行的地方,观察整个的代码,找到两次比较出现的地址。
第四步,用si进行跳转,到第一次比较的地方的时候用info registers进行第一次查看。
第五步,查看到第一个数字之后,退出这一轮,重新进行第二次查看的过程。(往下翻,两张图之后有注意的点,一定要耐心看)
第六步,得到两个数字,进行验证。

在这里插入图片描述图8 查看寄存器内容得到第二关的通关码

在这里插入图片描述图9 查看寄存器内容得到第二关的通关码

这里非常需要注意的点是(虽然有点绕,但是我相信挑战拆弹实验的你一定能看懂):

要耐心哦!

当通过gdb得到了输入格式之后(以我自己的为例),在第一次的查看寄存器的内容的时候,需要输入的是两个任意的整数,这样就可以通过info registers查看我所需要输入的第一个数字,在第一个数字得到之后,要做的结束此次查看的过程,重新进入第二次查看寄存器的内容,前面设置断点等操作都一样,不同的是,当输入两个数字的时候,就必须先输入我刚得到的正确的数字,第二个数字就可以写一个任意的整数,然后用si进行跳转,用info registers语句查看。

(这样操作的原因是,第一个数字输入正确与否,之后的语句跳转都依赖它,如果第一个数字输入错误,那么接下来就会跳转到炸弹爆炸的语句,第一次查看寄存器的时候,我任意输入了两个整数,当我得知了第一个正确的数之后,如果继续,必然爆炸。)

验证第二关答案,结果显示已过关
在这里插入图片描述图10 phase_1通过

第一关(phase_1)已破解!!!

阶段2
在这里插入图片描述图11 phase_2源代码及分析

在这里插入图片描述图12 phase_2源代码及分析

注意注意注意哈!
这里一定要先找到输入数字是多少个,然后把循环条件找到,再进行运算就可以算出来了!
细节如下:
通过对源代码的分析,找到了它的循环条件和循环体,对其进行运算:
number[i]=number[i-2]/2+1
又知,初始数字为0xb2=178 即number[0]=178。
number[1]=178/2+1=90;
number[2]=90/2+1=46;
number[3]=46/2+1=24;
number[4]=24/2+1=13;
number[5]=13/2+1=7。
验证第三关所得答案,结果显示已过关。
在这里插入图片描述图13 phase_2通过

第二关(phase_2)已破解!!!

阶段3
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述图14 15 16 phase_3源代码及分析

在无法获得源程序的情况下,只能通过对可执行程序进行反汇编来获得程序的汇编代码。观察bomb.s对应的汇编代码,分析源程序的功能。
在这里插入图片描述图17 通过gdb查看确定输出两个整数

这里输入格式也可能是“%d %c %d"(我朋友的就是),但是都大同小异,只要初始条件和循环找得好,破解这一关就不难。

结合源代码可以发现,程序内部对将要输入的第一个数字的要求是减去52后的值小于9,第二个输入数字应该根据第一个输入的整数的值来判断程序转到哪个分支执行,从而确定第二个数字的值应该输入哪个。
假设输入值为55,然后通过计算在gdb中查看表基址。
在这里插入图片描述图18 gdb查看表基址

根据所找到的0x08049607在bomb.s中查看跳转,然后得到了对应的结果176,验证成功。
(一定要看好自己的跳转)
在这里插入图片描述图19 phase_3通过

第三关(phase_3)已破解!!!

阶段4

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述图20 21 22 23 phase_4和func4源代码及分析

gdb进行调试确保推算的数字是正确的。
在这里插入图片描述
在这里插入图片描述图24 25 验证推算的数字的正确性
这里其实我的方法更偏向于暴力拆解,整个过程类似于前文中的第一关,是查看寄存器内容得到的。(这里不足的地方我会通过之后的博客进行补充,或者有朋友有其他方法也可私信我,我们一起讨论呀!)

验证第四关的结果:
在这里插入图片描述图26 第四关破解

第四关(phase_4)已破解!!!

阶段5
在这里插入图片描述
在这里插入图片描述图27 28 phase_5源代码及分析

这里用到了一个循环,可能一开始会比较懵,所以我先利用gdb查看了代码中明地址中到底存放了啥,于是就有了下图:
在这里插入图片描述图29 第一个明地址中存放的内容

在这里插入图片描述
图30 第二个明地址中存放的内容

乍一看,这都是啥,仔细一看,第二个明地址中有的字符第一个都有,这说明啥?
于是我想到了循环、指针、和索引!
应该就是根据循环,在一堆字符中找几个字符的那种
然后又有了下图
在这里插入图片描述图31 明地址找索引

由图31得知,此关的通关密码为ichf`knl
验证结果正确:
在这里插入图片描述图32 phase_5通过

这里其实我见到的更多的是给定一个数字,然后找出小于另一个数字的八九个数字之和是给定的这个数字,然后类似于我手写的那种找索引,再看ASCII码表把数字翻译出来就可以了。
第五关(phase_5)已破解!!!

阶段6
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述图33 34 35 36 37 phase_6源代码及分析

在此关中,对源代码进行分析,发现最终输出的结果是按照升序排列数字然后输出:
在这里插入图片描述图38 设置断点然后查看

对所得数字进行验证,得知最后得结果为5 2 4 7 1 3 6
在这里插入图片描述图39 phase_6通过
(这里其实有一点小暴力拆解的意思,有兴趣的朋友可以和我一起讨论哈!)
第六关(phase_6)已破解!!!

阶段7
这里的阶段七是对隐藏关进行破解的,刚开始我其实没有发现这个,这个隐藏关是我朋友发现的。
在这里插入图片描述
在这里插入图片描述图40 41 隐藏关入口

对隐藏关中的汇编进行分析,然后再通过gdb查看明地址中得内容,最终可得知隐藏关的入口在phase_4,密码为mcReh
在这里插入图片描述图42 隐藏关密码及其格式

在这里包含了一个小点,隐藏关的密码是紧跟在两个整数之后的,结合之前的破解以及分析(我徒手使试出来的),第一种情况如果将隐藏关密码同时加在phase_1;phase_3;phase_4之后,隐藏关是可以进入的,但是如果在phase_1或者phase_3二者之一加上密码的时候,关卡可以通过,但是不能进入隐藏关,(也就是phase_4后面不加的话就不能进入隐藏关。)所以,第二种情况就是仅仅在phase_4之后加上隐藏关的密码是可以进入隐藏关的,这也是结合汇编分析出来的结果。

这里我的猜想是,指针扫描,是一个个扫的,格式相同的后面加东西,指针应该会扫出来,而且还觉得是对的,但是在格式不一样的后面加东西,指针就会认为你破解有误(srds这是我的猜想,有不同意见的可以和我交流)
在这里插入图片描述
在这里插入图片描述
图43 44 第一种和第二种情况的对比
(这里就有我的猜想的验证,不过不一定正确。)

冲向隐藏关
Secret_phase
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述图45 46 47 48 隐藏关

这里其实整的挺复杂,不过不要怕,咱们有gdb。
先找明地址,然后用gdb看看里面是啥。
在这里插入图片描述
在这里插入图片描述图49 50 gdb查看

然后我连带着代码一起分析出了以下内容:

A2+1=5 - ->A=2 即有 * A<B
A
2=2 -->A=1 有 * A>B
A*2+1=1 - ->A=0 即有 * A<B(假设fun7中调用的是A B)
三次递归中两次执行了 “若 * A<B 将(A+8) 作为地址进入递归”系列代码,一次执行了 “若 * A>b,将(A+4) 作为地址进入递归”系列代码。使用 gdb 查询储存值,发现:
0x2f=47

验证结果:
在这里插入图片描述图51 隐藏关破解

隐藏关(secret_phase)已破解!!!

整体通关图:
在这里插入图片描述图52 正式通关

到这里,所有的关卡都已经通过!!!

哇哈哈!二进制炸弹破解正式结束啦!总而言之就是希望对大家有帮助,如果有人想和我一起讨论这个实验的话,欢迎和我一起来玩呀!
——张渣渣_

猜你喜欢

转载自blog.csdn.net/weixin_45809643/article/details/106875783