main
pour radare2 https://radare.gitbooks.io/radare2book/content/crackmes/avatao/01-reverse4/main.htmlTable des matières
Exercice de découverte de désassemblage avec radare2
Nous allons dans cette note d'exercice essayer de découvrir l'usage du logiciel de débogage et désassemblage Radare2.
Pour cela :
- utilisation d'un petit logiciel en C (codé avec les pieds) fourni
- Nous allons utiliser radare2 pas à pas
- Désassembler le logiciel en C
- découvrir quelques notions et manipulations basiques
- Récupérer le phrase de passe qui verrouille se logiciel
- Niveau prérequis :
- débutant⋅e avec curiosité
- usage rudimentaire de linux
- Matériel requis : une machine avec un système unix/linux
- Temps à dédier : 30 minutes à 1 heure grand max
Elle n'est pas applicable dans l'état à un manipulation de désassemblage sur un logiciel potentiellement malveillant − ce qui nécessiterait bien d'autres considérations et mise en place de sécurité.
Installation des logiciels nécessaires
gcc
GCC, the GNU Compiler Collection
Elle ne vise pas d'objectif d'apprentissage − nous ne nous y attarderons pas ici
Ce logiciel vous permettra de compiler le logiciel en langage C que vous allez désassembler.
« GCC (GNU Compiler Collection) est une suite de logiciels libres de compilation. On l'utilise dans le monde Linux dès que l'on veut transcrire du code source en langage machine, c'est le plus répandu des compilateurs. La suite gère le C et ses dérivés mais aussi le Java ou encore le Fortran. » Doc Ubuntu
À votre charge d'installer GCC avec votre gestionnaire paquet dans votre distribution (pacman, apt, yay, etc.)
logiciel en C pour désassemblage
Ceci afin de vous fournir un jouet de découverte et d'entraînement.
Ne soyez pas trop attentive, attentive à son écriture et son contenu
Le code source que vous devez copier dans un éditeur de texte (note, gdit…) ou de code (VScodium par exemple).
Placez vous dans le répertoire puis dossier qui vous convient et créez un fichier 1st_reverse.c
pour y écrire :
#include <stdio.h> #include <stdlib.h> #include <string.h> int main (int argc, char **argv) { int valeur; if (argc < 2) //Si mdp correct, le proramme se termine avec succès { fprintf (stderr, "Erreur manque un argument pour %s de type chaine de caractère \n (#>_<)\n", argv[0]); //Si programme excuté sans argument, affichage d'un message d'erreur return EXIT_FAILURE; //On sort du programme. } valeur = strcmp (argv[1],"FrenchCuisine"); //le `strcmp` effectue une opération de comparaison entre l'argument passée et le mot de passe codé en clair if (valeur == 0) // Si valeur = 0, signifie que le mdp rentré est correct printf ("Bravo ! \n Vous avez le bon mot de passe ! elf (fichier exécutable) cracké \n ⊂(“◉‿◉)つ \n '%s' est ton sésame\n", argv[1]); // affiche le texte signifiant "Réussite" else printf ("Pas le bon mot de passe, essaye encore ! '%s' est incorrect \n <(°_0)…>\n", argv[1]); // Affiche du texte "Échec" return EXIT_SUCCESS; //Fin du programme, sortie. }
Compilation du fichier source
Nous allons maintenant compiler 1st_reverse
pour obtenir un exécutable.
- Placez dans le dossier du répertoire contenant votre fichier
1st_reverse.c
- Taper
ls
comme commande dans votre terminal vous vérifier la présence de1st_reverse.c
- Entrez la commande
gcc –help
pour vérifier la disponibilité de GCC et avoir un aperçu des commande disponible −q
pour sortir
- Entrez la commande
gcc -o 1st_reverse 1st_reverse.c
-o
signifie à GCC que l'exécutable compilé se nommera1s_reverse
- Si tout se passe passe (y'a pas de raison que ça plante, normalement…) n'aurez pas d'affichage de message informatif à la fin du processus
- Entrer
ls
pour obtenir la liste des fichiers dans l'emplacement où vous êtes situé⋅e dans votre terminal 1st_reverse
devrait maintenant être disponible.
radare2
fr:Radare2 est un lociel libre destiné à la rétro-ingénierie et à l'analyse de fichiers binaires ; composé d'un jeu d'outils pouvant être utilisés ensemble, ou séparément depuis l'invite de commande.
Dans une démarche similaire à l'installation de GCC, installez Radare2 dans votre ordinateur.
Ou si vous êtes motivé⋅e⋅s, installation aussi possible ainsi :
> git clone https://github.com/radare/radare2.git > cd radare2 > ./sys/install.sh
Config de radare2
Pour une utilisation moins abrupte et quelques facilités d'usage, nous vous proposons après installation de créer un fichier de configuration pour radare2 nommé radare2rc
et placé ainsi dans son chemin ~/.config/radare2/radare2rc
Nous proposons de lui donner les paramètres de configuration suivants
# Show comments at right of disassembly e asm.cmt.right=true # Shows pseudocode in disassembly. Eg mov eax, str.ok = > eax = str.ok e asm.pseudo=false #ESIL EMU #e asm.emu=true #e asm.esil=true # Display stack and register values on top of disasembly view (visual mode) e cmd.stack=true # selected theme ; see https://r2wiki.readthedocs.io/en/latest/home/themes/ eco basic # Set color e scr.color=3 # Use UTF-8 to show cool arrows that do not look like crap :) e scr.utf8=true # to make the outlines beautiful e asm.describe=true # to enable command autocompletion e cfg.newtab=1 # Sanbox settings e cfg.sandbox=false # so on finest settings e asm.bits=64 e asm.lines.call=true e asm.lines.out=true # enable fortune in the starter e cfg.fortunes=true e cfg.fortunes.type=fun,tips,nsfw # enable the pager e scr.pager=less -R # Show tiny graph # e cmd.gprompt=aga # e cmd.vprompt= e graph.scroll=10 e graph.bubble=false e graph.dummy=true
Et pour activer ceux-ci tapez source ~/.bashrc
ou source ~/.zshrc
dans votre terminal pour les activer.
gdb + peda
Supplément optionnel à votre découverte, pour cela voir gdb+peda
Manipulations
Commençons enfin à manipuler ce que nous avons mis en place
Comme indiqué dans Astuces dans la pratique de Reverse avec outils embarqués pour OSINT, partons d'une petite mise en bouche rapide.
Essayez dans votre terminal :
> ./1st_reverse
Puis Enter
pour lancer.
Qui est ce qui semble le plus probable pour lance l'exécutable 1st_reverse
. Puis suivez votre intuition, répétez la commande et/ou ajoutez y ce qui vous semblera opportun après ./1st_reverse
dans votre terminal avant d'appuyer sur entrée.
Prise d'informations avant désassemblage
Utilisons file
pour observer ce qu'est 1st-reverse
La commande dans le terminal :
> file 1st_reverse 1st_reverse: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=7b20020d4fb2915355e8822387c7976d696822d6, for GNU/Linux 3.2.0, not stripped
Ce qui nous importe un premier est ELF
: notre fichier est un exécutable.
Notons également les infos complémentaires 64-bit
qui nous indique que cet exécutable à été par et pour un fr:Processeur_64_bits à partir d'une distribution Linux architecturée en x86-64 avec un noyau GNU/Linux 3.2.0
- La signature pas hashage fr:SHA-1 nous intéressera
- Empreinte du hash :
7b20020d4fb2915355e8822387c7976d696822d6
Utilisons maintenant strings
> strings 1st_reverse strings 1st_reverse /lib64/ld-linux-x86-64.so.2 mih" libc.so.6 stderr fprintf __cxa_finalize strcmp __libc_start_main GLIBC_2.2.5 _ITM_deregisterTMCloneTable __gmon_start__ _ITM_registerTMCloneTable u3UH []A\A]A^A_ Erreur manque un argument pour %s de type chaine de caract (#>_<) FrenchCuisine Bravo ! Vous avez le bon mot de passe ! elf (fichier executable) crack '%s' est ton s […]
Vous noterez peut-être des premières informations intéressantes telles qu'une erreur potentielle dans le code, voir bien plus grave infos…
Passons maintenant à xxd
> xxd 1st_reverse | less 00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............ 00000010: 0300 3e00 0100 0000 6010 0000 0000 0000 ..>.....`....... 00000020: 4000 0000 0000 0000 e039 0000 0000 0000 @........9...... 00000030: 0000 0000 4000 3800 0b00 4000 1d00 1c00 ....@.8...@..... 00000040: 0600 0000 0400 0000 4000 0000 0000 0000 ........@....... 00000050: 4000 0000 0000 0000 4000 0000 0000 0000 @.......@....... […] 00000290: 1802 0000 0000 0000 1802 0000 0000 0000 ................ 000002a0: 0100 0000 0000 0000 2f6c 6962 3634 2f6c ......../lib64/l 000002b0: 642d 6c69 6e75 782d 7838 362d 3634 2e73 d-linux-x86-64.s […] 00002050: 0046 7265 6e63 6843 7569 7369 6e65 0000 .FrenchCuisine.. […]
Nous obtenons confirmation d'informations précédentes ainsi que des compléments avec la vue hexadécimale (hexdump) de notre fichier
- Indexation du nombre de lignes. (ex :
00000000, 00000010, 00000020……………….00000220
) - Le nombre d'octets par défaut par groupe est de 2 (-e : 4 little-endian hexdump), ce qui correspond à une taille de groupe de 4 octets. (ex :
7f45 4c46………………..0000
) - La longueur standard de la colonne est égale à 16 bytes avec les espaces. (ex : pour la ligne terminant par
.ELF
) 7f 45 4c 46 02 01 01 00
Ces numéros aident le système à identifier le type de fichier utilisé. Certains fichiers qui ne sont pas écrits avec leur extension, sont identifiés à l'aide de ces nombres magiques.7F 45 4C 46
pour les ELF (notre fichier de code source avant compilation avait pour extension.c
)- Pour revenir à l'état de notre fichier avant le hexdump avec la commande
xxd
, faisons :
> xxd 1st_reverse > 1st_reverse.txt # Pour sauvegarder notre dump dans un fichier texte
Puis
> xxd -r 1st_reverse.txt […] Erreur manque un argument pour %s de type chaine de caractère (#>_<) FrenchCuisineBravo ! Vous avez le bon mot de passe ! elf (fichier executable) cracké ⊂(“◉‿◉)つ '%s' est ton sésame […]
Désassemblage avec radare2
Premier pas
Première étape, lancer radare2 visant notre fichier cible
> r2 1st_reverse -- This is just an existentialist experiment. [0x00001060]>
> r2 /bin/ls aaa # analyze all the things is # list symbols afl # list functions found pdf # disassemble function s <tab># seek to address v # enter visual panels mode
Maintenant commençons par lancer une analyse de tout notre « programme » du fichier cible
> r2 1st_reverse -- This is just an existentialist experiment. [0x00001060]> aaa [x] Analyze all flags starting with sym. and entry0 (aa) [x] Analyze function calls (aac) [x] Analyze len bytes of instructions for references (aar) [x] Check for objc references [x] Check for vtables [x] Type matching analysis for all functions (aaft) [x] Propagate noreturn information [x] Use -AA or aaaa to perform additional experimental analysis. [0x00001060]>
Avec la commande aaa
radare2 indique les étapes à suivre. Chaque étape a la commande qui en est responsable entre parenthèses.
aaa
est une commande qui exécute d'autres commandes. Elle affiche également une brève description de l'action de chaque commande. Vous trouverez des informations un peu plus détaillées sous aa?
Analyse des fonctions
Passons maintenant à l'étape suivante d'analyse de fonction avec la commande afl
[0x00001060]> afl 0x00001060 1 46 entry0 0x00001090 4 41 -> 34 sym.deregister_tm_clones 0x000010c0 4 57 -> 51 sym.register_tm_clones 0x00001100 5 65 -> 55 sym.__do_global_dtors_aux 0x00001150 1 9 entry.init0 0x00001000 3 27 sym._init 0x00001280 1 5 sym.__libc_csu_fini 0x00001288 1 13 sym._fini 0x00001210 4 101 sym.__libc_csu_init 0x00001159 7 168 main 0x00001030 1 6 sym.imp.printf 0x00001040 1 6 sym.imp.strcmp 0x00001050 1 6 sym.imp.fprintf
Nous avons ici :
- L'adresse de chaque fonction de notre fichier cible
1st_reverse
figure dans la première colonne et le symbole dans la dernière - 2ème colonne : Le nombre de blocs de base dans la fonction
- 3ème colonne : La taille de la fonction (en octets)
- 4ème colonne : Nom de la fonction
sym.imp.strcmp
qui nous interpelle. Cette fonction compare des chaînes de caractères, comme des phrases de passe entrées et celle correcte désirée, strcmp
retourne 0 si les chaînes comparer sont identiques. > man strcmp
dans votre terminal vous donnera plus d'indications.
Utiliser une sortie en JSON
La plupart des commandes informatives de radare2 peuvent être accompagnées d'un j
pour formater la sortie en JSON. Ajoutons ~{}
pour formater la sortie avec une indentation JSON pour une autre lisibilité et lecture :
Exemple :
>[0x00001060]> aflj~{}
Nous donne
Vue d'ensemble des fonctions et cartographie
la commande main
1)
Nous utilisons cette commande avec l'option de visualisation graphique fournie par radare2 avec VV
.
Ainsi
[0x00001060]> VV @main
Nous donne
Naviguer dans les fonctions du fichier
Depuis le graphique ascii de radare2 vous pouvez naviguer en utilisant les touches fléchées et pour zoomer +
et dézoomer -
. Si vous regardez le premier bloc du graphique en bleu, vous pouvez voir
; arg char **arg @ rsi
qui correspond à une instruction de requête de de chaîne de caractères.- Puis
push word, doubleword or quadword onto the stack
qui signifie qu'un chaîne de caractère, très probablement équivalente à une phrase de passe, est attendue dans la pile d'instruction de fonctionnement de notre fichier. ; compare two operands
signifie qu'il y une opération qui compare aux données saisies par la personne à l'aide de la fonction strcmp. Ensuite, il y a vérification de la condition si les chaînes sont égales ou non. Si elles ne sont pas égales, nous suivons la ligne verte T (qui signifie “true”) jusqu'à ces blocs de code :
Zoomons avec +
sur le bloc entouré en blanc
Que pouvons nous voir ?
La chaîne de caractère inscrite en clair telle que “FrenchCuisine”
nous interpelle.
Ensuite vous pouvez vous lancer à la recherche de notre premier mot de passe.
Avançons
Pour vérifier notre piste de FrenchCusine
comme phrase de valide suivons les fils de notre graphique ascii qui représente le comportement de la fonction main
de notre fichier cible
Lorsque nous tentons de faire fonctionner ./1st_reverse
sans aucun argument ou chaîne de caractères :
> ./1st_reverse Erreur manque un argument pour ./1st_reverse de type chaine de caractère (#>_<)
Repartons de notre 1er bloc (bleu) en haut de notre graphique
Rouge (f = false)
Si nous donnons un argument en chaîne de caractère, exemple :
> ./1st_reverse password Pas le bon mot de passe, essaye encore ! 'password' est incorrect <(°_0)…>
Si nous donnons un argument en chaîne de caractères avec FrenchCuisine
> ./1st_reverse FrenchCuisine Bravo ! Vous avez le bon mot de passe ! elf (fichier executable) cracké ⊂(“◉‿◉)つ 'FrenchCuisine' est ton sésame
Vous avez percez le secret de votre fichier qui était jusqu'à présent quasi totalement illisible et inexécutable correctement.
Ouvrons plus loin
Le fait de parcourir les fonctions et leurs comportements dans la pile d'instruction de notre fichier cible n'est pas encore à proprement parler du désassemblage.
Nous allons maintenant passer à un exercice de modification du code binaire fichier cible, notamment pour utiliser des commande de désassemblage dans radare2 telles que pdf
ou pd
Listes de ressources
Documentation générale
- Github doc intro https://github.com/radareorg/radare2/blob/master/doc/intro.md
radare2 writtings for practices
- 4 blog posts with clear approach https://insinuator.net/tag/radare2/
- Reverse Engineering With Radare2 — Part 2 https://archive.is/NQlKD
- CMU Bomb Lab with Radare2 — Phase 1 https://archive.is/wip/LfpIr
- rax2→ base converter
- rabin2→ extract binary
- inforasm2→ (dis)assembler
- rahash2→ crypto/hashing utility
- radiff2→ binary diffing
- ragg2→ compile tiny bins
- rarun2→run with different env
- rafind2→find byte patterns
- r2pm→ r2 package manager
- r2/radare2→ main tool
- Understanding buffer overflows using Radare2 https://rderik.com/blog/understanding-buffer-overflows-using-radare2/
Sub notes
For radare2rc
- cmd.stack → Command to display the stack in visual debug mode
- cmd.cprompt → Column visual prompt command
- cmd.gprompt → Graph visual prompt commands
- cmd.vprompt → Visual prompt commands