Artificial truth

The more you see, the less you believe.

[archives] [latest] | [homepage] | [atom/rss]

ndh2013 - crackmeimfamous
Tue 25 June 2013 — download

Back from the Nuit du Hack 2013, we managed with depierre to put the hackgyver name on the 23th position (iirc). I was a little bit disapointed by the wargame (Seriously, prisedetete, 450 !?), but talks were nice, we met amazing people, and had fun :) Ok, enough about this, let's talk about crackmeimfamous.

The crackme

You can get it here.

Reversing

It's a i686 binary, with some crypto stuff. The strings command tells us it's using OpenSSL. I checked here that AES-related functions where real AES stuffs, and not some idiotic deception trickery.

Run it

I had to softlink some libraries to make it run.

  • ldd crackmeimfamous
  • softlink/renames libs
  • export LD_LIBRARY_PATH=$(pwd)

Anti-debug

Nothing amazing; the gdb_check function, uses the classic ptrace trick inside a fork.

Crypto

The main function calls the check one

push   ebp
mov    ebp,esp
sub    esp,0x38
call   0x8048ae5 <gdb_check> ; anti-debug
test   eax,eax
je     0x8048cd3 <check+39>
mov    DWORD PTR [esp],0x8048e0e ; boo
call   0x80487e0 <puts@plt>
mov    DWORD PTR [esp],0x1
call   0x80487b0 <exit@plt>
call   0x8048bf2 <get_pass> ; crypto computations
mov    DWORD PTR [ebp-0xc],eax
mov    DWORD PTR [esp],0x80491ae ; "Password : "
call   0x80487c0 <printf@plt>
mov    eax,ds:0x804b060
mov    DWORD PTR [esp+0x8],eax
mov    DWORD PTR [esp+0x4],0x10
lea    eax,[ebp-0x1c]
mov    DWORD PTR [esp],eax
call   0x8048730 <fgets@plt>
mov    eax,DWORD PTR [ebp-0xc]
lea    edx,[ebp-0x1c]
mov    DWORD PTR [esp],edx
call   eax ; <- Weird call
leave
ret

The get_pass function is likely doing some AES decryption voodoo:

push   ebp
mov    ebp,esp
sub    esp,0x168
mov    DWORD PTR [ebp-0x138],0x3039
mov    DWORD PTR [ebp-0x134],0xd431
mov    DWORD PTR [ebp-0xc],0x8048e26 ; "b026324c6904b2a9", the AES key_data ?
mov    DWORD PTR [ebp-0x10],0x10
lea    eax,[ebp-0x130]
mov    DWORD PTR [esp+0x10],eax
lea    eax,[ebp-0xa4]
mov    DWORD PTR [esp+0xc],eax
lea    eax,[ebp-0x138]
mov    DWORD PTR [esp+0x8],eax
mov    eax,DWORD PTR [ebp-0x10]
mov    DWORD PTR [esp+0x4],eax
mov    eax,DWORD PTR [ebp-0xc]
mov    DWORD PTR [esp],eax
call   0x804892c <aes_init>
test   eax,eax
je     0x8048c58 <get_pass+102> ; aes_init failed :/
mov    eax,0xffffffff
jmp    0x8048caa <get_pass+184>
mov    DWORD PTR [ebp-0x14],0x8048e38 ; This is a large block of data
mov    DWORD PTR [ebp-0x13c],0x375 ; Data block size ?
lea    eax,[ebp-0x13c]
mov    DWORD PTR [esp+0x8],eax
mov    eax,DWORD PTR [ebp-0x14]
mov    DWORD PTR [esp+0x4],eax
lea    eax,[ebp-0x130]
mov    DWORD PTR [esp],eax
call   0x8048a14 <aes_decrypt>
mov    DWORD PTR [ebp-0x18],eax
lea    eax,[ebp-0x130]
mov    DWORD PTR [esp],eax
call   0x8048790 <EVP_CIPHER_CTX_cleanup@plt>
lea    eax,[ebp-0xa4]
mov    DWORD PTR [esp],eax
call   0x8048790 <EVP_CIPHER_CTX_cleanup@plt>
mov    eax,DWORD PTR [ebp-0x18]
leave
ret

Looks like this function is decrypting from 0x8048e38 to 0x8048e38+0x375, using a key/IV derived from b026324c6904b2a9.

First, I didn't saw that the function was decrypting a large block of data, and though that it was only used to get the password to compare with our output. I lost so much time looking for it! Remember the weird call eax stuff? It jumps inside the decrypted block!

Dumping

Since I felt so stupid, I finished this crackme in a quick'n'dirty manner, I:

  1. Bypassed by hand calls to check_gdb
  2. Set a breakpoint on the call eax
  3. Dumped the decrypted data using dump memory dirtydump 0x0804c209 0x0804c209+1024 > output.tmp in gdb
  4. ran strings on it

And we've got the flag:

strings output.tmp | grep - flag
2cd  Flag : 26ab0db90d72e28ad0ba1e22ee510510

Yay!