BOMB lab(phase_0 and phase_1)

Bomb(32bit)

Dr. Evil Incorporated (the PERPETRATOR) hereby grants you (the VICTIM) explicit permission to use this bomb (the BOMB).

This is a time limited license, which expires on the death of the VICTIM.

The PERPETRATOR takes no responsibility for damage, frustration, insanity, bug-eyes, carpal-tunnel syndrome, loss of sleep, or other harm to the VICTIM.

Unless the PERPETRATOR wants to take credit, that is.

The VICTIM may not distribute this bomb source code to any enemies of the PERPETRATOR. No VICTIM may debug, reverse-engineer, run “strings” on, decompile, decrypt, or use any other technique to gain knowledge of and defuse the BOMB.

BOMB proof clothing may not be worn when handling this program.

The PERPETRATOR will not apologize for the PERPETRATOR’s poor sense of humor.

This license is null and void where the BOMB is prohibited by law.

The next image is the changes in stack frame during procedure call

image-20201117000604340

The image blow is the entry parameters(入口参数) of the stack frame

image-20201117000852848

phase_0

Stage description: This stage requires the input of a byte sequence that matches a specific string built in the program

Main asm
 80492f1:       e8 90 0a 00 00          call   8049d86 <read_line> 
 80492f6:       89 45 f4                mov    %eax,-0xc(%ebp)
 80492f9:       83 ec 0c                sub    $0xc,%esp
 80492fc:       ff 75 f4                pushl  -0xc(%ebp)
 ;这里是输入的字符串,作为入口参数传递过去
 80492ff:       e8 50 01 00 00          call   8049454 <phase_0>
 8049304:       83 c4 10                add    $0x10,%esp
 8049307:       85 c0                   test   %eax,%eax
 8049309:       74 15                   je     8049320 <main+0xee>
 804930b:       e8 e2 0b 00 00          call   8049ef2 <phase_defused>
 8049310:       83 ec 0c                sub    $0xc,%esp
 8049313:       68 ac a0 04 08          push   $0x804a0ac
 8049318:       e8 73 fd ff ff          call   8049090 <puts@plt>
 804931d:       83 c4 10                add    $0x10,%esp
Phase_0
08049454 <phase_0>:
 8049454:       55                      push   %ebp
 8049455:       89 e5                   mov    %esp,%ebp
 8049457:       83 ec 08                sub    $0x8,%esp
 804945a:       83 ec 08                sub    $0x8,%esp
 804945d:       68 e0 a1 04 08          push   $0x804a1e0
 8049462:       ff 75 08                pushl  0x8(%ebp)   ;0x0804c260
 8049465:       e8 f7 07 00 00          call   8049c61 <strings_not_equal>;return address
 804946a:       83 c4 10                add    $0x10,%esp
 804946d:       85 c0                   test   %eax,%eax
 804946f:       74 0c                   je     804947d <phase_0+0x29>
 8049471:       e8 53 0a 00 00          call   8049ec9 <explode_bomb>
 8049476:       b8 00 00 00 00          mov    $0x0,%eax
 804947b:       eb 05                   jmp    8049482 <phase_0+0x2e>
 804947d:       b8 01 00 00 00          mov    $0x1,%eax
 8049482:       c9                      leave
 8049483:       c3                      ret

此时 GDB 调试该程序,进入 phase_0 函数内其 ebpesp 的如下

(gdb) i r esp ebp
esp            0xffffcfd0          0xffffcfd0
ebp            0xffffcfe8          0xffffcfe8

Here the stack frame is~~

image-20201119170650385
08049454 <phase_0>:
804945d:       68 e0 a1 04 08          push   $0x804a1e0
8049462:       ff 75 08                pushl  0x8(%ebp)   ;0x0804c260

The 0xffffcfd4 stored the 0x0804a1e0 where stored the specific string.

The 0xffffcfd0 stored the 0x0804c260 where stored the input string.

And then enter the string_not_equal function, here is the asm of this procedure call

