tsx81428 发表于 2022-10-8 20:04:39

BinaryBombs(二进制炸弹实验)

实验介绍


[*]使用所学知识拆除Binary Bombs来增强对程序的机器级表示、汇编语言、调试器和逆向工程等理解。
[*]Binary Bombs(二进制炸弹)是一个可执行程序,是C语言编译链接成的,包含phase1~phase6共6个阶段(还有隐藏阶段)。
[*]各阶段要求输入一个答案,若正确,该阶段炸弹被拆除,否则爆炸。
[*]你需要拆除尽可能多的炸弹
[*]实验提供一个bomb.c和bomb可执行文件,但是,bomb.c中只有主函数,和一些彩蛋。
[*]bomb有一个命令行参数,为读入的文件。所以你可以将答案写入到一个txt文件,每个答案一行。
实验技巧

gdb调试


[*](gdb)info reg查看所有寄存器的信息
[*](gdb)info frame查看栈的信息
[*](gdb)b * 0x405040在0x405040处设置断点
[*](gdb)b phase_1在函数phase_1处设置断点
[*](gdb)x/2s 0x405010输出0x405010开始的两个字符串
[*](gdb)stepi执行一条指令
[*](gdb)nexti类似于stepi,但以函数调用为单位
[*](gdb)c继续(遇到断点后)
[*](gdb)run ans.txt命令行参数运行
[*](gdb)q退出
[*](gdb)finish运行到当前函数返回
[*](gdb)delete删除所有断点
[*](gdb)delete 5删除断点 5
[*](gdb)layout asm展示当前的汇编语言(非常的好用,ctrl + L 刷新)
[*](gdb)p *(int *) 0x405012输出位于地址0x405012的整数
[*](gdb)p $rax输出%rax的值
[*](gdb)p /x $rax以十六进制输出%rax的值
[*](gdb)p *(int *)($rbp + 0x8)输出地址%rbp + 0x8的整数
[*](gdb)disas phase_1反汇编phase_1函数
我的实验经验


[*]先反汇编objdump -d bomb > asm.txt。然后把asm.txt的内容复制粘贴到word。用word来看汇编语言,方便涂色标注
[*]一边分析汇编语言,一边利用gdb调试。
[*]先熟读CSAPP第三章,最好把习题做完
phase_1

密码如下:I am not part of the problem. I am a Republican.

破解过程:

https://pic1.imgdb.cn/item/63412a4316f2c2beb1745cee.png

[*]在phase_1函数处设置断点。
[*]随便输出一个答案,如 abcdef。
[*]观察断点信息,input_strings可知,答案确实是一个字符串。
[*]反汇编观察到 strings_not_equal,推测是在判断字符串是否相等。然后,test命令测试返回值,如果非0,则爆炸。
[*]0为真,1为假,那么非0对于strings_not_equal,应该是字符串不等,所以现在要找到那个与输出的字符串匹配的字符串。
[*]观察到,传递给寄存器%esi的值0x403150
[*]打印此处的字符串: x/2s 0x403150
[*]得到答案
汇编代码:

点击查看代码00000000004013f9 <phase_1>:
4013f9:        55                           push   %rbp
4013fa:        48 89 e5                     mov    %rsp,%rbp
4013fd:        be 50 31 40 00               mov    $0x403150,%esi
401402:        e8 3d 04 00 00               callq401844 <strings_not_equal>
401407:        85 c0                        test   %eax,%eax
401409:        75 02                        jne    40140d <phase_1+0x14>
40140b:        5d                           pop    %rbp
40140c:        c3                           retq   
40140d:        e8 2e 05 00 00               callq401940 <explode_bomb>
401412:        eb f7                        jmp    40140b <phase_1+0x12>****phase_2

密码如下:0 1 3 6 10 15

破解过程:

