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 printfand 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.