From Leviathan 6 to Leviathan 7

Another CTF post, but this time, this is not a walkthrough.
There are some nice CTFs hosted here that I always forgot to play. The following post is about different approaches and obviously it is meant for newcomers. I am pretty sure that an experienced CTF player came up already with my solution.
So, in Leviathan 6 level, you are given a file called leviathan6 and you need to supply a pin. The whole concept is that you can execute the file and read a file that you are not normally allowed to read (Hint: Read getuid and setuid).
Anyway, the file asks for a 4-digit pin. The most obvious and straightforward solution is to write a script and try all 10000 combinations until you find the solution. This solution is called bruteforcing and there are a lot of write-ups available online.

There are some problems here with this solution though. I don’t like bruteforce and I use it as a last resort. I am lazy and I can’t stand watching monitors until I find the right solution (remember, in this scenario there are 10.000 combinations you have to try) etc etc etc. So, let’s think for a moment how this program works.

./leviathan6 4_Digit_Pin

Well, we could quickly try the following unix commands:

ltrace (check for library calls), strings (print all human readable ASCII strings in the file), strace (trace system calls and signals, pretty much interaction with the kernel) but we fail (or at least I did). But we already know from running the file command that the file is ELF format. I had to reverse an ELF file sometime around January, so I pretty much know the structure.

Let’s disassemble it quickly.

objdump -M intel -d leviathan6

This will spit out the assembly. The -M flag sets the flavor, and I like the intel Syntax. The default is AT&T and I don’t like AT&T. A quick check to see if there’s any obfuscation and there’s none. Let’s move on.

Skipping all the irrelevant stuff that come with the ELF file format (actually they are irrelevant in this case only), we skip to main. main (or _main) and check. There’s at the top of the main a CMP (compare) followed by a JE (Jump if Equal). Let’s think for a moment what we already know.

We know that unix terminal apps are pretty much like this

<code><span class="typ">int</span><span class="pln"> main</span><span class="pun">(</span><span class="typ">int</span><span class="pln"> argc</span><span class="pun">,</span> <span class="kwd">const</span> <span class="kwd">char</span> <span class="pun">*</span><span class="pln"> argv</span><span class="pun">[])

</span></code>

argc is arguments counter and argv[] is the array of arguments.

Based on the CMP and JE instructions we also know (or suspect) that the code we are interested in is pretty much like this

 

if(atoi(argv[1])==PIN){
  printf(A_STRING_WITH_THE_PASS);
}else{
  printf(WRONG PIN);
}

With these in mind, let’s run gdb (GNU debugger), put a breakpoint at the CMP we talked before and of course put the disassembly-flavor intel 😛

If we do so (friendly reminder: breakpoints in gdb are set b *0xADDRESS)

the program freezes at this point. If we do a print 0xADDRESS we get the 4 digit pin.

As a friendly reminder here, not everything needs to be solved by reversing it. Keep that in mind 🙂

Btw, beyond leviathan, I also solved krypton, bandit, natas (WHY SO MUCH BRUTEFORCE?) so if you get stuck, drop me a line at twitter.

/out

 

Leave a Reply

Your email address will not be published. Required fields are marked *