crackmes.one (Example 1)

Setup

Data

  • URL: nutcake’s WhiteRabbit
  • Language: C/C++
  • Platform: Unix/Linux (ELF64)
  • Description: “Can you find the rabbit hole cof cof, I mean, the hidden function?”

Output

$ ./hidden
The only way out is inward





...Voce consegue achar a funcao escondida?

Analysis

Tools
Cutter/Radare2

Disassembly (Origin)

144: secret ();
; var int64_t var_fh @ rbp-0xf
; var int64_t var_eh @ rbp-0xe
; var int64_t var_dh @ rbp-0xd
; var int64_t var_ch @ rbp-0xc
; var int64_t var_8h @ rbp-0x8
; var int64_t var_4h @ rbp-0x4
0x00001145      push    rbp
0x00001146      mov     rbp, rsp
0x00001149      sub     rsp, 0x10
0x0000114d      mov     dword [var_4h], 5
0x00001154      mov     dword [var_8h], 3
0x0000115b      mov     dword [var_ch], 4
0x00001162      mov     byte [var_dh], 0x73 ; 's'
0x00001166      mov     byte [var_eh], 0x64 ; 'd'
0x0000116a      mov     byte [var_fh], 0x63 ; 'c'
0x0000116e      movsx   r9d, byte [var_dh]
0x00001173      mov     eax, dword [var_4h]
0x00001176      sub     eax, dword [var_ch]
0x00001179      mov     r8d, eax
0x0000117c      movsx   edi, byte [var_eh]
0x00001180      mov     eax, dword [var_4h]
0x00001183      sub     eax, dword [var_ch]
0x00001186      mov     esi, eax
0x00001188      movsx   r10d, byte [var_eh]
0x0000118d      movsx   ecx, byte [var_fh]
0x00001191      movsx   edx, byte [var_dh]
0x00001195      mov     eax, dword [var_8h]
0x00001198      push    0
0x0000119a      push    0
0x0000119c      push    r9
0x0000119e      push    0
0x000011a0      push    r8
0x000011a2      mov     r8d, dword [var_ch]
0x000011a6      push    r8
0x000011a8      mov     r8d, dword [var_8h]
0x000011ac      push    r8
0x000011ae      push    0
0x000011b0      push    rdi
0x000011b1      push    rsi
0x000011b2      mov     r9d, r10d
0x000011b5      mov     r8d, 0
0x000011bb      mov     esi, eax
0x000011bd      lea     rdi, str.flag__d_c_c_dn_c_d_c_d__dh_M_d_ds_G_d_ct_dS_d ; 0x2008 ; const char *format
0x000011c4      mov     eax, 0
0x000011c9      call    printf     ; sym.imp.printf ; int printf(const char *format)
0x000011ce      add     rsp, 0x50
0x000011d2      nop
0x000011d3      leave
0x000011d4      ret
52: int main (int argc, char **argv, char **envp);
0x000011d5      push    rbp
0x000011d6      mov     rbp, rsp
0x000011d9      lea     rdi, str.The_only_way_out_is_inward ; 0x2038 ; const char *s
0x000011e0      call    puts       ; sym.imp.puts ; int puts(const char *s)
0x000011e5      lea     rdi, [0x00002058] ; const char *format
0x000011ec      mov     eax, 0
0x000011f1      call    printf     ; sym.imp.printf ; int printf(const char *format)
0x000011f6      lea     rdi, str.Voce_consegue_achar_a_funcao_escondida ; 0x2060 ; const char *s
0x000011fd      call    puts       ; sym.imp.puts ; int puts(const char *s)
0x00001202      mov     eax, 0
0x00001207      pop     rbp
0x00001208      ret

Conclusion
The disassembly shows that there is a function straight above the main function, which isn’t getting called. So let’s modify the main function that it calls the secret function.


Solution

Disassembly (Patched)

52: int main (int argc, char **argv, char **envp);
0x000011d5      push    rbp
0x000011d6      mov     rbp, rsp
0x000011d9      lea     rdi, str.The_only_way_out_is_inward ; 0x2038 ; const char *s
0x000011e0      call    puts       ; sym.imp.puts ; int puts(const char *s)
0x000011e5      lea     rdi, [0x00002058] ; const char *format
0x000011ec      mov     eax, 0
0x000011f1      call    secret     ; sym.secret
0x000011f6      nop
0x000011f7      nop
0x000011f8      nop
0x000011f9      nop
0x000011fa      nop
0x000011fb      nop
0x000011fc      nop
0x000011fd      nop
0x000011fe      nop
0x000011ff      nop
0x00001200      nop
0x00001201      nop
0x00001202      nop
0x00001203      nop
0x00001204      nop
0x00001205      nop
0x00001206      nop
0x00001207      pop     rbp
0x00001208      ret

Output

$ ./hidden
The only way out is inward





flag{3sc0nd1d0_3h_M41s_G0st0S0}