Codegate Prequals - BabyMISC

Hola majos! En el episodio de hoy os traemos el writeup de la prueba de BabyMISC de las Prequals de Codegate 2017. Esperamos que os guste.

.0x00. Intro

En este reto se nos facilitaba un binario y una ip donde corria un servicio, al conectarte aparecia lo siguiente:

[*] Ok, Let's Start. Input the write string on each stage!:)
[*] -- STAGE 01 ----------
[+] KEY : H��x�H)�H�H��L��H)���1� 
[+] Input >

Abrimos el binario con r2 y se observan 3 funciones que son llamadas desde el main que parecen corresponder con los 3 stages que hay que superar para obtener la flag.

.0x01. STAGE 01

La primera funcion, a parte de imprimir el texto, lee las cadena de entrada INPUT y realiza posteriormente 3 checks:

      .----------------------------------------------------------------------------.
      | [0x400ea8] ;[h]                                                            |
      | (fcn) fcn.stage01 349                                                      |
      |   fcn.stage01 ();                                                          |
      | ; var int local_98h @ rbp-0x98                                             |
      | ; var int local_90h @ rbp-0x90                                             |
      | ; var int local_88h @ rbp-0x88                                             |
      | ; var int local_80h @ rbp-0x80                                             |
      | ; var int local_18h @ rbp-0x18                                             |
      |    ; CALL XREF from 0x004012de (main)                                      |
      | push rbp                                                                   |
      | mov rbp, rsp                                                               |
      | | ;-- rip:                                                                 |
      | push rbx                                                                   |
      | sub rsp, 0x98                                                              |
      |    ; [0x28:8]=0x2208                                                       |
      |    ; '('                                                                   |
      | mov rax, qword fs:[0x28]                                                   |
      | mov qword [rbp - local_18h], rax                                           |
      | xor eax, eax                                                               |
      | mov qword [rbp - local_88h], str.TjBfbTRuX2M0bDFfYWc0aW5fWTNzdDNyZDR5Oig_  |
      |    ; [0x6020e8:8]=0x6e756275362d302e                                       |
      |    ; LEA obj.stdout                                                        |
      |    ; ".0-6ubuntu1~16.04.4) 5.4.0 20160609" @ 0x6020e8                      |
      | mov rax, qword [obj.stdout]                                                |
      | mov esi, 0                                                                 |
      | mov rdi, rax                                                               |
      | call sym.imp.setbuf ;[a]                                                   |
      |    ; "[*] -- STAGE 01 ----------" @ 0x401429                               |
      | mov edi, str._______STAGE_01___________                                    |
      | call sym.imp.puts ;[b]                                                     |
      | mov rax, qword [rbp - local_98h]                                           |
      | mov rsi, rax                                                               |
      |    ; "[+] KEY : %s." @ 0x401444                                            |
      | mov edi, str.____KEY_:__s_n                                                |
      | mov eax, 0                                                                 |
      |    ; sym.imp.setbuf-0xf0                                                   |
      | call sym.imp.printf ;[c]                                                   |
      |    ; "[+] Input > " @ 0x401452                                             |
      | mov edi, str.input                                                         |
      | call sym.imp.puts ;[b]                                                     |
      |    ; [0x6020e0:8]=0x342e352075746e75                                       |
      |    ; LEA obj.stdin                                                         |
      |    ; "untu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609" @ 0x6020e0              |
      | mov rax, qword [obj.stdin]                                                 |
      | mov esi, 0                                                                 |
      | mov rdi, rax                                                               |
      | call sym.imp.setbuf ;[a]                                                   |
      | lea rax, [rbp - local_80h]                                                 |
      | mov rsi, rax                                                               |
      |    ; "%99s" @ 0x40145f                                                     |
      | mov edi, str._99s                                                          |
      | mov eax, 0                                                                 |
      | call sym.imp.__isoc99_scanf ;[d]                                           |
      | lea rdx, [rbp - local_98h]                                                 |
      | mov rax, qword [rbp - local_88h]                                           |
      | mov rsi, rdx                                                               |
      | mov rdi, rax                                                               |
      | call fcn.00400d35 ;[e]                                                     |
      | lea rdx, [rbp - local_90h]                                                 |
      | lea rax, [rbp - local_80h]                                                 |
      | mov rsi, rdx                                                               |
      | mov rdi, rax                                                               |
      | call fcn.00400d35 ;[e]                                                     |
      | mov rax, qword [rbp - local_90h]                                           |
      | mov rsi, rax                                                               |
      |    ; "[*] USER : %s." @ 0x401464                                           |
      | mov edi, str.____USER_:__s_n                                               |
      | mov eax, 0                                                                 |
      |    ; sym.imp.setbuf-0xf0                                                   |
      | call sym.imp.printf ;[c]                                                   |
      | mov rax, qword [rbp - local_88h]                                           |
      | mov rdi, rax                                                               |
      | call sym.imp.strlen ;[f]                                                   |
      | mov rbx, rax                                                               |
      | lea rax, [rbp - local_80h]                                                 |
      | mov rdi, rax                                                               |
      | call sym.imp.strlen ;[f]                                                   |
      | cmp rbx, rax                                                               |
      | jne 0x400fe2 ;[g]                                                          |
      `----------------------------------------------------------------------------'
              f t
              '--------.---------------------------------.
                       |                                 |
                       |                                 |
               .-----------------------------------.     |
               |  0x400fa4 ;[j]                    |     |
               | mov rdx, qword [rbp - local_98h]  |     |
               | mov rax, qword [rbp - local_90h]  |     |
               | mov rsi, rdx                      |     |
               | mov rdi, rax                      |     |
               | call sym.imp.strcmp ;[i]          |     |
               | test eax, eax                     |     |
               | jne 0x400fe2 ;[g]                 |     |
               `-----------------------------------'     |
                       f t                               |
                 .-----' '-------------------------.     |
                 |                                 |     |
                 |                                 |     |
         .----------------------------------.      |     |
         |  0x400fc1 ;[k]                   |      |     |
         | mov rdx, qword [rbp - local_88h] |      |     |
         | lea rax, [rbp - local_80h]       |      |     |
         | mov rsi, rdx                     |      |     |
         | mov rdi, rax                     |      |     |
         | call sym.imp.strcmp ;[i]         |      |     |
         | test eax, eax                    |      |     |
         | je 0x400fe2 ;[g]                 |      |     |
         `----------------------------------'      |     |
                 f t                               |     |
                 '--.-------------------------.   .'-----'
                    |                         |   |
                    |                         |   |
            .--------------------.      .--------------------.
            |  0x400fdb ;[m]     |      |  0x400fe2 ;[g]     |
            | mov eax, 1         |      | mov eax, 0         |
            | jmp 0x400fe7 ;[l]  |      `--------------------'
            `--------------------'          v
                v                           |
                '--.------------------------'
                   |
                   |
               .-------------------------------------------.
               |  0x400fe7 ;[l]                            |
               |      ; JMP XREF from 0x00400fe0 (stage01) |
               | mov rcx, qword [rbp - local_18h]          |
               | xor rcx, qword fs:[0x28]                  |
               | je 0x400ffb ;[n]                          |
               `-------------------------------------------'
                       f t
        .--------------' '------------------------.
        |                                         |
        |                                         |
