Showing posts with label reverse engineering. Show all posts
Showing posts with label reverse engineering. Show all posts

Wednesday, November 30, 2011

Can you crack it? (nope, I tried though)

The UK govt created a challenge to find eligible code crackers. The website is http://www.canyoucrackit.co.uk/.

I got close, but my skills aren't up to par. Here is as far as I got. They give you the following code:

eb 04 af c2 bf a3 81 ec  00 01 00 00 31 c9 88 0c
0c fe c1 75 f9 31 c0 ba  ef be ad de 02 04 0c 00
d0 c1 ca 08 8a 1c 0c 8a  3c 04 88 1c 04 88 3c 0c
fe c1 75 e8 e9 5c 00 00  00 89 e3 81 c3 04 00 00
00 5c 58 3d 41 41 41 41  75 43 48 3d 42 42 42 42
75 3b 5a 89 d1 89 e6 89  df 29 cf f3 a4 89 de 89
d1 89 df 29 cf 31 c0 31  db 31 d2 fe c0 02 1c 06
8a 14 06 8a 34 1e 88 34  06 88 14 1e 00 f2 30 f6
8a 1c 16 8a 17 30 da 88  17 47 49 75 de 31 db 89
d8 fe c0 cd 80 90 90 e8  9d ff ff ff 41 41 41 41

What jumps out at me first are the nops (90 90) in the last line. My mind automagically tells me this is shellcode. I wasn't 100% sure, but it was the only guess I had. I copied the code over into gedit, and made the following adjustments.

\xeb\x04\xaf\xc2\xbf\xa3\x81\xec\x00\x01\x00\x00\x31\xc9\x88\x0c
\x0c\xfe\xc1\x75\xf9\x31\xc0\xba\xef\xbe\xad\xde\x02\x04\x0c\x00
\xd0\xc1\xca\x08\x8a\x1c\x0c\x8a\x3c\x04\x88\x1c\x04\x88\x3c\x0c
\xfe\xc1\x75\xe8\xe9\x5c\x00\x00\x00\x89\xe3\x81\xc3\x04\x00\x00
\x00\x5c\x58\x3d\x41\x41\x41\x41\x75\x43\x48\x3d\x42\x42\x42\x42
\x75\x3b\x5a\x89\xd1\x89\xe6\x89\xdf\x29\xcf\xf3\xa4\x89\xde\x89
\xd1\x89\xdf\x29\xcf\x31\xc0\x31\xdb\x31\xd2\xfe\xc0\x02\x1c\x06
\x8a\x14\x06\x8a\x34\x1e\x88\x34\x06\x88\x14\x1e\x00\xf2\x30\xf6
\x8a\x1c\x16\x8a\x17\x30\xda\x88\x17\x47\x49\x75\xde\x31\xdb\x89
\xd8\xfe\xc0\xcd\x80\x90\x90\xe8\x9d\xff\xff\xff\x41\x41\x41\x41

I then saved this into a shellcode.c file:

char shellcode[] = "\xeb\x04\xaf\xc2\xbf\xa3\x81\xec\x00\x01\x00\x00\x31\xc9\x88\x0c\x0c\xfe\xc1\x75\xf9\x31\xc0\xba\xef\xbe\xad\xde\x02\x04\x0c\x00\xd0\xc1\xca\x08\x8a\x1c\x0c\x8a\x3c\x04\x88\x1c\x04\x88\x3c\x0c\xfe\xc1\x75\xe8\xe9\x5c\x00\x00\x00\x89\xe3\x81\xc3\x04\x00\x00\x00\x5c\x58\x3d\x41\x41\x41\x41\x75\x43\x48\x3d\x42\x42\x42\x42\x75\x3b\x5a\x89\xd1\x89\xe6\x89\xdf\x29\xcf\xf3\xa4\x89\xde\x89\xd1\x89\xdf\x29\xcf\x31\xc0\x31\xdb\x31\xd2\xfe\xc0\x02\x1c\x06\x8a\x14\x06\x8a\x34\x1e\x88\x34\x06\x88\x14\x1e\x00\xf2\x30\xf6\x8a\x1c\x16\x8a\x17\x30\xda\x88\x17\x47\x49\x75\xde\x31\xdb\x89\xd8\xfe\xc0\xcd\x80\x90\x90\xe8\x9d\xff\xff\xff\x41\x41\x41\x41";

void main() {
   int *ret;

   ret = (int *)&ret + 2;
   (*ret) = (int)shellcode;

   printf("done");

}

Running it simply returned the "done" being printed by printf. This told me that the shellcode was at least not crashing, so it was probably valid shellcode. Looks like my first impression was correct. So I jumped to the asm that the shellcode produced to get a better understanding of it:

