Reversing the Binary
This challenge provided two binaries: dat-boinary
and libc.so.6
. Usually this combination requires you to leak memory, calculate offsets, and call system
or an exec
function from libc. With that in mind I jumped right in to reversing with radare2. The functions are rather large so I will leave this as an exercise to the reader. The binary can be found here.
The first block of main allocates a dynamic buffer of size 0x80 with malloc
and gets a "meme id" of up to 9 bytes that is stored in ebp-0x20. The next block provides five menu options: update the meme id, update the meme dankness, update meme content, print meme contents, and the super secret meme option. The first 4 are pretty straight forward, while the last is not so much.
Stack locations of interest are:
- ebp-0xc - location of menu choice (4 bytes)
- ebp-0x10 - Temporary storage for the dankness of the meme (4 bytes)
- ebp-0x14 -
malloc
ed buffer for meme content - (4 byte pointer) - ebp-0x18 - Meme dankness if the temporary dankness is greater than 0x7f (4 bytes)
- ebp-0x20 - meme id location (8 bytes)
After some trial and error in gdb I noticed that the initial fgets
for the id of the meme takes 9 characters instead of the provided 8. This would prove useful later.
Setting the meme id using the menu option used the length of the preexisting id to know how much to read from the user. This will also be useful, because as long as null bytes in the meme dankness can be avoided then the pointer to the malloc
ed buffer can be overwritten and arbitrary write can be achieved. The only issue here is that this bug can only be triggered once without somehow making strlen
return more than the actual strlen of the buffer. Again, that's a task for after investigation.
Setting the dankness involved reading in a number into ebp-0x10 (temporary dankness storage), checking if it was over 0x7f, and then moving it into the meme dankness memory location (ebp-0x18) if that check was false. This is a problem because the meme dankness is directly before the pointer that I wanted to overwrite.
The update content option does exactly what one would expect, but with one additional check: it uses fgets
to read into the buffer allocated by malloc. The number of bytes it reads is the dankness number. Before anything is read it checks if the dankness is over 0x80, because that would cause a buffer overflow.
Print contents is also straight forward; it prints the content of the meme with a proper call to printf
.
Finally, the secret meme function is passed the meme id buffer and then calls secret_meme
. The secret_meme
function sets meme id + 8 to 0x69696969 and prints something...
...