Tags: reversing 

Rating: 5.0

## CSAW CTF 2016 - hungman (Reversing 125pt)
##### 16/09 - 18/09/2016 (48hr)

### Description:

### Solution

This was an easy windows revering one. When we run the program we get the message:
"?W?h?a?t h?a?p?p?e?n?". A quick search for that string takes us into the following code:
.text:00C21224 call sub_C21620
.text:00C21229 mov byte ptr [ebp+var_4], 3
.text:00C2122D mov eax, [ebp+Dst]
.text:00C21233 mov eax, [eax+4]
.text:00C21236 test [ebp+eax+var_118], 6
.text:00C2123E jz short loc_C21265
.text:00C21240 mov ecx, ds:?cerr@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
.text:00C21246 mov edx, offset a?w?h?a?tH?a?p? ; "?W?h?a?t h?a?p?p?e?n?"
.text:00C2124B push offset sub_C22C50
.text:00C21250 call sub_C22A00
.text:00C21255 mov ecx, eax
.text:00C21257 call ds:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ;
.text:00C2125D push 0FFFFFFFFh ; Code
.text:00C2125F call ds:__imp_exit
.text:00C21265 loc_C21265:

function sub_C21620() is invoked, and if the value is not 6 this message is not displayed.
Inside this function there's another one:
.text:00C216EE call sub_C22550

Once we enter inside, we can see this interesting thing:
.text:00C22587 push offset aCUsersCsaw2016 ; "C:\\Users\\CSAW2016\\haha\\flag_dir\\fl"...
.text:00C2258C call ds:?_Fiopen@std@@YAPAU_iobuf@@PBDHH@Z ; std::_Fiopen(char const *,int,int)

Ok. It's obvious. Program tries to open that file. If we create it we can see that we don't get the
"W?h?a?t h?a?p?p?e?n?" message anymore. But this time we get the message: "=W=r=o=n=g=K=e=y=":
.text:00C21415 mov edx, offset aCongratsYouGot ; "Congrats You got it!"
.text:00C2141A push offset sub_C22C50
.text:00C2141F jmp short loc_C21426
.text:00C21421 ; ---------------------------------------------------------------------------
.text:00C21421 WRONG_C21421: ; CODE XREF: sub_C21100+238?j
.text:00C21421 mov edx, offset aWRONGKEY ; "=W=r=o=n=g=K=e=y="

The critical comparison is here:
.text:00C21323 lea ecx, [ebp+var_54]
.text:00C21326 call check_flag_4020C0
.text:00C2132B mov ecx, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
.text:00C21331 push offset sub_C22C50
.text:00C21336 test eax, eax
.text:00C21338 jnz WRONG_C21421

Function check_flag_4020C0() must return zero. In order to speed up our process, we
write some contents in the flag.txt file and we see how they are processed.
First the flag length is checked. It must be 0x12 (=18) characters long:
.text:00C220D7 mov ebx, [ebp+arg_C] ; chk first 12 chars
.text:00C220DA cmp edi, ebx
.text:00C220DC mov edx, ebx
.text:00C220DE cmovb edx, edi
.text:00C220E1 test edx, edx
.text:00C220E3 jz short WRONG_C22141 ; pw must be 0x12

Then the first 12 characters are compared with those from flag.txt:
.text:00C220F0 LOOP_1_C220F0: ; CODE XREF: check_flag_4020C0+3F?j
.text:00C220F0 mov eax, [ecx]
.text:00C220F2 cmp eax, [esi]
.text:00C220F4 jnz short NEXT_C22106
.text:00C220F6 add ecx, 4
.text:00C220F9 add esi, 4
.text:00C220FC sub edx, 4
.text:00C220FF jnb short LOOP_1_C220F0
.text:00C22101 GO_ON_C22101: ; CODE XREF: check_flag_4020C0+2C?j
.text:00C22101 cmp edx, 0FFFFFFFCh
.text:00C22104 jz short loc_C2213A

The comparison is straight forward, so the first part from the flag is: "idg_cni~bjbf".
Note that there's some code that "decrypts" this string; we don't care about decryption,
as we can read the decrypted one.

Then we continue manually comparing characters one by one:
.text:00C22106 NEXT_C22106: ; CODE XREF: check_flag_4020C0+34?j
.text:00C22106 mov al, [ecx]
.text:00C22108 cmp al, [esi] ; flag[12] == 'i'
.text:00C2210A jnz short loc_C22133
.text:00C2210C cmp edx, 0FFFFFFFDh
.text:00C2210F jz short loc_C2213A
.text:00C22111 mov al, [ecx+1]
.text:00C22114 cmp al, [esi+1]
.text:00C22117 jnz short loc_C22133
.text:00C22119 cmp edx, 0FFFFFFFEh
.text:00C2211C jz short loc_C2213A
.text:00C2211E mov al, [ecx+2]
.text:00C22121 cmp al, [esi+2]
.text:00C22124 jnz short loc_C22133
.text:00C22126 cmp edx, 0FFFFFFFFh
.text:00C22129 jz short loc_C2213A
.text:00C2212B mov al, [ecx+3]
.text:00C2212E cmp al, [esi+3]
.text:00C22131 jz short loc_C2213A

If the flag is **idg_cni~bjbfi|gsxb** then we can pass the checks and get the congratz message.

Original writeup (https://github.com/ispoleet/ctf-writeups/tree/master/csaw_ctf_2016/key).