Large Bin Attack

Reading time: 3 minutes

tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Apoya a HackTricks

Información Básica

Para más información sobre qué es un large bin, consulta esta página:

Bins & Memory Allocations

Es posible encontrar un gran ejemplo en how2heap - large bin attack.

Básicamente, aquí puedes ver cómo, en la última versión "actual" de glibc (2.35), no se verifica: P->bk_nextsize permitiendo modificar una dirección arbitraria con el valor de un chunk de large bin si se cumplen ciertas condiciones.

En ese ejemplo puedes encontrar las siguientes condiciones:

  • Se asigna un chunk grande
  • Se asigna un chunk grande más pequeño que el primero pero en el mismo índice
  • Debe ser más pequeño, así que debe ir primero en el bin
  • (Se crea un chunk para evitar la fusión con el chunk superior)
  • Luego, se libera el primer chunk grande y se asigna un nuevo chunk más grande que él -> Chunk1 va al large bin
  • Luego, se libera el segundo chunk grande
  • Ahora, la vulnerabilidad: El atacante puede modificar chunk1->bk_nextsize a [target-0x20]
  • Luego, se asigna un chunk más grande que el chunk 2, por lo que chunk2 se inserta en el large bin sobrescribiendo la dirección chunk1->bk_nextsize->fd_nextsize con la dirección de chunk2

tip

Hay otros escenarios potenciales, la cuestión es añadir al large bin un chunk que sea más pequeño que un chunk X actual en el bin, por lo que debe insertarse justo antes de él en el bin, y necesitamos poder modificar bk_nextsize de X, ya que ahí es donde se escribirá la dirección del chunk más pequeño.

Este es el código relevante de malloc. Se han añadido comentarios para entender mejor cómo se sobrescribió la dirección:

c
/* if smaller than smallest, bypass loop below */
assert (chunk_main_arena (bck->bk));
if ((unsigned long) (size) < (unsigned long) chunksize_nomask (bck->bk))
{
fwd = bck; // fwd = p1
bck = bck->bk; // bck = p1->bk

victim->fd_nextsize = fwd->fd; // p2->fd_nextsize = p1->fd (Note that p1->fd is p1 as it's the only chunk)
victim->bk_nextsize = fwd->fd->bk_nextsize; // p2->bk_nextsize = p1->fd->bk_nextsize
fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim; // p1->fd->bk_nextsize->fd_nextsize = p2
}

Esto podría usarse para sobrescribir la variable global global_max_fast de libc para luego explotar un ataque de fast bin con bloques más grandes.

Puedes encontrar otra gran explicación de este ataque en guyinatuxedo.

Otros ejemplos

  • La casa de papel. HackOn CTF 2024
  • Ataque de large bin en la misma situación en la que aparece en how2heap.
  • La primitiva de escritura es más compleja, porque global_max_fast es inútil aquí.
  • Se necesita FSOP para terminar el exploit.

tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Apoya a HackTricks