0000000000601040 :
  601040: eb 04                 jmp    601046 
  601042: af                    scas   %es:(%rdi),%eax
  601043: c2 bf a3              retq   $0xa3bf
  601046: 81 ec 00 01 00 00     sub    $0x100,%esp
  60104c: 31 c9                 xor    %ecx,%ecx
  60104e: 88 0c 0c              mov    %cl,(%rsp,%rcx,1)
  601051: fe c1                 inc    %cl
  601053: 75 f9                 jne    60104e 
  601055: 31 c0                 xor    %eax,%eax
  601057: ba ef be ad de        mov    $0xdeadbeef,%edx
  60105c: 02 04 0c              add    (%rsp,%rcx,1),%al
  60105f: 00 d0                 add    %dl,%al
  601061: c1 ca 08              ror    $0x8,%edx
  601064: 8a 1c 0c              mov    (%rsp,%rcx,1),%bl
  601067: 8a 3c 04              mov    (%rsp,%rax,1),%bh
  60106a: 88 1c 04              mov    %bl,(%rsp,%rax,1)
  60106d: 88 3c 0c              mov    %bh,(%rsp,%rcx,1)
  601070: fe c1                 inc    %cl
  601072: 75 e8                 jne    60105c 
  601074: e9 5c 00 00 00        jmpq   6010d5 
  601079: 89 e3                 mov    %esp,%ebx
  60107b: 81 c3 04 00 00 00     add    $0x4,%ebx
  601081: 5c                    pop    %rsp
  601082: 58                    pop    %rax
  601083: 3d 41 41 41 41        cmp    $0x41414141,%eax
  601088: 75 43                 jne    6010cd 
  60108a: 48 3d 42 42 42 42     cmp    $0x42424242,%rax
  601090: 75 3b                 jne    6010cd 
  601092: 5a                    pop    %rdx
  601093: 89 d1                 mov    %edx,%ecx
  601095: 89 e6                 mov    %esp,%esi
  601097: 89 df                 mov    %ebx,%edi
  601099: 29 cf                 sub    %ecx,%edi
  60109b: f3 a4                 rep movsb %ds:(%rsi),%es:(%rdi)
  60109d: 89 de                 mov    %ebx,%esi
  60109f: 89 d1                 mov    %edx,%ecx
  6010a1: 89 df                 mov    %ebx,%edi
  6010a3: 29 cf                 sub    %ecx,%edi
  6010a5: 31 c0                 xor    %eax,%eax
  6010a7: 31 db                 xor    %ebx,%ebx
  6010a9: 31 d2                 xor    %edx,%edx
  6010ab: fe c0                 inc    %al
  6010ad: 02 1c 06              add    (%rsi,%rax,1),%bl
  6010b0: 8a 14 06              mov    (%rsi,%rax,1),%dl
  6010b3: 8a 34 1e              mov    (%rsi,%rbx,1),%dh
  6010b6: 88 34 06              mov    %dh,(%rsi,%rax,1)
  6010b9: 88 14 1e              mov    %dl,(%rsi,%rbx,1)
  6010bc: 00 f2                 add    %dh,%dl
  6010be: 30 f6                 xor    %dh,%dh
  6010c0: 8a 1c 16              mov    (%rsi,%rdx,1),%bl
  6010c3: 8a 17                 mov    (%rdi),%dl
  6010c5: 30 da                 xor    %bl,%dl
  6010c7: 88 17                 mov    %dl,(%rdi)
  6010c9: 47                    rex.RXB
  6010ca: 49 75 de              rex.WB jne    6010ab 
  6010cd: 31 db                 xor    %ebx,%ebx
  6010cf: 89 d8                 mov    %ebx,%eax
  6010d1: fe c0                 inc    %al
  6010d3: cd 80                 int    $0x80
  6010d5: 90                    nop
  6010d6: 90                    nop
  6010d7: e8 9d ff ff ff        callq  601079 
  6010dc: 41                    rex.B
  6010dd: 41                    rex.B
  6010de: 41                    rex.B
  6010df: 41 00 00              add    %al,(%r8)

Definitely legitimate shellcode. The x86 asm gcc spits out is exactly what I wanted to see. Not only that, but do you see the 0xdeadbeef?

Once I knew I was in the right direction, I loaded the binary into gdb. I through a breakpoint on the printf line with
break printf
and ran the binary. I looked at the stack frame, traversed through the memory and found the strings I suspected were what we were supposed to be looking for. However, they seemed to be all multi-byte characters. I wasn't able to decipher any of them within the time limit. I had found out about the contest about 2 hours before it was over. This took me about an hour to get to traversing the stack for the strings, and I got stuck.

Oh well. Maybe next time if I have more time I can get a bit further.