https://pic1.imgdb.cn/item/63412a4316f2c2beb1745d12.png
<ol>在phase_2设置断点。
运行,参数为ans.txt,其中写有刚刚得到的第一个的答案。
先随便输入,这里输入一个数 5。
反汇编观察,一开始调用了函数,那么可以先把输入改为6个数
继续观察下面的汇编语言,发现 -30(%rbp)不就是存放第一个数的位置吗?这里判断第一个数必须为0,否则炸弹爆炸
在后面,%ebx先赋值为1,然后判断是否大于5,是一个循环,然后根据输入的6个数,每轮打印发现规律。
得出代码:for(int i = 1; i > 31 + (c - b)] / 2 + b\).
化简一下,\(res = (c - b) / 2 + b\).
再看后面的分支,和分支的执行:
0000000000401414 <phase_2>:
401414:        55                           push   %rbp
401415:        48 89 e5                     mov    %rsp,%rbp
401418:        53                           push   %rbx
401419:        48 83 ec 28                  sub    $0x28,%rsp
40141d:        48 8d 75 d0                  lea    -0x30(%rbp),%rsi
401421:        e8 3c 05 00 00               callq401962 <read_six_numbers>
401426:        83 7d d0 00                  cmpl   $0x0,-0x30(%rbp)
40142a:        78 07                        js   401433 <phase_2+0x1f>
40142c:        bb 01 00 00 00               mov    $0x1,%ebx
401431:        eb 0f                        jmp    401442 <phase_2+0x2e>
401433:        e8 08 05 00 00               callq401940 <explode_bomb>
401438:        eb f2                        jmp    40142c <phase_2+0x18>
40143a:        e8 01 05 00 00               callq401940 <explode_bomb>
40143f:        83 c3 01                     add    $0x1,%ebx
401442:        83 fb 05                     cmp    $0x5,%ebx
401445:        7f 17                        jg   40145e <phase_2+0x4a>
401447:        48 63 c3                     movslq %ebx,%rax
40144a:        8d 53 ff                     lea    -0x1(%rbx),%edx
40144d:        48 63 d2                     movslq %edx,%rdx
401450:        89 d9                        mov    %ebx,%ecx
401452:        03 4c 95 d0                  add    -0x30(%rbp,%rdx,4),%ecx
401456:        39 4c 85 d0                  cmp    %ecx,-0x30(%rbp,%rax,4)
40145a:        74 e3                        je   40143f <phase_2+0x2b>
40145c:        eb dc                        jmp    40143a <phase_2+0x26>
40145e:        48 83 c4 28                  add    $0x28,%rsp
401462:        5b                           pop    %rbx
401463:        5d                           pop    %rbp
401464:        c3                           retq   
[*]现在从最终返回值5倒推一下:


[*]\(5 = 2 * 2 + 1\) ,                \(res = (14 - 0) / 2 + 0 = 7\)                当前func4(a, 0, 14, 7)   则递归func4(a, 8, 14, 7)
[*]\(2 = 2 * 1\)        ,                    \(res = (14 - 8) / 2 + 8 = 11\)       当前func4(a, 8, 14, 11) 则递归func4(a, 8, 10, 11)
[*]\(1 = 2 * 0 + 1\)         ,        \(res = (10 - 8) / 2 + 8 = 9\)               当前func4(a, 8, 10, 9)   则递归func4(a, 10, 10, 9)
[*]\(0 = 0\) ,递归终止条件,此时$ res = (10 - 10) / 2 + 10 = 10$
好,那么可以得出 a = 10

[*]则答案为 10, 5
汇编代码:

点击查看代码401489: 8b 45 fcmov-0x4(%rbp),%eax
40148c: 83 f8 07cmp$0x7,%eax
40148f: 77 7b   ja   40150c <phase_3+0xa7> phase_5

密码如下:ionefg

破解过程:


[*]设置断点,运行,反汇编
[*]观察到
4014cf: 39 45 f8                   cmp%eax,-0x8(%rbp)
4014d2: 74 05                   je4014d9 <phase_3+0x74>
4014d4: e8 67 04 00 00callq 401940 <explode_bomb>
4014d9: c9                      leaveq ​                        推测输入为字符串,且长度为6

