BinaryBombs(二进制炸弹实验)

打印 上一主题 下一主题

主题 525|帖子 525|积分 1575

实验介绍


  • 使用所学知识拆除Binary Bombs来增强对程序的机器级表示、汇编语言、调试器和逆向工程等理解。
  • Binary Bombs(二进制炸弹)是一个可执行程序,是C语言编译链接成的,包含phase1~phase6共6个阶段(还有隐藏阶段)。
  • 各阶段要求输入一个答案,若正确,该阶段炸弹被拆除,否则爆炸
  • 你需要拆除尽可能多的炸弹
  • 实验提供一个bomb.cbomb可执行文件,但是,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.

破解过程:



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

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

密码如下:0 1 3 6 10 15

破解过程:


<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\).
再看后面的分支,和分支的执行:
  1. 0000000000401414 <phase_2>:
  2.   401414:        55                           push   %rbp
  3.   401415:        48 89 e5                     mov    %rsp,%rbp
  4.   401418:        53                           push   %rbx
  5.   401419:        48 83 ec 28                  sub    $0x28,%rsp
  6.   40141d:        48 8d 75 d0                  lea    -0x30(%rbp),%rsi
  7.   401421:        e8 3c 05 00 00               callq  401962 <read_six_numbers>
  8.   401426:        83 7d d0 00                  cmpl   $0x0,-0x30(%rbp)
  9.   40142a:        78 07                        js     401433 <phase_2+0x1f>
  10.   40142c:        bb 01 00 00 00               mov    $0x1,%ebx
  11.   401431:        eb 0f                        jmp    401442 <phase_2+0x2e>
  12.   401433:        e8 08 05 00 00               callq  401940 <explode_bomb>
  13.   401438:        eb f2                        jmp    40142c <phase_2+0x18>
  14.   40143a:        e8 01 05 00 00               callq  401940 <explode_bomb>
  15.   40143f:        83 c3 01                     add    $0x1,%ebx
  16.   401442:        83 fb 05                     cmp    $0x5,%ebx
  17.   401445:        7f 17                        jg     40145e <phase_2+0x4a>
  18.   401447:        48 63 c3                     movslq %ebx,%rax
  19.   40144a:        8d 53 ff                     lea    -0x1(%rbx),%edx
  20.   40144d:        48 63 d2                     movslq %edx,%rdx
  21.   401450:        89 d9                        mov    %ebx,%ecx
  22.   401452:        03 4c 95 d0                  add    -0x30(%rbp,%rdx,4),%ecx
  23.   401456:        39 4c 85 d0                  cmp    %ecx,-0x30(%rbp,%rax,4)
  24.   40145a:        74 e3                        je     40143f <phase_2+0x2b>
  25.   40145c:        eb dc                        jmp    40143a <phase_2+0x26>
  26.   40145e:        48 83 c4 28                  add    $0x28,%rsp
  27.   401462:        5b                           pop    %rbx
  28.   401463:        5d                           pop    %rbp
  29.   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
汇编代码:

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

密码如下:ionefg

