This weekend, I participated briefly in the Codegate CTF (mostly during bits of SharifCTF downtime, as they overlapped heavily). I contributed to a solve for the BaskinRobins31 challenge, for which the writeup is below.
This was a joint effort between me and 0x4a47. The majority of the effort is not mine: when I got started, the exploit was mostly there and structurally functional.
This challenge was presented as a 64-bit Linux binary, which you can download here.
This is somewhat similar to the “pwn1/vuln” challenge from SharifCTF, with the only significant difference being that it is 64-bit. In IDA:
We can clearly see a stack overflow. The read() function is used, which works to our benefit – we won’t need to worry about null bytes. Unfortunately, exploitation is a little more tricky – libc isn’t provided, so we’ll need to work out our own libc, and 64-bit’s calling conventions require arguments to be in registers, making life a little bit harder.
Fortunately, the “helper” function helpfully allows us to convert arguments onto the stack into arguments in registers.
Our first task is to leak the address of libc – we can do this by pointing helper to a write call, with the argument being somewhere in the GOT:
By writing two known addresses (so 16 bytes) out to ourselves, we can determine the version of libc in use:
We can match this with an online libc database to determine which libc we’re looking at (and thus, the base address of libc, and everything we need to drop a shell). We initially tried libcdb.com, with no success, but then 0x4a47 pointed me to this website, which had a more comprehensive database, with which we got a match (and the libc binary).
With our hands on a copy of libc, it is a trivial exercise to identify the location of system and the string “/bin/sh”. We continue the rop chain to “reset” the overflow, allowing us a second shot at the helper function, triggering a call to system(“/bin/sh”):
The final exploit we used is here.
Thanks to the Codegate organisers for yet another high-quality CTF: playing events like this are always a good ego check, and an indicator of which direction we should go next to improve ourselves.