溢出攻击测试

来源:互联网 发布:成都数据库培训 编辑:程序博客网 时间:2024/04/28 13:50

      缓冲区溢出漏洞出现已经好多年了,但直至今日仍然有用武之地,可见实在是经典之至啊!实践一把,写一个简单的程序:
test.c:
#include<stdio.h>
int main()
{
   char getpwd[8];
   printf("please enter the password :");
   gets(getpwd);
   if(!strcmp(getpwd,"123456"))
   printf("login success!/n");
   else
   printf("login failed!/n");
   return 1;
}

disas 一下:
Dump of assembler code for function main:
0x080484c8 <main+0>:    lea    0x4(%esp),%ecx
0x080484cc <main+4>:    and    $0xfffffff0,%esp
0x080484cf <main+7>:    pushl  -0x4(%ecx)
0x080484d2 <main+10>:    push   %ebp
0x080484d3 <main+11>:    mov    %esp,%ebp
0x080484d5 <main+13>:    push   %ecx
0x080484d6 <main+14>:    sub    $0x24,%esp
0x080484d9 <main+17>:    mov    %gs:0x14,%eax
0x080484df <main+23>:    mov    %eax,-0x8(%ebp)
0x080484e2 <main+26>:    xor    %eax,%eax
0x080484e4 <main+28>:    movl   $0x8048626,(%esp)
0x080484eb <main+35>:    call   0x80483bc <printf@plt>
0x080484f0 <main+40>:    lea    -0x10(%ebp),%eax
0x080484f3 <main+43>:    mov    %eax,(%esp)
0x080484f6 <main+46>:    call   0x804839c <gets@plt>
0x080484fb <main+51>:    movl   $0x8048642,0x4(%esp)
0x08048503 <main+59>:    lea    -0x10(%ebp),%eax
0x08048506 <main+62>:    mov    %eax,(%esp)
0x08048509 <main+65>:    call   0x80483ec <strcmp@plt>
0x0804850e <main+70>:    test   %eax,%eax
0x08048510 <main+72>:    jne    0x8048520 <main+88>
0x08048512 <main+74>:    movl   $0x8048649,(%esp)
---Type <return> to continue, or q <return> to quit---
0x08048519 <main+81>:    call   0x80483dc <puts@plt>
0x0804851e <main+86>:    jmp    0x804852c <main+100>
0x08048520 <main+88>:    movl   $0x8048658,(%esp)
0x08048527 <main+95>:    call   0x80483dc <puts@plt>
0x0804852c <main+100>:    mov    $0x1,%eax
0x08048531 <main+105>:    mov    -0x8(%ebp),%edx
0x08048534 <main+108>:    xor    %gs:0x14,%edx
0x0804853b <main+115>:    je     0x8048542 <main+122>
0x0804853d <main+117>:    call   0x80483cc <__stack_chk_fail@plt>
0x08048542 <main+122>:    add    $0x24,%esp
0x08048545 <main+125>:    pop    %ecx
0x08048546 <main+126>:    pop    %ebp
0x08048547 <main+127>:    lea    -0x4(%ecx),%esp
0x0804854a <main+130>:    ret   
End of assembler dump.

在gets函数返回后设断点,运行,提示输入密码时输入“123456“
查看一下寄存器内容:
esp            0xbfc34870
ebp            0xbfc34898
此时esp的内容应该指向刚输入的密码:
(gdb) x/30cb *0xbfc34870
0xbfc34888:    49 '1'    50 '2'    51 '3'    52 '4'    53 '5'    54 '6'    0 '/0'    8 '/b'
0xbfc34890:    -42 '�'    -88 '�'    -127 '/201'    -89 '�'    -80 '�'    72 'H'    -61 '�'    -65 '�'
0xbfc34898:    8 '/b'    73 'I'    -61 '�'    -65 '�'    117 'u'    23 '/027'    -37 '�'    -73 '�'
0xbfc348a0:    96 '`'    -123 '/205'    4 '/004'    8 '/b'    0 '/0'    -124 '/204'

注意到地址为0xbfc34888,对整个反汇编程序分析后,不难得出此时的堆栈结构如下所示:
                        地址                        内容
esp -----> 0xbfc34870       
       
                ----间隔24----

                0xbfc34888                    123456
      
               -----间隔16----                           
 
                0xbfc34898                     原esp+4
                0xbfc3489c                     原ebp   
边界------> 0xbfc348a0                    原esp

我们在c源程序中为getpwd分配了8个字节,而这里空闲的空间为16字节。即如果超过16字节,那么将覆盖有用信息了。
原esp即程序返回的EIP,而原esp+4指的是程序的返回值。0xa0-0x88 = 28,即只需覆盖28字节即可。测试一下:
caobin@caobin-desktop:~$ ./test
please enter the password :AAAAAAAAAAAAAAAAAAAAABCD   
login failed!
*** stack smashing detected ***: ./test terminated
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)[0xb7fb7da8]
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x0)[0xb7fb7d60]
./test[0x8048542]
[0x44434241]
======= Memory map: ========
......................

呵呵,看到了么,EIP已经指向0x44434241了,己所改写的ABCD的逆序,溢出攻击算是成功了。
这里说明我们可以操控EIP了,但并不意味着可以改写成任意值,因为还涉及到不可见字符的问题。

原创粉丝点击