String_not_equal
8049c61 <strings_not_equal>:
 8049c61:       55                      push   %ebp
 8049c62:       89 e5                   mov    %esp,%ebp
 8049c64:       53                      push   %ebx
 8049c65:       83 ec 10                sub    $0x10,%esp
 8049c68:       ff 75 08                pushl  0x8(%ebp);input string
 8049c6b:       e8 c5 ff ff ff          call   8049c35 <string_length>
 8049c70:       83 c4 04                add    $0x4,%esp
 8049c73:       89 c3                   mov    %eax,%ebx
 8049c75:       ff 75 0c                pushl  0xc(%ebp);specific string
 8049c78:       e8 b8 ff ff ff          call   8049c35 <string_length>
 8049c7d:       83 c4 04                add    $0x4,%esp
 8049c80:       39 c3                   cmp    %eax,%ebx;length equal?
 8049c82:       74 07                   je     8049c8b <strings_not_equal+0x2a>
 8049c84:       b8 01 00 00 00          mov    $0x1,%eax
 8049c89:       eb 3c                   jmp    8049cc7 <strings_not_equal+0x66>
 8049c8b:       8b 45 08                mov    0x8(%ebp),%eax
 8049c8e:       89 45 f8                mov    %eax,-0x8(%ebp);input string
 8049c91:       8b 45 0c                mov    0xc(%ebp),%eax
 8049c94:       89 45 f4                mov    %eax,-0xc(%ebp);specific string
 8049c97:       eb 1f                   jmp    8049cb8 <strings_not_equal+0x57>
 8049c99:       8b 45 f8                mov    -0x8(%ebp),%eax
 8049c9c:       0f b6 10                movzbl (%eax),%edx
 8049c9f:       8b 45 f4                mov    -0xc(%ebp),%eax
 8049ca2:       0f b6 00                movzbl (%eax),%eax
 8049ca5:       38 c2                   cmp    %al,%dl
 8049ca7:       74 07                   je     8049cb0 <strings_not_equal+0x4f>
 8049ca9:       b8 01 00 00 00          mov    $0x1,%eax
 8049cae:       eb 17                   jmp    8049cc7 <strings_not_equal+0x66>
 8049cb0:       83 45 f8 01             addl   $0x1,-0x8(%ebp)
 8049cb4:       83 45 f4 01             addl   $0x1,-0xc(%ebp)
 8049cb8:       8b 45 f8                mov    -0x8(%ebp),%eax
 8049cbb:       0f b6 00                movzbl (%eax),%eax
 8049cbe:       84 c0                   test   %al,%al
 8049cc0:       75 d7                   jne    8049c99 <strings_not_equal+0x38>
 8049cc2:       b8 00 00 00 00          mov    $0x0,%eax
 8049cc7:       8b 5d fc                mov    -0x4(%ebp),%ebx
 8049cca:       c9                      leave
 8049ccb:       c3                      ret

Break point in the 0x8049c6b which call 8049c35 <string_length>. Here is the stack frame in this time. And now the entry parameters is the input string address 0x0804c260

image-20201119170725833

So now we enter the string_length function~~

String_length
08049c35 <string_length>:
 8049c35:       55                      push   %ebp
 8049c36:       89 e5                   mov    %esp,%ebp
 8049c38:       83 ec 10                sub    $0x10,%esp 
 8049c3b:       8b 45 08                mov    0x8(%ebp),%eax;entry parameter
 8049c3e:       89 45 f8                mov    %eax,-0x8(%ebp);input string add
 8049c41:       c7 45 fc 00 00 00 00    movl   $0x0,-0x4(%ebp);Record times
 8049c48:       eb 08                   jmp    8049c52 <string_length+0x1d>
 8049c4a:       83 45 f8 01             addl   $0x1,-0x8(%ebp)
 8049c4e:       83 45 fc 01             addl   $0x1,-0x4(%ebp)
 8049c52:       8b 45 f8                mov    -0x8(%ebp),%eax
 8049c55:       0f b6 00                movzbl (%eax),%eax
 8049c58:       84 c0                   test   %al,%al
 8049c5a:       75 ee                   jne    8049c4a <string_length+0x15>
 8049c5c:       8b 45 fc                mov    -0x4(%ebp),%eax
 8049c5f:       c9                      leave
 8049c60:       c3                      ret

