Descripción

Find the flag in the program.

Write-Up

El reto consiste en obtener la flag del fichero ejecutable “getflag”, por lo que lo primero que habrá que hacer será obtener información del propio fichero y ejecutarlo. Utilizando el comando “file getflag” podemos ver que el fichero es un binario compilado para Linux de 64 bits:

getflag: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=18a5f1324218e0ec3b49fd89ac3c750dc528dec8, not stripped

Por lo que procedemos a ejecutarlo:

Enter the key to obtain the flag: aaa
Bad luck. Try again…

Pongamos lo que pongamos en el programa siempre nos dirá lo mismo: “Bad luck. Try again…” así que tendremos que observar el código y ver el flujo del programa. En este paso utilizaremos la herramienta Radare 2 (comando “r2 -w getflag” para abrir el binario en modo escritura). Analizamos el fichero poniendo varias “a” y buscamos las funciones que hay en el binario mediante el comando “afl”:

[0x004004e0]> aaaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze len bytes of instructions for references (aar)
[x] Analyze function calls (aac)
[x] Emulate code to find computed references (aae)
[x] Analyze consecutive function (aat)
[x] Constructing a function name for fcn.* and sym.func.* functions (aan)
[x] Type matching analysis for all functions (afta)
[0x004004e0]> afl
0x00400000 2 64 loc.imp.__gmon_start
0x00400041 1 176 fcn.00400041
0x00400460 3 26 sym._init
0x00400490 1 6 sym.imp.puts
0x004004a0 1 6 sym.imp.printf
0x004004b0 1 6 sym.imp.__libc_start_main
0x004004c0 1 6 sym.imp.__isoc99_scanf
0x004004d0 1 6 sub.__gmon_start___248_4d0
0x004004e0 1 41 entry0
0x00400510 4 50 -> 41 sym.deregister_tm_clones
0x00400550 3 53 sym.register_tm_clones
0x00400590 3 28 sym.__do_global_dtors_aux
0x004005b0 4 38 -> 35 entry1.init
0x004005d6 4 185 main
0x00400690 4 101 sym.__libc_csu_init
0x00400700 1 2 sym.__libc_csu_fini
0x00400704 1 9 sym._fini

A simple vista, a parte del “main” no parece haber ninguna función interesante, por lo que nos movemos a su posición de memoria (“s 0x004005d6”) y desensamblamos su código (“pdf”):

