Off by one overflow
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
ystrcpy
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.
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:
Este ataque ya no funciona debido al uso de Tcaches.
Además, si intentas abusar de él usando fragmentos más grandes (para que no intervengan las tcaches), obtendrás el error:
malloc(): invalid next size (unsorted)
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
yC
(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 enB
. Abusa del desbordamiento de un byte para modificar el camposize
deB
de 0x21 a 0x41.Ahora tenemos que
B
contiene el fragmento libreC
Libera
B
y asigna un fragmento de 0x40 (se colocará aquí nuevamente)Podemos modificar el puntero
fd
deC
, 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 camposize
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