Reversing the Binary
This challenge provided two binaries:
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 -
malloced 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
malloced 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
Finally, the secret meme function is passed the meme id buffer and then calls
secret_meme function sets meme id + 8 to 0x69696969 and prints something...