Sunday, March 12, 2017

BSidesIndy 2017 CTF - Solving TREMENDOUS/starter

I went to BSidesIndy without the intention of participating in the CTF so I didn’t take my computer with me. I saw some of the people I knew playing so I decided to try to help but without my computer, I wasn’t much of a help.

I did this at home…

This is a reversing challenge.

I ran strings and got this.

Of course, that flag does not work…

We can move on to gdb and Hopper at this point.

Let’s start by figuring out when WRONG is used. We’ll call the block that print WRONG “wrong_func” for the sake of simplicity.

Below you can see that the JMP instruction jumps wrong_func.

Before the jump, you can strlen then comparison. If the comparison results in true, then we jump to 0x40066b, instead of going to wrong_func.

This is good. We can put a breakpoint at 0x400652 (je instruction) and examine the registers in gdb.

RAX is 0x20 (32) and RBX is 0x5 (5).
We know that we put in HELLO, which is 5 chars long. We need our input to be 32 char long for RAX to equal RBX.


Look at that. CMP results in true. The program will now jump to 0x40066b instead of going to wrong_func.

Even if we supply 32 char input, the program still go to wrong_func.

Let’s examine 0x40066b now.

It does bunch of stuff but I am not going to spend time trying to figure it out. I can just look at the call graph instead.

Notice the CMP under 0x400690. If CMP does not result in true, JNE 0x400656 is executed. That goes to nop, which then goes to wrong_func. Now we have to just avoid JNE from executing.

I do want to point out that we’re trying to get to 0x4006eb, which prints TREMENDOUS!. It will happen when we have the correct flag.

Back in GDB, we can put a breakpoint on JNE 0x400656 instruction.

In the picture above, you can see that RAX contains our input (A) and RDX contains expected input (I), since the CMP failed, we jump to nop and wrong_func is executed.

We can change our input to be IAAABBBBCCCCDDDDAAAABBBBCCCCDDDD and keep using the break point to figure out what our input should be but that’s not fun.

We’ll use Angr ( instead.

So far we know that input should be 32 char long. We also know that we want to AVOID going to 0x400656 (nop -> wrong_func) and 0x400657 (wrong_func) and we want to FIND a path to 0x4006eb, which prints “TREMENDOUS!”

I don’t know how to deal with args in Angr. Lintile(, the CTF organizer, told me to look at some Angr CTF examples so I did. I found one that I could modify and get the flag with. Here is it is:

This is the code that I used:

Argv1 is 32 char long.
I told Angr what I wanted to find and what I wanted to avoid.
After the path is found, print the argv1 required.

I ran the script and found the flag!

And yes, the flag does work.