[*]再看接下来一段
0000000000401465 <phase_3>:
401465:        55                           push   %rbp
401466:        48 89 e5                     mov    %rsp,%rbp
401469:        48 83 ec 10                  sub    $0x10,%rsp
40146d:        48 8d 4d f8                  lea    -0x8(%rbp),%rcx
401471:        48 8d 55 fc                  lea    -0x4(%rbp),%rdx
401475:        be 1f 33 40 00               mov    $0x40331f,%esi
40147a:        b8 00 00 00 00               mov    $0x0,%eax
40147f:        e8 8c fc ff ff               callq401110 <__isoc99_sscanf@plt>
401484:        83 f8 01                     cmp    $0x1,%eax
401487:        7e 11                        jle    40149a <phase_3+0x35>
401489:        8b 45 fc                     mov    -0x4(%rbp),%eax
40148c:        83 f8 07                     cmp    $0x7,%eax
40148f:        77 7b                        ja   40150c <phase_3+0xa7>
401491:        89 c0                        mov    %eax,%eax
401493:        ff 24 c5 c0 31 40 00         jmpq   *0x4031c0(,%rax,8)
40149a:        e8 a1 04 00 00               callq401940 <explode_bomb>
40149f:        eb e8                        jmp    401489 <phase_3+0x24>
4014a1:        b8 00 00 00 00               mov    $0x0,%eax
4014a6:        2d 7b 02 00 00               sub    $0x27b,%eax
4014ab:        05 2c 01 00 00               add    $0x12c,%eax
4014b0:        2d 60 03 00 00               sub    $0x360,%eax
4014b5:        05 60 03 00 00               add    $0x360,%eax
4014ba:        2d 60 03 00 00               sub    $0x360,%eax
4014bf:        05 60 03 00 00               add    $0x360,%eax
4014c4:        2d 60 03 00 00               sub    $0x360,%eax
4014c9:        83 7d fc 05                  cmpl   $0x5,-0x4(%rbp)
4014cd:        7f 05                        jg   4014d4 <phase_3+0x6f>
4014cf:        39 45 f8                     cmp    %eax,-0x8(%rbp)
4014d2:        74 05                        je   4014d9 <phase_3+0x74>
4014d4:        e8 67 04 00 00               callq401940 <explode_bomb>
4014d9:        c9                           leaveq
4014da:        c3                           retq   
4014db:        b8 95 02 00 00               mov    $0x295,%eax
4014e0:        eb c4                        jmp    4014a6 <phase_3+0x41>
4014e2:        b8 00 00 00 00               mov    $0x0,%eax
4014e7:        eb c2                        jmp    4014ab <phase_3+0x46>
4014e9:        b8 00 00 00 00               mov    $0x0,%eax
4014ee:        eb c0                        jmp    4014b0 <phase_3+0x4b>
4014f0:        b8 00 00 00 00               mov    $0x0,%eax
4014f5:        eb be                        jmp    4014b5 <phase_3+0x50>
4014f7:        b8 00 00 00 00               mov    $0x0,%eax
4014fc:        eb bc                        jmp    4014ba <phase_3+0x55>
4014fe:        b8 00 00 00 00               mov    $0x0,%eax
401503:        eb ba                        jmp    4014bf <phase_3+0x5a>
401505:        b8 00 00 00 00               mov    $0x0,%eax
40150a:        eb b8                        jmp    4014c4 <phase_3+0x5f>
40150c:        e8 2f 04 00 00               callq401940 <explode_bomb>
401511:        b8 00 00 00 00               mov    $0x0,%eax
401516:        eb b1                        jmp    4014c9 <phase_3+0x64>
[*]
401562: be 1f 33 40 00mov$0x40331f,%esi
401567: b8 00 00 00 00mov$0x0,%eax
40156c: e8 9f fb ff ffcallq 401110 <__isoc99_sscanf@plt>可以看出,它取出字符串中每一个字符,然后转为的一个数,然后从地址0x403200 加这个数的偏移量,然后取出一个东西,再把它放入栈的内存中,注意!这里的%dl说明是一个字节,那不还是字符嘛
好,先打印下0x403200处的字符串
https://pic1.imgdb.cn/item/63412a4b16f2c2beb1746a67.png
​                发现打印出的一段奇怪的字符串。
​                但是,根据刚刚分析出的的偏移量,我们取出前16个字符
​                得到:maduiersnfotvbyl

