Introduction au reverse engineering avec Radare2 & compagnie - Partie 1
Introduction au reverse engineering avec Radare2 & compagnie - Partie 1
Objectif
Cet article est le premier d’une série traitant du reverse-engineering logiciel. L’objectif de cette première partie est simplement la découverte de quelques outils utiles dans ce domaine.
Dans une partie 2 à venir, nous traiterons la résolution d’un challenge du type capture the flag grâce à ces outils.
Introduction
La rétro-ingénierie (ou en moins franchouillard et plus courant reverse engineering) consiste à étudier le comportement d’un système afin d’en comprendre son fonctionnement interne. En informatique, les applications du reverse engineering de fichiers binaires sont multiples:
- 🕵 analyser des programmes malveillants
- 🕵 améliorer la sécurité / rechercher des failles
- 🥷 contourner des protections logicielles
- 🥷 altérer le comportement d’un programme
Un fichier binaire est généralement constitué de plusieurs choses :
- des méta-données et un entête
- des données
- des instructions codées dans un langage compréhensible par un type de processeur, pour un système donné
Pour ce premier tutoriel, on posera les bases du reverse en se concentrant sur les fichiers ELF (Executable and Linkable Format) sous Linux.
Fichiers ELF
Sous Linux, ELF est le format le plus courant de fichiers binaires. Dans ce format, un binaire est constitué d’un entête fixe, de segments et de sections.
man elf
permet d’obtenir des informations détaillées sur la structure ELF.
Pour la suite du tutoriel, nous prendrons comme victime la commande ls
, que l’on trouve sur n’importe quel poste Linux.
Outils disponibles par défaut sous Linux
Pour commencer à disséquer notre programme ls
, plusieurs commandes doivent déjà être disponibles par défaut sous Linux.
Si elles ne sont pas présentes, vous pouvez les installer via votre installeur préféré (apt
, yum
, etc.)
strings
strings
permet d’extraire et afficher toutes les chaînes de caractères incluses dans un exécutable.
Lancez la commande suivante et observez le résultat :
strings /bin/ls
ltrace
Permet de tracer les appels de fonctions de bibliothèques.
ltrace /bin/ls
strace
Même chose que ltrace
, mais pour les appels système.
strace /bin/ls
file
file
affiche les caractéristiques de l’exécutable passé en paramètre. On verra plus loin que rabin2
, qui vient avec radare2
, remplit aussi cette fonction.
|
|
hexdump
hexdump
affiche la représentation hexadécimale de l’exécutable.
Exemple : hexdump -C binary.bin | less
Radare2
Passons aux choses sérieuses. Les petits tools présentés plus haut sont sympa, mais nous allons voir un outil beaucoup plus complet, et qui permet aussi bien l’analyse statique sans exécuter le programme) que l’analyse dynamique (en débugant/exécutant le programme, avec des points d’arrêts, etc.)
Radare2 est un framework opensource pour l’analyse de binaires. Il comprend énormément de formats différents, dont ELF. Sa CLI ergonomique permet de désassembler un binaire, analyser ses données, patcher, comparer, chercher, faire des remplacements, etc.
Installation
Clonez le repo, lancez le script d’install et allez chercher un ☕ le temps de l’installation.
|
|
Les updates sont réguliers. Pour être à jour, il suffit de lancer ./sys/install.sh
Premières commandes pour découvrir
rabin2
Ok, commençons par extraire quelques informations de base grâce à la commande rabin2
:
rabin2 -I /bin/ls
-I
équivaut à l’option Show binary info
r2
Analysons la commande ls : r2 /bin/ls
.
Une fois radare2 lancé, entrez la commande vpp
. Vous affichez ainsi un des modes graphiques de radare2.
La touche p permet d’alterner entre les affichages graphiques. Pour quitter le mode graphique, appuyez sur q.
💡 Si vous ne comprenez rien aux symboles et au code obscure, pas de panique. L’objectif de ce premier article n’est pas de tout comprendre, mais simplement se familiariser avec l’outillage. Dans un prochain article, nous nous attarderons sur les aspects généraux du code assembleur, de son rapport avec le code machine, et les principes de fonctionnement d’un programme, des registres processeurs, de la pile d’exécution, etc.
Lancez la commande aaa
, qui permet de lancer une analyse par défaut.
L’analyse permet à Radare2 d’identifier des zones du programme intéressantes (ce qu’on appelle les flags), et les catégoriser en flagspaces.
Autrement dit, un flag est une information intéressante, d’une certaine catégorie (section, fonction, symbol, chaine de caractère, etc.). Un flagspace correspond donc à un ensemble de flags de la même catégorie.
Par exemple
Pour afficher un résumé des flagspaces, entrez fs
.
|
|
Choisissons le flagspace strings : fs strings
.
Une fois un flagspace sélectionné, il suffit d’entrer f
pour afficher les flags correspondants:
|
|
Quick reference - mémo - cheatsheet
Commande | Description |
---|---|
r2 -d commande ou r2 -d pid |
Lance radare2 en mode debug et se positionne juste avant l’entry point main |
vpp |
Entre en mode debugger visuel: - La touche p permet de switcher entre les modes visuels- [F7] pour debug step into- [F8] pour debug step over- [F2] pour positionner un breakpoint |
fs |
Affiche les flagspaces |
fs * |
Sélectionne tous les flagspaces (par défault) |
fs strings |
Sélectionne le flagspace des chaines de caractère |
f |
Affiche les valeurs du (des) flagspace(s) courant(s) |
"? 1 + 2 * 12" |
Calcule une expression : |
dr ou dr= |
Affiche la valeur des registres généraux |
i |
Affiche des infos sur le fichier binaire (même chose que rabin2 -I monfic) |
iS= |
Affiche les sections avec une visualisation en barres ascii art. Pour la notion de section, se référer à la doc officielle de radare2 |
pd |
Désassemble le code |
ie |
Affiche le point d’entrée du programme |
aaa |
Lance une analyse automatique des fonctions du programme |
afl |
Liste les fonctions du programme |
pdc@0x080485f5 |
Désassemble en pseudo-c le code de la fonction ayant pour adresse 0x080485f5 |
Tips - astuces
Astuce |
---|
Pour afficher une aide contextuelle à une commande, ajouter un point d’intérrogation. Ex: afl? |
Pour répéter une commande plusieurs fois, préfixer du nombre de répétitions. Ex: 3px |
En mode visuel (Vpp ), les commandes classiques sont disponibles en appuyant préalablement sur : (comme dans vi) |
On peut chaîner plusieurs commandes avec le point-virgule, comme dans un shell. Ex: fs strings; f |
Pour les outputs json, ajouter ~{} pour prettifier le résultat. Ex: of~{} au lieu de of |
Ressources externes
Le Radare2 book officiel : https://book.rada.re/