覆盖堆栈上存储的 return 地址不起作用
Overwriting the stored return address on the stack doesn't work
我试图通过覆盖堆栈上存储的 return 地址 (saved eip
) 来控制 C 程序的执行:
(gdb) info frame
Stack level 0, frame at 0xbffff550:
eip = 0x8048831 in main (6.c:52); saved eip = 0xbffffdef
source language c.
Arglist at 0xbffff538, args: argc=6, argv=0xbffff5e4
Locals at 0xbffff538, Previous frame's sp is 0xbffff550
Saved registers:
ebx at 0xbffff534, ebp at 0xbffff538, eip at 0xbffff54c
值 0xbffffdef
是一个 "Hello, world!"
shellcode 的地址,它已被组装,检查任何空字节并放入环境变量 SHELLCODE
:
(gdb) x/s *((char **)environ + 7)
0xbffffdef: "SHELLCODE=33Y100[=12=]413C1Ҳ7̀0[=12=]1K̀00777Hello, world!\n\r"
不幸的是,程序无法打印预期的问候语:
Program received signal SIGSEGV, Segmentation fault.
0xbffffdfd in ?? ()
为什么会崩溃,如何解决?
备注:
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
// program was compiled with the following flags:
-m32 -fno-stack-protector -z execstack -fno-PIE -no-pie -g
节目来源:
感谢@Nate Eldredge
此特定崩溃背后的原因是不正确的 return 地址 0xbffffdef
。环境变量SHELLCODE
的位置其实指向字符串的开头"SHELLCODE=..."
(gdb) x/s *((char **)environ + 7)
0xbffffdef: "SHELLCODE=33Y100[=10=]413C1Ҳ7̀0[=10=]1K̀00777Hello, world!\n\r"
为了解决这个问题,我们必须通过跳过前 10 个字符并指向 "33Y10..."
:
来调整地址
0xbffffdef + 0xa = 0xbffffdf9
当用这个值 0xbffffdf9
覆盖存储的 return 地址时,程序被强制进入问候世界:
(gdb) info frame
Stack level 0, frame at 0xbffff550:
eip = 0x8048831 in main (6.c:52); saved eip = 0xbffffdf9
source language c.
Arglist at 0xbffff538, args: argc=6, argv=0xbffff5e4
Locals at 0xbffff538, Previous frame's sp is 0xbffff550
Saved registers:
ebx at 0xbffff534, ebp at 0xbffff538, eip at 0xbffff54c
(gdb) cont
Continuing.
Hello, world!
[Inferior 1 (process 28591) exited normally]
我试图通过覆盖堆栈上存储的 return 地址 (saved eip
) 来控制 C 程序的执行:
(gdb) info frame
Stack level 0, frame at 0xbffff550:
eip = 0x8048831 in main (6.c:52); saved eip = 0xbffffdef
source language c.
Arglist at 0xbffff538, args: argc=6, argv=0xbffff5e4
Locals at 0xbffff538, Previous frame's sp is 0xbffff550
Saved registers:
ebx at 0xbffff534, ebp at 0xbffff538, eip at 0xbffff54c
值 0xbffffdef
是一个 "Hello, world!"
shellcode 的地址,它已被组装,检查任何空字节并放入环境变量 SHELLCODE
:
(gdb) x/s *((char **)environ + 7)
0xbffffdef: "SHELLCODE=33Y100[=12=]413C1Ҳ7̀0[=12=]1K̀00777Hello, world!\n\r"
不幸的是,程序无法打印预期的问候语:
Program received signal SIGSEGV, Segmentation fault.
0xbffffdfd in ?? ()
为什么会崩溃,如何解决?
备注:
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
// program was compiled with the following flags:
-m32 -fno-stack-protector -z execstack -fno-PIE -no-pie -g
节目来源:
感谢@Nate Eldredge
此特定崩溃背后的原因是不正确的 return 地址 0xbffffdef
。环境变量SHELLCODE
的位置其实指向字符串的开头"SHELLCODE=..."
(gdb) x/s *((char **)environ + 7)
0xbffffdef: "SHELLCODE=33Y100[=10=]413C1Ҳ7̀0[=10=]1K̀00777Hello, world!\n\r"
为了解决这个问题,我们必须通过跳过前 10 个字符并指向 "33Y10..."
:
0xbffffdef + 0xa = 0xbffffdf9
当用这个值 0xbffffdf9
覆盖存储的 return 地址时,程序被强制进入问候世界:
(gdb) info frame
Stack level 0, frame at 0xbffff550:
eip = 0x8048831 in main (6.c:52); saved eip = 0xbffffdf9
source language c.
Arglist at 0xbffff538, args: argc=6, argv=0xbffff5e4
Locals at 0xbffff538, Previous frame's sp is 0xbffff550
Saved registers:
ebx at 0xbffff534, ebp at 0xbffff538, eip at 0xbffff54c
(gdb) cont
Continuing.
Hello, world!
[Inferior 1 (process 28591) exited normally]