Protecciones de Libc
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.
Chunk Alignment Enforcement
Malloc asigna memoria en agrupaciones de 8 bytes (32-bit) o 16 bytes (64-bit). Esto significa que el final de los chunks en sistemas 32-bit debe alinearse con 0x8, y en sistemas 64-bit con 0x0. La característica de seguridad comprueba que cada chunk esté correctamente alineado en estas ubicaciones específicas antes de usar un pointer desde un bin.
Beneficios de seguridad
La aplicación de la alineación de chunks en sistemas 64-bit mejora significativamente la seguridad de Malloc al limitar la colocación de fake chunks a solo 1 de cada 16 direcciones. Esto complica los intentos 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.
- Fastbin Attack on
__malloc_hook
Las nuevas reglas de alineación en Malloc también frustran un ataque clásico que implicaba __malloc_hook. Anteriormente, los atacantes podían manipular tamaños de chunk para sobrescribir este puntero a función y obtener ejecución de código. Ahora, el requisito estricto de alineación asegura que tales manipulaciones ya no sean viables, cerrando una ruta común de explotación y mejorando la seguridad en general.
Nota: Desde glibc 2.34 los legacy hooks (
__malloc_hook,__free_hook, etc.) fueron eliminados del ABI exportado. Los exploits modernos ahora apuntan a otros punteros de función escribibles (p. ej. tcache per-thread struct, vtable-style callbacks) o se basan ensetcontext,_IO_list_allprimitives, etc.
Pointer Mangling on fastbins and tcache
Pointer Mangling es una mejora de seguridad usada para proteger los fastbin y tcache Fd pointers en las 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 leak o que manipulan ubicaciones de memoria directamente relativas a posiciones conocidas (overwrites relativos).
El núcleo de esta técnica es una fórmula de ofuscación:
New_Ptr = (L >> 12) XOR P
- L es la Storage Location del pointer.
- P es el actual fastbin/tcache Fd Pointer.
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 en la naturaleza determinista de los 12 bits menos significativos de las direcciones de memoria, que típicamente son predecibles debido a las restricciones de la arquitectura del sistema. Al desplazar los bits, la porción predecible se mueve fuera de la ecuación, aumentando la aleatoriedad del nuevo pointer ofuscado y, por tanto, protegiendo contra exploits que dependen de la previsibilidad de esos bits.
Este pointer mangled aprovecha la aleatoriedad existente proporcionada por Address Space Layout Randomization (ASLR), que randomiza las direcciones usadas por los programas para dificultar que un atacante prediga el layout de memoria de un proceso.
El proceso de demangling del pointer para recuperar la dirección original implica usar la misma operación XOR. Aquí, el pointer mangled se trata como P en la fórmula, y cuando se aplica XOR con la Storage Location (L) sin cambios, resulta en la revelación del pointer original. Esta simetría en mangling y demangling garantiza que el sistema pueda codificar y decodificar pointers de forma eficiente sin una sobrecarga significativa, mientras incrementa sustancialmente la seguridad contra ataques que manipulan pointers de memoria.
Beneficios de seguridad
Pointer mangling busca prevenir sobrescrituras parciales y completas de pointers en la gestión del heap, una mejora significativa en seguridad. Esta característica impacta las técnicas de explotación de varias maneras:
- Prevención de Bye Byte Relative Overwrites: Anteriormente, los atacantes podían cambiar parte de un pointer para redirigir chunks del heap a diferentes ubicaciones sin conocer direcciones exactas, una técnica evidente en el leakless House of Roman exploit. Con pointer mangling, tales overwrites relativos sin un heap leak ahora requieren brute forcing, reduciendo drásticamente su probabilidad de éxito.
- Mayor dificultad en ataques contra Tcache Bin/Fastbin: 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 implicar filtrar (leak) una dirección de LibC, liberar un chunk en el tcache bin y luego sobrescribir el Fd pointer para redirigirlo a__malloc_hookpara ejecución arbitraria de código. Con pointer mangling, estos pointers deben estar correctamente mangled, exigiendo un heap leak para una manipulación precisa, elevando así la barrera de explotación. - Requisito de Heap Leaks en ubicaciones no-heap: Crear un fake chunk en áreas no-heap (como la stack, la sección .bss, o PLT/GOT) ahora también requiere un heap leak debido a la necesidad de pointer mangling. Esto extiende la complejidad de explotar estas áreas, similar al requisito para manipular direcciones de LibC.
- Hacer más difícil el leaking de direcciones del heap: Pointer mangling restringe la utilidad de los Fd pointers en fastbin y tcache bins como fuentes para leak de direcciones del heap. Sin embargo, los pointers en unsorted, small y large bins permanecen sin manglear, por lo que todavía son utilizables para filtrar (leak) direcciones. Este cambio empuja a los atacantes a explorar estos bins en busca de información explotable, aunque algunas técnicas aún pueden permitir demangling de pointers antes de un leak, aunque con restricciones.
Safe-Linking Bypass (page-aligned leak scenario)
Even with safe-linking enabled (glibc ≥ 2.32), if you can leak the mangled pointer and both the corrupted chunk and victim chunk share the same 4KB page, the original pointer can be recovered with just the page offset:
// leaked_fd is the mangled Fd read from the chunk on the same page
uintptr_t l = (uintptr_t)&chunk->fd; // storage location
uintptr_t original = (leaked_fd ^ (l >> 12)); // demangle
Esto restaura el Fd y permite el clásico tcache/fastbin poisoning. Si los chunks se ubican en páginas diferentes, forzar por fuerza bruta el page offset de 12 bits (0x1000 posibilidades) suele ser factible cuando los patrones de asignación son deterministas o cuando los crashes son aceptables (p. ej., CTF-style exploits).
Demangling Pointers with a Heap Leak
Caution
Para una mejor explicación del proceso revisa la publicación original aquí.
Algorithm Overview
La fórmula usada para mangling y demangling pointers es:
New_Ptr = (L >> 12) XOR P
Donde L es la ubicación de almacenamiento y P es el Fd pointer. Cuando L se desplaza a la derecha 12 bits, expone los bits más significativos de P, debido a la naturaleza de XOR, que devuelve 0 cuando bits se XORean consigo mismos.
Pasos clave en el algoritmo:
- Initial Leak of the Most Significant Bits: Al XORear la porción desplazada de L con P, efectivamente obtienes los 12 bits superiores de P porque la parte desplazada de L será cero, dejando los bits correspondientes de P sin cambios.
- Recovery of Pointer Bits: Dado que XOR es reversible, conocer el resultado y uno de los operandos permite calcular el otro operando. Esta propiedad se usa para deducir el conjunto completo de bits de P al XORear sucesivamente conjuntos de bits conocidos con partes del mangled pointer.
- Iterative Demangling: El proceso se repite, cada vez usando los bits recién descubiertos de P del paso anterior para decodificar el siguiente segmento del mangled pointer, hasta recuperar todos los bits.
- Handling Deterministic Bits: Los últimos 12 bits de L se pierden debido al shift, pero son deterministas y pueden reconstruirse después del proceso.
Puedes encontrar una implementación de este algoritmo aquí: https://github.com/mdulin2/mangle
Pointer Guard
Pointer Guard es una técnica de mitigación de exploits usada en glibc para proteger function pointers almacenados, particularmente aquellos registrados por llamadas de librería como atexit(). Esta protección implica enmarañar los punteros XOReándolos con un secreto almacenado en los datos del hilo (fs:0x30) y aplicando una rotación de bits. Este mecanismo tiene como objetivo impedir que un atacante secuestre el flujo de control sobrescribiendo function pointers.
Bypassing Pointer Guard with a leak
- Understanding Pointer Guard Operations: El scrambling (mangling) de pointers se realiza usando la macro
PTR_MANGLE, que XORea el pointer 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 pointer original la manejaPTR_DEMANGLE. - Attack Strategy: El ataque se basa en un enfoque de known-plaintext, donde el atacante necesita conocer tanto la versión original como la versión mangled de un pointer para deducir el secreto usado para el mangling.
- Exploiting Known Plaintexts:
- Identifying Fixed Function Pointers: Al examinar el código fuente de glibc o tablas de function pointers inicializadas (como
__libc_pthread_functions), un atacante puede encontrar function pointers predecibles. - Computing the Secret: Usando un function pointer conocido como
__pthread_attr_destroyy su versión mangled desde la tabla de function pointers, el secreto se puede calcular rotando en sentido contrario (rotación a la derecha) el mangled pointer y luego XOReándolo con la dirección de la función.
- Alternative Plaintexts: El atacante también puede experimentar mangling pointers con valores conocidos como 0 o -1 para ver si estos producen patrones identificables en memoria, lo que potencialmente revelaría el secreto cuando se encuentren estos patrones en volcados de memoria.
- Practical Application: Después de calcular el secreto, un atacante puede manipular pointers de forma controlada, esencialmente bypassing la protección Pointer Guard en una aplicación multihilo con conocimiento de la base de libc y la habilidad de leer ubicaciones arbitrarias de memoria.
GLIBC Tunables & Recent Loader Bugs
El dynamic loader parsea GLIBC_TUNABLES antes del inicio del programa. Los bugs de mis-parsing aquí afectan directamente a libc antes de que la mayoría de mitigaciones entren en acción. El bug “Looney Tunables” de 2023 (CVE-2023-4911) es un ejemplo: un valor sobre-largo en GLIBC_TUNABLES desborda buffers internos en ld.so, permitiendo privilege escalation en muchas distribuciones cuando se combina con binarios SUID. La explotación solo requiere crear el entorno y ejecutar repetidamente el binario objetivo; pointer guard o safe-linking no lo previenen porque la corrupción ocurre en el loader antes de que se configure el heap.
References
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.