.------------------------------------.      .--------------------.
|  0x400ff6 ;[p]                     |      |  0x400ffb ;[n]     |
| call sym.imp.__stack_chk_fail ;[o] |      | add rsp, 0x98      |
`------------------------------------'      | pop rbx            |
                                            | pop rbp            |
                                            | ret                |
                                            `--------------------'

El primer check comprueba que la cadena introducida tenga la misma longitud que cierta cadena en base64 contenida en el binario:

0x00400f81      488b8578ffff.  mov rax, qword [rbp - local_88h] ; local_88h contiene string TjBfbTRuX2M0bDFfYWc0aW5fWTNzdDNyZDR5Oig=
0x00400f88      4889c7         mov rdi, rax
0x00400f8b      e870fbffff     call sym.imp.strlen        ; size_t strlen(const char *s)
0x00400f90      4889c3         mov rbx, rax
0x00400f93      488d4580       lea rax, [rbp - local_80h] ; local_80h contiene el string enviado como INPUT
0x00400f97      4889c7         mov rdi, rax
0x00400f9a      e861fbffff     call sym.imp.strlen        ; size_t strlen(const char *s)
0x00400f9f      4839c3         cmp rbx, rax
0x00400fa2      753e           jne 0x400fe2               ; salta a exit

El segundo check comprueba que la decodificacion de la cadena introducida sea la misma que la decodificacion de la cadena en base64 contenida en el binario (N0_m4n_c4l1_ag4in_Y3st3rd4y:():

0x00400f39      488d9568ffff.  lea rdx, [rbp - local_98h] ; local_98h contendra el string TjBfbTRuX2M0bDFfYWc0aW5fWTNzdDNyZDR5Oig= decodeado en base64 ("N0_m4n_c4l1_ag4in_Y3st3rd4y:(")
0x00400f40      488b8578ffff.  mov rax, qword [rbp - local_88h] ; local_88h contiene string TjBfbTRuX2M0bDFfYWc0aW5fWTNzdDNyZDR5Oig=
0x00400f47      4889d6         mov rsi, rdx
0x00400f4a      4889c7         mov rdi, rax
0x00400f4d      e8e3fdffff     call 0x400d35              ; funcion que hace el decoding base64
0x00400f52      488d9570ffff.  lea rdx, [rbp - local_90h] ; local_90h contendra el string enviado como INPUT decodeado en base64
0x00400f59      488d4580       lea rax, [rbp - local_80h] ; local_80h contiene el string enviado como INPUT
0x00400f5d      4889d6         mov rsi, rdx
0x00400f60      4889c7         mov rdi, rax
0x00400f63      e8cdfdffff     call 0x400d35              ; funcion que hace el decoding base64

...

0x00400fa4      488b9568ffff.  mov rdx, qword [rbp - local_98h] ; local_98h contiene
0x00400fab      488b8570ffff.  mov rax, qword [rbp - local_90h]
0x00400fb2      4889d6         mov rsi, rdx
0x00400fb5      4889c7         mov rdi, rax
0x00400fb8      e893fbffff     call sym.imp.strcmp        ; int strcmp(const char *s1, const char *s2)
0x00400fbd      85c0           test eax, eax
0x00400fbf      7521           jne 0x400fe2               ; salta a exit

Por último el tercer check comprueba que la cadena introducida no sea la misma que la cadena en base64 contenida en el binario:

0x00400fc1      488b9578ffff.  mov rdx, qword [rbp - local_88h] ; local_88h contiene string TjBfbTRuX2M0bDFfYWc0aW5fWTNzdDNyZDR5Oig=
0x00400fc8      488d4580       lea rax, [rbp - local_80h] ; local_80h contiene el string enviado como INPUT
0x00400fcc      4889d6         mov rsi, rdx
0x00400fcf      4889c7         mov rdi, rax
0x00400fd2      e879fbffff     call sym.imp.strcmp        ; int strcmp(const char *s1, const char *s2)
0x00400fd7      85c0           test eax, eax
0x00400fd9      7407           je 0x400fe2                ; salta a exit

Para que el string introducido cumpla estas tres condiciones, se encodea en base64 la cadena N0_m4n_c4l1_ag4in_Y3st3rd4y:( añadiéndole el caracter nulo al final de la misma, de tal manera que queda la siguiente cadena en base64:

~ echo "TjBfbTRuX2M0bDFfYWc0aW5fWTNzdDNyZDR5Oig=" | base64 -d
N0_m4n_c4l1_ag4in_Y3st3rd4y:(%
~ echo "TjBfbTRuX2M0bDFfYWc0aW5fWTNzdDNyZDR5OigA" | base64 -d
N0_m4n_c4l1_ag4in_Y3st3rd4y:(%   

.0x02. STAGE 02

La segunda funcion, lee dos cadenas de entrada y posteriormente realiza 2 checks:

            .----------------------------------------------------------------.
            | [0x401005] ;[g]                                                |
            | (fcn) fcn.stage02 317                                          |
            |   fcn.stage02 ();                                              |
            | ; var int local_100h @ rbp-0x100                               |
            | ; var int local_f8h @ rbp-0xf8                                 |
            | ; var int local_f0h @ rbp-0xf0                                 |
            | ; var int local_80h @ rbp-0x80                                 |
            | ; var int local_18h @ rbp-0x18                                 |
            |    ; CALL XREF from 0x004012f6 (main)                          |
            |    ; CALL XREF from 0x00401005 (fcn.stage02)                   |
            | push rbp                                                       |
            | mov rbp, rsp                                                   |
            | push rbx                                                       |
            | sub rsp, 0xf8                                                  |
            |    ; [0x28:8]=0x2208                                           |
            |    ; '('                                                       |
            | mov rax, qword fs:[0x28]                                       |
            | mov qword [rbp - local_18h], rax                               |
            | xor eax, eax                                                   |
            |    ; [0x6020e8:8]=0x6e756275362d302e                           |
            |    ; LEA obj.stdout                                            |
            |    ; ".0-6ubuntu1~16.04.4) 5.4.0 20160609" @ 0x6020e8          |
            | mov rax, qword [obj.stdout]                                    |
            | mov esi, 0                                                     |
            | mov rdi, rax                                                   |
            | call sym.imp.setbuf ;[a]                                       |
            |    ; "[*] -- STAGE 02 ----------" @ 0x401473                   |
            | mov edi, str._______STAGE_02___________                        |
            | call sym.imp.puts ;[b]                                         |
            |    ; "[+] Input 1 " @ 0x40148e                                 |
            | mov edi, str.____Input_1                                       |
            | call sym.imp.puts ;[b]                                         |
            |    ; [0x6020e0:8]=0x342e352075746e75                           |
            |    ; LEA obj.stdin                                             |
            |    ; "untu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609" @ 0x6020e0  |
            | mov rax, qword [obj.stdin]                                     |
            | mov esi, 0                                                     |
            | mov rdi, rax                                                   |
            | call sym.imp.setbuf ;[a]                                       |
            | lea rax, [rbp - local_f0h]                                     |
            | mov rsi, rax                                                   |
            |    ; "%99s" @ 0x40145f                                         |
            | mov edi, str._99s                                              |
            | mov eax, 0                                                     |
            | call sym.imp.__isoc99_scanf ;[c]                               |
            |    ; "[+] Input 2 " @ 0x40149b                                 |
            | mov edi, str.____Input_2                                       |
            | call sym.imp.puts ;[b]                                         |
            |    ; [0x6020e0:8]=0x342e352075746e75                           |
            |    ; LEA obj.stdin                                             |
            |    ; "untu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609" @ 0x6020e0  |
            | mov rax, qword [obj.stdin]                                     |
            | mov esi, 0                                                     |
            | mov rdi, rax                                                   |
            | call sym.imp.setbuf ;[a]                                       |
            | lea rax, [rbp - local_80h]                                     |
            | mov rsi, rax                                                   |
            |    ; "%99s" @ 0x40145f                                         |
            | mov edi, str._99s                                              |
            | mov eax, 0                                                     |
            | call sym.imp.__isoc99_scanf ;[c]                               |
            | lea rdx, [rbp - local_100h]                                    |
            | lea rax, [rbp - local_f0h]                                     |
            | mov rsi, rdx                                                   |
            | mov rdi, rax                                                   |
            | call fcn.00400d35 ;[d]                                         |
            | lea rdx, [rbp - local_f8h]                                     |
            | lea rax, [rbp - local_80h]                                     |
            | mov rsi, rdx                                                   |
            | mov rdi, rax                                                   |
            | call fcn.00400d35 ;[d]                                         |
            | lea rax, [rbp - local_f0h]                                     |
            | mov rdi, rax                                                   |
            | call sym.imp.strlen ;[e]                                       |
            | mov rbx, rax                                                   |
            | lea rax, [rbp - local_80h]                                     |
            | mov rdi, rax                                                   |
            | call sym.imp.strlen ;[e]                                       |
            | cmp rbx, rax                                                   |
            | je 0x40111f ;[f]                                               |
            `----------------------------------------------------------------'
                    f t
                    '-.-----------------------------------.
                      |                                   |
                      |                                   |
              .------------------------------------.      |
              |  0x4010fb ;[i]                     |      |
              | mov rdx, qword [rbp - local_f8h]   |      |
              | mov rax, qword [rbp - local_100h]  |      |
              | mov rsi, rdx                       |      |
              | mov rdi, rax                       |      |
              | call sym.imp.strcmp ;[h]           |      |
              | test eax, eax                      |      |
              | jne 0x40111f ;[f]                  |      |
              `------------------------------------'      |
                      f t                                 |
                     .' '----------------------.   .------'
                     |                         |   |
                     |                         |   |
             .--------------------.      .--------------------.
             |  0x401118 ;[k]     |      |  0x40111f ;[f]     |
             | mov eax, 1         |      | mov eax, 0         |
             | jmp 0x401124 ;[j]  |      `--------------------'
             `--------------------'          v
                 v                           |
                 '.--------------------------'
                  |
                  |
              .-----------------------------------------------.
              |  0x401124 ;[j]                                |
              |      ; JMP XREF from 0x0040111d (fcn.stage02) |
              | mov rcx, qword [rbp - local_18h]              |
              | xor rcx, qword fs:[0x28]                      |
              | je 0x401138 ;[l]                              |
              `-----------------------------------------------'
                      f t
         .------------' '--------------------------.
         |                                         |
         |                                         |
 .------------------------------------.      .--------------------.
 |  0x401133 ;[n]                     |      |  0x401138 ;[l]     |
 | call sym.imp.__stack_chk_fail ;[m] |      | add rsp, 0xf8      |
 `------------------------------------'      | pop rbx            |
                                             | pop rbp            |
                                             | ret                |
                                             `--------------------'

El primer check comprueba que las cadenas introducidas no tengan la misma longitud:

0x004010d8      488d8510ffff.  lea rax, [rbp - local_f0h] ; local_f0h contiene input1
0x004010df      4889c7         mov rdi, rax
0x004010e2      e819faffff     call sym.imp.strlen        ; size_t strlen(const char *s)
0x004010e7      4889c3         mov rbx, rax
0x004010ea      488d4580       lea rax, [rbp - local_80h] ; local_80h contiene input2
0x004010ee      4889c7         mov rdi, rax
0x004010f1      e80afaffff     call sym.imp.strlen        ; size_t strlen(const char *s)
0x004010f6      4839c3         cmp rbx, rax
0x004010f9      7424           je 0x40111f                ; salta a exit

El segundo check comprueba que las cadenas introducidas decodeadas en base64 sean iguales:

0x004010a9      488d9500ffff.  lea rdx, [rbp - local_100h] ; local_100h contendra input1 decodeado en base64
0x004010b0      488d8510ffff.  lea rax, [rbp - local_f0h]  ; local_f0h contiene input1
0x004010b7      4889d6         mov rsi, rdx
0x004010ba      4889c7         mov rdi, rax
0x004010bd      e873fcffff     call fcn.00400d35           ; funcion que hace el decoding base64
0x004010c2      488d9508ffff.  lea rdx, [rbp - local_f8h]  ; local_f8h contendra input2 decodeado en base64
0x004010c9      488d4580       lea rax, [rbp - local_80h]  ; local_80h contiene input2
0x004010cd      4889d6         mov rsi, rdx
0x004010d0      4889c7         mov rdi, rax
0x004010d3      e85dfcffff     call fcn.00400d35           ; funcion que hace el decoding base64

...

0x004010fb      488b9508ffff.  mov rdx, qword [rbp - local_f8h]  ; local_f8h contiene input2 decodeado en base64
0x00401102      488b8500ffff.  mov rax, qword [rbp - local_100h] ; local_100h contiene input1 decodeado en base64
0x00401109      4889d6         mov rsi, rdx
0x0040110c      4889c7         mov rdi, rax
0x0040110f      e83cfaffff     call sym.imp.strcmp        ; int strcmp(const char *s1, const char *s2)
0x00401114      85c0           test eax, eax
0x00401116      7507           jne 0x40111f               ; salta a exit

Por tanto para cumplir estos requisitos se puede añadir padding a cualquier cadena en base64 al final de la misma añadiendo un simbolo “=”:

~ echo "aG9sYQo=" | base64 -d
hola
~ echo "aG9sYQo==" | base64 -d
hola

.0x03. STAGE 03

La tercera función nos permite ejecutar un comando:

  .---------------------------------------------------------------------------.
  | [0x401142] ;[g]                                                           |
  | (fcn) fcn.stage03 373                                                     |
  |   fcn.stage03 ();                                                         |
  | ; var int local_e8h @ rbp-0xe8                                            |
  | ; var int local_e0h @ rbp-0xe0                                            |
  | ; var int local_70h @ rbp-0x70                                            |
  | ; var int local_8h @ rbp-0x8                                              |
  |    ; CALL XREF from 0x0040130e (main)                                     |
  |    ; CALL XREF from 0x00401142 (fcn.stage03)                              |
  | push rbp                                                                  |
  | mov rbp, rsp                                                              |
  | sub rsp, 0xf0                                                             |
  |    ; [0x28:8]=0x2208                                                      |
  |    ; '('                                                                  |
  | mov rax, qword fs:[0x28]                                                  |
  | mov qword [rbp - local_8h], rax                                           |
  | xor eax, eax                                                              |
  |    ; [0x6020e8:8]=0x6e756275362d302e                                      |
  |    ; LEA obj.stdout                                                       |
  |    ; ".0-6ubuntu1~16.04.4) 5.4.0 20160609" @ 0x6020e8                     |
  | mov rax, qword [obj.stdout]                                               |
  | mov esi, 0                                                                |
  | mov rdi, rax                                                              |
  | call sym.imp.setbuf ;[a]                                                  |
  |    ; "[*] -- STAGE 03 ----------" @ 0x4014a8                              |
  | mov edi, str._______STAGE_03___________                                   |
  | call sym.imp.puts ;[b]                                                    |
  |    ; "[+] Ok, It's easy task to you, isn't it? :)" @ 0x4014c8             |
  | mov edi, str.____Ok__It_s_easy_task_to_you__isn_t_it__:_                  |
  | call sym.imp.puts ;[b]                                                    |
  |    ; "[+] So I will give a chance to execute one command! :)" @ 0x4014f8  |
  | mov edi, str.____So_I_will_give_a_chance_to_execute_one_command__:_       |
  | call sym.imp.puts ;[b]                                                    |
  |    ; "[*] Input > " @ 0x40152f                                            |
  | mov edi, str.____Input__                                                  |
  | call sym.imp.puts ;[b]                                                    |
  |    ; [0x6020e0:8]=0x342e352075746e75                                      |
  |    ; LEA obj.stdin                                                        |
  |    ; "untu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609" @ 0x6020e0             |
  | mov rax, qword [obj.stdin]                                                |
  | mov esi, 0                                                                |
  | mov rdi, rax                                                              |
  | call sym.imp.setbuf ;[a]                                                  |
  | lea rax, [rbp - local_e0h]                                                |
  | mov rsi, rax                                                              |
  |    ; "%99s" @ 0x40145f                                                    |
  | mov edi, str._99s                                                         |
  | mov eax, 0                                                                |
  | call sym.imp.__isoc99_scanf ;[c]                                          |
  | lea rdx, [rbp - local_e8h]                                                |
  | lea rax, [rbp - local_e0h]                                                |
  | mov rsi, rdx                                                              |
  | mov rdi, rax                                                              |
  | call fcn.00400d35 ;[d]                                                    |
  | mov rax, qword [rbp - local_e8h]                                          |
  | mov rdi, rax                                                              |
  | call fcn.00400e0b ;[e]                                                    |
  | test eax, eax                                                             |
  | je 0x401205 ;[f]                                                          |
  `---------------------------------------------------------------------------'
          f t
          '.'------------------------------------.
           |                                     |
           |                                     |
   .--------------------------------.      .---------------------------------.
   |  0x4011f1 ;[i]                 |      |  0x401205 ;[f]                  |
   |      ; "[*] NoNoNo" @ 0x40153c |      | lea rax, [rbp - local_70h]      |
   | mov edi, str.____NoNoNo        |      | movabs rcx, 0x206e2d206f686365  |
   | call sym.imp.puts ;[b]         |      | mov qword [rax], rcx            |
   | mov eax, 0                     |      | mov byte [rax + 8], 0           |
   | jmp 0x4012a1 ;[h]              |      | lea rdx, [rbp - local_e0h]      |
   `--------------------------------'      | lea rax, [rbp - local_70h]      |
       v                                   | mov rsi, rdx                    |
       |                                   | mov rdi, rax                    |
       |                                   | call sym.imp.strcat ;[j]        |
       |                                   | lea rax, [rbp - local_70h]      |
       |                                   | mov rcx, -1                     |
       |                                   | mov rdx, rax                    |
       |                                   | mov eax, 0                      |
       |                                   | mov rdi, rdx                    |
       |                                   | repne scasb al, byte [rdi]      |
       |                                   | mov rax, rcx                    |
       |                                   | not rax                         |
       |                                   | lea rdx, [rax - 1]              |
       |                                   | lea rax, [rbp - local_70h]      |
       |                                   |    ; '('                        |
       |                                   | add rax, rdx                    |
       |                                   | movabs rsi, 0x3665736162207c20  |
       |                                   | mov qword [rax], rsi            |
       |                                   | movabs rcx, 0x73207c20642d2034  |
       |                                   | mov qword [rax + 8], rcx        |
       '------------.                      |    ; 'h'                        |
                    |                      |    ; [0x68:2]=504               |
                    |                      |    ; 'h'                        |
                    |                      | mov word [rax + 0x10], 0x68     |
                    |                      | lea rax, [rbp - local_70h]      |
                    |                      | mov rsi, rax                    |
                    |                      |    ; "# %99s." @ 0x401547       |
                    |                      | mov edi, str.___99s_n           |
                    |                      | mov eax, 0                      |
                    |                      |    ; sym.imp.setbuf-0xf0        |
                    |                      | call sym.imp.printf ;[k]        |
                    |                      | lea rax, [rbp - local_70h]      |
                    |                      | mov rdi, rax                    |
                    |                      | call sym.imp.system ;[l]        |
                    |                      | mov eax, 1                      |
                    |                      `---------------------------------'
                    |                          v
                    .--------------------------'
                    |
                    |
                .-----------------------------------------------.
                |  0x4012a1 ;[h]                                |
                |      ; JMP XREF from 0x00401200 (fcn.stage03) |
                | mov rdx, qword [rbp - local_8h]               |
                | xor rdx, qword fs:[0x28]                      |
                | je 0x4012b5 ;[m]                              |
                `-----------------------------------------------'
                        f t
           .------------' '--------------------------.
           |                                         |
           |                                         |
   .------------------------------------.      .--------------------.
   |  0x4012b0 ;[o]                     |      |  0x4012b5 ;[m]     |
   | call sym.imp.__stack_chk_fail ;[n] |      | leave              |
   `------------------------------------'      | ret                |
                                               `--------------------'

Pero previamente decodifica la cadena de entra en base64 y llama a una función que sanitiza el comando introducido:

0x004011c5      488d9518ffff.  lea rdx, [rbp - local_e8h]  ; local_e8h contendra la cadena introducida decodificada en base64 
0x004011cc      488d8520ffff.  lea rax, [rbp - local_e0h]  ; local_e0h contiene la cadena introducida
0x004011d3      4889d6         mov rsi, rdx
0x004011d6      4889c7         mov rdi, rax
0x004011d9      e857fbffff     call fcn.00400d35           ; funcion que decodifica en base64
0x004011de      488b8518ffff.  mov rax, qword [rbp - local_e8h]
0x004011e5      4889c7         mov rdi, rax
0x004011e8      e81efcffff     call fcn.00400e0b           ; funcion que compara contra blacklist
0x004011ed      85c0           test eax, eax
0x004011ef      7414           je 0x401205                 ; salta a exit

Aquí tenemos las funciones en detalle:

/ (fcn) fcn.00400e0b 157
|   fcn.00400e0b ();
|           ; var int local_68h @ rbp-0x68
|           ; var int local_5ch @ rbp-0x5c
|           ; var int local_58h @ rbp-0x58
|           ; var int local_50h @ rbp-0x50
|           ; var int local_8h @ rbp-0x8
|           ; var int local_0h @ rbp-0x0
|              ; CALL XREF from 0x004011e8 (fcn.stage03)
|              ; CALL XREF from 0x00400e0b (fcn.00400e0b)
|           0x00400e0b      55             push rbp
|           0x00400e0c      4889e5         mov rbp, rsp
|           0x00400e0f      4883ec70       sub rsp, 0x70               ; 'p'
|           0x00400e13      48897d98       mov qword [rbp - local_68h], rdi
|           0x00400e17      64488b042528.  mov rax, qword fs:[0x28]    ; [0x28:8]=0x2208 ; '('
|           0x00400e20      488945f8       mov qword [rbp - local_8h], rax
|           0x00400e24      31c0           xor eax, eax
|           0x00400e26      48c745a8c813.  mov qword [rbp - local_58h], str._________________________cat___flag___bin___sh___bash_
|           0x00400e2e      488b4da8       mov rcx, qword [rbp - local_58h]
|           0x00400e32      488d45b0       lea rax, [rbp - local_50h]
|           0x00400e36      ba01000000     mov edx, 1
|           0x00400e3b      4889ce         mov rsi, rcx
|           0x00400e3e      4889c7         mov rdi, rax
|           0x00400e41      e8dafcffff     call sym.imp.regcomp
|           0x00400e46      85c0           test eax, eax
|       ,=< 0x00400e48      7407           je 0x400e51
|       |   0x00400e4a      b800000000     mov eax, 0
|      ,==< 0x00400e4f      eb41           jmp 0x400e92
|      |`-> 0x00400e51      488b7598       mov rsi, qword [rbp - local_68h]
|      |    0x00400e55      488d45b0       lea rax, [rbp - local_50h]
|      |    0x00400e59      41b800000000   mov r8d, 0
|      |    0x00400e5f      b900000000     mov ecx, 0
|      |    0x00400e64      ba00000000     mov edx, 0
|      |    0x00400e69      4889c7         mov rdi, rax
|      |    0x00400e6c      e82ffcffff     call sym.imp.regexec
|      |    0x00400e71      8945a4         mov dword [rbp - local_5ch], eax
|      |    0x00400e74      488d45b0       lea rax, [rbp - local_50h]
|      |    0x00400e78      4889c7         mov rdi, rax
|      |    0x00400e7b      e8f0fcffff     call sym.imp.regfree       ; void free(void *ptr)
|      |    0x00400e80      837da400       cmp dword [rbp - local_5ch], 0
|      |,=< 0x00400e84      7507           jne 0x400e8d
|      ||   0x00400e86      b801000000     mov eax, 1
|     ,===< 0x00400e8b      eb05           jmp 0x400e92
|     ||`-> 0x00400e8d      b800000000     mov eax, 0
|     ||       ; JMP XREF from 0x00400e8b (fcn.00400e0b)
|     ||       ; JMP XREF from 0x00400e4f (fcn.00400e0b)
|     ``--> 0x00400e92      488b55f8       mov rdx, qword [rbp - local_8h]
|           0x00400e96      644833142528.  xor rdx, qword fs:[0x28]
|       ,=< 0x00400e9f      7405           je 0x400ea6
|       |   0x00400ea1      e89afcffff     call sym.imp.__stack_chk_failvoid)
|       `-> 0x00400ea6      c9             leave
\           0x00400ea7      c3             ret

La blacklist es la siguiente:

[0x00400e0b]> ps@str._________________________cat___flag___bin___sh___bash_
[/|$|-|_|&|>|`|'|"|%|;]|(cat)|(flag)|(bin)|(sh)|(bash)

Por tanto utilizando el comando tail sobre todos los ficheros de la carpeta nos bypasseamos el blacklist:

~ echo "tail *" | base64
dGFpbCAqCg==

.0x04. EL FINAL

Juntando el resultado de los 3 stages nos conectamos al servicio e introducimos las cadenas obtenidas conseguiendo el flag:

~ nc 110.10.212.138 19090
[*] Ok, Let's Start. Input the write string on each stage!:)
[*] -- STAGE 01 ----------
[+] KEY : H��x�H)�H 
[+] Input > 
TjBfbTRuX2M0bDFfYWc0aW5fWTNzdDNyZDR5OigA
[*] USER : N0_m4n_c4l1_ag4in_Y3st3rd4y:(
[+] -- NEXT STAGE! ----------
[*] -- STAGE 02 ----------
[+] Input 1 
aG9sYQo=
[+] Input 2 
aG9sYQo==
[+] -- NEXT STAGE! ----------
[*] -- STAGE 03 ----------
[+] Ok, It's easy task to you, isn't it? :)
[+] So I will give a chance to execute one command! :)
[*] Input > 
dGFpbCAqCg==
#                                                               echo -n dGFpbCAqCg== | base64 -d | sh
FLAG{Nav3r_L3t_y0ur_L3ft_h4nd_kn0w_wh4t_y0ur_r1ghT_h4nd5_H4ck1ng}

Nos vemos en los bares!!

kms

Made with lots of coffee and Hugo.