[*]再将断点设在循环内,每次打印出%dl , 发现对于输入的abcdef,得到了aduier的ASCII码,再联系一下ASCII码的十六进制,a 为0x61。和0xf做与运算得到 0x1 。
[*]发现,输出的字符串中的字符的ASCII码对0x60的偏移量 与 原字符串的字符的下标是相等的。
[*]继续向下看
401576:8b 45 fc   mov-0x4(%rbp),%eax
401579:85 c0      test%eax,%eax
40157b:78 05      js   401582 <phase_4+0x30>
40157d:83 f8 0e   cmp$0xe,%eax
401580:7e 05      jle401587 <phase_4+0x35>
401582:e8 b9 03 00 00callq 401940 <explode_bomb>
401587:ba 0e 00 00 00mov$0xe,%edx​                        发现又是字符串匹配,先看看0x4031ae处的字符串
https://pic1.imgdb.cn/item/63412a4b16f2c2beb1746a70.png
​                        根据前面得到的结论。先取出这些字符,看在原字符串中的下标。
​                        得到:9 15 14 5 6 7,然后加上0x60, 查阅ASCII码
​                        得到:ionefg
汇编代码:

点击查看代码401594:e8 7f ff ff ff callq 401518 <func4>
401599: 83 f8 05           cmp$0x5,%eax
40159c:75 06                   jne4015a4 <phase_4+0x52>phase_6

密码如下:2 6 4 3 1 5

破解过程:


[*]设置断点,运行,反汇编
[*]解读汇编代码知:

[*]读6个数
[*]二重循环,判断是否每个数大于6,判断是否和其他数相等。即,输入的应该为1~6的排列
[*]将每个数i转化为\(j = 7 – i\)
[*]取出链表的第j个元素的值,放入栈中
[*]遍历一遍放入栈的6个链表元素,判断是否为降序

[*]链表的发现:
40159e: 83 7d f8 05              cmpl$0x5,-0x8(%rbp)
4015a2: 74 05                         je   4015a9 <phase_4+0x57>
4015a4: e8 97 03 00 00           callq 401940 <explode_bomb>发现是链式结构,设置断点,打印出:
https://pic1.imgdb.cn/item/63412a4b16f2c2beb1746a7b.png
发现nodej也是在提示
第一个为链表值,第二个为链表游标,第三个为next指针

[*]那么,将链表值按降序排序,得到游标为5 1 3 4 6 2
[*]再,由 \(j = 7 – i\), 得到答案 2 6 4 3 1 5
汇编代码:

点击查看代码40151c: 89 d1         mov%edx,%ecx
40151e: 29 f1         sub%esi,%ecx
401520: 89 c8         mov%ecx,%eax
401522: c1 e8 1f      shr$0x1f,%eax// 逻辑右移31
401525:01c8         add%ecx,%eax                                                      401527: d1 f8         sar%eax //算术右移
401529: 01 f0         add%esi,%eaxsecret_phase

密码如下:47

破解过程:


[*]首先要找到入口,看phase_defused函数
if(a < res) func4(a, b, res – 1, res), res *= 2, return res
else if(a > res) func(a, res + 1, c, res), res = res * 2 + 1; return res
else return 0​       在0x401ad0处设置断点,然后打印出0x3c9c(%rip)
​        发现分别为 1 2 3 4 5 6
​        则可以推断出,要在6个炸弹都拆后才可以进入后边。
0000000000401518 <func4>:
401518:        55                           push   %rbp
401519:        48 89 e5                     mov    %rsp,%rbp
40151c:        89 d1                        mov    %edx,%ecx
40151e:        29 f1                        sub    %esi,%ecx
401520:        89 c8                        mov    %ecx,%eax
401522:        c1 e8 1f                     shr    $0x1f,%eax
401525:        01 c8                        add    %ecx,%eax
401527:        d1 f8                        sar    %eax
401529:        01 f0                        add    %esi,%eax
40152b:        39 f8                        cmp    %edi,%eax
40152d:        7f 09                        jg   401538 <func4+0x20>
40152f:        7c 13                        jl   401544 <func4+0x2c>
401531:        b8 00 00 00 00               mov    $0x0,%eax
401536:        5d                           pop    %rbp
401537:        c3                           retq   
401538:        8d 50 ff                     lea    -0x1(%rax),%edx
40153b:        e8 d8 ff ff ff               callq401518 <func4>
401540:        01 c0                        add    %eax,%eax
401542:        eb f2                        jmp    401536 <func4+0x1e>
401544:        8d 70 01                     lea    0x1(%rax),%esi
401547:        e8 cc ff ff ff               callq401518 <func4>
40154c:        8d 44 00 01                  lea    0x1(%rax,%rax,1),%eax
401550:        eb e4                        jmp    401536 <func4+0x1e>

