目 录
第3章 各阶段炸弹破解与分析............................................................................. - 5 -
3.7 阶段7的破解与分析(隐藏阶段).................................................................. - 6 -
第3章 各阶段炸弹破解与分析
3.1 阶段1的破解与分析
密码如下:I am not part of the problem. I am a Republican.
破解过程:
通过阅读bomb,b可以初步确定第一个炸弹的判断在phase1中,因而上图给出了phase1的汇编,对phase1分析一下就会发现,其是将
%edi(初始输入的字符串)和之后又拿去的%esi(字符串)两个参数带入到strings not equal,比较是否一致,那么肯定我们想要的就在这个0x403150中,
使用gdb看一下就可以了
可以看到,这个地址就是答案。
3.2 阶段2的破解与分析
密码如下:1 2 4 8 16 32
破解过程:
和阶段1一样,显然阶段2就是phase_2
首先分析一下,可以通过read_six_numbers这个函数看出来,这个phase2是要我们输入六个数字
然后继续分析,首先这里出现了第一个判断,这个判断如果一旦成立,则直接爆炸,所以不让炸弹爆炸,这个必须满足,看一下条件,就是rbp-0x30的值是1,即第一值必须是1,接下来从40122c到401447可以发现是在执行一个循环,循环在遍历这6个数,并执行前一个数*2(加两次这个操作)和下一个数比较(401455),这个比较同样重要,如果出错一个,就全错,即1后面的每个数都必须是前一个数的2倍,ok
直接就是答案 1 2 4 8 16 32
3.3 阶段3的破解与分析
密码如下:2 558
破解过程:同样,阶段3直接去phase_3中去找
这个里面首先可以看到一个sscanf的库函数,而我们直到,这个函数很简单,就是按照指定格式读取内容并作为eax返回,显然,从401483里面的内容可以看出来,这个eax不应该小于1,不可以大于7,如果可以满足这个要求,就可以从401492的无条件跳转指令直接跳到一个地址,但这个地址是什么?直接用gdb看看
这个后面看似好像没啥,但你仔细和后面的那一堆跳转指令的地址对应一下,好了,这不就是个jump table吗 那就简单了,要我输入具体的case,然后看case和最后的值是不是对应不就完了,所以答案为
2 558
3 3b2
4 2e7
5 38c
6 11b
7 cc
8 0
9 15d
3.4 阶段4的破解与分析
密码如下:20x x(4>=x>1) DrEvil
破解过程:这个同样直接看phase_4
大致一看发现还调用了fun4所以
现在再看看phase_4
他要求输入的第二个参数必须保持在2,4之间,否则直接爆炸,那第一个呢,第一个在fun4中出来,也就是说如果fun4最后出来的函数是输入的第一个参数则成功,这个时候就必须对fun4进行细致阅读了,最后总结成下面这个:
前半个递归
edi=rdi-6;5,4,3,2,1直到1时
r12d=edi=6,5,4,3,2,1;
ebx=esi=第1个参数;
中间:eax=esi
后半个递归:
edi=1:给一个esi
edi=2:r13d=rax(前半个递归的1给的)+rbx*1=2*esi
edi=r12-2=0;
esi=esi(最初始的esi)
eax=2*esi+0
edi=3:r13d=rax(2给的是0)+rbx*1=2+1+1=4
edi=1;
esi=esi;
edi-1=0;
eax=4esi
edi=4:r13d=4+1+2=7
edi=2;
esi=esi;
edi=1;
edi=5:r13d=7+1+4=12
edi=3;
esi=esi;
edi=2;
edi=6:r13d=12+1+7=20
edi=4
综上可以发现,最后出来的一定是进入参数的20倍,所以答案
40,2;
60,3
80,4均可,置于后面的彩蛋到最后一起讲
3.5 阶段5的破解与分析
密码如下:5 115
破解过程:
这道题直接看phase_5,看起来还挺简单,不多,直接阅读,首先还是只有两个参数edi,esi并调用sscanf函数读取,但是要注意,第一个参数不可以小于等于1,否则直接爆炸,接下来从4015ab到4015cb有点不知道在干什么,没关系,下一句我知道,直接用gdb看内容
Gdb:
可以看到,这不就是个数组吗,在回头瞅一眼前面的,ok,就是说要遍历15次,将这个数组一个不拉的全部取完,重点在于最后结束的时候是看f也就是说前14次不可以出现f,就有下面这个唯一路
403224(6)<-403256(e)<-403208(2)<-403204(1)<-403240(a)<-403200(0)<-403232(8)<-403216(4)<-403236(9)<-403252(d)<-403244(b)<-403228(7)<-403212(3)<-403248(c)<-403220(5)
所以,答案 5 115
3.6 阶段6的破解与分析
密码如下:6 4 1 2 3 5
破解过程:同样直接上汇编
首先,光看汇编就可以发现,这第六个不好整,我看了几遍发现了一个点0x4052d0这个地址,为啥始终要用这个地址呢?,直接开看
Gdb:
证明方向对了,在看一下后面的内容,这有一个十分重要的判断,证明后面选的值必须要比前面小,否则直接爆炸,那此时就知道那个6个数字序列是什么了,就是给这个递减序列排顺序。
那就简单了,但还要注意最后一点,就是输入和压栈相反,所以递减序列的序号反过来就对了:
答案:6 4 1 2 3 5
3.7 阶段7的破解与分析(隐藏阶段)
密码如下:22/20
破解过程:此时再看一下bomb.c函数里面有没有什么遗忘了的,有这样一句话:
?看来有彩蛋,其实前面翻看汇编的时候就可看到secret_phase了,那这个彩蛋是怎么进去的呢?直接对所有汇编搜索:
原来是在一直没有看的phase_defused里面,但是,这个函数也不是简单直接调用secret_phase,分析一波:
首先就是这个0x3cb6(rip)和6比较,不应该啊,这个函数有没有参数,为什么要和6比较呢?,直接gdb看这个里面存的是什么,又是在这6个阶段里面怎么变化的
结论看来一目了然,正是必须要走过6个阶段才可以,同样,后面的优势string not equal 和第一个一样直接看到的是DrEvil,所以只需要在阶段4的答案后面给出DrEvil,并正确给出6个答案,就可以开启隐藏关;
现在再来看看secret_phase和fun7
这里面很简短,从secret_phase中的atoi可以看出来,只需要出入一个数字即可,之后调用fun7,只要fun7返回的值是2就胜利,那么剩下的问题就是如何让fun7返回2呢?
采用从后往前推的方法,如果eax=2,那么上一次就必须放回1,并经过2*1,如果上一次返回1,那么上上一次就必须返回0,而我为什么敢于直接从后开始呢,因为如果看一下ox4050f0里面的内容就知道了,又是node,又将大小分成2部分遍历,那这不就是二叉树的遍历吗,直接画出来
如下:
好了,再根据刚才推的可以知道,先从0(根节点开始)-右>左,所以答案是
20/22