Partie 24 - Annexe n°2 - gérer plusieurs versions de gdb et principales commandes pour déboguer le tas
Annexe n°2 : Gérer plusieurs versions de gdb et principales commandes pour déboguer le tas
Ce tutoriel se déroule en deux étapes :
- dans un premier temps, nous allons apprendre à faire cohabiter plusieurs versions de gdb ensemble ;
- dans un second temps, nous allons nous intéresser aux principales commandes à connaître lorsque l’on débogue un programme utilisant le tas.
Installation de plusieurs versions de gdb
Versions installées
Pour différentes raisons, il se peut que vous ayez envie d’installer différentes versions de gdb. Par “version” on entend ici “variante” et non pas le numéro de version.
Installer différentes versions permet de passer de l’une vers l’autre afin de profiter des avantages de chacune d’elles. Le principal souci réside dans leur cohabitation pour qu’elles ne s’emmêlent pas les pinceaux.
Voici les différentes versions que nous allons installer :
- gdb-pwndbg ;
- gdb-peda ;
- gdb-gef (version classique) ;
- gdb-gef (fork de bata24).
Par souci de clarté,
gdb-gefdésignera la version “classique” degeftandis quegdb-gef++désignera la version forkée contenant davantage de fonctionnalités.
Comment les installer
J’ai teeellement la flemme de les installer une par une 😩.
Ça tombe bien, nous allons utiliser un script qui fera (presque) tout le sale boulot pour nous !
Pour installer ces différentes versions ensemble, nous allons nous servir du projet gdb-peda-pwndbg-gef.
Comme indiqué dans le tutoriel, lançons les commandes suivantes :
1
2
3
cd ~ && git clone https://github.com/apogiatzis/gdb-peda-pwndbg-gef.git
cd ~/gdb-peda-pwndbg-gef
./install.sh
Voilà ! Les versions suivantes sont désormais installées :
- gdb-pwndbg ;
- gdb-peda ;
- gdb-gef (version classique) ;
Malheureusement, gdb-gef++ n’est pas installé par ce script, il va donc falloir le faire nous-mêmes, vous verrez, ça vaut le coup !
Installation de gdb-gef++
gdb-gef++ est un fork de gdb-gef avec e nombreuses fonctionnalités supplémentaires notamment :
- débogage du noyau sans symboles : commandes heuristiques pour déboguer le noyau Linux sans
vmlinux; - support multi-architectures : compatibilité étendue avec
qemu-userpour plusieurs plateformes ; - analyse avancée du tas : commandes spécifiques pour examiner le tas ;
- optimisations diverses : ajouts et améliorations pour une meilleure expérience utilisateur.
Évidemment, il n’est pas forcément meilleur que toutes les autres versions, les goûts et les couleurs, toussa toussa. Néanmoins, pour ce qui est de l’exploitation dans le tas, il reste très intéressant.
Pour l’installation de gdb-gef++, vous pouvez simplement suivre ce qui est indiqué dans la rubrique d’installation en fonction de la version de votre système.
La commande d’installation est lancée avec
sudo. Cela facilite peut-être l’installation des paquets nécessaires pour éviter de demander le mot de passeroot.
Étant donné que les fichiers d’installation sont placés dans /root, nous allons devoir faire quelques changements et déplacer le fichier d’initialisation :
1
2
3
4
5
mkdir ~/gdb-gef++
sudo cp /root/.gdbinit ~/gdb-gef++
sudo cp -R /root/.gef ~/gdb-gef++
# Donner les droits de l'utilisateur courant
sudo chown -R $(whoami):$(id -gn) ~/gdb-gef++
Une fois ces étapes terminées, ouvrez le fichier ~/.gdbinit et ajoutez le bloc suivant :
1
2
3
4
5
6
define init-gef-bata24
source ~/gdb-gef++/.gef/gef.py
end
document init-gef-bata24
Initializes bata24-GEF (GDB Enhanced Features)
end
Enfin, créez le fichier /usr/bin/gdb-gef++ avec le contenu suivant :
1
2
#!/bin/sh
exec gdb -q -ex init-gef-bata24 "$@"
N’oubliez pas de lui accorder les droits d’exécution :
sudo chmod +x /usr/bin/gdb-gef++.
Et voilà, vous pouvez lancer gdb-gef++ !
Principales commandes pour déboguer le tas
Cette section est divisée en deux parties :
- un résumé des principales commandes ;
- les détails des commandes, souvent accompagnés d’une image d’illustration.
Vous pouvez rechercher avec
Ctrl+Fle nom d’une commande sur la page pour trouver les détails de celle-ci un peu plus bas.
Liste des commandes :
chunks: affiche les différents blocs alloués et libres présents sur le tas en se focalisant sur leurs métadonnées ;heap chunk 0xaddr: affiche les détails d’un bloc en particulier ;visual-heap: affiche une liste des différents blocs alloués et libres présents sur le tas. Très pratique pour avoir une vue d’ensemble ;arenas: affiche la liste des arènes ;arena: affiche les détails d’une arène en particulier ;top: affiche les détails du bloc du sommet ;bins: affiche le contenu des différentes corbeilles du tas ;tcachebins;fastbins;unsortedbin;smallbins;largebins.
heap bins-simple: affiche une vue d’ensemble des différentes corbeilles ;try-free: simule la libération d’un bloc ;try-malloc: simule l’allocation d’un bloc ;heap find-fake-fast: recherche un bloc de taillenqui pourrait être utilisé pour exploiter lafastbinde même taille.
chunks
💡 Résumé
Affiche les différents blocs alloués et libres présents sur le tas en se focalisant sur leurs métadonnées
📃 Détails
Les différents chunks (blocs) sont affichés avec différents détails :
- les blocs libres apparaissent en 🟡 ;
- les informations liées aux différentes métadonnées sont affichées avec différentes couleurs ;
- le bloc du sommet est visible avec la mention
top; - l’adresse
baseindique l’adresse du début du bloc, contenant les métadonnées, tandis que l’adresseaddrindique l’adresse à partir de laquelle commencent les données du bloc (adresse retournée parmalloc).
heap chunk 0xaddr
💡 Résumé
Affiche les détails d’un bloc en particulier.
📃 Détails
Cette commande permet d’avoir plus d’informations à propos d’un bloc en particulier.
L’adresse à saisir n’est pas l’adresse
basemaisaddr, celle qui pointe vers les données du bloc.
N’oubliez pas le mot clé
heapdans la commandeheap chunk 0xaddrpour que celle-ci puisse s’exécuter correctement.
visual-heap
💡 Résumé
Affiche une vue d’ensemble des différents blocs alloués et libres présents sur le tas en se focalisant sur leur contenu.
- Raccourcis :
vis
📃 Détails
Cette commande permet de visualiser rapidement le contenu des différents blocs présents sur le tas qu’ils soient libres ou alloués. Si un bloc appartient à une corbeille en particulier, cette dernière sera affichée.
Cette commande est très utile pour avoir en tête la structure des différents blocs en mémoire.
Astuce gdb : l’option
-dpermet d’utiliser des couleurs sombres (-dark) afin d’éviter d’avoir mal à la tête 😵💫. L’option-npermet d’afficher directement le tas sans utiliser une visualisation “à laless”.
arenas
💡 Résumé
Afficher la liste des arènes.
📃 Détails
Cette commande permet d’afficher la liste des arènes utilisées par le programme.
Pour rappel, un processus peut utiliser plusieurs arènes mémoire, notamment dans les programmes multithreadés.
arena
💡 Résumé
Afficher les détails d’une arène en particulier.
📃 Détails
Cette commande permet d’afficher pas mal d’informations sur une arène :
- les adresses des différentes corbeilles (toutes les corbeilles sauf le
tcache) ; - l’adresse du bloc du sommet ;
- plusieurs variables intervenant dans le fonctionnement interne de
free,mallocet autres fonctions de gestion de mémoire.
Astuce gdb : par défaut, c’est l’arène principale qui est affichée. Vous pouvez spécifier une autre arène avec l’option
-a. Par exemple :arena -a 0x7ffff0000030.
top
💡 Résumé
Afficher les détails du bloc du sommet.
📃 Détails
Cette commande affiche plusieurs informations concernant le bloc du sommet.
Astuce gdb : par défaut, le bloc du sommet affiché est celui de l’arène principale. Vous pouvez spécifier une autre arène avec l’option
-a. Par exemple :top -a 0x7ffff7e1ac80.
bins
💡 Résumé
Afficher le contenu des différentes corbeilles du tas.
📃 Détails
Si vous cherchez une commande permettant d’avoir une vue panoramique sur les différentes corbeilles du tas, c’est la commande qu’il vous faut !
Les différents blocs libres sont listés avec les informations concernant leurs métadonnées. De plus, dans le cas où une corruption de liste chaînée, par exemple, a eu lieu, cette commande indiquera la présence d’une corruption.
Astuce gdb : pour avoir la liste de toutes les corbeilles, même celles qui sont vides, vous pouvez utiliser l’option
-v.
Vous pouvez restreindre les informations affichées à une corbeille en particulier avec les commandes suivantes :
tcachebins;fastbins;unsortedbin;smallbins;largebins.
heap bins-simple
💡 Résumé
Afficher une vue d’ensemble des différentes corbeilles.
📃 Détails
Il s’agit d’une version plus concise de la commande bins.
N’oubliez pas le mot clé
heapdans la commandeheap bins-simplepour que celle-ci puisse s’exécuter correctement.
try-free
💡 Résumé
Simuler la libération d’un bloc.
📃 Détails
Cette commande est très utile en pwn car elle permet de simuler la libération d’un bloc. Cela permet de savoir à l’avance si appeler free sur ce bloc va générer une erreur ou non. De cette manière, vous pouvez savoir si une libération de bloc va passer toutes les vérifications.
Un point essentiel de cette commande est que la libération est simulée, donc ne vous inquiétez pas, free ne sera pas réellement appelée.
L’adresse à donner en paramètre de cette commande est l’adresse qui pointe vers les données du bloc et non ses métadonnées.
try-malloc
💡 Résumé
Simuler l’allocation d’un bloc.
📃 Détails
De la même manière que try-free simule la libération d’un bloc, try-malloc simule l’allocation d’un bloc pour une taille donnée. La fonction retourne l’adresse qui aurait été retournée si malloc avait réellement été appelé avec cette taille en paramètre.
Cela est pratique pour voir si votre exploit est propre et fonctionnel. Par exemple, dans le cas d’une tcache attack ou fastbin attack, si vous ne gérez pas correctement la liste chaînée, il se peut que la prochaine allocation échoue, chose que vous devriez observer si vous lancez try-malloc.
heap find-fake-fast
💡 Résumé
Rechercher un bloc de taille n qui pourrait être utilisé pour exploiter la fastbin de même taille.
📃 Détails
Étant donné que depuis la version 2.3.4 de la glibc, la taille des blocs utilisés est vérifiée lorsqu’un bloc de taille n est alloué en utilisant la fastbin de même taille, nous ne pouvons plus utiliser n’importe quel bloc pour réaliser une fastbin attack, par exemple.
Cette commande permet ainsi de pouvoir trouver en mémoire de potentiels blocs de taille n que l’on pourrait utiliser pour exploiter la liste chaînée de la fastbin.
N’oubliez pas le mot clé
heapdans la commandeheap find-fake-fastpour que celle-ci puisse s’exécuter correctement.










