I didn’t really bother reversing this binary, but directly started it up in gdb and analyzed it (which worked out pretty well)…
The binary itself is obfuscated, and builds up the real binary into a mapped area and runs it from there.
Within gdb one could easily spot, that the binary checked, if our input starts with HEAD, so when playing around with HEAD it quickly occured, that it will output the first 7 lines of a file.
If the file, we’re trying to preview is shorter than 7 lines, it will just tell us, that That resource is not very interesting, feel free to select another (so it cannot be used to just print the flag ;))
Feeding it with a longer string will trigger a buffer overflow, but since the binary uses canaries, it will detect stack smashing:
Didn’t find a way to leak the canary, since overflowing into the canary would immediately crash the binary.
But when checking the canary in gdb, something struck my mind :)
The canary here is 0x1a2e1fd117178c00. I have seen this pattern somewhere already!!!
Spotted it, too?
The canary starts with the first half of the starting address of the r-xp section of ld-2.23.so. And the beginning of the r-xp section of the mapped section (which is the binary) forms the second half.
So, we can construct the canary for ourself by reading /proc/self/maps, parsing the output and take those segments from the memory map
Canary = 1a2e1fd + 117178c + 00
Let’s prepare leaking the addresses from /proc/self/maps, which we’ll need anyways and building that canary:
With the canary at hand, we now can safely overflow the buffer, preparing a ropchain and call it.
For the final exploit I used a stager ropchain, which would
read another ropchain to the bss and stack pivot there
this one leaks libc and reads… yes another ropchain
the final ropchain then simply open/read/writes the flag
There was also an rwx section mapped, containing shellcode, which could have been used for this, but I just sticked to ropping.
open/read/write got plus some rop gadgets are all we need:
So, first let’s read another ropchain to the bss and pivot the stack there:
We use the second ropchain to print out write got to leak libc address and read another ropchain.
Armed with this, we can now do the final ropchain.
Might have also just put this into two ropchains, but it worked out pretty quickly and there were still more challenges to do, than cleaning up an already working exploit :-)