Source originale : http://repository.hwc-crew.com//Docs...86_by_fr0g.txt
(J'ai retiré les accents pour éviter les problèmes d'encodage sur le repo)
################################
# Author : fr0g
# Mail : [email protected]
# Website : http://hwc-crew.com
#
# Special Thank'x :
#
# - int_0x80 (big-daddy.fr)
# - eko
################################
Introduction au reversing sous GNU/Linux x86
Avant toute chose, je tiens a preciser qu'il est preferable
d'avoir quelques connaissances en langage assembleur afin de comprendre ce paper, (et de connaitre
correctement le fonctionnement de Linux)
# 1/ Les outils Necessaires
Pour vous expliquer le but de cet article, je le redige dans le but
de familiariser un peu les debutants en R-E sur linux, avec les outils
gratuits les plus courants sur notre cher systeme open source
(ayant moi-meme eut des difficultes quand je me suis retrouve avec
les outils de Linux entre les mains, alors que j'avais l'habitude de OllyDbg sous Windows.)
Les outils que nous allons utiliser ici sont :
- GDB (desassembleur/debugger pour Linux)
- KhexEdit (editeur hexadecimal pour interface KDE, il en existe evidemment d'autres
comme Ghexedit (sous Gnome))
2# / Le desassemblage
Bon commençons, pour la demonstration j'ai utilise un crack-me du site
root-me.org (le code obtenu ne sera pas celui qui valide la vrai epreuve,
afin de ne pas spoiler leur travail)
Afin de desassembler notre programme (appele ch1.bin), on lance le terminal,
accedez au dossier contenant ch1.bin via la commande "cd" :
Ensuite, lancez GDB avec en parametre le nom du fichier a desassembler:
A partir de la, ch1.bin est ouvert par GDB, il vous suffit maintenant de
desassembler le programme a partir de son point d'entree (appele "main" par defaut):
A partir de la ligne 0x08048700, on voit que le code teste si EAX = 0 (test %eax,%eax), et fais un
saut inconditionnel (JNE (JUMP if NOT EQUAL)) apres.
Plaçons un BreakPoint sur l'instruction call 0x80484d8, grace a la commande :
on lance ensuite notre programme en tapant "run" :
On entre un passe bidon (dans mon cas "AAAAAA"), le programme va evidemment
nous dire que le password est invalide ^^ (sinon c'est pas drole)
mais avant cela, il va faire une pause sur le BreakPoint :
Maintenant, jetons un oeil au registre $eax (qui a ete manipule dans les precedantes instructions) :
Bof, un resultat qui a premiere vue ne nous dit pas grand chose, cependant,
si on affiche le contenu de eax sous forme de chaine de characteres, on obtiens cela :
Le code que nous avons entre, c'est bien, mais cela ne nous avance pas beaucoup ^^.
penchons nous donc sur l'instruction suivante dans le code qui etait :
Plaçons un BreakPoint dessus, comme tout a l'heure :
Puis, on va dire au programme de continuer jusqu'au prochain breakpoint :
Bon revenons a l'instruction JNE, comme je l'ai explique plus haut (et si vous connaissez un peu
l'ASM, vous devez le savoir) il s'agit d'un saut "si les valeurs comparees ne sont pas egales),
on voit donc que le programme va sauter a la ligne 0x804871e si les valeurs comparees sont inegales.
Nous allons donc modifier cette instruction, pour on va demander a GDB de nous renvoyer
la valeur hexadecimale de l'instruction JNE en question, puis, appuyez plusieurs fois
sur Entr pour obtenir les valeurs hexadecimales suivantes:
le 0x75 (75 hexa) correspond a l'instruction JNE "brute", les valeurs suivantes (soit : 0x15, 0x8b, 0x45) correspondent aux valeurs suivantes du code.
NOTE : Il est important de savoir que si on demande a gdb de nous renvoyer la valeur hexa de la
ligne de code ou est le JNE en question, celui ci nous renverra :
Afin de comprendre pourquoi l'ordre des valeurs est inverse (75 apparait en dernier), documentez vous sur les fonctionnement du processeur, et de la "PILE" (la premiere valeur a y entrer est la derniere a en sortir) , je n'argumenterai pas sur ce sujet ici .
Notez donc la valeur "75158b75" dans par exemple un fichier texte (ou dans votre tête ), nous allons maintenant modifier notre programme via KhexEdit,
pour cela, lancez KhexEdit dans un second terminal avec en parametre le nom du programme (ch1.bin)
# 3/ L'edition en hexadecimal
KhexEdit s'ouvre et nous affiche le code du programme (en hexadecimal), de tete ce n'est pas vraiment
comprehensible, mais nous savons deja ce que nous cherchons la sequence hexadecimale : 75158b45
Il suffit alors de chercher cette sequence en la tapant dans la barre de recherche de KhexEdit (ou en faisant CTRL+F)
Boom, le programme la trouve (et il n'y en a qu'une, on a de la chance )
NOTE : Pourquoi n'aije pas simplement tape 75 (pour JNE) ?
Car le 75 peut apparaitre plusieurs fois dans un programme (c'est d'ailleurs souvent le cas) mais une sequence contenant 75****** apparait plus difficilement plusieurs fois dans le meme fichier)
On va donc remplacer le 75 par un 74 (74 = JE (Jump if Equal)), soit remplacer la chaine recherchee : 75158b45 par 74158b45 .
On enregistre le code (fermez GDB sinon vous n'aurez pas la permission de modifier le programme)
On relance notre programme dans la console :
(en realite une fois cracke, le programme nous donne le code qui valide l'epreuve, je ne l'ai pas affiche ici)
NOTE : Etant donne que l'on a remplace JNE par un JE via l'editeur hexadecimal, si l'on entre le vrai password dans le programme, celui ci nous renverra le message d'erreur, pour eviter cela, on peut remplacer le 75 (JNE) par un 90 (NOP) qui n'execute aucune instruction)
Voila, j'espere que ce tuto vous aura un peu aide a comprendre les fonctionnements et commandes les plus pratiques de GDB sous Linux.
cordialement, fr0g.
(J'ai retiré les accents pour éviter les problèmes d'encodage sur le repo)
################################
# Author : fr0g
# Mail : [email protected]
# Website : http://hwc-crew.com
#
# Special Thank'x :
#
# - int_0x80 (big-daddy.fr)
# - eko
################################
Introduction au reversing sous GNU/Linux x86
Avant toute chose, je tiens a preciser qu'il est preferable
d'avoir quelques connaissances en langage assembleur afin de comprendre ce paper, (et de connaitre
correctement le fonctionnement de Linux)
# 1/ Les outils Necessaires
Pour vous expliquer le but de cet article, je le redige dans le but
de familiariser un peu les debutants en R-E sur linux, avec les outils
gratuits les plus courants sur notre cher systeme open source
(ayant moi-meme eut des difficultes quand je me suis retrouve avec
les outils de Linux entre les mains, alors que j'avais l'habitude de OllyDbg sous Windows.)
Les outils que nous allons utiliser ici sont :
- GDB (desassembleur/debugger pour Linux)
- KhexEdit (editeur hexadecimal pour interface KDE, il en existe evidemment d'autres
comme Ghexedit (sous Gnome))
2# / Le desassemblage
Bon commençons, pour la demonstration j'ai utilise un crack-me du site
root-me.org (le code obtenu ne sera pas celui qui valide la vrai epreuve,
afin de ne pas spoiler leur travail)
Afin de desassembler notre programme (appele ch1.bin), on lance le terminal,
accedez au dossier contenant ch1.bin via la commande "cd" :
Code:
[email protected]:~$ cd Desktop [email protected]:~/Desktop$
Code:
[email protected]:~/Desktop$ gdb ch1.bin GNU gdb 6.6-debian Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i486-linux-gnu"... (no debugging symbols found) Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". (gdb)
desassembler le programme a partir de son point d'entree (appele "main" par defaut):
Code:
(gdb) disass main Dump of assembler code for function main: 0x0804869d <main+0>: lea 0x4(%esp),%ecx 0x080486a1 <main+4>: and $0xfffffff0,%esp 0x080486a4 <main+7>: pushl 0xfffffffc(%ecx) 0x080486a7 <main+10>: push %ebp 0x080486a8 <main+11>: mov %esp,%ebp 0x080486aa <main+13>: push %ecx 0x080486ab <main+14>: sub $0x24,%esp 0x080486ae <main+17>: movl $0x8048841,0xfffffff8(%ebp) 0x080486b5 <main+24>: movl $0x804884c,(%esp) 0x080486bc <main+31>: call 0x80484c8 <[email protected]> 0x080486c1 <main+36>: movl $0x804888c,(%esp) 0x080486c8 <main+43>: call 0x80484c8 <[email protected]> 0x080486cd <main+48>: movl $0x80488cc,(%esp) 0x080486d4 <main+55>: call 0x80484c8 <[email protected]> 0x080486d9 <main+60>: movl $0x804890c,(%esp) 0x080486e0 <main+67>: call 0x8048498 <[email protected]> 0x080486e5 <main+72>: mov 0xfffffff4(%ebp),%eax 0x080486e8 <main+75>: mov %eax,(%esp) 0x080486eb <main+78>: call 0x80485fe <getString> 0x080486f0 <main+83>: mov %eax,0xfffffff4(%ebp) 0x080486f3 <main+86>: mov 0xfffffff8(%ebp),%eax 0x080486f6 <main+89>: mov %eax,0x4(%esp) 0x080486fa <main+93>: mov 0xfffffff4(%ebp),%eax 0x080486fd <main+96>: mov %eax,(%esp) 0x08048700 <main+99>: call 0x80484d8 <[email protected]> 0x08048705 <main+104>: test %eax,%eax 0x08048707 <main+106>: jne 0x804871e <main+129> 0x08048709 <main+108>: mov 0xfffffff8(%ebp),%eax 0x0804870c <main+111>: mov %eax,0x4(%esp) 0x08048710 <main+115>: movl $0x8048930,(%esp) 0x08048717 <main+122>: call 0x8048498 <[email protected]> 0x0804871c <main+127>: jmp 0x804872a <main+141> 0x0804871e <main+129>: movl $0x8048970,(%esp) 0x08048725 <main+136>: call 0x80484c8 <[email protected]> 0x0804872a <main+141>: mov $0x0,%eax 0x0804872f <main+146>: add $0x24,%esp 0x08048732 <main+149>: pop %ecx 0x08048733 <main+150>: pop %ebp 0x08048734 <main+151>: lea 0xfffffffc(%ecx),%esp 0x08048737 <main+154>: ret End of assembler dump. (gdb)
saut inconditionnel (JNE (JUMP if NOT EQUAL)) apres.
Code:
0x08048700 <main+99>: call 0x80484d8 <[email protected]> 0x08048705 <main+104>: test %eax,%eax 0x08048707 <main+106>: jne 0x804871e <main+129>
Code:
(gdb) b *main+99 Breakpoint 1 at 0x8048700
Code:
(gdb) run Starting program: /home/fr0g/Desktop/ch1.bin (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) ############################################################ ## Bienvennue dans ce challenge de cracking ## ############################################################ Veuillez entrer le mot de passe :
nous dire que le password est invalide ^^ (sinon c'est pas drole)
mais avant cela, il va faire une pause sur le BreakPoint :
Code:
Veuillez entrer le mot de passe : AAAAAA Breakpoint 1, 0x08048700 in main () (gdb)
Code:
(gdb) print $eax $1 = 134524936 (gdb)
si on affiche le contenu de eax sous forme de chaine de characteres, on obtiens cela :
Code:
(gdb) x/s $eax 0x804b008: "AAAAAA" (gdb)
penchons nous donc sur l'instruction suivante dans le code qui etait :
0x08048707 <main+106>: jne 0x804871e <main+129>
Code:
(gdb) b *main+106 Breakpoint 2 at 0x8048707 (gdb)
Code:
(gdb) c Continuing. Breakpoint 2, 0x08048707 in main () (gdb)
l'ASM, vous devez le savoir) il s'agit d'un saut "si les valeurs comparees ne sont pas egales),
on voit donc que le programme va sauter a la ligne 0x804871e si les valeurs comparees sont inegales.
Nous allons donc modifier cette instruction, pour on va demander a GDB de nous renvoyer
la valeur hexadecimale de l'instruction JNE en question, puis, appuyez plusieurs fois
sur Entr pour obtenir les valeurs hexadecimales suivantes:
Code:
(gdb) x/b 0x08048707 0x8048707 <main+106>: 0x75 (gdb) 0x8048708 <main+107>: 0x15 (gdb) 0x8048709 <main+108>: 0x8b (gdb) 0x804870a <main+109>: 0x45
NOTE : Il est important de savoir que si on demande a gdb de nous renvoyer la valeur hexa de la
ligne de code ou est le JNE en question, celui ci nous renverra :
Code:
(gdb) x/x 0x08048707 0x8048707 <main+106>: 0x458b1575
Notez donc la valeur "75158b75" dans par exemple un fichier texte (ou dans votre tête ), nous allons maintenant modifier notre programme via KhexEdit,
pour cela, lancez KhexEdit dans un second terminal avec en parametre le nom du programme (ch1.bin)
# 3/ L'edition en hexadecimal
KhexEdit s'ouvre et nous affiche le code du programme (en hexadecimal), de tete ce n'est pas vraiment
comprehensible, mais nous savons deja ce que nous cherchons la sequence hexadecimale : 75158b45
Il suffit alors de chercher cette sequence en la tapant dans la barre de recherche de KhexEdit (ou en faisant CTRL+F)
Boom, le programme la trouve (et il n'y en a qu'une, on a de la chance )
NOTE : Pourquoi n'aije pas simplement tape 75 (pour JNE) ?
Car le 75 peut apparaitre plusieurs fois dans un programme (c'est d'ailleurs souvent le cas) mais une sequence contenant 75****** apparait plus difficilement plusieurs fois dans le meme fichier)
On va donc remplacer le 75 par un 74 (74 = JE (Jump if Equal)), soit remplacer la chaine recherchee : 75158b45 par 74158b45 .
On enregistre le code (fermez GDB sinon vous n'aurez pas la permission de modifier le programme)
On relance notre programme dans la console :
Code:
[email protected]:~/Desktop$ ./ch1.bin ############################################################ ## Bienvennue dans ce challenge de cracking ## ############################################################ Veuillez entrer le mot de passe : AAAAAA Bien joue, vous pouvez valider l'epreuve.
NOTE : Etant donne que l'on a remplace JNE par un JE via l'editeur hexadecimal, si l'on entre le vrai password dans le programme, celui ci nous renverra le message d'erreur, pour eviter cela, on peut remplacer le 75 (JNE) par un 90 (NOP) qui n'execute aucune instruction)
Voila, j'espere que ce tuto vous aura un peu aide a comprendre les fonctionnements et commandes les plus pratiques de GDB sous Linux.
cordialement, fr0g.
Commentaire