Always the first step of procedure call is push %ebp , this make the esp-=4 to get a new stack frame storage unit. And then execute mov %esp, %ebp, make ebp->(esp->)

image-20201119170749139

M[0x0804c260] is the ASCII for the input string. this function get one BYTE once, if this BYTE is not zero, that is mean not end, so inc the num and loop again. We can use the x/40xw to read 40 Word start from 0x0804c260. It can be found that it happened to be the string we entered.

The same we can get the specific string from the address 0x0804a1e0 as followers:

0x804a1e0:  0x65742041  0x6c207478  0x20656e69  0x61207369
0x804a1f0:  0x71657320  0x636e6575  0x666f2065  0x43534120
0x804a200:  0x63204949  0x61726168  0x72657463  0x25002e73;Little endian 73 2e 00

Keep it simple we can use (gdb)x/1s 0x0804a1e0 to display the specific string which is A text line is a sequence of ASCII characters.

phase_1

Stage description: We don’t anything about this stage, so we have to study step and step in assembly code

Main

Always in Main procedure call. It read a input string first and deliver it to phase_1 function as the entry parameters. And the %eax stored the return value of the phase_1 function, then if %eax equals 1, defused the BOMB!

 804931d:       83 c4 10                add    $0x10,%esp
 8049320:       e8 61 0a 00 00          call   8049d86 <read_line>
 8049325:       89 45 f4                mov    %eax,-0xc(%ebp)
 8049328:       83 ec 0c                sub    $0xc,%esp
 804932b:       ff 75 f4                pushl  -0xc(%ebp)
 804932e:       e8 51 01 00 00          call   8049484 <phase_1>
 8049333:       83 c4 10                add    $0x10,%esp
 8049336:       85 c0                   test   %eax,%eax
 8049338:       74 15                   je     804934f <main+0x11d>
 804933a:       e8 b3 0b 00 00          call   8049ef2 <phase_defused>

phase_1

And now let’s enter the phase_1 procedure call to Check it out.

08049484 <phase_1>:
 8049484:       55                      push   %ebp
 8049485:       89 e5                   mov    %esp,%ebp
 8049487:       83 ec 28                sub    $0x28,%esp
 804948a:       c7 45 f4 a1 84 76 09    movl   $0x97684a1,-0xc(%ebp)
 8049491:       db 45 f4                fildl  -0xc(%ebp)
 8049494:       dd 5d e8                fstpl  -0x18(%ebp)
 ;Prepare for the function call below
 8049497:       8d 45 e0                lea    -0x20(%ebp),%eax
 804949a:       50                      push   %eax
 804949b:       8d 45 e4                lea    -0x1c(%ebp),%eax
 804949e:       50                      push   %eax
 804949f:       68 0f a2 04 08          push   $0x804a20f;the 
 80494a4:       ff 75 08                pushl  0x8(%ebp);the input string
 80494a7:       e8 24 fc ff ff          call   80490d0 <__isoc99_sscanf@plt>

If you want to create a stack frame, you should push %ebp(old) and make the ebp point to esp.

The core of this assembly code is fildl and fstpl. fildl mean (double)int which convert int(32bit) to double(80bit) and stored in ST(0). fstpl mean pop the ST(0)(80bit) and stored in -0x18(%ebp)(64bit). we notice that it may cause accuracy loss(精度损失).

(gdb) x/4xw $ebp-0x18
0xffffd000:	0x42000000	0x41a2ed09	0xffffd028	0x097684a1
(gdb) x/fg $ebp-0x18
0xffffd000:	158762145
(gdb) x/dw $ebp-0xc
0xffffd00c:	158762145

