Reykjavik
3 minutos de lectura
Se nos proporciona un binario de 64 bits llamado Reykjavik
:
$ file Reykjavik
Reykjavik: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=9bc04368dbcefb4491573ac8feea3a32e31ed59f, for GNU/Linux 3.2.0, not stripped
Si lo ejecutamos, vemos que necesita un argumento de línea de comandos:
$ ./Reykjavik
Usage: Reykjavik CTFlearn{flag}
$ ./Reykjavik 'CTFlearn{flag}'
Welcome to the CTFlearn Reversing Challenge Reykjavik v2: CTFlearn{flag}
Compile Options: ${CMAKE_CXX_FLAGS} -O0 -fno-stack-protector -mno-sse
Sorry Dude, 'CTFlearn{flag}' is not the flag :-(
Vamos a usar GDB para depurar el programa. Primero, podemos mostrar el desensamblado de la función main
:
$ gdb -q Reykjavik
Reading symbols from Reykjavik...
(No debugging symbols found in Reykjavik)
gef➤ disassemble main
Dump of assembler code for function main:
0x00000000000010a0 <+0>: endbr64
0x00000000000010a4 <+4>: push r13
0x00000000000010a6 <+6>: push r12
0x00000000000010a8 <+8>: push rbp
0x00000000000010a9 <+9>: sub rsp,0x20
0x00000000000010ad <+13>: cmp edi,0x1
0x00000000000010b0 <+16>: je 0x11b5 <main+277>
0x00000000000010b6 <+22>: mov rbp,QWORD PTR [rsi+0x8]
0x00000000000010ba <+26>: mov edi,0x1
0x00000000000010bf <+31>: xor eax,eax
0x00000000000010c1 <+33>: lea rsi,[rip+0xf60] # 0x2028
0x00000000000010c8 <+40>: mov rdx,rbp
0x00000000000010cb <+43>: call 0x1090 <__printf_chk@plt>
0x00000000000010d0 <+48>: lea rdi,[rip+0xf91] # 0x2068
0x00000000000010d7 <+55>: call 0x1070 <puts@plt>
0x00000000000010dc <+60>: lea rdx,[rip+0xfcd] # 0x20b0
0x00000000000010e3 <+67>: mov ecx,0x20
0x00000000000010e8 <+72>: mov rsi,rbp
0x00000000000010eb <+75>: mov rdi,rdx
0x00000000000010ee <+78>: repz cmps BYTE PTR ds:[rsi],BYTE PTR es:[rdi]
0x00000000000010f0 <+80>: seta al
0x00000000000010f3 <+83>: sbb al,0x0
0x00000000000010f5 <+85>: test al,al
0x00000000000010f7 <+87>: je 0x11c9 <main+297>
0x00000000000010fd <+93>: mov rdx,QWORD PTR [rip+0x2f0c] # 0x4010 <data>
0x0000000000001104 <+100>: mov r13,rsp
0x0000000000001107 <+103>: mov rsi,rbp
0x000000000000110a <+106>: mov BYTE PTR [rsp+0x1b],0x0
0x000000000000110f <+111>: movabs rax,0xabababababababab
0x0000000000001119 <+121>: mov rdi,r13
0x000000000000111c <+124>: xor rdx,rax
0x000000000000111f <+127>: mov QWORD PTR [rsp],rdx
0x0000000000001123 <+131>: mov rdx,QWORD PTR [rip+0x2eee] # 0x4018 <data+8>
0x000000000000112a <+138>: xor rdx,rax
0x000000000000112d <+141>: xor rax,QWORD PTR [rip+0x2eec] # 0x4020 <data+16>
0x0000000000001134 <+148>: mov QWORD PTR [rsp+0x10],rax
0x0000000000001139 <+153>: movzx eax,BYTE PTR [rip+0x2ee8] # 0x4028 <data+24>
0x0000000000001140 <+160>: mov QWORD PTR [rsp+0x8],rdx
0x0000000000001145 <+165>: xor eax,0xffffffab
0x0000000000001148 <+168>: mov BYTE PTR [rsp+0x18],al
0x000000000000114c <+172>: movzx eax,BYTE PTR [rip+0x2ed6] # 0x4029 <data+25>
0x0000000000001153 <+179>: xor eax,0xffffffab
0x0000000000001156 <+182>: mov BYTE PTR [rsp+0x19],al
0x000000000000115a <+186>: movzx eax,BYTE PTR [rip+0x2ec9] # 0x402a <data+26>
0x0000000000001161 <+193>: xor eax,0xffffffab
0x0000000000001164 <+196>: mov BYTE PTR [rsp+0x1a],al
0x0000000000001168 <+200>: call 0x1080 <strcmp@plt>
0x000000000000116d <+205>: mov r12d,eax
0x0000000000001170 <+208>: test eax,eax
0x0000000000001172 <+210>: jne 0x1197 <main+247>
0x0000000000001174 <+212>: mov rdx,r13
0x0000000000001177 <+215>: lea rsi,[rip+0xf7a] # 0x20f8
0x000000000000117e <+222>: mov edi,0x1
0x0000000000001183 <+227>: xor eax,eax
0x0000000000001185 <+229>: call 0x1090 <__printf_chk@plt>
0x000000000000118a <+234>: add rsp,0x20
0x000000000000118e <+238>: mov eax,r12d
0x0000000000001191 <+241>: pop rbp
0x0000000000001192 <+242>: pop r12
0x0000000000001194 <+244>: pop r13
0x0000000000001196 <+246>: ret
0x0000000000001197 <+247>: mov rdx,rbp
0x000000000000119a <+250>: mov edi,0x1
0x000000000000119f <+255>: xor eax,eax
0x00000000000011a1 <+257>: mov r12d,0x4
0x00000000000011a7 <+263>: lea rsi,[rip+0xf7a] # 0x2128
0x00000000000011ae <+270>: call 0x1090 <__printf_chk@plt>
0x00000000000011b3 <+275>: jmp 0x118a <main+234>
0x00000000000011b5 <+277>: lea rdi,[rip+0xe4c] # 0x2008
0x00000000000011bc <+284>: mov r12d,0x1
0x00000000000011c2 <+290>: call 0x1070 <puts@plt>
0x00000000000011c7 <+295>: jmp 0x118a <main+234>
0x00000000000011c9 <+297>: lea rsi,[rip+0xf00] # 0x20d0
0x00000000000011d0 <+304>: mov edi,0x1
0x00000000000011d5 <+309>: mov r12d,0x2
0x00000000000011db <+315>: call 0x1090 <__printf_chk@plt>
0x00000000000011e0 <+320>: jmp 0x118a <main+234>
End of assembler dump.
Vemos que hay una llamada a strcmp
en main+200
. Podemos poner un breakpoint justo ahí y ejecutar el programa:
gef➤ break *main+200
Breakpoint 1 at 0x1168
gef➤ run 'CTFlearn{flag}'
Starting program: ./Reykjavik 'CTFlearn{flag}'
Welcome to the CTFlearn Reversing Challenge Reykjavik v2: CTFlearn{flag}
Compile Options: ${CMAKE_CXX_FLAGS} -O0 -fno-stack-protector -mno-sse
Breakpoint 1, 0x0000555555555168 in main ()
Ahora que estamos en esa instrucción, podemos mostrar el primer argumento de strcmp
(que está en $rdi
en x64). Y vemos la flag:
gef➤ x/s $rdi
0x7fffffffe650: "CTFlearn{Eye_L0ve_Iceland_}"