0000000000401552 <phase_4>:
401552:        55                           push   %rbp
401553:        48 89 e5                     mov    %rsp,%rbp
401556:        48 83 ec 10                  sub    $0x10,%rsp
40155a:        48 8d 4d f8                  lea    -0x8(%rbp),%rcx
40155e:        48 8d 55 fc                  lea    -0x4(%rbp),%rdx
401562:        be 1f 33 40 00               mov    $0x40331f,%esi
401567:        b8 00 00 00 00               mov    $0x0,%eax
40156c:        e8 9f fb ff ff               callq401110 <__isoc99_sscanf@plt>
401571:        83 f8 02                     cmp    $0x2,%eax
401574:        75 0c                        jne    401582 <phase_4+0x30>
401576:        8b 45 fc                     mov    -0x4(%rbp),%eax
401579:        85 c0                        test   %eax,%eax
40157b:        78 05                        js   401582 <phase_4+0x30>
40157d:        83 f8 0e                     cmp    $0xe,%eax
401580:        7e 05                        jle    401587 <phase_4+0x35>
401582:        e8 b9 03 00 00               callq401940 <explode_bomb>
401587:        ba 0e 00 00 00               mov    $0xe,%edx
40158c:        be 00 00 00 00               mov    $0x0,%esi
401591:        8b 7d fc                     mov    -0x4(%rbp),%edi
401594:        e8 7f ff ff ff               callq401518 <func4>
401599:        83 f8 05                     cmp    $0x5,%eax
40159c:        75 06                        jne    4015a4 <phase_4+0x52>
40159e:        83 7d f8 05                  cmpl   $0x5,-0x8(%rbp)
4015a2:        74 05                        je   4015a9 <phase_4+0x57>
4015a4:        e8 97 03 00 00               callq401940 <explode_bomb>
4015a9:        c9                           leaveq
4015aa:        c3                           retq   先打印出这三个地址的字符串:
https://pic1.imgdb.cn/item/63412a4f16f2c2beb1747206.png
可以推断出,输入为两个整型变量和一个字符串。
且这个字符串必须为DrEvil。但是,phase_4和phase_3的输入都是两个整数
那么我们在判断字符串相等处,设置断点,打印出值观察:
https://pic1.imgdb.cn/item/63412a4f16f2c2beb174720a.png
10 和 5!
那么就确定为phase_4的答案后加上DrEvil

[*]成功进入隐藏关。
[*]看secret_phase函数
4015b7: e8 74 02 00 00           callq 401830 <string_length>
4015bc: 83 f8 06              cmp$0x6,%eax
4015bf: 75 24                         jne4015e5 <phase_5+0x3a>那么现在由返回值5逆推
4015c1: b8 00 00 00 00           mov$0x0,%eax
4015c6: 83 f8 05              cmp$0x5,%eax//循环了6次
4015c9: 7f 21                         jg   4015ec <phase_5+0x41>则可以调试打印出:
https://pic1.imgdb.cn/item/63412a4f16f2c2beb1747201.png

[*]\(0x2f = 47\)
汇编代码:

点击查看代码4015cb: 48 63 c8              movslq %eax,%rcx
4015ce: 0f b6 14 0b              movzbl (%rbx,%rcx,1),%edx
// 逐个取你输的字符
4015d2: 83 e2 0f                       and$0xf,%edx // 转为
4015d5: 0f b6 92 00 32 40 00movzbl 0x403200(%rdx),%edx
4015dc: 88 54 0d e9              mov%dl,-0x17(%rbp,%rcx,1)
4015e0: 83 c0 01              add$0x1,%eax 后记

做了一遍挺痛苦,然后写实验报告梳理了一遍思路,还是挺有收获的。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: BinaryBombs(二进制炸弹实验)