hacktricks/binary-exploitation/libc-heap/house-of-orange.md

9.7 KiB

Casa de Orange

{% hint style="success" %} 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)

Apoya a HackTricks
{% endhint %}

Información Básica

Código

Objetivo

  • Abusar de la función malloc_printerr

Requisitos

  • Sobrescribir el tamaño del top chunk
  • Fugas de información de Libc y heap

Antecedentes

Algunos antecedentes necesarios de los comentarios de este ejemplo:

La cuestión es que, en versiones antiguas 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 provocará que se ejecute malloc_printerr.
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

Ataque

El ataque comienza logrando obtener el top chunk dentro del unsorted bin. Esto se logra llamando a malloc con un tamaño mayor al tamaño actual del top chunk pero menor que mmp_.mmap_threshold (por defecto es 128K), lo cual de lo contrario activaría la asignación de 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 manera 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 colocar el top chunk en el unsorted bin.

El antiguo top chunk está ahora 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 al 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 se escribirá un puntero al unsorted bin en _IO_list_all.

El siguiente paso implica reducir el tamaño del antiguo top chunk para que quepa en un small bin, estableciendo específicamente su tamaño en 0x61. Esto sirve para dos propósitos:

  1. 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 mediante el ataque al unsorted bin.
  2. Desencadenar una Verificación de Malloc: Esta manipulación del tamaño del chunk causará que malloc realice verificaciones internas. Cuando verifica el tamaño del chunk falso hacia adelante, que será cero, desencadena 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 falsa de _IO_FILE. La estructura se crea 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 se establece un puntero de instrucción 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 de _IO_FILE: Superponer el antiguo top chunk con la falsa estructura de _IO_FILE y establecer los campos de manera adecuada para secuestrar el flujo de ejecución.

El siguiente paso implica forjar una falsa estructura de _IO_FILE que se superpone con el antiguo top chunk actualmente en el unsorted bin. Los primeros bytes de esta estructura se crean cuidadosamente para incluir un puntero a un comando (por ejemplo, "/bin/sh") que se ejecutará.

Los campos clave en la falsa estructura de _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 se establece un puntero de instrucción 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 desencadena la ejecución del código a través de la estructura manipulada de _IO_FILE. Esto permite la ejecución de código arbitrario, lo que generalmente resulta en el inicio de un shell u otra carga maliciosa.

Resumen del Ataque:

  1. Configurar el top chunk: Asignar un chunk y modificar el tamaño del top chunk.
  2. Forzar el top chunk en el unsorted bin: Asignar un chunk más grande.
  3. Filtrar direcciones de Libc: Utilizar la vulnerabilidad para leer desde el unsorted bin.
  4. Realizar el ataque al unsorted bin: Escribir en _IO_list_all utilizando un desbordamiento.
  5. Reducir el antiguo top chunk: Ajustar su tamaño para que quepa en un small bin.
  6. Configurar una estructura falsa de _IO_FILE: Forjar una estructura de archivo falsa para secuestrar el flujo de control.
  7. Desencadenar la ejecución de código: Asignar un chunk para ejecutar el ataque y ejecutar código arbitrario.

Este enfoque explota los mecanismos de gestión de heap, las fugas de información de libc y los desbordamientos de heap para lograr la ejecución de código sin llamar directamente a free. Al crear cuidadosamente la falsa estructura de _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 potencialmente resulta en un shell u otras actividades maliciosas.

Referencias

{% hint style="success" %} 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)

Apoya a HackTricks
{% endhint %}