Libc Protections
Last updated
Last updated
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)
Malloc asigna memoria en agrupaciones de 8 bytes (32 bits) o 16 bytes (64 bits). Esto significa que el final de los chunks en sistemas de 32 bits debe alinearse con 0x8, y en sistemas de 64 bits con 0x0. La característica de seguridad verifica que cada chunk se alinee correctamente en estas ubicaciones específicas antes de usar un puntero de un bin.
La aplicación de la alineación de chunks en sistemas de 64 bits mejora significativamente la seguridad de Malloc al limitar la colocación de chunks falsos a solo 1 de cada 16 direcciones. Esto complica los esfuerzos de explotación, especialmente en escenarios donde el usuario tiene control limitado sobre los valores de entrada, haciendo que los ataques sean más complejos y difíciles de ejecutar con éxito.
Ataque Fastbin en __malloc_hook
Las nuevas reglas de alineación en Malloc también frustran un ataque clásico que involucra el __malloc_hook
. Anteriormente, los atacantes podían manipular los tamaños de los chunks para sobrescribir este puntero de función y obtener ejecución de código. Ahora, el requisito de alineación estricta asegura que tales manipulaciones ya no sean viables, cerrando una ruta de explotación común y mejorando la seguridad general.
Mangling de Punteros es una mejora de seguridad utilizada para proteger los punteros Fd de fastbin y tcache en operaciones de gestión de memoria. Esta técnica ayuda a prevenir ciertos tipos de tácticas de explotación de memoria, específicamente aquellas que no requieren información de memoria filtrada o que manipulan ubicaciones de memoria directamente en relación con posiciones conocidas (sobrescrituras relativas).
El núcleo de esta técnica es una fórmula de ofuscación:
New_Ptr = (L >> 12) XOR P
L es la Ubicación de Almacenamiento del puntero.
P es el Puntero Fd de fastbin/tcache.
La razón del desplazamiento a la derecha de la ubicación de almacenamiento (L) por 12 bits antes de la operación XOR es crítica. Esta manipulación aborda una vulnerabilidad inherente a la naturaleza determinista de los 12 bits menos significativos de las direcciones de memoria, que son típicamente predecibles debido a las limitaciones de la arquitectura del sistema. Al desplazar los bits, la porción predecible se mueve fuera de la ecuación, mejorando la aleatoriedad del nuevo puntero mangled y, por lo tanto, protegiendo contra exploits que dependen de la predictibilidad de estos bits.
Este puntero mangled aprovecha la aleatoriedad existente proporcionada por Randomización de Diseño de Espacio de Direcciones (ASLR), que aleatoriza las direcciones utilizadas por los programas para dificultar que los atacantes predigan el diseño de memoria de un proceso.
Desmangling del puntero para recuperar la dirección original implica usar la misma operación XOR. Aquí, el puntero mangled se trata como P en la fórmula, y cuando se XOR con la ubicación de almacenamiento sin cambios (L), resulta en la revelación del puntero original. Esta simetría en el mangling y desmangling asegura que el sistema pueda codificar y decodificar punteros de manera eficiente sin un overhead significativo, mientras aumenta sustancialmente la seguridad contra ataques que manipulan punteros de memoria.
El mangling de punteros tiene como objetivo prevenir sobrescrituras parciales y completas de punteros en la gestión de heap, una mejora significativa en la seguridad. Esta característica impacta las técnicas de explotación de varias maneras:
Prevención de Sobrescrituras Relativas de Byte a Byte: Anteriormente, los atacantes podían cambiar parte de un puntero para redirigir chunks de heap a diferentes ubicaciones sin conocer direcciones exactas, una técnica evidente en el exploit sin filtraciones House of Roman. Con el mangling de punteros, tales sobrescrituras relativas sin una filtración de heap ahora requieren fuerza bruta, reduciendo drásticamente su probabilidad de éxito.
Aumento de la Dificultad de Ataques a Tcache Bin/Fastbin: Los ataques comunes que sobrescriben punteros de función (como __malloc_hook
) manipulando entradas de fastbin o tcache se ven obstaculizados. Por ejemplo, un ataque podría involucrar filtrar una dirección de LibC, liberar un chunk en el bin de tcache y luego sobrescribir el puntero Fd para redirigirlo a __malloc_hook
para ejecución de código arbitrario. Con el mangling de punteros, estos punteros deben estar correctamente mangled, necesitando una filtración de heap para una manipulación precisa, elevando así la barrera de explotación.
Requisito de Filtraciones de Heap en Ubicaciones No Heap: Crear un chunk falso en áreas no heap (como la pila, sección .bss o PLT/GOT) ahora también requiere una filtración de heap debido a la necesidad de mangling de punteros. Esto extiende la complejidad de explotar estas áreas, similar al requisito de manipular direcciones de LibC.
Filtrar Direcciones de Heap se Vuelve Más Desafiante: El mangling de punteros restringe la utilidad de los punteros Fd en fastbin y tcache como fuentes para filtraciones de direcciones de heap. Sin embargo, los punteros en bins no ordenados, pequeños y grandes permanecen sin mangling, por lo que aún son utilizables para filtrar direcciones. Este cambio empuja a los atacantes a explorar estos bins en busca de información explotable, aunque algunas técnicas pueden permitir desmangling de punteros antes de una filtración, aunque con restricciones.
Para una mejor explicación del proceso revisa la publicación original desde aquí.
La fórmula utilizada para mangling y desmangling de punteros es:
New_Ptr = (L >> 12) XOR P
Donde L es la ubicación de almacenamiento y P es el puntero Fd. Cuando L se desplaza a la derecha por 12 bits, expone los bits más significativos de P, debido a la naturaleza de XOR, que produce 0 cuando los bits se XOR con sí mismos.
Pasos Clave en el Algoritmo:
Filtración Inicial de los Bits Más Significativos: Al XORear el L desplazado con P, efectivamente obtienes los 12 bits superiores de P porque la porción desplazada de L será cero, dejando los bits correspondientes de P sin cambios.
Recuperación de Bits del Puntero: Dado que XOR es reversible, conocer el resultado y uno de los operandos te permite calcular el otro operando. Esta propiedad se utiliza para deducir el conjunto completo de bits para P al XORear sucesivamente conjuntos de bits conocidos con partes del puntero mangled.
Desmangling Iterativo: El proceso se repite, cada vez utilizando los nuevos bits descubiertos de P del paso anterior para decodificar el siguiente segmento del puntero mangled, hasta que se recuperen todos los bits.
Manejo de Bits Deterministas: Los últimos 12 bits de L se pierden debido al desplazamiento, pero son deterministas y pueden ser reconstruidos después del proceso.
Puedes encontrar una implementación de este algoritmo aquí: https://github.com/mdulin2/mangle
El guardián de punteros es una técnica de mitigación de exploits utilizada en glibc para proteger punteros de función almacenados, particularmente aquellos registrados por llamadas a bibliotecas como atexit()
. Esta protección implica desordenar los punteros mediante XOR con un secreto almacenado en los datos del hilo (fs:0x30
) y aplicar una rotación a nivel de bits. Este mecanismo tiene como objetivo prevenir que los atacantes secuestren el flujo de control sobrescribiendo punteros de función.
Entendiendo las Operaciones del Guardián de Punteros: El desordenamiento (mangling) de punteros se realiza utilizando el macro PTR_MANGLE
que XORea el puntero con un secreto de 64 bits y luego realiza una rotación a la izquierda de 0x11 bits. La operación inversa para recuperar el puntero original es manejada por PTR_DEMANGLE
.
Estrategia de Ataque: El ataque se basa en un enfoque de texto plano conocido, donde el atacante necesita conocer tanto la versión original como la mangled de un puntero para deducir el secreto utilizado para el mangling.
Explotando Textos Planos Conocidos:
Identificación de Punteros de Función Fijos: Al examinar el código fuente de glibc o tablas de punteros de función inicializadas (como __libc_pthread_functions
), un atacante puede encontrar punteros de función predecibles.
Cálculo del Secreto: Usando un puntero de función conocido como __pthread_attr_destroy
y su versión mangled de la tabla de punteros de función, el secreto puede ser calculado rotando inversamente (rotación a la derecha) el puntero mangled y luego XOReándolo con la dirección de la función.
Textos Planos Alternativos: El atacante también puede experimentar con mangling de punteros con valores conocidos como 0 o -1 para ver si estos producen patrones identificables en la memoria, revelando potencialmente el secreto cuando se encuentran estos patrones en volcado de memoria.
Aplicación Práctica: Después de calcular el secreto, un atacante puede manipular punteros de manera controlada, esencialmente eludiendo la protección del Guardián de Punteros en una aplicación multihilo con conocimiento de la dirección base de libc y la capacidad de leer ubicaciones de memoria arbitrarias.
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)