# Hacking Tube

## CSAW CTF 2015 -- wyvern

Category: Reversing
Points: 500

Here they gave us another 64 bit ELF, which is apparently written in C++.

It will ask us to input a secret, and tell us if we failed or success. The checking secret part in the program was really hard to understand what the actual f*ck is it doing, so I decide to reverse only the critical part.

This is the partial pseudo code from the checking secret function. The variable legend was stored in the data segment 0x610138 with the initial value 0x73. Knowing that 0x73 >> 2 == 28, I'm guessing that the secret's length is going to be 28.

To verify the assumption, I launch the program with gdb, and set the breakpoint at the end of the checking secret function. Then, I start sending the input with different length. I found out that when the input length is 28, the return value will be 0, which is different from other inputs (return value = 0x1c). Although I don't know the exact secret ( because the return value should be 1 for the correct secret ), I'm now quite sure that the secret length should be 28.

Now let's take a look at other part of the checking function:

It will be a pain in the ass if we try to reverse the whole checking algorithm, so we're going to find some critical point. Notice that there're some while loop and some if-else condition in the checking function, so I assume that maybe ( just maybe ) the checking function will process the input characters one by one. If the current character failed to pass some specific condition, it will break out the loop immediately, failing the check. If it pass the specific condition successfully, it will continue the loop and check the next byte, which means that it will run more instructions than the failing one.

It's like side-channel attack. We guess the current character, and count the instructions it ran. If we get a number that is larger than the others, we'll know that this might be the right character, and so we can move on to guessing the next character.

To achieve this, I use Intel pin to count the instructions number. Here's the script (written in ruby):

Run the script and wait a couple of minutes, we'll get the correct secret:

Verify the secret:

Cool! The flag is: dr4g0n_or_p4tric1an_it5_LLVM (without flag{})