Aller au contenu principal
own2pwn
Comprendre le heap avant de l'attaquer

Comprendre le heap avant de l'attaquer

Presentation de ptmalloc2 (pthread malloc v2), l'allocateur de heap utilise par la glibc : raison d'etre de la heap face a la stack, et plan d'attaque pour comprendre chunks, arenas, bins et tcache.

Maxime J5 min de lecture

Un doute sur votre exposition ?

On audite votre surface d'attaque externe et on vous dit ce qui est exploitable.

Parler à un pentester

Prerequis

  • Langage C
  • Syscalls Linux
  • Maniement de GCC

Hello ! o/

A travers une serie d'articles vous allez comprendre comment la heap est geree dans l'implementation de ptmalloc2 (pthread malloc v2). ptmalloc2 est le systeme de la heap qui est actuellement utilise dans la glibc. Comme d'habitude, on verra assez en profondeur pour que vous ayez une vue qui ne soit pas biaisee, mais pas trop non plus, sinon il suffirait de vous rediriger vers le code source.

Ces articles sont divises en 4 et on en tirera tous les details necessaires :

  • Les chunks : le bloc memoire que vous allouez sur la heap
  • Les arenas : les structures qui gerent les differentes heap
  • Les bins : ou sont stockes les chunks liberes
  • Le tcache : qui resout les conflits de threads

Heap vs Stack : pourquoi avoir les deux ?

Un peu de contexte : la heap permet de gerer les allocations dynamiques, typiquement quand vous voulez creer une structure de donnee qui augmente de taille au runtime, genre une liste chainee. La stack ne peut pas gerer ce type d'allocation du fait que chaque stackframe (memoire reservee a une fonction) a une taille definie par les declarations des variables, donc ecrire par-dessus risque tres fortement d'en reecrire d'autres.

Toute la problematique d'une heap reside dans la vitesse d'allocation et de gestion de la memoire : il faut pouvoir reutiliser au mieux et au plus vite ce qui a ete libere.

La heap est donc un espace memoire a part entiere, separee de la stack. Elle est creee par l'intermediaire de votre premier malloc(3), ou d'un call sur brk(2), mmap(2) ou tout autre syscall qui peut creer une plage d'adresses memoire.

Stack vs Heap en bref

La stack grandit vers le bas, taille fixee a la compilation. La heap grandit vers le haut, taille variable au runtime. Ce sont deux segments distincts dans l'espace d'adressage d'un processus.

Premier malloc : la heap nait

Voila un exemple minimal qui illustre exactement quand la heap apparait en memoire :

c
#include <stdio.h>
#include <stdlib.h>

int
main (int argc,
      char * argv [])
{
    unsigned short i;
    short * ptr;

    if (argc > 1)
    {
        fprintf(stderr, "[!] Error: Usage: ./program\n");
        exit(EXIT_FAILURE);
    }
    // Il n'y a toujours pas de heap en memoire a partir d'ici
    ptr = (short *) malloc ( sizeof(short) * 10 );
    // Et la, elle est declaree

    for (i = 0; i < 10; i++)
    {
        ptr[i] = i;
    }
    fprintf(stdout, "%hd\n", ptr[3]);

    return EXIT_SUCCESS;
}
maps-avant-apres-malloc.txt
Avant le premier malloc() : pas de segment [heap] dans /proc/PID/maps. Apres : le segment apparait, alloue par brk().

Comment verifier ca vous-meme

Compilez le programme, lancez-le sous GDB, posez un breakpoint avant et apres le malloc(), puis inspectez cat /proc/$pid/maps. Vous verrez le segment [heap] apparaitre exactement entre les deux breakpoints.

Plan de la serie

Maintenant qu'on sait pourquoi la heap existe, voila comment on va l'eplucher dans les articles suivants :

PartieSujetCe qu'on y comprend
pt2ChunksStructure d'un bloc memoire alloue : header, flags, pointeurs
pt3ArenasStructures qui gerent les heap (une par thread dans certains cas)
pt4BinsListes de chunks liberes (fastbins, smallbins, largebins, unsorted)
pt5TcacheThread-local cache, introduit en glibc 2.26 pour regler les contentions multi-thread

Veille sécurité

La suite, une fois par mois

Ce qui bouge vraiment sur la surface d'attaque externe, NIS2 et la sécurité applicative, écrit par le pentester qui signe ces articles. Un envoi par mois, désinscription en un clic.

Votre adresse ne sert qu'à cet envoi. Voir la politique de confidentialité.