Defcon was finally here and I was so totally pumped for it. When it dropped, so did my jaw, it wasn't going to be easy. That's for sure. Defcon had some of the evilest, trickiest challenges I've ever faced in a CTF. And it was super fun because of it.
This challenge itself was a break from all the pwnables which I found really irritating in their multilayered complexity. This was simple, get in, work on data, get the flag. Single step stuff.
The challenge gives only the following clue:
meow catwestern_631d7907670909fc4df2defc13f2057c.quals.shallweplayaga.me 9999
Upon connecting to that host with netcat we see the following:
Hrmm, whats this even about?
Given that it's talking about registers, my first thought is that maybe the binary data represents a memory dump of registers that we're supposed to unpack and send back. But after some thought, that was not much of a challenge so I looked for other vectors.
Next I thought about the terminology used in the server response. "Initial Register State"? "Send solution in same format"? Hmm. Well what operates on registers? Machine code I suppose. I wrote a quick Python client to grab just the binary data from the host into a file called "data.bin".
I then wrote a quick C program to act as a host for my test:
Next I used GDB to inject my data.bin file into this process:
As I suspected, the binary blob is x86 instructions that operate on registers and then returns. Cool. Now, how to programatically do this?
Since my host binary is working so well in hosting this parasite, I decided to make GDB do all the heavy lifting in this exploit and simply script it to do what I wanted.
In Python I grab the binary data and initial states from the network, write a GDB script to load the binary data into the main() function of a hello world C program. Execute the code, crash on the "ret" instruction, examine the final state registers and send them to the server.
The output looks like this:
And here's the code!