It turns out that there is no loss of precision(精确度) in this question 😃

Ok, now we must be find What format string do we need. Next 4 instruct stored 2 address in stack frame. And then push $0x804a20f, what is this mean?🧐 Maybe we can found a clue in the process of using gdb.

(gdb) x/xw 0x0804a20f
0x804a20f:	0x25206425
(gdb) x/s 0x0804a20f
0x804a20f:	"%d %d"
(gdb) x/s 0x0804c2b0
0x804c2b0 <input_strings+80>:	"9 8"

Oh! Oh! Oh! Get it. The format of the input string. And %ebp+8 usually is the entry parameters of this procedure call. That is our input string.

The next instruct is call 80490d0 __isoc99_sscanf@plt. The sscanf is the C standard library functions.

int sscanf(const char *str, const char *format, ...)
return the number of successful matches and assignments

The first entry parameter is char *str, corresponding to the “9 8” we input. And the second entry parameter is char *format, corresponding to the “%d %d”.

  1. we can get the %eax which is the return value must be 2.
  2. we can konw -0x1c(%ebp) and -0x20(%ebp) is the address which stored the binary number(convert from the input string)

Now we can move to the next step.

 80494ac:       83 c4 10                add    $0x10,%esp
 80494af:       83 f8 02                cmp    $0x2,%eax
 80494b2:       74 0c                   je     80494c0 <phase_1+0x3c>
 80494b4:       e8 10 0a 00 00          call   8049ec9 <explode_bomb>
 80494b9:       b8 00 00 00 00          mov    $0x0,%eax
 80494be:       eb 2c                   jmp    80494ec <phase_1+0x68>
 80494c0:       8d 45 e8                lea    -0x18(%ebp),%eax
 80494c3:       8b 10                   mov    (%eax),%edx
 80494c5:       8b 45 e4                mov    -0x1c(%ebp),%eax
 80494c8:       39 c2                   cmp    %eax,%edx
 80494ca:       75 0f                   jne    80494db <phase_1+0x57>
 80494cc:       8d 45 e8                lea    -0x18(%ebp),%eax
 80494cf:       83 c0 04                add    $0x4,%eax
 80494d2:       8b 10                   mov    (%eax),%edx
 80494d4:       8b 45 e0                mov    -0x20(%ebp),%eax
 80494d7:       39 c2                   cmp    %eax,%edx
 80494d9:       74 0c                   je     80494e7 <phase_1+0x63>
 80494db:       e8 e9 09 00 00          call   8049ec9 <explode_bomb>
 80494e0:       b8 00 00 00 00          mov    $0x0,%eax
 80494e5:       eb 05                   jmp    80494ec <phase_1+0x68>
 80494e7:       b8 01 00 00 00          mov    $0x1,%eax
 80494ec:       c9                      leave
 80494ed:       c3                      ret

If the return value of the sccanf is not 2, it will explode the BOMB! Or je to 80494c0

(gdb) x/10xw $esp
0xffffcff0:	0x0804a3b7	0xf7fb0000	0x00000008	0x00000009
0xffffd000:	0x42000000	0x41a2ed09	0xffffd028	0x097684a1
(gdb) i r ebp esp
ebp            0xffffd018          0xffffd018
esp            0xffffcff0          0xffffcff0

The first input number stored in 0xffffcffc and the second input number stroed in 0xffffcff8

 80494c0:       8d 45 e8                lea    -0x18(%ebp),%eax
 80494c3:       8b 10                   mov    (%eax),%edx
 80494c5:       8b 45 e4                mov    -0x1c(%ebp),%eax
 80494c8:       39 c2                   cmp    %eax,%edx

Determine whether M[0xffffcffc] and M[0xffffd000] are equal.

And next Determine whether M[0xffffcff8] and M[0xffffd004] are equal

So the first number we input must be 0x42000000 and the next is 0x41a2ed09. Decimal is 1107296256 1101196553

Good job!🤪

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值