Tuesday, December 2, 2014

Kaizen - Binary Exploitation #1 (reverse engineering "turnstile" binary)

File: binary-expl-1.zip

While I've used tools like IDA before, I'm still pretty new to reverse engineering. The "turnstile" challenge from the kaizen CTF was a good one to practice the basics on.

The first thing I did was run file:

$ file turnstile.bin
turnstile.bin: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped

It shows that turnstile is a Linux executable file and, lucky for us, is unstripped.

Then I opened up IDA and took a look around.

Here's the disassembled main() function:

This doesn't look too bad. It initially compares argc against the constant value 2 to make sure the binary has been invoked correctly. If the check fails, it jumps to loc_80486D3, prints the usage information, and exits. It the check passes, it goes on to call isValidPassword and checks the return value (eax) to see if it's 1. 

From this, it's pretty clear that if we can find the password to make isValidPassword return 1, we'll have the flag.

Let's take a look at the disassembled isValidPassword:

Ok this looks a bit more complicated, but nothing too difficult to understand. Let's work our way backwards, looking at places where the return value (eax) is set.

It looks like it's set with both the xor eax, eax and mv eax, 1 instructions. Xor-ing a register with itself is a shorthand for clearing the register (more info here), so we definitely want to hit the move instruction instead. So how can we get there?

It looks like the 2nd and 3rd boxes together form a for loop that compares the value passed in against the password stored in memory (the 2nd box does the comparison of the password, the 3rd box is the comparison from the for loop). Now we just need to find what values it's expecting, so that we can pass the correct string in.

Looking at the top of the first block, you can see the fixed values being moved into the [ebp + var_41x] addresses. If you look at the comparison below, you can see eax is used as the offset variable to sweep through this same address range!

If we use python to print out the hexadecimal characters the turnstile.bin file is expecting, we can see if it works:

$ ./turnstile.bin $(python3 -c "print('\x57\x69\x6B\x69\x6C\x65\x61\x6B\x73')")
Turnstile Unlocked.
Your passcode is: 0xcffe6b8c

It does!

No comments:

Post a Comment