I'm trying to take control of a C program's execution by overwriting the stored return address (saved eip
) on the stack:
(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
The value 0xbffffdef
is the address of a "Hello, world!"
shellcode which has been assembled, checked for any null bytes and put in an environment variable SHELLCODE
:
(gdb) x/s *((char **)environ + 7)
0xbffffdef: "SHELLCODE=\353\023Y1\300\260\004\061\333C1Ҳ\017̀\260\001K̀\350\350\377\377\377Hello, world!\n\r"
Unfortunately the program fails to print the expected greeting:
Program received signal SIGSEGV, Segmentation fault.
0xbffffdfd in ?? ()
Why did it crash and how to solve the problem?
Notes:
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
program source: link
Credits to @Nate Eldredge
The reason behind this specific crash is the incorrect return address 0xbffffdef
. The location of the environment variable SHELLCODE
actually points to the beginning of the string "SHELLCODE=..."
(gdb) x/s *((char **)environ + 7)
0xbffffdef: "SHELLCODE=\353\023Y1\300\260\004\061\333C1Ҳ\017̀\260\001K̀\350\350\377\377\377Hello, world!\n\r"
In order to fix the issue, we have to adjust the address by skipping the first 10 characters and point to the "\353\023Y1\300..."
:
0xbffffdef + 0xa = 0xbffffdf9
When overwriting the stored return address with this value 0xbffffdf9
, the program is coerced into greeting the world:
(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]