[0x004004e0]> s 0x004005d6
[0x004005d6]> pdf
;-- main:
/ (fcn) main 185
| main ();
| ; var int local_24h @ rbp-0x24
| ; var int local_20h @ rbp-0x20
| ; var int local_9h @ rbp-0x9
| ; var int local_8h @ rbp-0x8
| ; DATA XREF from 0x004004fd (entry0)
| 0x004005d6 55 push rbp
| 0x004005d7 4889e5 mov rbp, rsp
| 0x004005da 4883ec30 sub rsp, 0x30 ; '0'
| 0x004005de c745dc010000. mov dword [local_24h], 1
| 0x004005e5 48c745f81807. mov qword [local_8h], str.hAck11t_Fl4g ; 0x400718 ; "hAck11t_Fl4g"
| 0x004005ed bf28074000 mov edi, str.Enter_the_key_to_obtain_the_flag: ; 0x400728 ; "Enter the key to obtain the flag: " ; const char * format
| 0x004005f2 b800000000 mov eax, 0
| 0x004005f7 e8a4feffff call sym.imp.printf ; int printf(const char *format)
| 0x004005fc 488d45e0 lea rax, qword [local_20h]
| 0x00400600 4889c6 mov rsi, rax
| 0x00400603 bf4b074000 mov edi, 0x40074b
| 0x00400608 b800000000 mov eax, 0
| 0x0040060d e8aefeffff call sym.imp.__isoc99_scanf
| 0x00400612 c645f761 mov byte [local_9h], 0x61 ; 'a' ; 97
| 0x00400616 8b45dc mov eax, dword [local_24h]
| 0x00400619 85c0 test eax, eax
| ,=< 0x0040061b 7561 jne 0x40067e | | 0x0040061d 0fbe45f7 movsx eax, byte [local_9h] | | 0x00400621 448d48e7 lea r9d, dword [rax - 0x19] | | 0x00400625 0fbe45f7 movsx eax, byte [local_9h] | | 0x00400629 448d40ec lea r8d, dword [rax - 0x14] | | 0x0040062d 0fbe45f7 movsx eax, byte [local_9h] | | 0x00400631 0fbe55f7 movsx edx, byte [local_9h] | | 0x00400635 8d7a1e lea edi, dword [rdx + 0x1e] ; 30 | | 0x00400638 0fbe55f7 movsx edx, byte [local_9h] | | 0x0040063c 448d5a03 lea r11d, dword [rdx + 3] ; 3 | | 0x00400640 0fbe55f7 movsx edx, byte [local_9h] | | 0x00400644 448d5213 lea r10d, dword [rdx + 0x13] ; 19 | | 0x00400648 0fbe55f7 movsx edx, byte [local_9h] | | 0x0040064c 8d4a0f lea ecx, dword [rdx + 0xf] ; 15 | | 0x0040064f 0fbe55f7 movsx edx, byte [local_9h] | | 0x00400653 83c214 add edx, 0x14 | | 0x00400656 0fbe75f7 movsx esi, byte [local_9h] | | 0x0040065a 83c601 add esi, 1 | | 0x0040065d 4151 push r9 | | 0x0040065f 4150 push r8 | | 0x00400661 50 push rax | | 0x00400662 57 push rdi | | 0x00400663 4589d9 mov r9d, r11d | | 0x00400666 4589d0 mov r8d, r10d | | 0x00400669 bf50074000 mov edi, str.The_hackiit_flag_is:__c_c_c_c_c_c_c_c_c ; 0x400750 ; "The hackiit_flag is: %c%c%c%c%c%c%c%c%c\n" ; const char * format | | 0x0040066e b800000000 mov eax, 0 | | 0x00400673 e828feffff call sym.imp.printf ; int printf(const char *format) | | 0x00400678 4883c420 add rsp, 0x20 | ,==< 0x0040067c eb0a jmp 0x400688 | || ; JMP XREF from 0x0040061b (main) | |-> 0x0040067e bf79074000 mov edi, str.Bad_luck._Try_again... ; rdi ; 0x400779 ; "Bad luck. Try again..." ; const char * s | | 0x00400683 e808feffff call sym.imp.puts ; int puts(const char *s) | | ; JMP XREF from 0x0040067c (main) |--> 0x00400688 b800000000 mov eax, 0
| 0x0040068d c9 leave
\ 0x0040068e c3 ret

Observando el código nos damos cuenta de que hay un condicional “jne” (jump short if not equal/not zero) el cual si no se cumple cierta condición realizará un salto a la línea correspondiente al resultado “Bad luck. Try again…”, por lo que deberemos de parchearlo para que el programa continúe ejecutándose por donde podemos ver el string “The hackiit_flag is: %c%c%c%c%c%c%c%c%c\n”.  Para ello cambiaremos el “jne” por un “je” (jump short if equal), es decir, si se cumple la condición (que nunca se cumplirá) saltará a la parte “Bad luck. Try again…” y si no se cumple (este es nuestro objetivo) saltará al apartado deseado. Para realizar este parche primero nos movemos a la posición de memoria del “jne” con “s 0x0040061b” y lo sustituimos por el “je” con “wa je 0x40067e”. Una vez sustituido solo nos queda salir de radare con “q” y ejecutar el programa de nuevo, obteniendo así la flag:

root@hackiit:/home/carliquiss/CrackMe# ./getflag
Enter the key to obtain the flag: a
The hackiit_flag is: buptdaMH

Por lo tanto la flag es:

hackiit_flag{buptdaMH}

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *