NDH2K13 crackme300 writeup
Connect to the remote machine and break the code. Oh wait, maybe you'll
need some tools.
Score 300
Link ssh://user:ndh2k13@z0b.nuitduhack.com:2222/
We are able to retrieve two files:
- an ELF asking for a password
- a vmlinux
Launching crackme
on my box failed miserably. The code didn’t make any sense
and the e_flags field of the ELF header which was supposed to be 0 was equal
to 0x20.
As we were provided with a vmlinux, I guessed the ELF loading routine of the
kernel had been modified to check if e_flags was 0x20, and in this case apply
some operation. When reversing load_elf_binary
(fs/binfmt_elf.c
), you see
that the code is xored. It can be fixed with the following code:
#include <stdio.h>
#define OFFSET (0x610)
#define SIZE (0x418 + 0xe + 0x28)
int main(int argc, char** argv)
{
char key[] =
"\x12\x43\x34\x65\x78\xcf\xdc\xca\x98\x90"
"\x65\x31\x21\x56\x83\xfa\xcd\x30\xfd\x12"
"\x84\x98\xb7\x54\xa5\x62\x61\xf9\xe3\x09"
"\xc8\x94\x12\xe6\x87";
FILE* f = fopen(argv[1], "r+");
char buf[SIZE];
fseek(f, OFFSET, SEEK_SET);
fread(buf, 1, SIZE, f);
for (int i = 0; i < SIZE; ++i)
buf[i] = buf[i] ^ key[i % 35];
fseek(f, OFFSET, SEEK_SET);
fwrite(buf, 1, SIZE, f);
fclose(f);
return 0;
}
Now that we have a working ELF, we can look at it and see that it a quite straightforward to reverse. There may only be four different characters:
- w
- a
- s
- d
Looking closer, we can see that there is to globals, which begin at 0, and that must both be equals to 15 to have the right password. We can also se that there is a 16x16 table filled with ones and zeroes, and the globals (which are in fact w and h position in the table) must point to a 0 (it’s a maze, you must get from (0, 0) to (15, 15) without going through a wall).
The following python script find the correct sequence of keys, which is the key:
#! /usr/bin/env python3
import sys
TABLE = [
0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01,
0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01,
0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01,
0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00,
0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01,
0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00,
0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00,
]
CHARS = {
"w" : "wad",
"s" : "sad",
"a" : "was",
"d" : "wsd",
}
def get_counts(key):
count_1 = 0
count_2 = 0
for i in key:
if i == 's':
count_1 += 1
elif i == 'd':
count_2 += 1
elif i == 'w':
count_1 -= 1
else:
count_2 -= 1
return count_1, count_2
def test(key):
count_1, count_2 = get_counts(key)
if count_1 == 15 and count_2 == 15:
print(key)
sys.exit(0)
if count_1 < 0 or count_2 < 0 or count_1 > 15 or count_2 > 15:
return False
offset = (count_1 << 4) + count_2
if TABLE[offset] != 0:
return False
print(key)
for c in CHARS[key[-1:]]:
test(key + c)
return False
test("s")
Key is:
```text ssddsssassdddssssdssaawaasssddddddwwwwwwddwwwwwdwwdddsssssaassssaasssddddwwddsss