As the first exploitation challenge for RCTF event, the exploit requires information leak some ROP programming and ret2libc techniques.
Main function looks like this:
So we have a read() that takes in 0x400 bytes which is not enough to overwrite the RET of main. The echo() function looks like this:
Seems like the vulnerability is here. We see a local buffer of 0x20 bytes and a loop that copies bytes one by one from the buffer of main() to the local buffer of echo(). The loop copies bytes until it sees a null byte, obviously we can overwrite the RET of echo() here.
By executing the binary and passing a single newline to read(), we can cause a print of a leak in libc. No overwrites here, a single leak to confirm whether ASLR is enabled or not.
Yes, I’m executing it locally and I see that ASLR is enabled (on my system) however, I did the same to the remote box by doing something like:
and I got randomized leak just like in my local tests… meaning ASLR is enabled. With ASLR enabled and PIE disabled we will have everything but the .text segment of the binary randomized… nothing new here, let’s continue.
By looking for ROP gadgets in the binary, there was not a single syscall gadget, making exploitation by ROP from the binary only impossible… We either need syscall from a library or we need ret2libc. I’m going with ret2libc, so next I needed to find their version of libc.
Let’s construct a payload to overwrite RET of echo(), put the address we would like to leak in RDI and jump to 0x4007b0 which is the call to puts.
I used http://libcdb.com/ to find the libc version, I used the address of __libc_start_main and fflush, in the run above we get 0x00007fb98b74bdd0 and 0x00007fb98b797ee0. The search brings us here the following libraries http://libcdb.com/search?symbolA=__libc_start_main&addressA=0x00007fb98b74bdd0&symbolB=fflush&addressB=0x00007fb98b797ee0. Now we can download libc or we can just use the website to calculate the offset of “/bin/sh\x00” string in libc and the offset of system() from the base of libc.
Next step is to get a leak from libc load address, calculate the offset to “/bin/sh\x00” string and system() while we loop again to overwrite the RET.
- Thank you for watching :)