Off by one overflow

Apoya a HackTricks

Información básica

Tener acceso a un desbordamiento por uno de 1 byte permite a un atacante modificar el campo size del siguiente chunk. Esto permite manipular qué chunks se liberan realmente, potencialmente generando un chunk que contiene otro chunk legítimo. La explotación es similar a la de doble liberación o a la de solapamiento de chunks.

Existen 2 tipos de vulnerabilidades de desbordamiento por uno:

  • Byte arbitrario: Este tipo permite sobrescribir ese byte con cualquier valor.

  • Byte nulo (off-by-null): Este tipo permite sobrescribir ese byte solo con 0x00.

  • Un ejemplo común de esta vulnerabilidad se puede ver en el siguiente código donde el comportamiento de strlen y strcpy es inconsistente, lo que permite establecer un byte 0x00 al principio del siguiente chunk.

  • Esto se puede explotar con el House of Einherjar.

  • Si se utiliza Tcache, esto se puede aprovechar para una situación de doble liberación.

Off-by-null

```c // From https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off_by_one/ int main(void) { char buffer[40]=""; void *chunk1; chunk1 = malloc(24); puts("Get Input"); gets(buffer); if(strlen(buffer)==24) { strcpy(chunk1,buffer); } return 0; } ```

Entre otras comprobaciones, ahora cada vez que se libera un fragmento, se compara el tamaño anterior con el tamaño configurado en los metadatos del fragmento, lo que hace que este ataque sea bastante complejo a partir de la versión 2.28.

Ejemplo de código:

Objetivo

  • Hacer que un fragmento esté contenido dentro de otro fragmento para que el acceso de escritura sobre ese segundo fragmento permita sobrescribir el contenido del fragmento contenido

Requisitos

  • Desbordamiento de un byte para modificar la información de metadatos de tamaño

Ataque general de desbordamiento de un byte

  • Asigna tres fragmentos A, B y C (digamos de tamaño 0x20), y otro para evitar la consolidación con el fragmento superior.

  • Libera C (insertado en la lista de fragmentos libres de Tcache de 0x20).

  • Usa el fragmento A para desbordar en B. Abusa del desbordamiento de un byte para modificar el campo size de B de 0x21 a 0x41.

  • Ahora tenemos que B contiene el fragmento libre C

  • Libera B y asigna un fragmento de 0x40 (se colocará aquí nuevamente)

  • Podemos modificar el puntero fd de C, que todavía está libre (envenenamiento de Tcache)

Ataque de desbordamiento de nulo

  • Se reservan 3 fragmentos de memoria (a, b, c) uno tras otro. Luego se libera el del medio. El primero contiene una vulnerabilidad de desbordamiento de un byte y el atacante la abusa con un 0x00 (si el byte anterior fuera 0x10, haría que el fragmento del medio indicara que es 0x10 más pequeño de lo que realmente es).

  • Luego, se asignan 2 fragmentos más pequeños en el fragmento liberado del medio (b), sin embargo, como b + b->size nunca actualiza el fragmento c porque la dirección apuntada es más pequeña de lo que debería.

  • Luego, se liberan b1 y c. Como c - c->prev_size todavía apunta a b (ahora b1), ambos se consolidan en un solo fragmento. Sin embargo, b2 todavía está dentro entre b1 y c.

  • Finalmente, se realiza un nuevo malloc reclamando esta área de memoria que en realidad va a contener b2, lo que permite al propietario del nuevo malloc controlar el contenido de b2.

Esta imagen explica perfectamente el ataque:

Otros Ejemplos y Referencias

  • Desbordamiento de un byte debido a que strlen considera el campo size del siguiente fragmento.

  • Se está utilizando Tcache, por lo que los ataques generales de desbordamiento de un byte funcionan para obtener un primitivo de escritura arbitraria con envenenamiento de Tcache.

  • Es posible abusar de un desbordamiento de un byte para filtrar una dirección de la pila porque el byte 0x00 del final de una cadena está siendo sobrescrito por el siguiente campo.

  • Se obtiene una escritura arbitraria abusando del desbordamiento de un byte para hacer que el puntero apunte a otro lugar donde se construirá una estructura falsa con punteros falsos. Luego, es posible seguir el puntero de esta estructura para obtener una escritura arbitraria.

  • La dirección de libc se filtra porque si la pila se extiende usando mmap, la memoria asignada por mmap tiene un desplazamiento fijo desde libc.

  • Finalmente, se abusa de la escritura arbitraria para escribir en la dirección de __free_hook con un gadget único.

  • Hay una vulnerabilidad de desbordamiento de un byte nulo en la función getline que lee líneas de entrada de usuario. Esta función se utiliza para leer la "clave" del contenido y no el contenido.

  • Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de Github.

Last updated