破解过程:


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

  • 再看接下来一段
  1. 0000000000401465 <phase_3>:
  2.   401465:        55                           push   %rbp
  3.   401466:        48 89 e5                     mov    %rsp,%rbp
  4.   401469:        48 83 ec 10                  sub    $0x10,%rsp
  5.   40146d:        48 8d 4d f8                  lea    -0x8(%rbp),%rcx
  6.   401471:        48 8d 55 fc                  lea    -0x4(%rbp),%rdx
  7.   401475:        be 1f 33 40 00               mov    $0x40331f,%esi
  8.   40147a:        b8 00 00 00 00               mov    $0x0,%eax
  9.   40147f:        e8 8c fc ff ff               callq  401110 <__isoc99_sscanf@plt>
  10.   401484:        83 f8 01                     cmp    $0x1,%eax
  11.   401487:        7e 11                        jle    40149a <phase_3+0x35>
  12.   401489:        8b 45 fc                     mov    -0x4(%rbp),%eax
  13.   40148c:        83 f8 07                     cmp    $0x7,%eax
  14.   40148f:        77 7b                        ja     40150c <phase_3+0xa7>
  15.   401491:        89 c0                        mov    %eax,%eax
  16.   401493:        ff 24 c5 c0 31 40 00         jmpq   *0x4031c0(,%rax,8)
  17.   40149a:        e8 a1 04 00 00               callq  401940 <explode_bomb>
  18.   40149f:        eb e8                        jmp    401489 <phase_3+0x24>
  19.   4014a1:        b8 00 00 00 00               mov    $0x0,%eax
  20.   4014a6:        2d 7b 02 00 00               sub    $0x27b,%eax
  21.   4014ab:        05 2c 01 00 00               add    $0x12c,%eax
  22.   4014b0:        2d 60 03 00 00               sub    $0x360,%eax
  23.   4014b5:        05 60 03 00 00               add    $0x360,%eax
  24.   4014ba:        2d 60 03 00 00               sub    $0x360,%eax
  25.   4014bf:        05 60 03 00 00               add    $0x360,%eax
  26.   4014c4:        2d 60 03 00 00               sub    $0x360,%eax
  27.   4014c9:        83 7d fc 05                  cmpl   $0x5,-0x4(%rbp)
  28.   4014cd:        7f 05                        jg     4014d4 <phase_3+0x6f>
  29.   4014cf:        39 45 f8                     cmp    %eax,-0x8(%rbp)
  30.   4014d2:        74 05                        je     4014d9 <phase_3+0x74>
  31.   4014d4:        e8 67 04 00 00               callq  401940 <explode_bomb>
  32.   4014d9:        c9                           leaveq
  33.   4014da:        c3                           retq   
  34.   4014db:        b8 95 02 00 00               mov    $0x295,%eax
  35.   4014e0:        eb c4                        jmp    4014a6 <phase_3+0x41>
  36.   4014e2:        b8 00 00 00 00               mov    $0x0,%eax
  37.   4014e7:        eb c2                        jmp    4014ab <phase_3+0x46>
  38.   4014e9:        b8 00 00 00 00               mov    $0x0,%eax
  39.   4014ee:        eb c0                        jmp    4014b0 <phase_3+0x4b>
  40.   4014f0:        b8 00 00 00 00               mov    $0x0,%eax
  41.   4014f5:        eb be                        jmp    4014b5 <phase_3+0x50>
  42.   4014f7:        b8 00 00 00 00               mov    $0x0,%eax
  43.   4014fc:        eb bc                        jmp    4014ba <phase_3+0x55>
  44.   4014fe:        b8 00 00 00 00               mov    $0x0,%eax
  45.   401503:        eb ba                        jmp    4014bf <phase_3+0x5a>
  46.   401505:        b8 00 00 00 00               mov    $0x0,%eax
  47.   40150a:        eb b8                        jmp    4014c4 <phase_3+0x5f>
  48.   40150c:        e8 2f 04 00 00               callq  401940 <explode_bomb>
  49.   401511:        b8 00 00 00 00               mov    $0x0,%eax
  50.   401516:        eb b1                        jmp    4014c9 <phase_3+0x64>
复制代码


  1. 401562: be 1f 33 40 00  mov  $0x40331f,%esi
  2. 401567: b8 00 00 00 00  mov  $0x0,%eax
  3. 40156c: e8 9f fb ff ff  callq 401110 <__isoc99_sscanf@plt>
复制代码
可以看出,它取出字符串中每一个字符,然后转为[0, 15]的一个数,然后从地址0x403200 加这个数的偏移量,然后取出一个东西,再把它放入栈的内存中,注意!这里的%dl说明是一个字节,那不还是字符嘛
好,先打印下0x403200处的字符串

​                发现打印出的一段奇怪的字符串。
​                但是,根据刚刚分析出的[0,15]的偏移量,我们取出前16个字符
​                得到:maduiersnfotvbyl

  • 再将断点设在循环内,每次打印出%dl , 发现对于输入的abcdef,得到了aduierASCII码,再联系一下ASCII码十六进制a0x61。和0xf运算得到 0x1
  • 发现,输出的字符串中的字符的ASCII码0x60的偏移量 与 原字符串的字符的下标是相等的。
  • 继续向下看
  1. 401576:8b 45 fc     mov  -0x4(%rbp),%eax
  2. 401579:85 c0      test  %eax,%eax
  3. 40157b:78 05      js   401582 <phase_4+0x30>
  4. 40157d:83 f8 0e     cmp  $0xe,%eax
  5. 401580:7e 05      jle  401587 <phase_4+0x35>
  6. 401582:e8 b9 03 00 00  callq 401940 <explode_bomb>
  7. 401587:ba 0e 00 00 00  mov  $0xe,%edx
复制代码
​                        发现又是字符串匹配,先看看0x4031ae处的字符串

​                        根据前面得到的结论。先取出这些字符,看在原字符串中的下标。
​                        得到:9 15 14 5 6 7,然后加上0x60, 查阅ASCII码
​                        得到:ionefg
汇编代码:

点击查看代码
  1. 401594:  e8 7f ff ff ff callq 401518 <func4>
  2. 401599: 83 f8 05             cmp  $0x5,%eax
  3. 40159c:  75 06                     jne  4015a4 <phase_4+0x52>
复制代码
phase_6

密码如下:2 6 4 3 1 5

破解过程:


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

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

  • 链表的发现:
  1. 40159e: 83 7d f8 05              cmpl  $0x5,-0x8(%rbp)
  2. 4015a2: 74 05                         je   4015a9 <phase_4+0x57>
  3. 4015a4: e8 97 03 00 00           callq 401940 <explode_bomb>
复制代码
发现是链式结构,设置断点,打印出:

发现nodej也是在提示
第一个为链表值,第二个为链表游标,第三个为next指针

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

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

密码如下:47

破解过程:


  • 首先要找到入口,看phase_defused函数
  1. if(a < res) func4(a, b, res – 1, res), res *= 2, return res
  2. else if(a > res) func(a, res + 1, c, res), res = res * 2 + 1; return res
  3. else return 0
