• Saltar al contenido principal
  • Saltar a la barra lateral principal

DiegoAltF4

julio 26, 2022 Por diegoaltf4

Heap Exploitation 0x01 | Chunks

¿Qué es el Heap?

A diferencia del stack, el heap es una zona de memoria que puede ser asignada de forma dinámica. Podemos asignar y liberar espacio en casi cualquier momento. Es importante saber que, al contrario que el stack, el heap crece hacia direcciones de memoria crecientes.

Para que nos situemos mejor, he creado un pequeño diagrama que intenta reflejar el espacio de direcciones virtuales en Linux. Este diagrama nos va a ser de gran utilidad para que, en cada momento, sepamos dónde nos encontramos y hacia qué zona queremos desplazarnos. No es lo mismo alocar un chunk para sobreescribir el valor de una dirección que se encuentra en «.data» que sobreescribir una función que se encuentra en la GLIBC.

Nota: Las direcciones de memoria que aparecen son ejemplos. No se deben tomar como rangos fijos.

Malloc Internals

Los chunks son la unidad básica de memoria con la que trabaja Malloc. Están formados por un campo size (8 bytes) y por los datos de usuarios.

Los chunks tienen la siguiente estructura en una arquitectura x86_64:

Allocated Chunks

Código de ejemplo:

Vamos a utilizar ese ejemplo para entender mejor el funcionamiento de los chunks.

Comenzamos desensamblando la función main:

Ahora vamos a establecer un breakpoint en main + 17. En ese punto es cuando se efectúa la primera llamada a malloc:


b *main+17

Ejecutamos el programa y visualizamos los chunks con el comando vis:

Como se puede ver, no hay chunks actualmente porque no se ha llegado a efectuar la llamada a malloc.

Continuamos con la ejecución y visualizamos nuevamente los chunks:

Ahora sí que tenemos datos sobre el chunk reservado. Vamos a analizarlos:

En el primer malloc, hemos reservado 1 solo byte; sin embargo, GDB nos indica que el chunk tiene un tamaño de 0x20 bytes, es decir, 32 bytes en base decimal. De estos 32 bytes, tan solo 8 se utilizan para indicar el tamaño y los 24 restantes son los que almacenan la información. En consecuencia, el tamaño mínimo (usable) de chunk es de 0x20 bytes, de los cuales 0x18 son de datos.

El tamaño de los chunks se incrementa en múltiplos de 16 bytes (malloc está alineado a 16 bytes). Por tanto, tenemos la siguiente secuencia de tamaños: 0x20, 0x30, 0x40, 0x50, etc.

Por consiguiente, si queremos reservar entre 25 y 40 bytes de datos, el tamaño del chunk será de 0x30.

Veámoslo con el código de ejemplo.

Ahora, vamos a establecer un breakpoint en main + 59:


b *main + 59

Arrancamos el programa y visualizamos los chunks:

Efectivamente, se reservan 0x30 bytes para cada una de las siguientes líneas:


char * buf3 = malloc(25); 
char * buf4 = malloc(40);

Top Chunk

El top chunk se encuentra en la parte superior del heap. Si se asigna más espacio, se desplaza hacia abajo y da el espacio. Si el chunk se libera, se vuelve a recuperar el espacio.

Vamos a verlo con el mismo ejemplo de antes:

Con el primer malloc, el tamaño del top chunk toma el siguiente valor:

Con el segundo malloc, el tamaño del top chunk toma el siguiente valor:

Como se puede ver el tamaño del top chunk actual 0x0000000000020d31 = 0x0000000000020d51 – 0x20

Con el tercer malloc, el tamaño del top chunk toma el siguiente valor:

0x0000000000020d01 = 0x0000000000020d31 – 0x30

Con el tercer malloc, el tamaño del top chunk toma el siguiente valor:

0x0000000000020cd1 = 0x0000000000020d01 – 0x30

Free Chunks

Cuando «liberamos» un chunk a través de free, algunos quadwords que antes se utilizaban para almacenar la información del usuario, comienzan a formar parte de la información de malloc.

El campo size se mantiene, pero el primer quadword que contenía información de usuario, se utiliza como forward pointer y el segundo quadword se utiliza como backward pointer. Estos punteros se utilizan para clasificar los chunks en bins. Por tanto, la estructura es similar a la siguiente imagen:

Nota: hay más quadwords asociados a los datos del usuario que se reutilizan. Los veremos en más detalle en futuros artículos en los que hablemos sobre bins, pero para los más curiosos, en el malloc.c se define la siguiente estructura:

Chunks Flags

Dado que los tamaños que reserva malloc siempre terminan en 0, los últimos 3 LSBs del campo size se usan como flags para indicar estados del chunk. Por tanto, los chunks adquieren la siguiente forma:

NON_MAIN_ARENA (0x04)

Este bit indica si el chunk NO pertenece a la arena principal (main arena).

IS_MMAPPED (0x02)

Este bit indica si el chunk fue alocado usando mmap().

PREV_INUSE (0x01)

Este bit indica si el chunk anterior está en uso. Es importante saber que algunos chunks como los fastbins tienen este bit activado a pesar de haber sido liberados por la aplicación (free).

Para más información podéis consultar la wiki de GLIBC

Referencias

– https://ir0nstone.gitbook.io/notes/types/heap
– https://guyinatuxedo.github.io/25-heap/index.html
– https://heap-exploitation.dhavalkapil.com/diving_into_glibc_heap/malloc_chunk
– https://www.youtube.com/watch?v=s-GJ-buCGio
– https://heap-exploitation.dhavalkapil.com/

 

Espero que os haya gustado y, lo más importante, que hayáis aprendido.

 

DiegoAltF4

 

Inicio

Interacciones con los lectores

Deja una respuesta Cancelar la respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Barra lateral principal

Buscar

advertencia

Toda la información proporcionada es de uso y fines educativos, DiegoAltF4 no se responsabiliza de los daños causados por la gente que haga un mal uso de la información proporcionada. Hacer un mal uso de esta información es un delito tipificado en el articulo 197.3 del código penal.

Entradas recientes

  • Heap Exploitation 0x02 | House of Force
  • Heap Exploitation 0x01 | Chunks
  • Writeup Una Al Mes – Junio 2022
  • Writeup Challenge 7 | pwn101 TryHackMe
  • Writeup VulnLawyers ctfchallenge

¿Quieres colaborar conmigo ?

Contáctame

si quieres aprender más

Base64
Underc0de
LinuxSeguridad
Security News
© 2023

DiegoAltF4