Heap Overflow
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)
Un desbordamiento de montículo es como un desbordamiento de pila pero en el montículo. Básicamente significa que se reservó un espacio en el montículo para almacenar algunos datos y los datos almacenados eran más grandes que el espacio reservado.
En los desbordamientos de pila sabemos que algunos registros como el puntero de instrucción o el marco de pila se van a restaurar desde la pila y podría ser posible abusar de esto. En el caso de los desbordamientos de montículo, no hay información sensible almacenada por defecto en el fragmento de montículo que puede ser desbordado. Sin embargo, podría haber información sensible o punteros, por lo que la criticidad de esta vulnerabilidad depende de qué datos podrían ser sobrescritos y cómo un atacante podría abusar de esto.
Para encontrar los desplazamientos de desbordamiento, puedes usar los mismos patrones que en desbordamientos de pila.
En los desbordamientos de pila, la disposición y los datos que van a estar presentes en la pila en el momento en que se puede activar la vulnerabilidad son bastante confiables. Esto se debe a que la pila es lineal, siempre aumentando en memoria colisionante, en lugares específicos de la ejecución del programa, la memoria de la pila generalmente almacena un tipo similar de datos y tiene una estructura específica con algunos punteros al final de la parte de la pila utilizada por cada función.
Sin embargo, en el caso de un desbordamiento de montículo, la memoria utilizada no es lineal, sino que los fragmentos asignados suelen estar en posiciones separadas de la memoria (no uno al lado del otro) debido a bins y zonas que separan las asignaciones por tamaño y porque la memoria previamente liberada se utiliza antes de asignar nuevos fragmentos. Es complicado saber el objeto que va a colisionar con el que es vulnerable a un desbordamiento de montículo. Por lo tanto, cuando se encuentra un desbordamiento de montículo, es necesario encontrar una manera confiable de hacer que el objeto deseado esté al lado en memoria del que puede ser desbordado.
Una de las técnicas utilizadas para esto es Heap Grooming, que se utiliza, por ejemplo, en esta publicación. En la publicación se explica cómo, cuando en el núcleo de iOS, una zona se queda sin memoria para almacenar fragmentos de memoria, se expande por una página del núcleo, y esta página se divide en fragmentos de los tamaños esperados que se utilizarían en orden (hasta la versión 9.2 de iOS, luego estos fragmentos se utilizan de manera aleatoria para dificultar la explotación de estos ataques).
Por lo tanto, en la publicación anterior donde ocurre un desbordamiento de montículo, para forzar que el objeto desbordado colisione con un orden de víctima, se forzan varios kallocs
por varios hilos para intentar asegurar que todos los fragmentos libres estén llenos y que se cree una nueva página.
Para forzar este llenado con objetos de un tamaño específico, la asignación fuera de línea asociada con un puerto mach de iOS es un candidato ideal. Al elaborar el tamaño del mensaje, es posible especificar exactamente el tamaño de la asignación kalloc
y cuando el puerto mach correspondiente se destruye, la asignación correspondiente se liberará inmediatamente de nuevo a kfree
.
Luego, algunos de estos marcadores de posición pueden ser liberados. La lista libre kalloc.4096
libera elementos en un orden de último en entrar, primero en salir, lo que básicamente significa que si algunos marcadores de posición son liberados y el exploit intenta asignar varios objetos de víctima mientras intenta asignar el objeto vulnerable al desbordamiento, es probable que este objeto sea seguido por un objeto de víctima.
En esta página es posible encontrar una emulación básica de desbordamiento de montículo que muestra cómo sobrescribir el bit de uso previo del siguiente fragmento y la posición del tamaño previo es posible consolidar un fragmento utilizado (haciéndolo pensar que es no utilizado) y luego asignarlo nuevamente pudiendo sobrescribir datos que están siendo utilizados en un puntero diferente también.
Otro ejemplo de protostar heap 0 muestra un ejemplo muy básico de un CTF donde un desbordamiento de montículo puede ser abusado para llamar a la función ganadora para obtener la bandera.
En el ejemplo de protostar heap 1 es posible ver cómo abusando de un desbordamiento de búfer es posible sobrescribir en un fragmento cercano una dirección donde se van a escribir datos arbitrarios del usuario.
En la página https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/ puedes encontrar un ejemplo de desbordamiento de montículo donde un comando que se va a ejecutar se almacena en el siguiente fragmento del fragmento desbordado. Por lo tanto, es posible modificar el comando ejecutado sobrescribiéndolo con un exploit fácil como:
Usamos una vulnerabilidad de desbordamiento de enteros para obtener un desbordamiento de heap.
Corrompemos punteros a una función dentro de un struct
del chunk desbordado para establecer una función como system
y obtener ejecución de código.
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)