3.9 KiB
Ataque al Large Bin
Aprende hacking en AWS desde cero hasta experto con htARTE (HackTricks AWS Red Team Expert)!
Otras formas de apoyar a HackTricks:
- Si deseas ver tu empresa anunciada en HackTricks o descargar HackTricks en PDF ¡Consulta los PLANES DE SUSCRIPCIÓN!
- Obtén artículos oficiales de PEASS & HackTricks
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte tus trucos de hacking enviando PRs a los repositorios de HackTricks y HackTricks Cloud.
Información Básica
Para obtener más información sobre qué es un large bin, consulta esta página:
{% content-ref url="bins-and-memory-allocations.md" %} bins-and-memory-allocations.md {% endcontent-ref %}
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 fragmento de large bin si se cumplen ciertas condiciones.
En ese ejemplo puedes encontrar las siguientes condiciones:
- Se asigna un fragmento grande
- Se asigna un fragmento grande más pequeño que el primero pero en el mismo índice
- Debe ser más pequeño para que vaya primero en el bin
- (Se crea un fragmento para evitar la fusión con el fragmento superior)
- Luego, se libera el primer fragmento grande y se asigna un nuevo fragmento más grande que él -> El fragmento1 va al large bin
- Luego, se libera el segundo fragmento grande
- Ahora, la vulnerabilidad: El atacante puede modificar
chunk1->bk_nextsize
a[target-0x20]
- Luego, se asigna un fragmento más grande que el fragmento 2, por lo que el fragmento2 se inserta en el large bin sobrescribiendo la dirección
chunk1->bk_nextsize->fd_nextsize
con la dirección del fragmento2
{% hint style="success" %}
Existen otros escenarios potenciales, la idea es agregar al large bin un fragmento que sea más pequeño que un fragmento X actual en el bin, por lo que debe insertarse justo antes en el bin, y debemos poder modificar bk_nextsize
de X ya que ahí es donde se escribirá la dirección del fragmento más pequeño.
{% endhint %}
Este es el código relevante de malloc. Se han añadido comentarios para entender mejor cómo se sobrescribió la dirección:
{% code overflow="wrap" %}
/* 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
}
{% endcode %}
Esto podría ser utilizado para sobrescribir la variable global global_max_fast
de libc para luego explotar un ataque de fast bin con fragmentos más grandes.
Puedes encontrar otra excelente explicación de este ataque en guyinatuxedo.