Ret2lib
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 suministrado por el atacante en la pila. El atacante crea un payload que modifica la dirección de retorno en la pila para apuntar a la función de la biblioteca deseada, al mismo tiempo que organiza que los argumentos necesarios se configuren correctamente según 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
Encontrar las direcciones
Suponiendo que la
libc
utilizada es la de la máquina actual, puedes encontrar dónde se cargará en memoria con:
Si deseas verificar si ASLR está cambiando la dirección de libc, puedes hacer lo siguiente:
Conociendo la libc utilizada también es posible encontrar el desplazamiento a la función
system
con:
Conocer la libc utilizada también es posible encontrar el desplazamiento a la función de la cadena
/bin/sh
con:
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
:
Usando /proc/<PID>/maps
Si el proceso está creando hijos cada vez que interactúas 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 cargará para cada hijo del proceso.
En este caso se carga en 0xb75dc000 (Esta será la dirección base de la libc)
Librería libc desconocida
Podría 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é librería libc se está utilizando:
Leaking libc address with ROPY puedes encontrar una plantilla de pwntools para esto en:
Leaking libc - templateConocer la libc con 2 offsets
Consulta la página https://libc.blukat.me/ y utiliza un par de direcciones de funciones dentro de la libc para descubrir la versión utilizada.
Saltando 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 la libc (útil para sistemas de 32 bits):
Si estás atacando un servidor remoto, podrías intentar hacer fuerza bruta en la dirección de la función
usleep
delibc
, pasando como argumento 10 (por ejemplo). Si en algún momento el servidor tarda 10 segundos adicionales en responder, encontraste la dirección de esta función.
One Gadget
Ejecuta una shell saltando a una dirección específica en libc:
One GadgetEjemplo de Código x86 Ret2lib
En este ejemplo, la fuerza bruta de ASLR está integrada en el código y el binario vulnerable está ubicado en un servidor remoto:
Ejemplo de Código x64 Ret2lib
Ver el ejemplo en:
ROP - Return Oriented ProgramingEjemplo de ARM64 Ret2lib
En el caso de ARM64, la instrucción ret salta a donde apunta el registro x30 y no a donde apunta el registro de la pila. Por lo tanto, 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).
Ver el ejemplo en:
Ret2lib + Printf leak - arm64Ret-into-printf (o puts)
Esto permite filtrar 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
permitirá filtrar la dirección de puts
en la 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
Ret2lib, dado un leak a la dirección de una función en libc, utilizando un gadget
64 bits, ASLR habilitado pero sin PIE, el primer paso es llenar un desbordamiento hasta el byte 0x00 del canary para luego llamar a puts y filtrarlo. Con el canary se crea un gadget ROP para llamar a puts y filtrar la dirección de puts de la GOT y un gadget ROP para llamar a
system('/bin/sh')
64 bits, ASLR habilitado, sin canary, desbordamiento de pila en main desde una función secundaria. Gadget ROP para llamar a puts y filtrar la dirección de puts de la GOT y luego llamar a un gadget.
64 bits, sin pie, sin canary, sin relro, nx. Usa la función write para filtrar la dirección de write (libc) y llama a un gadget.
Utiliza una cadena de formato para filtrar el canary de la pila y un desbordamiento de búfer para llamar a system (está en la GOT) con la dirección de
/bin/sh
.32 bits, sin relro, sin canary, nx, pie. Abusa de un mal indexado para filtrar direcciones de libc y heap de la pila. Abusa del desbordamiento de búfer para hacer un ret2lib llamando a
system('/bin/sh')
(se necesita la dirección del heap para evitar una comprobación).
Last updated