CSCAMP CTF Quals 2014: Elf 1 write-up

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

Upon execution of the challenge binary, we are presented with a greeting banner and password prompt:

*********************************
  welcome to cracking challenge
*********************************
Enter you password:

Disassembling the main function using IDA shows that there is some anti-debugging: first using ptrace and then by checking if a breakpoint has been set on the first instruction of the xxxxx function:

.text:0000000000400968                 mov     ecx, 0
.text:000000000040096D                 mov     edx, 1
.text:0000000000400972                 mov     esi, 0
.text:0000000000400977                 mov     edi, 0          ; request
.text:000000000040097C                 mov     eax, 0
.text:0000000000400981                 call    _ptrace
.text:0000000000400986                 test    rax, rax
.text:0000000000400989                 jns     short loc_400995
.text:000000000040098B                 mov     edi, 0          ; status
.text:0000000000400990                 call    _exit
.text:0000000000400995 ; ---------------------------------------------------------------------------
.text:0000000000400995
.text:0000000000400995 loc_400995:                             ; CODE XREF: main+25j
.text:0000000000400995                 mov     eax, offset xxxxx
.text:000000000040099A                 mov     eax, eax
.text:000000000040099C                 mov     eax, [rax]
.text:000000000040099E                 and     eax, 0FFh
.text:00000000004009A3                 cmp     eax, 0CCh
.text:00000000004009A8                 jnz     short loc_4009B4
.text:00000000004009AA                 mov     edi, 0          ; status
.text:00000000004009AF                 call    _exit
.text:00000000004009B4 loc_4009B4:                             ; CODE XREF: main+44j
.text:00000000004009B4                 mov     eax, 0
.text:00000000004009B9                 call    xxxx

The main functionality is implemented within the xxxx routine, which is called if both tests for the presence of a debugger are passed. xxxx outputs a greeting banner and prompts for a password:

.text:00000000004008B4                 call    x
.text:00000000004008B9                 mov     eax, offset aEnterYouPasswo ; "Enter you password: "
.text:00000000004008BE                 mov     rdi, rax        ; format
.text:00000000004008C1                 mov     eax, 0
.text:00000000004008C6                 call    _printf
.text:00000000004008CB                 mov     eax, offset aS  ; "%s"
.text:00000000004008D0                 lea     rdx, [rbp+var_7E0]
.text:00000000004008D7                 mov     rsi, rdx
.text:00000000004008DA                 mov     rdi, rax
.text:00000000004008DD                 mov     eax, 0
.text:00000000004008E2                 call    ___isoc99_scanf
.text:00000000004008E7                 lea     rax, [rbp+var_7E0]
.text:00000000004008EE                 mov     rdi, rax
.text:00000000004008F1                 call    xx
.text:00000000004008F6                 mov     [rbp+var_7E4], eax
.text:00000000004008FC                 cmp     [rbp+var_7E4], 0Ch
.text:0000000000400903                 jnz     short loc_40093F
.text:0000000000400905                 lea     rax, [rbp+var_7E0]
.text:000000000040090C                 mov     rdx, rax
.text:000000000040090F                 mov     eax, offset aAaaaaaaaaaaa ; "AAAAAAAAAAAA"
.text:0000000000400914                 mov     ecx, 0Dh
.text:0000000000400919                 mov     rsi, rdx
.text:000000000040091C                 mov     rdi, rax
.text:000000000040091F                 repe cmpsb
.text:0000000000400921                 setnbe  dl
.text:0000000000400924                 setb    al
.text:0000000000400927                 mov     ecx, edx
.text:0000000000400929                 sub     cl, al
.text:000000000040092B                 mov     eax, ecx
.text:000000000040092D                 movsx   eax, al
.text:0000000000400930                 test    eax, eax
.text:0000000000400932                 jnz     short loc_40093F
.text:0000000000400934                 mov     [rbp+var_7F0], offset aEwffcmfnzww ; "eWFfcmFnZWw="
.text:000000000040093F
.text:000000000040093F loc_40093F:                             ; CODE XREF: xxxx+6Ej
.text:000000000040093F                                         ; xxxx+9Dj
.text:000000000040093F                 lea     rax, [rbp+var_7E0]
.text:0000000000400946                 mov     rdi, rax
.text:0000000000400949                 call    xxxxx

xx computes the length of the input value, this is then compared with 12; if it’s equal some junk-code is executed which then flows to the input validation routine, xxxxx:

lea     rax, [rbp+var_7E0]
mov     rdi, rax
call    xxxxx

In xxxxx, the first 7 characters are base64 decoded and then the first 5 characters of the output are compared against the string ‘samir’:

.text:00000000004007BB                 mov     esi, 7
.text:00000000004007C0                 mov     rdi, rax
.text:00000000004007C3                 call    base64_decode
.text:00000000004007C8                 lea     rax, [rbp+var_30]
.text:00000000004007CC                 mov     rdx, rax
.text:00000000004007CF                 mov     eax, offset aSamir ; "samir"
.text:00000000004007D4                 mov     ecx, 5
.text:00000000004007D9                 mov     rsi, rdx
.text:00000000004007DC                 mov     rdi, rax
.text:00000000004007DF                 repe cmpsb

If equal then the flag is first constructed by base64 decoding some hard-coded value and then written to the standard output:

.text:00000000004007F8                 mov     [rbp+var_60], 6E564761h
.text:00000000004007FF                 mov     [rbp+var_5C], 35705859h
.text:0000000000400806                 mov     [rbp+var_58], 0Ah
.text:000000000040080C                 mov     [rbp+var_50], 7A453263h
.text:0000000000400813                 mov     [rbp+var_4C], 3D3D415Ah
.text:000000000040081A                 mov     [rbp+var_48], 0Ah
.text:0000000000400820                 mov     [rbp+var_20], 463263h
.text:0000000000400827                 mov     [rbp+var_80], 6174h
.text:000000000040082D                 mov     [rbp+var_7E], 0
.text:0000000000400831                 mov     [rbp+var_10], 3D4958h
.text:0000000000400838                 mov     [rbp+var_70], 756C4763h
.text:000000000040083F                 mov     [rbp+var_6C], 7731795Ah
.text:0000000000400846                 mov     [rbp+var_68], 6E353262h
.text:000000000040084D                 mov     [rbp+var_64], 0
.text:0000000000400851                 lea     rdx, [rbp+var_40]
.text:0000000000400855                 lea     rax, [rbp+var_70]
.text:0000000000400859                 mov     esi, 0Ch
.text:000000000040085E                 mov     rdi, rax
.text:0000000000400861                 call    base64_decode
.text:0000000000400866                 mov     eax, offset format ; "Flag: %s\n"
.text:000000000040086B                 lea     rdx, [rbp+var_40]
.text:000000000040086F                 mov     rsi, rdx
.text:0000000000400872                 mov     rdi, rax        ; format
.text:0000000000400875                 mov     eax, 0
.text:000000000040087A                 call    _printf

The base64 decoding of ‘63476c757731795a6e35326200’ gives ping-pong as the flag. Interestingly, running the executable and providing the correct password the output (for the flag is):

*********************************
  welcome to cracking challenge
*********************************
Enter you password: c2FtaXIK
Flag: ping-pong you pasamir

…which is not accepted as correct.