-2

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

Boris
  • 22,667
  • 16
  • 50
  • 71
  • Show the source code of the program, please. Disassembly of the shellcode would be helpful as well. – Nate Eldredge Oct 14 '21 at 14:56
  • 1
    Wait a minute, your shellcode is at `0xbffffdef` but you are jumping to `0xffffddef`? Typo? Also, what's at `0xbffffdef` is the bytes of the letters `SHELLCODE=` which you don't want to execute, so add 11 to end up with `0xbffffdfa`. – Nate Eldredge Oct 14 '21 at 14:59
  • @Nate Eldredge thank you very much, skipping the `SHELLCODE` (but adding 10, not 11) helped! Should I post a full answer? – Boris Oct 14 '21 at 15:18
  • Sure, go ahead. (Yes, you're right, 10, I miscounted.) – Nate Eldredge Oct 14 '21 at 15:28

1 Answers1

0

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]
Boris
  • 22,667
  • 16
  • 50
  • 71