CSAW CTF Quals 2014 - csaw2013reversing2.exe (200pts) writeup

The challenge description was: We got a little lazy so we just tweaked an old one a bit

Unfortunately I didn't participated in earlier CSAW CTF so I'm not sure what they meant by that, but looking at the binary file name it was apparently a challenge from CSAW 2013 they modified.

Let's download it and see what is going on when we run it:

CSAW CTF Quals 2014 - csaw2013reversing2.exe (200pts) writeup - 01

Well, that's cute. Not much to do from there. After opening the binary with Ollydbg I noticed a couple anti-debugging calls such as INT 3 and IsDebuggerPresent.

0040108C     FF15 14604000  CALL DWORD PTR DS:[<&KERNEL32.IsDebugger>;  kernel32.IsDebuggerPresent
00401092 . 85C0 TEST EAX,EAX
00401094 . 74 23 JE SHORT csaw2013.004010B9
00401096 > 41 INC ECX
00401097 . 41 INC ECX
00401098 . 41 INC ECX
00401099 . 41 INC ECX
0040109A CC INT3
0040109B . 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C]
0040109E . E8 5DFFFFFF CALL csaw2013.00401000

Since IsDebuggerPresent returns false when there is no debugger detected, let's just NOP both of these calls we don't need them anyway.

0040108C     90             NOP
0040108D 90 NOP
0040108E 90 NOP
0040108F 90 NOP
00401090 90 NOP
00401091 90 NOP
00401092 . 85C0 TEST EAX,EAX
00401094 . 74 23 JE SHORT csaw2013.004010B9
00401096 > 41 INC ECX
00401097 . 41 INC ECX
00401098 . 41 INC ECX
00401099 . 41 INC ECX
0040109A 90 NOP
0040109B . 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C]
0040109E . E8 5DFFFFFF CALL csaw2013.00401000

Now I'm really curious to know what is the method just after the call to INT 3 is doing exactly. If there is a call to trap any debugger before it maybe it's something important:

00401000  /$ 56             PUSH ESI
00401001 |. 8B35 389B4000 MOV ESI,DWORD PTR DS:[409B38]
00401007 |. 8D42 01 LEA EAX,DWORD PTR DS:[EDX+1]
0040100A |. 57 PUSH EDI
0040100B |. 8D78 01 LEA EDI,DWORD PTR DS:[EAX+1]
0040100E |> 8A08 /MOV CL,BYTE PTR DS:[EAX]
00401010 |. 40 |INC EAX
00401011 |. 84C9 |TEST CL,CL
00401013 |.^75 F9 \JNZ SHORT csaw2013.0040100E
00401015 |. 2BC7 SUB EAX,EDI
00401017 |. C1E8 02 SHR EAX,2
0040101A |. 33C9 XOR ECX,ECX
0040101C |. 40 INC EAX
0040101D |. 74 08 JE SHORT csaw2013.00401027
0040101F |> 31348A /XOR DWORD PTR DS:[EDX+ECX*4],ESI
00401022 |. 41 |INC ECX
00401023 |. 3BC8 |CMP ECX,EAX
00401025 |.^72 F8 \JB SHORT csaw2013.0040101F
00401027 |> 5F POP EDI ; ntdll.7C910208
00401028 |. 5E POP ESI
00401029 \. C3 RETN

Looks like there are two loops in this method, one to get some bytes and another to XOR them. Let's just put a breakpoint on 0x00401027 and see if there is anything interesting in memory.

Stack [0012FF58]=7C910208 (ntdll.7C910208)
EDI=00381EA2, (ASCII "lag{reversing_is_not_that_hard!}")
Jump from 0040101D

00381EA2 6C 61 67 7B 72 65 76 65 lag{reve
00381EAA 72 73 69 6E 67 5F 69 73 rsing_is
00381EB2 5F 6E 6F 74 5F 74 68 61 _not_tha
00381EBA 74 5F 68 61 72 64 21 7D t_hard!}

We got our flag:

reversing_is_not_that_hard!