House of Orange
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Encuentra un ejemplo en https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c
La técnica de explotación fue corregida en este parche así que esto ya no funciona (funcionando en versiones anteriores a 2.26)
Mismo ejemplo con más comentarios en https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html
Abusar de la función malloc_printerr
Sobrescribir el tamaño del top chunk
Fugas de libc y heap
Algunos antecedentes necesarios de los comentarios de este ejemplo:
La cuestión es que, en versiones anteriores de libc, cuando se llamaba a la función malloc_printerr
, iteraba a través de una lista de estructuras _IO_FILE
almacenadas en _IO_list_all
, y realmente ejecutaba un puntero de instrucción en esa estructura.
Este ataque forjará una estructura _IO_FILE
falsa que escribiremos en _IO_list_all
, y hará que malloc_printerr
se ejecute.
Luego ejecutará cualquier dirección que tengamos almacenada en la tabla de saltos de las estructuras _IO_FILE
, y obtendremos ejecución de código.
El ataque comienza al lograr obtener el top chunk dentro del unsorted bin. Esto se logra llamando a malloc
con un tamaño mayor que el tamaño actual del top chunk pero menor que mmp_.mmap_threshold
(el valor predeterminado es 128K), lo que de otro modo activaría la asignación mmap
. Siempre que se modifique el tamaño del top chunk, es importante asegurarse de que el top chunk + su tamaño esté alineado a página y que el bit prev_inuse del top chunk esté siempre establecido.
Para obtener el top chunk dentro del unsorted bin, asigna un chunk para crear el top chunk, cambia el tamaño del top chunk (con un desbordamiento en el chunk asignado) de modo que top chunk + tamaño esté alineado a página con el bit prev_inuse establecido. Luego asigna un chunk más grande que el nuevo tamaño del top chunk. Ten en cuenta que free
nunca se llama para llevar el top chunk al unsorted bin.
El antiguo top chunk ahora está en el unsorted bin. Suponiendo que podemos leer datos dentro de él (posiblemente debido a una vulnerabilidad que también causó el desbordamiento), es posible filtrar direcciones de libc desde él y obtener la dirección de _IO_list_all.
Se realiza un ataque de unsorted bin abusando del desbordamiento para escribir topChunk->bk->fwd = _IO_list_all - 0x10
. Cuando se asigna un nuevo chunk, el antiguo top chunk se dividirá, y un puntero al unsorted bin se escribirá en _IO_list_all
.
El siguiente paso implica reducir el tamaño del antiguo top chunk para que quepa en un small bin, específicamente estableciendo su tamaño en 0x61. Esto sirve para dos propósitos:
Inserción en Small Bin 4: Cuando malloc
escanea el unsorted bin y ve este chunk, intentará insertarlo en el small bin 4 debido a su pequeño tamaño. Esto hace que el chunk termine en la cabeza de la lista del small bin 4, que es la ubicación del puntero FD del chunk de _IO_list_all
ya que escribimos una dirección cercana en _IO_list_all
a través del ataque de unsorted bin.
Activar una Verificación de Malloc: Esta manipulación del tamaño del chunk hará que malloc
realice verificaciones internas. Cuando verifica el tamaño del chunk falso hacia adelante, que será cero, activa un error y llama a malloc_printerr
.
La manipulación del small bin te permitirá controlar el puntero hacia adelante del chunk. La superposición con _IO_list_all se utiliza para forjar una estructura _IO_FILE falsa. La estructura se elabora cuidadosamente para incluir campos clave como _IO_write_base
y _IO_write_ptr
establecidos en valores que pasan las verificaciones internas en libc. Además, se crea una tabla de saltos dentro de la estructura falsa, donde un puntero de instrucción se establece en la dirección donde se puede ejecutar código arbitrario (por ejemplo, la función system
).
Para resumir la parte restante de la técnica:
Reducir el Antiguo Top Chunk: Ajustar el tamaño del antiguo top chunk a 0x61 para que quepa en un small bin.
Configurar la Estructura Falsa _IO_FILE
: Superponer el antiguo top chunk con la estructura falsa _IO_FILE y establecer los campos apropiadamente para secuestrar el flujo de ejecución.
El siguiente paso implica forjar una estructura falsa _IO_FILE que se superponga con el antiguo top chunk actualmente en el unsorted bin. Los primeros bytes de esta estructura se elaboran cuidadosamente para incluir un puntero a un comando (por ejemplo, "/bin/sh") que se ejecutará.
Los campos clave en la estructura falsa _IO_FILE, como _IO_write_base
y _IO_write_ptr
, se establecen en valores que pasan las verificaciones internas en libc. Además, se crea una tabla de saltos dentro de la estructura falsa, donde un puntero de instrucción se establece en la dirección donde se puede ejecutar código arbitrario. Típicamente, esta sería la dirección de la función system
u otra función que pueda ejecutar comandos de shell.
El ataque culmina cuando una llamada a malloc
activa la ejecución del código a través de la estructura manipulada _IO_FILE. Esto permite efectivamente la ejecución de código arbitrario, lo que generalmente resulta en un shell que se genera o en otro payload malicioso que se ejecuta.
Resumen del Ataque:
Configurar el top chunk: Asignar un chunk y modificar el tamaño del top chunk.
Forzar el top chunk en el unsorted bin: Asignar un chunk más grande.
Filtrar direcciones de libc: Usar la vulnerabilidad para leer del unsorted bin.
Realizar el ataque de unsorted bin: Escribir en _IO_list_all usando un desbordamiento.
Reducir el antiguo top chunk: Ajustar su tamaño para que quepa en un small bin.
Configurar una estructura falsa _IO_FILE: Forjar una estructura de archivo falsa para secuestrar el flujo de control.
Activar la ejecución de código: Asignar un chunk para ejecutar el ataque y ejecutar código arbitrario.
Este enfoque explota mecanismos de gestión de heap, fugas de información de libc y desbordamientos de heap para lograr la ejecución de código sin llamar directamente a free
. Al elaborar cuidadosamente la estructura falsa _IO_FILE y colocarla en la ubicación correcta, el ataque puede secuestrar el flujo de control durante las operaciones estándar de asignación de memoria. Esto permite la ejecución de código arbitrario, lo que puede resultar en un shell u otras actividades maliciosas.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)