Note CC

carnet de recherche-action, ateliers et notes libres

Outils pour utilisateurs

Outils du site


norae:si:exercice_de_decouverte_de_desassemblage_avec_radare2

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
Cette note concerne un exercice pédagogique de découverte et absolument pas une pratique professionnelle.

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

Cette étape est uniquement prévue pour vous fournir un petit logiciel non compromettant à analyser afin permettre de découvrir radare2.

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

Ce petit bout de logiciel écrit avec les pieds n'a pas d'autre vocation que d'être compilé pour fournir un exécutable (ELF.

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.

  1. Ouvrez un terminal depuis votre menu de bureau ou en faisant ctrl+alt+t.
  2. Placez dans le dossier du répertoire contenant votre fichier 1st_reverse.c
    1. Taper ls comme commande dans votre terminal vous vérifier la présence de 1st_reverse.c
    2. Entrez la commande gcc –help pour vérifier la disponibilité de GCC et avoir un aperçu des commande disponible − q pour sortir
  3. Entrez la commande gcc -o 1st_reverse 1st_reverse.c
    1. -o signifie à GCC que l'exécutable compilé se nommera 1s_reverse
    2. 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
    3. Entrer ls pour obtenir la liste des fichiers dans l'emplacement où vous êtes situé⋅e dans votre terminal
    4. 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

Pour de prochaines aventures
  • 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]>
Rappel
> 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
le numéro qui vient après le “→”. Si c'est le cas, lorsqu'il y a un “→”, le nombre de gauche est la plage de la fonction, tandis que celui de droite indique la taille de la fonction. Cela ne se produit que lorsque la plage et la taille sont différentes.
Dans notre cas d'exemple 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 main1)

Nous utilisons cette commande avec l'option de visualisation graphique fournie par radare2 avec VV.

Ainsi

[0x00001060]> VV @main

Nous donne

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

−−> 1er désassemblage avec radare2

Listes de ressources

Documentation générale

radare2 writtings for practices

Tools included
  • 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

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
Vous pourriez laisser un commentaire si vous étiez connecté.
norae/si/exercice_de_decouverte_de_desassemblage_avec_radare2.txt · Dernière modification: 2020/07/31 14:41 par xavcc