codegate 2014 Write-up: dodoCrackme

February 26, 2014

The first challenge of the codegate 2014 ctf was a reversing challenge.
Linux file command showed us:

 crackme_d079a0af0b01789c01d5755c885da4f6: ELF 64-bit LSB executable,
 x86-64, version 1 (SYSV), statically linked,
 BuildID[sha1]=0xb300ef9227a8911db0d6aea538fe03fe4dfb20fe, stripped

Ok it’s a 64Bit ELF binary, which means no “F5 in IDA”. Opening with
IDA64, an alert popped up that there are more then 1000 Nodes to show. WTF?
After changing the node limit the graph showed a single extreme huge function.
After a quick look we noticed many syscalls and inc instructions and
no imports at all. In short the whole thing looked strange.
As there were no strings in it, we gave it a try and executed the file:

 root@localhost's password: test
 Permission denied (password).

It seems the code prints strings, which try to tell us it’s
establishing a ssh connection to localhost, which is just a fake. If there are
no strings in the code, they must be generated at runtime. That would
explain all those syscalls. So lets run it withing gdb and set a
breakpoint in the first node with some syscalls.

 (gdb) b *0x400328
 Breakpoint 1 at 0x400328
 (gdb) r
 Starting program: ~/codegate2014/crackme_d079a0af0b01789c01d5755c885da4f6
 Breakpoint 1, 0x0000000000400328 in ?? ()

As expected it really generates strings char by char at the first
syscall node. So the other node with syscalls must be the error message.
All syscalls are called with rax = 1 and rdi = 1, which writes to
stdout. But one syscall is called with rax = and rdi = 0, which is read
from stdin. Full information table here.

That should be the prompt which asks for the root password. The code
must check the input against something between the input syscall and the
output syscall.

 00000000004065AE                 mov     eax, 0
 00000000004065B3                 mov     edi, 0
 00000000004065B8                 mov     rsi, rbp
 00000000004065BB                 mov     edx, 1
 00000000004065C0                 syscall
 00000000004065C2                 lea     rbp, [rbp-8]

So we set a breakpoint at 0x4065C2 direct after the read syscall.
According to the system call table rsi points to the address where the
string is stored and rdx sets the read count.
After restarting the programm and hitting the breakpoint, we took a look at rsi:

 (gdb) x/20d $rsi
 0x7ffff7ff9b38: 116     0       0       0
 0x7ffff7ff9b48: 0       0       0       0
 0x7ffff7ff9b58: 72      0       0       0
 0x7ffff7ff9b68: 52      0       0       0
 0x7ffff7ff9b78: 80      0       0       0

116 is our first ‘t’, but hey whats that 72,52,80? After expanding the
scope we get: 72, 52, 80, 80, 89, 95, 67, 48, 68, 69, 71, 97, 84, 69,
95, 50, 48, 49, 52, 95, 67, 85, 95, 49, 78, 95, 75, 48, 82, 69, 52
After converting the hex values to a string we get
“H4PPY_C0DEGaTE_2014_CU_1N_K0RE4” which is the flag, worth 200 points.

One Response to “codegate 2014 Write-up: dodoCrackme”

  1. Nice writeup!

    The binary appears to be brainfuck code that went though some compilation. The repeated inc and dec instructions and “mov esi, 30000” in the beginning are big clues. Too bad, we didn’t need to know this to get the flag.

Leave a Reply