Phase_1
使用objdump -d查看汇编代码,打开bomb.s文件后,从main函数开始看,会发现存在好几个以Phase为开头的函数,大概就是对应着我们需要闯关的关卡。首先我们从phase_1开始分析。
这里就是phase_1的代码,我们可以发现80488db位置有一个call explode_bomb,这个应该就是引爆炸弹的位置。那前面的je指令应该就是跳过炸弹爆炸的条件。我们在phase_1处下断点。
程序停在了80488c0位置,单步执行。
执行到这里时,即将调用strings_not_equal函数,可以看到栈顶的两个参数分别为我们随机输入的123和一个字符串。而调用的函数名含义为判断string是否相同(不同),那么猜测就是将我们的输入和内存中的某个字符串进行比较。call之前内存出现了字符串”With great power comes great responsibility.“试一试。
answer1:With great power comes great responsibility.
Phase_2
首先和phase_1的步骤类似,在phase_2的位置下断点。
运行到phase_2时,先查看phase_2的汇编,发现80488f8位置有一个函数叫read_six_numbers,猜测这个炸弹的解法应该是输入合适的6个数字。先随便输入6个试试看:
直接运行到read_six_numbers函数,这个时候我们来看一下函数运行前后寄存器的值和内存中的值,理论上来说应该会将我们输入的这6个数 存入内存。
发现在call之后立刻进行了第一次的cmp,比较的对象是esp+18所指的数字和3,那么这个地址指的东西是什么呢?发现是我们输入的第一个数,所以第一个数应该是3。
同理,第二个数应该是5。
前两位过了以后,我们跳转到了
这个地址,会发现执行了两部之后又跳走了,
这里很明显,是取此时的两个数字进行相加,并与输入的第三个数字进行比较。由于是一个循环过程,我们猜测之后的过程应该也是这样的,所以我们尝试构造输入:
3 5 8 13 21 34 55
go next one!
Phase_3
首先查看一下汇编源码,主要观察有没有直接的调用函数。
call 8048600 __isoc99_sscanf@plt
会发现有一条这样的指令在Phase_3的开头就出现了,我们直接跑到这里看看发生了什么。
首先是$EAX被修改了。之后紧跟了一个cmp语句,所以这里应该就是第一个爆炸点。
我一开始输入了2个随机的数,不知道怎么就过了。。。我们就继续往下吧
然后就将一个数与7比较,如果比7大就boom,那我输入的是1,就继续往下。
从这里开始,将eax置为0,开始了漫长的计算。。。
我们直接去看结果吧...
好像变成了这个值,这个是多少呢?
0xfffffe39 = 1111 1111 1111 1111 1111 1110 0011 1001
由于第一步是将0减去一个正数,所以我们把这个结果当作有符号的整数处理。
0xfffffe39 = -455
继续往下运行发现,就是把这个数字和你输入的第二个值比较。
那么我们的输入就来了!
Phase_4
发现了一个不一样的调用就是func4,我们先解决前面的问题。
在phase_4位置下断点。同时,我们发现了跟phase_3相同的函数,运行到此处发现它提示我们要输入2个整数。随便输入两个好了:
1 2
就这两个吧。调用之后立刻比较了eax和2的大小,我们的输入通过了。
接下来将eax-2后与2比较大小,要想不爆炸,eax就应该<=4。那么eax是什么呢,其实就是我们输入的第二个整数。
根据__isoc99_sscanf@plt函数和之前的炸弹限制,我们可以把第二个输入确定为4。此时,在func4的后一句下一个断点,将第二个输入指定为4后,随便选一个数作为第一个输入,查看eax的值。
发现是0x30,换算一下就是48,所以我们的输入应该是:
48 4
Phase_5
做完实验发现,这涉及到了一个字典。。。
结果就是这样,但其实应该还有别的答案的。
汇编中其实是把6位的字符串输入当作一个偏移量,来对内存中某位置已经存在的字符串进行偏移。我的方法是,直接攻击出整个字典,也就是说输入a会得到什么,b会得到什么...
a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
a | d | u | i | e | r | s | n | f | o | t | v | b | y | l | m | a | d | u | i | e | r | s | n | f | o |
整个字典如上,问题自然就 迎刃而解了。
对了,还有一个问题是
从这里可以判断出,输入应该是一个6位的字符串类型。
answer:reldog
Phase_6
来到第六关,在查看了汇编代码之后发现代码比较长,这里我需要使用辅助工具来帮助我理解,使用的是IDA pro。直接将文件拖进IDA后使用伪源码功能(F5)查看源码,这里的源码在命名和指针方面也不是很清晰,主要是用来帮助理解汇编的。
首先是定义了很多变量,备注里标注的是这些变量对应的内存/寄存器。
接下来这一段,从代码本身看起来有些别扭,但大致看了一下之后进行动态调试就会发现,他是在规定输入的6个数字的范围。既不能相等也需要在1-6的整数范围内。所以将问题改为1-6的六个整数以某种方式输入,输入正确就可以解除炸弹。
这一段就是这六个数字究竟应该怎么排列的代码了。我们直接找到explode_bomb的位置,发现他是在比较result和v7所指的内容,再继续往上追踪发现,v7在循环开始时被v15赋值。那么v15又是什么呢?
*(&v15 + v2++) = (int)v4;
我们会看到这一段。因为输入无非就是1 2 3 4 5 6六个数字,我们一个一个带进去试试看。
当输入为1的时候,v15指向的是node1 + v2,v2取决于循环的次数。
当输入为2的时候,v15指向的是node1[2]+v2,虽然我这里的写法不是很规范,但大致意思就是从node1的位置向后寻址,并读数。
继续往后分析也是类似的,那么我们就会猜测出一个这样的框架。
最终决定输入的,应该是最右边那个值的排序顺序。
我选择查看一下node1-node6的所有值:
node1:0x0000000000000010000011b
node2:0x804b11c0000000200000069
node3:0x804b12800000003000002a6
node4:0x804b1340000000400000105
node5:0x804b1400000000500000320
node6:0x804b14c0000000600000178
会发现的是,node其实是一个链表指针的结构,前几位是下一个node对应的地址,后几位标注了node的编号,最后三位应该就是对应的值。
我们把node进行排序,根据最后三位的大小来试一试:
2<4<1<6<3<5
answer:2 4 1 6 3 5
成功!
Secret_phase
做到这里,我在IDA中发现了一个叫secret_phase的调用函数。根据关卡的命名,这个应该是一个隐藏关卡,可是按照之前的输入,并没有提示我进入。那到底该怎么进呢?
我们阅读之前的关卡伪源码会发现,还有一个调用的函数叫做phase_defused,阅读源码后发现应该是在第四关的时候,如果你的输入在多一个合适的字符串的话,就会在最后一关之后跳转到隐藏关卡。
好像就应该是DrEvil
试试看?
可以看到我们加了一个输入,最后就提示我进入了隐藏关卡了!
这里我们去查看一下隐藏关卡的拆弹方法...
可以看到有两个引爆条件,一个是v1>1001,另一个是fun7的返回值!=3。
v1比较好理解,他是read_line函数的返回值,也许只是将输入的字符串强制转化为int型并与1001比较,所以输入应该是1-1001的正整数。
关键是我们需要理解一下fun7的构造。
可以发现是一个递归函数。从secret_phase我们可以发现,我们需要的result应该是3,否则就会爆炸。
分析之后发现,这个fun7要想获得结果为3,只有一种情况:
2 * (2 * 0 + 1) + 1
含义是,第一次进入时,*a < b;第二次 *(a + 8) < b;第三次 *(a+16) == b。
我们会发现,secret_phase在调用fun7的时候传入的参数为(int&n1,v1),v1就是我们的输入,我们可以在IDA中双击&n1,查看一下对应地址的结构。
![图片.png](https://upload-images.jianshu.io/upload_images/17084259-0bee96264e68b371.png?imageMogr2/auto-orient
就在这个位置开始,从fun7中可以看到有两种判别方法,一种是 *(a+4) 一种是 *(a+8),这里对应的也是一样。所以我们可以根据
第一次进入时,*a < b;第二次 *(a + 8) < b;第三次 *(a+16) == b
这个判断,从地址中寻找数字。
结论如下:
input > 0x24; input >0x32; input == 0x6b == 107/strip%7CimageView2/2/w/1240)
终于!我们保卫了国家,拆除了炸弹!!!