backdoorctf2017 | baby-0x41414141
by Keramas
CTF:backdoorctf 2017
Challenge:
baby-0x41414141
Category:
PWN
NCing into the challenge, I threw a couple of different tests at it, and quickly discovered we have a format string exploit on our hands here. By passing in "%x" as an argument, you can see that it starts to leak memory addresses, so adding a bunch of them after a short egg string "AAAA", we find that our string is in fact placed on the stack. Furthermore, it's directly accessible in the 10th spot in, which you can verify by passing the program "AAAA.%10$x" (I just like to add the period in there to make it easier to read so the memory addresses get segmented better.).
Okay, so what to do now with this? Well, we need to explore the program a bit more in depth to find out if there are any functions we can call that will give us the flag.
Using Hopper we can find something pretty interesting:
We have a function that calls system and sends the command "cat flag.txt", so this is definitely what we want to use in our exploit. The address we want to execute is 0x804870b, but how to do that?
I'm not sure whether there was an easier way to accomplish this, but I used two short writes to change the address of the global offset table. (More on this soon...)
Disassembling main in GDB, we see the final instruction is "exit@plt", and disassembling this address we find that there is indeed a jump to the global offset table at 0x804a034.
Let's try to simulate changing the address of the GOT to the flag() address in GDB.
We set a breakpoint in our program right at the call to printf and another breakpoint at the exit@plt call, and then run the program. Once it hits the first breakpoint we are going to set the GOT to our new address, and then confirm it by examining the address.
Now that it's changed, let's continue running our program. Once it hits the call to exit@plt it should be redirected to our flag() function.
And yep, it did. You can see it is trying to execute /bin/dash.
Now we just have to do the actual overwriting which is possible with two short writes using the information we gathered from our format string exploit and some trial and error. If you aren't familiar with what a short write is, what we are essentially going to do is break up our 4 byte address into 2 bytes and 2 bytes, and change them individually by writing our new address values via a format string exploit.
There is a great video about this process by Live Overflow and it's very similar to a challenge from Protostar. He will be able to explain things much better than me, for sure.
I whipped up the following exploit with Python:
After exporting this into a file, we are ready to deliver the payload to our challenge.
The program starts printing out a bunch of stuff, but ultimately it terminates giving us our flag!
(Flag partially omitted per the request of backdoorctf.)