CSCAMP CTF Quals 2014: PE 2 write-up

Created:2014.11.24, last modified: 2014.11.24 by xorpse
Status: Complete

As with PE 1, the challenge executable requires a secret key:

Using IDA Pro to disassemble the binary, and viewing the ‘main’ function, we see that it’s relatively simple:

.text:0040151B                 push    ebp
.text:0040151C                 mov     ebp, esp
.text:0040151E                 and     esp, 0FFFFFFF0h
.text:00401521                 sub     esp, 20h
.text:00401524                 call    ___main
.text:00401529                 call    __Z10user_inputv ; user_input(void)
.text:0040152E                 mov     [esp+1Ch], eax
.text:00401532                 mov     eax, [ebp+argv]
.text:00401535                 mov     [esp], eax      ; char **
.text:00401538                 call    __Z8get_sizePPc ; get_size(char **)
.text:0040153D                 mov     [esp+18h], eax
.text:00401541                 mov     eax, [esp+18h]
.text:00401545                 mov     [esp+4], eax    ; int
.text:00401549                 mov     eax, [esp+1Ch]
.text:0040154D                 mov     [esp], eax      ; int
.text:00401550                 call    __Z5checkii     ; check(int,int)
.text:00401555                 mov     eax, 0
.text:0040155A                 leave
.text:0040155B                 retn

user_input() presents the input prompt and collects the input. get_size(char *str) takes the first element of the argv array (the program name) and obtains the file size (in bytes):

.text:004013B6                 mov     eax, [ebp+arg_0]
.text:004013B9                 mov     eax, [eax]
.text:004013BB                 lea     edx, [ebp+var_30]
.text:004013BE                 mov     [esp+4], edx    ; struct stat *
.text:004013C2                 mov     [esp], eax      ; char *
.text:004013C5                 call    _stat
.text:004013CA                 mov     eax, [ebp+var_30.st_size]

Finally, check(int input, int file_size) compares the computed file size with the value input and outputs the input value as the flag if they are equivalent:

.text:004014A6                 mov     eax, [ebp+arg_0]
.text:004014A9                 cmp     eax, [ebp+arg_4]
.text:004014AC                 jnz     short loc_4014E2
.text:004014AE                 mov     dword ptr [esp+4], offset aFlag ; "Flag: "
.text:004014B6                 mov     dword ptr [esp], offset __ZSt4cout ; std::cout
.text:004014BD                 call    __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
.text:004014C2                 mov     edx, [ebp+arg_0]
.text:004014C5                 mov     [esp], edx
.text:004014C8                 mov     ecx, eax
.text:004014CA                 call    __ZNSolsEi      ; std::ostream::operator<<(int)
.text:004014CF                 sub     esp, 4
.text:004014D2                 mov     dword ptr [esp+4], offset asc_474088 ; "\n"
.text:004014DA                 mov     [esp], eax      ; this
.text:004014DD                 call    __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc