Welcome back on Exploitnetworking! PingPong was a pwn challenge of SECT CTF 2018, based on buffer overflow. The main goal was use an overflow to leak the memory addresses of remote libc (for bypass aslr) and then create a ropchain for spawn a shell.
First step is see what protections the binary has, using the utility checksec:
We can observe that there are all protections enable in the binary. Next step is execute it for see his behavior:
In this execution we can see two important particular:
- Whit our little input (AAA) there is the output: AaA��_ this has two meanings: first that the program change our input before print it because there is AaA instead of AAA. Second there is also a bad characters, this means that the program print until it reaches a null byte “\x00”. Maybe that bad characters represent the bytes of an address.
- With a big input the program going into segmentation fault.
Examine now the core dump created for see what happened:
How can see, the program crash in:
because in rdx there isn’t a valid address (in fact there is 0x4141414141414141) that is our input. Note that in memory our input not change, but change only during printing.
Ok, now the idea is: insert a valid address in rdx (with our big input), and then the program copy the bytes in that address. But which address to write? Let’s examine the execution with gdb:
first step is set a breakpoint in to that address for see which address is loaded normally in rdx.
How we can see, in rdx is saved the init of the buffer, (this is the second ping, otherwise there was nothing in memory). After 0x41414141 there is 0x00007fff, this is our bad characters! For leak an address we can use the values in the stack, in fact 48 bytes after the init there is 0x00007ffff7a64b62 that is the puts in libc:
Ok, in this way we can calculate the address of libc base (because the libc was given to us), and then we can bypass aslr. Now where write our ropchain?
the idea is overwrite the return address (in other word, we insert in rdx the address of stack that contain the return address of this function). For leak the stack address we can use the same technique for leak the libc address (we can leak rbp for example and then calculate the position of return address).
Where 8 is the offset between init of buffer and ret address. Ok, we have a stack address, libc address, now search some gadgets for create our ropchain that spawn a shell using execve syscall. I have used ROPgadget on libc, in this way we have many more gadgets.
The method “decode_memory” is used for decode the program output (remember that the program modify our input before print it).
Now run it:
Are you stuck with binary exploitation? Try to read the Holy Bibly:
Or try whit this wonderful book: