First Fit

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

First Fit

Cuando liberas memoria en un programa que utiliza glibc, se utilizan diferentes "bins" para gestionar los fragmentos de memoria. Aquí tienes una explicación simplificada de dos escenarios comunes: bins desordenados y fastbins.

Bins Desordenados

Cuando liberas un fragmento de memoria que no es un fragmento rápido, este va al bin desordenado. Este bin actúa como una lista donde se añaden los nuevos fragmentos liberados al principio (la "cabeza"). Cuando solicitas un nuevo fragmento de memoria, el asignador mira el bin desordenado desde el final (la "cola") para encontrar un fragmento lo suficientemente grande. Si un fragmento del bin desordenado es más grande de lo que necesitas, se divide, devolviendo la parte delantera y manteniendo la parte restante en el bin.

Ejemplo:

  • Asignas 300 bytes (a), luego 250 bytes (b), liberas a y solicitas nuevamente 250 bytes (c).

  • Cuando liberas a, va al bin desordenado.

  • Si luego solicitas 250 bytes de nuevo, el asignador encuentra a en la cola y lo divide, devolviendo la parte que se ajusta a tu solicitud y manteniendo el resto en el bin.

  • c apuntará al a anterior y estará lleno con los datos de a.

char *a = malloc(300);
char *b = malloc(250);
free(a);
char *c = malloc(250);

Fastbins

Fastbins se utilizan para pequeños fragmentos de memoria. A diferencia de los bines desordenados, los fastbins añaden nuevos fragmentos al principio, creando un comportamiento de último en entrar, primero en salir (LIFO). Si solicitas un pequeño fragmento de memoria, el asignador tomará del principio del fastbin.

Ejemplo:

  • Asignas cuatro fragmentos de 20 bytes cada uno (a, b, c, d).

  • Cuando los liberas en cualquier orden, los fragmentos liberados se añaden al principio del fastbin.

  • Si luego solicitas un fragmento de 20 bytes, el asignador devolverá el fragmento liberado más recientemente desde el principio del fastbin.

char *a = malloc(20);
char *b = malloc(20);
char *c = malloc(20);
char *d = malloc(20);
free(a);
free(b);
free(c);
free(d);
a = malloc(20);   // d
b = malloc(20);   // c
c = malloc(20);   // b
d = malloc(20);   // a

Otras Referencias y Ejemplos

  • ARM64. Use after free: Generar un objeto de usuario, liberarlo, generar un objeto que obtenga el fragmento liberado y permita escribir en él, sobrescribiendo la posición de la contraseña de usuario de la anterior. Reutilizar el usuario para burlar la verificación de la contraseña

  • El programa permite crear notas. Una nota tendrá la información de la nota en un malloc(8) (con un puntero a una función que podría ser llamada) y un puntero a otro malloc(<size>) con el contenido de la nota.

  • El ataque consistiría en crear 2 notas (nota0 y nota1) con contenidos de malloc más grandes que el tamaño de la información de la nota y luego liberarlas para que entren en el fast bin (o tcache).

  • Luego, crear otra nota (nota2) con tamaño de contenido 8. El contenido estará en nota1 ya que el fragmento se reutilizará, donde podríamos modificar el puntero de la función para que apunte a la función de victoria y luego Use-After-Free en la nota1 para llamar al nuevo puntero de función.

  • Es posible asignar algo de memoria, escribir el valor deseado, liberarlo, realojarlo y como los datos anteriores siguen allí, se tratará según la nueva estructura esperada en el fragmento, lo que hace posible establecer el valor o obtener la bandera.

  • En este caso es necesario escribir 4 dentro de un fragmento específico que es el primero que se asigna (incluso después de liberarlos forzosamente todos). En cada nuevo fragmento asignado se almacena su número en el índice del array. Luego, asignar 4 fragmentos (+ el inicialmente asignado), el último tendrá 4 en su interior, liberarlos y forzar la reasignación del primero, que utilizará el último fragmento liberado que es el que tiene 4 en su interior.

Last updated