复制代码
​         在0x401ad0处设置断点,然后打印出0x3c9c(%rip)
​        发现分别为 1 2 3 4 5 6
​        则可以推断出,要在6个炸弹都拆后才可以进入后边。
  1. 0000000000401518 <func4>:
  2.   401518:        55                           push   %rbp
  3.   401519:        48 89 e5                     mov    %rsp,%rbp
  4.   40151c:        89 d1                        mov    %edx,%ecx
  5.   40151e:        29 f1                        sub    %esi,%ecx
  6.   401520:        89 c8                        mov    %ecx,%eax
  7.   401522:        c1 e8 1f                     shr    $0x1f,%eax
  8.   401525:        01 c8                        add    %ecx,%eax
  9.   401527:        d1 f8                        sar    %eax
  10.   401529:        01 f0                        add    %esi,%eax
  11.   40152b:        39 f8                        cmp    %edi,%eax
  12.   40152d:        7f 09                        jg     401538 <func4+0x20>
  13.   40152f:        7c 13                        jl     401544 <func4+0x2c>
  14.   401531:        b8 00 00 00 00               mov    $0x0,%eax
  15.   401536:        5d                           pop    %rbp
  16.   401537:        c3                           retq   
  17.   401538:        8d 50 ff                     lea    -0x1(%rax),%edx
  18.   40153b:        e8 d8 ff ff ff               callq  401518 <func4>
  19.   401540:        01 c0                        add    %eax,%eax
  20.   401542:        eb f2                        jmp    401536 <func4+0x1e>
  21.   401544:        8d 70 01                     lea    0x1(%rax),%esi
  22.   401547:        e8 cc ff ff ff               callq  401518 <func4>
  23.   40154c:        8d 44 00 01                  lea    0x1(%rax,%rax,1),%eax
  24.   401550:        eb e4                        jmp    401536 <func4+0x1e>
  25. 0000000000401552 <phase_4>:
  26.   401552:        55                           push   %rbp
  27.   401553:        48 89 e5                     mov    %rsp,%rbp
  28.   401556:        48 83 ec 10                  sub    $0x10,%rsp
  29.   40155a:        48 8d 4d f8                  lea    -0x8(%rbp),%rcx
  30.   40155e:        48 8d 55 fc                  lea    -0x4(%rbp),%rdx
  31.   401562:        be 1f 33 40 00               mov    $0x40331f,%esi
  32.   401567:        b8 00 00 00 00               mov    $0x0,%eax
  33.   40156c:        e8 9f fb ff ff               callq  401110 <__isoc99_sscanf@plt>
  34.   401571:        83 f8 02                     cmp    $0x2,%eax
  35.   401574:        75 0c                        jne    401582 <phase_4+0x30>
  36.   401576:        8b 45 fc                     mov    -0x4(%rbp),%eax
  37.   401579:        85 c0                        test   %eax,%eax
  38.   40157b:        78 05                        js     401582 <phase_4+0x30>
  39.   40157d:        83 f8 0e                     cmp    $0xe,%eax
  40.   401580:        7e 05                        jle    401587 <phase_4+0x35>
  41.   401582:        e8 b9 03 00 00               callq  401940 <explode_bomb>
  42.   401587:        ba 0e 00 00 00               mov    $0xe,%edx
  43.   40158c:        be 00 00 00 00               mov    $0x0,%esi
  44.   401591:        8b 7d fc                     mov    -0x4(%rbp),%edi
  45.   401594:        e8 7f ff ff ff               callq  401518 <func4>
  46.   401599:        83 f8 05                     cmp    $0x5,%eax
  47.   40159c:        75 06                        jne    4015a4 <phase_4+0x52>
  48.   40159e:        83 7d f8 05                  cmpl   $0x5,-0x8(%rbp)
  49.   4015a2:        74 05                        je     4015a9 <phase_4+0x57>
  50.   4015a4:        e8 97 03 00 00               callq  401940 <explode_bomb>
  51.   4015a9:        c9                           leaveq
  52.   4015aa:        c3                           retq   
复制代码
先打印出这三个地址的字符串:

可以推断出,输入为两个整型变量和一个字符串。
且这个字符串必须为DrEvil。但是,phase_4phase_3的输入都是两个整数
那么我们在判断字符串相等处,设置断点,打印出值观察:

10 和 5!
那么就确定为phase_4的答案后加上DrEvil

  • 成功进入隐藏关。
  • secret_phase函数
  1. 4015b7: e8 74 02 00 00             callq 401830 <string_length>
  2. 4015bc: 83 f8 06                cmp  $0x6,%eax
  3. 4015bf: 75 24                         jne  4015e5 <phase_5+0x3a>
复制代码
那么现在由返回值5逆推
  1. 4015c1: b8 00 00 00 00             mov  $0x0,%eax
  2. 4015c6: 83 f8 05                cmp  $0x5,%eax//循环了6次
  3. 4015c9: 7f 21                         jg   4015ec <phase_5+0x41>
复制代码
则可以调试打印出:


  • \(0x2f = 47\)
汇编代码:

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

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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

tsx81428

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表