<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://futex.re/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Introduction_au_reverse</id>
	<title>Introduction au reverse - Historique des versions</title>
	<link rel="self" type="application/atom+xml" href="https://futex.re/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Introduction_au_reverse"/>
	<link rel="alternate" type="text/html" href="https://futex.re/mediawiki/index.php?title=Introduction_au_reverse&amp;action=history"/>
	<updated>2026-04-16T20:54:14Z</updated>
	<subtitle>Historique des versions pour cette page sur le wiki</subtitle>
	<generator>MediaWiki 1.39.17</generator>
	<entry>
		<id>https://futex.re/mediawiki/index.php?title=Introduction_au_reverse&amp;diff=1915&amp;oldid=prev</id>
		<title>Futex : /* Binaire exam3 */</title>
		<link rel="alternate" type="text/html" href="https://futex.re/mediawiki/index.php?title=Introduction_au_reverse&amp;diff=1915&amp;oldid=prev"/>
		<updated>2012-10-12T19:12:43Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Binaire exam3&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nouvelle page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Aux Rencontres Mondiales du Logiciel Libre, [http://www.r00ted.com/ RootBSD] consultant et chercheur en sécurité informatique mainteneur du projet [http://www.malware.lu Malware.lu] tenait un atelier de reverse engineering. À la suite de cet atelier, il a publié les crackmes/fichiers utilisés durant celui-ci. Ces fichiers étant parfait pour débuter, nous allons donc les utiliser pour découvrir cette discipline.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Mais qu&amp;#039;est ce donc que le Reverse Engineering ? ==&lt;br /&gt;
&lt;br /&gt;
Dans la langue de Molière, le Reverse Engineering se dit rétroingénierie ou ingénierie inversé. &lt;br /&gt;
&lt;br /&gt;
Plus simplement, il s&amp;#039;agit de l&amp;#039;étude du fonctionnement ou de la conception d&amp;#039;un objet fini afin de comprendre son fonctionnement interne ou sa méthode de fabrication. Par la suite il s&amp;#039;agira pourquoi pas tenter de modifier cet objet voire même de tenter de le recréer.&lt;br /&gt;
&lt;br /&gt;
Lorsque l&amp;#039;on observe les objets qui nous entoure et que l&amp;#039;on cherche à deviner les constituants d&amp;#039;un tel objet nous effectuons sans le savoir de la rétroingénierie :&lt;br /&gt;
Prenez par exemple une tarte aux pommes, si l&amp;#039;on observe cet &amp;quot;objet&amp;quot; dans sa globalité on a un succulent dessert qui n&amp;#039;attend qu&amp;#039;une chose : être dévoré. Mais si maintenant l&amp;#039;on s’intéresse à ses constituants on observe que cette tarte est composée de pâte brisée, éventuellement de cannelle et ... de pommes ! C&amp;#039;est ça, la rétroingénierie !&lt;br /&gt;
&lt;br /&gt;
== Et légalement ? ==&lt;br /&gt;
&lt;br /&gt;
C&amp;#039;est la partie compliquée, le reverse est dans certains cas illégale. Tout ce qui est soumis à des brevets, droits d&amp;#039;auteur, protections.... c&amp;#039;est hors la loi et cela dépend de la législation du pays.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Concernant tout ce qui est logiciels libres, aucun soucis, le code source est fournis, on peut faire ce que l&amp;#039;on veut.&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
Et cequi est code fermé, en France, c&amp;#039;est légal dans certaines conditions. Pour les savoir, il faut se référer à la licence du logiciel si elle l&amp;#039;autorise, vous savez le truc que personne ne lit et clique sur &amp;quot;J’accepte les termes et conditions d’utilisation&amp;quot;.&lt;br /&gt;
Une des conditions pour lequel on peut le faire, c&amp;#039;est l&amp;#039;intéropérabilité. Par exemple, le faite d&amp;#039;adapter un programme s&amp;#039;exécutant sous Windows pour le rendre compatible avec MacOS ou Linux.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Dans tout les cas, il est interdit de reverser un programme et le modifier pour le revendre. Ca sera considéré comme de la contrefaçon.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Pour plus de détails, vous pouvez lire le [http://legifrance.gouv.fr/affichCodeArticle.do;jsessionid=974DD3C19D8CA7CDB53CC1582953C1D5.tpdjo05v_1?idArticle=LEGIARTI000006278920&amp;amp;cidTexte=LEGITEXT000006069414&amp;amp;dateTexte=20120826&amp;amp;categorieLien=id Code de la propriété intellectuelle]&lt;br /&gt;
&lt;br /&gt;
== A l&amp;#039;attaque! ==&lt;br /&gt;
&lt;br /&gt;
Les binaires du cours sont disponibles à cette [http://schedule2012.rmll.info/Atelier-Reverse-Engineering-sur-plateforme-libre?lang=fr adresse] ou [[Fichier:Workshop.tgz]]&lt;br /&gt;
&lt;br /&gt;
L&amp;#039;archive est composé de deux premiers binaires servant à crypter l&amp;#039;image éponyme. Le but du jeux, c&amp;#039;est de trouver l&amp;#039;algorithme de cryptage, le reverser, et décrypter les images.&lt;br /&gt;
Le dossier binaries contient cinq binaires dans lesquels il faut trouver le mot de passe. On va commencer par la.&lt;br /&gt;
&lt;br /&gt;
== Binaire exam1 ==&lt;br /&gt;
&lt;br /&gt;
La première chose, faire connaissance avec ce binaire. Pour ce faire, nous allons utiliser la commande file qui permet de déterminer le type d&amp;#039;un fichier et éventuellement d&amp;#039;autres informations comme les dimensions pour une image ou les codecs.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Reverse1.1.jpg]]&lt;br /&gt;
&lt;br /&gt;
On apprend qu&amp;#039;on est en présence d&amp;#039;un binaire ELF 32 bits un format de fichiers exécutables sur les OS Linux-Unix. Que celui-ci à été conçus pour utiliser les processeurs de type 80386. qu&amp;#039;il utilise des librairies dynamiques, et qu&amp;#039;il possède les symboles de débogages (not stripped). C&amp;#039;est la fête !&lt;br /&gt;
&lt;br /&gt;
Ensuite on utilise la commande nm qui permet de lister la table des symboles importés et exportés. T pour pour ceux écrit dans le code, et U/u pour undefined (ce qui est le cas pour les fonctions appelés dans les librairies dynamiques). &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Reverse1.3.jpg]]&lt;br /&gt;
&lt;br /&gt;
On retrouve la fonction _start qui s&amp;#039;occupe de préparer l&amp;#039;environnement d&amp;#039;exécution et de lancer le main, dans lequel est ensuite exécuter un printf, un puts et surtout un strcmp qui va nous intéresser. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A partir de la, on constate qu&amp;#039;il y a pas de fonctions louches, on peut lancer notre binaire sans craintes :) (on est jamais trop prudent)&lt;br /&gt;
&lt;br /&gt;
Autre commande importante, strings. Méthode un peu à la sauvage qui va afficher les chaînes de caractère présentes dans le fichier. Et la que voit t&amp;#039;on?&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Reverse1.4.jpg]]&lt;br /&gt;
&lt;br /&gt;
Le mot de passe est écrit en clair, il a dû être seter en dur dans le code source pour qu&amp;#039;il apparaisse ainsi.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Reverse1.5.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Binaire exam2 ==&lt;br /&gt;
&lt;br /&gt;
Deuxième binaire. Au départ le principe est le même.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  $ file exam2&lt;br /&gt;
  exam2: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped&lt;br /&gt;
&lt;br /&gt;
Toujours non strippé ca va bien nous aider.&lt;br /&gt;
&lt;br /&gt;
  $ strings exam2&lt;br /&gt;
  /lib/ld-linux.so.2&lt;br /&gt;
  __gmon_start__&lt;br /&gt;
  libc.so.6&lt;br /&gt;
  _IO_stdin_used&lt;br /&gt;
  puts&lt;br /&gt;
  __stack_chk_fail&lt;br /&gt;
  printf&lt;br /&gt;
  strcmp&lt;br /&gt;
  __libc_start_main&lt;br /&gt;
  GLIBC_2.4&lt;br /&gt;
  GLIBC_2.0&lt;br /&gt;
  PTRh&lt;br /&gt;
  D$,1&lt;br /&gt;
  D$$A&lt;br /&gt;
  D$&amp;amp;c&lt;br /&gt;
  D$&amp;#039;6&lt;br /&gt;
  T$,e3&lt;br /&gt;
  [^_]&lt;br /&gt;
  Usage: %s key&lt;br /&gt;
  Bad key&lt;br /&gt;
  Good key&lt;br /&gt;
&lt;br /&gt;
Cette fois-ci le mot de passe n&amp;#039;apparaît pas en clair, mais on voit bien qu&amp;#039;un strcmp est appelé.&lt;br /&gt;
&lt;br /&gt;
Utilisons objdump pour désassembler notre programme en recherchant le strcmp.&lt;br /&gt;
&lt;br /&gt;
  $ objdump -d exam2 | grep strcmp&lt;br /&gt;
  080483dc &amp;lt;strcmp@plt&amp;gt;:&lt;br /&gt;
  8048539:	e8 9e fe ff ff       	call   80483dc &amp;lt;strcmp@plt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok il se trouve à l&amp;#039;adresse 0x8048539&lt;br /&gt;
&lt;br /&gt;
Sortons gdb et debuggont:&lt;br /&gt;
&lt;br /&gt;
  $ gdb -q exam2&lt;br /&gt;
  Reading symbols from /home/futex/Bureau/to_student/binaries/exam2...(no debugging symbols found)...done.&lt;br /&gt;
  (gdb) &lt;br /&gt;
&lt;br /&gt;
On pose un breakpoint à l&amp;#039;adresse du strcmp:&lt;br /&gt;
&lt;br /&gt;
  (gdb) b *0x8048539&lt;br /&gt;
  Breakpoint 1 at 0x8048539&lt;br /&gt;
&lt;br /&gt;
On lance le programme avec en paramètre un mot de passe bidon (AAAA):&lt;br /&gt;
&lt;br /&gt;
  (gdb) r AAAA&lt;br /&gt;
  Breakpoint 1, 0x08048539 in main ()&lt;br /&gt;
&lt;br /&gt;
Ensuite on regarde ce que contient le registre eax:&lt;br /&gt;
&lt;br /&gt;
  (gdb) x/10s $eax&lt;br /&gt;
  0xffffd3d4:	 &amp;quot;AFc6mcw&amp;quot;&lt;br /&gt;
  0xffffd3dc:	 &amp;quot;&amp;quot;&lt;br /&gt;
  .......&lt;br /&gt;
&lt;br /&gt;
Intéressant :)&lt;br /&gt;
&lt;br /&gt;
  $ ./exam2 AFc6mcw&lt;br /&gt;
  Good key&lt;br /&gt;
&lt;br /&gt;
Une autre façon intéressante de le cracker est d&amp;#039;utiliser la variable d&amp;#039;environnement LD_PRELOAD.&lt;br /&gt;
Cette variable permet de charger des librairies dynamiques en priorité à l&amp;#039;exécution d&amp;#039;un programme. On va donc l&amp;#039;utiliser pour usurpé la fonction strcmp du programme.&lt;br /&gt;
Écrivons ce petit bout de code en C:&lt;br /&gt;
  $ cat strcmp.c &lt;br /&gt;
  #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  #include &amp;lt;string.h&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  int strcmp (const char *s1, const char *s2)&lt;br /&gt;
  {&lt;br /&gt;
    printf (&amp;quot;argument1: %s, argument2: %s\n&amp;quot;, s1, s2);&lt;br /&gt;
    return 0;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Notre fonction se contente d&amp;#039;afficher les deux chaîne passé en paramètre, le mot de passe qu&amp;#039;on rentrera et le bon mot de passe. Puis retourne 0, ainsi la comparaison sera toujours juste.&lt;br /&gt;
On compile notre librairie de la façon suivante:&lt;br /&gt;
  $ gcc -m32 strcmp.c -shared -fPIC -o /tmp/strcmp.so&lt;br /&gt;
&lt;br /&gt;
Les binaires étant en 32 bit, si vous êtes en 64 bit il faut mettre l&amp;#039;option -m32, -shared pour spécifier qu&amp;#039;on compile une librairie dynamique, -fPIC (Position Independent Code).&lt;br /&gt;
On set la variable LD_PRELOAD&lt;br /&gt;
  $ export LD_PRELOAD=&amp;quot;/tmp/strcmp.so&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Et le résultat final:&lt;br /&gt;
  $ ./exam2 123&lt;br /&gt;
  argument1: AFc6mcw, argument2: 123&lt;br /&gt;
  Good key&lt;br /&gt;
&lt;br /&gt;
Une troisième façon encore plus simple d&amp;#039;avoir le mot de passe, le tracer:&lt;br /&gt;
  $ ltrace -s128 ./exam2 123&lt;br /&gt;
  __libc_start_main(0x80484a4, 2, 0xffb133f4, 0x8048590, 0x8048580 &amp;lt;unfinished ...&amp;gt;&lt;br /&gt;
  strcmp(&amp;quot;AFc6mcw&amp;quot;, &amp;quot;123&amp;quot;)                        = 1&lt;br /&gt;
  puts(&amp;quot;Bad key&amp;quot;Bad key&lt;br /&gt;
  )                                 = 8&lt;br /&gt;
  +++ exited (status 0) +++&lt;br /&gt;
&lt;br /&gt;
== Binaire exam3 ==&lt;br /&gt;
&lt;br /&gt;
Comme d&amp;#039;habitude on commence par faire connaissance avec ce binaire:&lt;br /&gt;
  $ file exam3 &lt;br /&gt;
  exam3: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped&lt;br /&gt;
&lt;br /&gt;
  $ strings exam3 &lt;br /&gt;
  /lib/ld-linux.so.2&lt;br /&gt;
  __gmon_start__&lt;br /&gt;
  libc.so.6&lt;br /&gt;
  _IO_stdin_used&lt;br /&gt;
  exit&lt;br /&gt;
  puts&lt;br /&gt;
  printf&lt;br /&gt;
  strlen&lt;br /&gt;
  __libc_start_main&lt;br /&gt;
  GLIBC_2.0&lt;br /&gt;
  PTRh&lt;br /&gt;
  [^_]&lt;br /&gt;
  Bad key&lt;br /&gt;
  Usage: %s key&lt;br /&gt;
  Good key&lt;br /&gt;
&lt;br /&gt;
Un objdump -d exam3 nous apprendra que le mot de passe fait 9 caractères.&lt;br /&gt;
  $ objdump -d -j .text exam3 | grep -A 2 strlen&lt;br /&gt;
  80484dc:	e8 a7 fe ff ff       	call   8048388 &amp;lt;strlen@plt&amp;gt;&lt;br /&gt;
  &amp;lt;big&amp;gt;80484e1:	83 f8 09             	cmp    $0x9,%eax&amp;lt;/big&amp;gt;&lt;br /&gt;
  80484e4:	74 05                	je     80484eb &amp;lt;main+0x49&amp;gt;&lt;br /&gt;
  80484e6:	e8 99 ff ff ff       	call   8048484 &amp;lt;loose&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On notera aussi que le call (adresse 80484e6) sur la fonction loose sera appelé en cas d&amp;#039;échec.&lt;br /&gt;
&lt;br /&gt;
On va faire un grep sur les appels à cette fonction&lt;br /&gt;
  $ objdump -d -j .text exam3 | grep -B 2 loose&lt;br /&gt;
  8048483:	90                   	nop&amp;lt;br&amp;gt;&lt;br /&gt;
  08048484 &amp;lt;loose&amp;gt;:&lt;br /&gt;
  --&lt;br /&gt;
   80484e1:	83 f8 09             	cmp    $0x9,%eax               // Test de la longueur du mot de passe, vu juste avant&lt;br /&gt;
   80484e4:	74 05                	je     80484eb &amp;lt;main+0x49&amp;gt;&lt;br /&gt;
   80484e6:	e8 99 ff ff ff       	call   8048484 &amp;lt;loose&amp;gt;&lt;br /&gt;
  --&lt;br /&gt;
   80484f6:	3c 41                	cmp    $0x41,%al               //Test du premier caractère 0x41 est le code ascii en hexadécimal de A&lt;br /&gt;
   80484f8:	74 05                	je     80484ff &amp;lt;main+0x5d&amp;gt;&lt;br /&gt;
   80484fa:	e8 85 ff ff ff       	call   8048484 &amp;lt;loose&amp;gt;&lt;br /&gt;
  --&lt;br /&gt;
   8048521:	39 c2                	cmp    %eax,%edx               //A voir plus loin&lt;br /&gt;
   8048523:	74 05                	je     804852a &amp;lt;main+0x88&amp;gt;&lt;br /&gt;
   8048525:	e8 5a ff ff ff       	call   8048484 &amp;lt;loose&amp;gt;&lt;br /&gt;
  --&lt;br /&gt;
   8048538:	3c 31                	cmp    $0x31,%al               //Troisième caractère, 0x31 est le 1&lt;br /&gt;
   804853a:	74 05                	je     8048541 &amp;lt;main+0x9f&amp;gt;&lt;br /&gt;
   804853c:	e8 43 ff ff ff       	call   8048484 &amp;lt;loose&amp;gt;&lt;br /&gt;
  --&lt;br /&gt;
   804854f:	3c 33                	cmp    $0x33,%al               //Quatrième caractère, 0x33 est le 3&lt;br /&gt;
   8048551:	74 05                	je     8048558 &amp;lt;main+0xb6&amp;gt;&lt;br /&gt;
   8048553:	e8 2c ff ff ff       	call   8048484 &amp;lt;loose&amp;gt;&lt;br /&gt;
  --&lt;br /&gt;
   804857d:	39 d0                	cmp    %edx,%eax               //A voir plus loin&lt;br /&gt;
   804857f:	74 05                	je     8048586 &amp;lt;main+0xe4&amp;gt;&lt;br /&gt;
   8048581:	e8 fe fe ff ff       	call   8048484 &amp;lt;loose&amp;gt;&lt;br /&gt;
  --&lt;br /&gt;
   8048594:	3c 78                	cmp    $0x78,%al               //Sixième caractère, 0x78 est le x&lt;br /&gt;
   8048596:	74 05                	je     804859d &amp;lt;main+0xfb&amp;gt;&lt;br /&gt;
   8048598:	e8 e7 fe ff ff       	call   8048484 &amp;lt;loose&amp;gt;&lt;br /&gt;
  --&lt;br /&gt;
   80485ab:	3c 68                	cmp    $0x68,%al               //Septième caractère, 0x68 est le h&lt;br /&gt;
   80485ad:	74 05                	je     80485b4 &amp;lt;main+0x112&amp;gt;&lt;br /&gt;
   80485af:	e8 d0 fe ff ff       	call   8048484 &amp;lt;loose&amp;gt;&lt;br /&gt;
  --&lt;br /&gt;
   80485d9:	39 d0                	cmp    %edx,%eax               //A voir plus loin&lt;br /&gt;
   80485db:	74 05                	je     80485e2 &amp;lt;main+0x140&amp;gt;&lt;br /&gt;
   80485dd:	e8 a2 fe ff ff       	call   8048484 &amp;lt;loose&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notre mot de passe ressemble à cela pour le moment: A.13.xh..&lt;br /&gt;
&lt;br /&gt;
Alors maintenant on va manipuler un peu gdb :)&lt;br /&gt;
On charge le binaire:&lt;br /&gt;
  $ gdb -q exam3&lt;br /&gt;
On pose des breackpoints sur les cmp inconnues&lt;br /&gt;
  (gdb) b *0x8048521&lt;br /&gt;
  (gdb) b *0x804857d&lt;br /&gt;
  (gdb) b *0x80485d9&lt;br /&gt;
Et on l&amp;#039;exécute:&lt;br /&gt;
  (gdb) r A.13.ND..&lt;br /&gt;
  Breakpoint 1, 0x8048521 in main ()&lt;br /&gt;
&lt;br /&gt;
Regardons ce qu&amp;#039;il y a dans les registre eax et edx&lt;br /&gt;
  Breakpoint 1, 0x08048521 in main ()&lt;br /&gt;
  (gdb) print $eax &lt;br /&gt;
  $1 = 68                //code décimal ascii de D&lt;br /&gt;
  (gdb) print $edx&lt;br /&gt;
  $2 = 46                //code décimal ascii de notre . &lt;br /&gt;
Pour pouvoir continuer on force edx à 68&lt;br /&gt;
  (gdb) set $edx=68&lt;br /&gt;
  (gdb) print $edx&lt;br /&gt;
  $3 = 68&lt;br /&gt;
&lt;br /&gt;
MDP: AD13.xh.. &lt;br /&gt;
&lt;br /&gt;
Même manip au cmp suivant:&lt;br /&gt;
  Breakpoint 2, 0x0804857d in main ()&lt;br /&gt;
  (gdb) print $edx&lt;br /&gt;
  $4 = 61                //code décimal ascii de =&lt;br /&gt;
  (gdb) print $eax&lt;br /&gt;
  $5 = 46                //code décimal ascii de notre .                &lt;br /&gt;
Pour pouvoir continuer on force eax à 61&lt;br /&gt;
  (gdb) set $eax=61&lt;br /&gt;
  (gdb) print $eax&lt;br /&gt;
  $6 = 61&lt;br /&gt;
&lt;br /&gt;
MDP: AD13=xh.. &lt;br /&gt;
&lt;br /&gt;
Toujours la même manip au troisième breackpoint:&lt;br /&gt;
  Breakpoint 3, 0x080485d9 in main ()&lt;br /&gt;
  (gdb) print $eax&lt;br /&gt;
  $7 = 46&lt;br /&gt;
  (gdb) print $edx&lt;br /&gt;
  $8 = 99               //code décimal ascii de c&lt;br /&gt;
On force eax&lt;br /&gt;
  (gdb) set $eax=99&lt;br /&gt;
  (gdb) continue&lt;br /&gt;
  Good key&lt;br /&gt;
&lt;br /&gt;
Le mot de passe final est donc AD13=xhc.&lt;br /&gt;
Le dernier caractère n&amp;#039;étant pas testé, on peut mettre ce que l&amp;#039;on veut.&lt;br /&gt;
&lt;br /&gt;
== Binaire exam4 ==&lt;br /&gt;
&lt;br /&gt;
  Hash md5:&lt;br /&gt;
  $ md5sum exam4 &lt;br /&gt;
  c5ada58ca8731be76bc275df4b2feb6d  exam4&lt;br /&gt;
&lt;br /&gt;
  $ file exam4 &lt;br /&gt;
  exam4: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, stripped&lt;br /&gt;
  &lt;br /&gt;
Différence avec les précédents, ce binaire est strippé. &lt;br /&gt;
&lt;br /&gt;
  $ strings exam4&lt;br /&gt;
  UPX!&lt;br /&gt;
  &amp;gt;(nW&lt;br /&gt;
  h6hI&lt;br /&gt;
  PTRh &lt;br /&gt;
  h`QVh&lt;br /&gt;
  ...&lt;br /&gt;
  $Info: This file is packed with the UPX executable packer http://upx.sf.net $&lt;br /&gt;
  $Id: UPX 3.07 Copyright (C) 1996-2010 the UPX Team. All Rights Reserved. $&lt;br /&gt;
  PROT_EXEC|PROT_WRITE failed.&lt;br /&gt;
  (/proc/self/exe&lt;br /&gt;
  [jUX&lt;br /&gt;
  POl&amp;lt;&lt;br /&gt;
  jZ^[&lt;br /&gt;
  nEf}&lt;br /&gt;
  UPX!u&lt;br /&gt;
  @bQs&lt;br /&gt;
  55|k&lt;br /&gt;
  ;P(2)&lt;br /&gt;
  jH/M&lt;br /&gt;
  UPX!&lt;br /&gt;
&lt;br /&gt;
On apprends qu&amp;#039;il est aussi packer via UPX. Les intérêts de packer un binaire est de réduire la taille de l&amp;#039;exécutable et de compliquer la tache du réverseur. &lt;br /&gt;
&lt;br /&gt;
Pour le dépacker, c&amp;#039;est très simple avec la commande upx:&lt;br /&gt;
  $ upx -d exam4&lt;br /&gt;
  Ultimate Packer for eXecutables&lt;br /&gt;
  Copyright (C) 1996 - 2010&lt;br /&gt;
  UPX 3.05        Markus Oberhumer, Laszlo Molnar &amp;amp; John Reiser   Apr 27th 2010wbr&amp;gt;&lt;br /&gt;
        File size         Ratio      Format      Name&lt;br /&gt;
   --------------------   ------   -----------   -----------&lt;br /&gt;
    578492 &amp;lt;-    251396   43.46%  linux/elf386   exam4&amp;lt;br&amp;gt;&lt;br /&gt;
  Unpacked 1 file.&lt;br /&gt;
&lt;br /&gt;
Nous voila avec un autre binaire&lt;br /&gt;
  $ md5sum exam4 &lt;br /&gt;
  e2892e36f8d052aa315fb09c6411a0b3  exam4&lt;br /&gt;
&lt;br /&gt;
  $ file exam4&lt;br /&gt;
  exam4: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.6.15, not stripped&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  $ strings exam4 | more&lt;br /&gt;
  PTRh &lt;br /&gt;
  &amp;lt;[^_]&lt;br /&gt;
  ,[^_]&lt;br /&gt;
  [^_]&lt;br /&gt;
  [^_] &lt;br /&gt;
  t!e3&lt;br /&gt;
  [^_]&lt;br /&gt;
  H$[]&lt;br /&gt;
  ~hxX&lt;br /&gt;
  [^_]&lt;br /&gt;
  $[^_]&lt;br /&gt;
  SH9z&lt;br /&gt;
  [^_]&lt;br /&gt;
  ([^_]&lt;br /&gt;
  [^_]&lt;br /&gt;
  [^_]&lt;br /&gt;
  ....&lt;br /&gt;
&lt;br /&gt;
On apprend rien d&amp;#039;intéressant via cette commande.&lt;br /&gt;
&lt;br /&gt;
Ouvrons le binaire dans [http://www.hex-rays.com IDA]. IDA est un désassembleur commercial (une version gratuite existe), reconnaissant plusieurs type d&amp;#039;exécutable (PE, ELF, XCOFF, ...) sur plusieurs type de CPU (x86, ARM, PowerPC, ...)&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ida1.JPG]]&lt;br /&gt;
&lt;br /&gt;
A droite dans la fenêtre &amp;#039;Names Window&amp;#039; on voit notre fonction &amp;#039;main&amp;#039; et une &amp;#039;check&amp;#039; qui semble plus intéressante.&lt;br /&gt;
&lt;br /&gt;
Jetons un oeil à cette fonction&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ida2.JPG]]&lt;br /&gt;
&lt;br /&gt;
On voit qu&amp;#039;elle commence par un appelle à la fonction strlen, puis compare le retour de la fonction qui rappelons le se retrouve toujours dans eax à 7. On peut en déduire la taille de notre mot de passe. Si le test échoue on part dans la branche à gauche qui va afficher à l&amp;#039;écran &amp;quot;Bad key&amp;quot; et met fin au programme. Si le test est bon, on va comparer les caractères.&lt;br /&gt;
&lt;br /&gt;
On voit tout de suite une comparaison à 45h code ACSII de E. Ca sera le premier caractère de notre mot de passe.&lt;br /&gt;
&lt;br /&gt;
Dans le test suivant:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ida3.JPG]]&lt;br /&gt;
&lt;br /&gt;
Le programme va charger dans eax l&amp;#039;adresse sur la pile du mot de passe qu&amp;#039;on a rentré, puis va incrémenter l&amp;#039;adresse de 1 pour pointer sur le second caractère et copier ce caractère dans edx.&lt;br /&gt;
Ensuite il va charger une adresse dans eax, adresse qui pointe sur une autre adresse pointant sur le mot de passe qu&amp;#039;on a rentré et copier le premier caractère dans eax, soit donc 0x45 E en ACSII et ajouter 0xA, 10 en décimal. eax vaudra alors 0x4f, O en ACSII.&lt;br /&gt;
&lt;br /&gt;
Ca sera le second caractère du vrai mot de passe EO?????&lt;br /&gt;
&lt;br /&gt;
Troisième test:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ida4.JPG]]&lt;br /&gt;
&lt;br /&gt;
On charge de nouveau l&amp;#039;adresse de notre mot de passe dans eax, on incrémente l&amp;#039;adresse de 2 pour pointer sur le troisième caractère (le premier étant en position 0 pour ceux qui suivent pas au fond).&lt;br /&gt;
Puis on le compare à 0x6f, o en ACSII. Le mot de passe devient donc EOo???? &lt;br /&gt;
&lt;br /&gt;
Quatrième test:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ida5.JPG]]&lt;br /&gt;
&lt;br /&gt;
Même chose, on compare le quatrième caractère à 0x30, 0 en ACSII. Le mot de passe devient donc EOo0???&lt;br /&gt;
&lt;br /&gt;
Cinquième test:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ida6.JPG]]&lt;br /&gt;
&lt;br /&gt;
Exactement la même chose que précédemment. Le mot de passe devient donc EOo00??&lt;br /&gt;
&lt;br /&gt;
Dernier test:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ida7.JPG]]&lt;br /&gt;
&lt;br /&gt;
Comme d&amp;#039;hab, on charge le 5+1 ème caractère du mot de passe rentré à la mano dans eax. &lt;br /&gt;
Et comme dans le troisième test, on charge aussi son adresse dans edx, puis on l&amp;#039;incrémente de 4, il va donc pointé sur 0 (0x30). Et il sera incrémenter de 0x14, soit 0x68, D en ACSII.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:ida8.JPG]]&lt;br /&gt;
&lt;br /&gt;
Notre mot de passe sera donc: EOo00D?, on peut mettre ce qu&amp;#039;on veut pour le dernier caractère il n&amp;#039;est pas testé.&lt;br /&gt;
  $ ./exam4 EOo00DA&lt;br /&gt;
  Good key&lt;br /&gt;
&lt;br /&gt;
== Binaire exam5 ==&lt;br /&gt;
&lt;br /&gt;
== Binaire simple1 ==&lt;br /&gt;
&lt;br /&gt;
Ce petit binaire sert à obfusquer des fichiers, tels que l&amp;#039;image &amp;quot;simple1.png&amp;quot; dans l&amp;#039;archive. L&amp;#039;idée et de réverser la routine de d&amp;#039;obfusquation pour en refaire un programme et desobfusquer l&amp;#039;image.&lt;br /&gt;
&lt;br /&gt;
On ouvre le binaire dans IDA, on y trouve plusieurs fonctions.&lt;br /&gt;
main, ca on connait :)&amp;lt;br&amp;gt;&lt;br /&gt;
syntaxe, qui va afficher l&amp;#039;utilisation du binaire.&amp;lt;br&amp;gt;&lt;br /&gt;
super_encrypt, qui est bien plus intéressante.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Simple1 1.jpg]]&lt;br /&gt;
&lt;br /&gt;
La fonction prends deux paramètres arg0 qui est le fichier en question, et arg4 sa taille.&lt;br /&gt;
&lt;br /&gt;
La boucle servant au cryptage du fichier:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:Simple1 2.jpg]]&lt;br /&gt;
&lt;br /&gt;
Qui ne fait que de lire notre fichier octet par octet et sur chacun va utiliser octet par octet le contenu de la variable key_2193 pour y faire un XOR.&lt;br /&gt;
&lt;br /&gt;
Le contenu de la variable key_2193:&lt;br /&gt;
[[Fichier:Simple1 3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Ce qui n&amp;#039;est autre que les valeurs hexa de la chaîne &amp;quot;rootbsd&amp;quot;. Les caractères sont à l&amp;#039;envers, n&amp;#039;oubliez pas qu&amp;#039;on est en little endian.&lt;br /&gt;
&lt;br /&gt;
L&amp;#039;opération XOR est souvent utiliser dans des opérations d&amp;#039;obfuscage simple (on peut pas vraiment parler d&amp;#039;un cryptage), son fonctionnement est super simple:&lt;br /&gt;
&lt;br /&gt;
Si par exemple, on fait un XOR de A et de B on obtient la valeur C.&amp;lt;br&amp;gt;&lt;br /&gt;
La même opération, entre A et C on obtient B.&amp;lt;br&amp;gt;&lt;br /&gt;
Et bien sur B XOR C = A.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Donc pour desobfusquer notre fichier, il suffit de faire XOR octet par octet de son contenu avec la chaîne &amp;quot;rootbsd&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
On fait un petit programme &amp;quot;superdecrypt.py&amp;quot; en python qui va nous faire ça pour nous:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  #!/usr/bin/python&lt;br /&gt;
  # encoding: utf-8&amp;lt;br&amp;gt;&lt;br /&gt;
  key_2193 = &amp;quot;rootbsd\x00&amp;quot;&lt;br /&gt;
  crypt_file=open(&amp;quot;./simple.png&amp;quot;,&amp;quot;rb&amp;quot;).read()&lt;br /&gt;
  crypt_file_size=len(crypt_file)&lt;br /&gt;
  uncrypt_content=&amp;quot;&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
  for i in range(crypt_file_size):&lt;br /&gt;
    tmp = ord(crypt_file[i]) ^ ord(key_2193[i%len(key_2193)])&lt;br /&gt;
    uncrypt_content += chr(tmp)&amp;lt;br&amp;gt;&lt;br /&gt;
  uncrypt_file=open(&amp;quot;./simple1.png&amp;quot;,&amp;quot;w&amp;quot;)&lt;br /&gt;
  uncrypt_file.write(uncrypt_content)&lt;br /&gt;
  uncrypt_file.close()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Voila l&amp;#039;image cachée:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier: Simple1.png]]&lt;br /&gt;
&lt;br /&gt;
== Binaire encrypt ==&lt;br /&gt;
&lt;br /&gt;
Ce binaire fait la même chose que le précédent, seule la routine d&amp;#039;obfuscation est différente:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier:Encrypt1.jpg]]&lt;br /&gt;
&lt;br /&gt;
Au début de  la routine un add eax, 0AH est fait. A ce moment la eax contient un octet de notre fichier. On lui ajoute 0xA (10 en décimal).&amp;lt;br&amp;gt;&lt;br /&gt;
Puis son contenu est copier dans edx, et un caractère de la chaîne &amp;quot;rootbsd&amp;quot; est chargé dans eax.&amp;lt;br&amp;gt;&lt;br /&gt;
Et on a de nouveau un XOR de fait entre les registres eax et edx.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suffit de modifier légèrement notre script:&lt;br /&gt;
&lt;br /&gt;
  #!/usr/bin/python&lt;br /&gt;
  # encoding: utf-8&amp;lt;br&amp;gt;&lt;br /&gt;
  key_2193 = &amp;quot;rootbsd\x00&amp;quot;&lt;br /&gt;
  crypt_file=open(&amp;quot;./encrypt.png&amp;quot;,&amp;quot;rb&amp;quot;).read()&lt;br /&gt;
  crypt_file_size=len(crypt_file)&lt;br /&gt;
  uncrypt_content=&amp;quot;&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
  for i in range(crypt_file_size):&lt;br /&gt;
    tmp = ord(crypt_file[i]) ^ ord(key_2193[i%len(key_2193)])&lt;br /&gt;
    tmp -= 0xa&lt;br /&gt;
    if tmp &amp;lt; 0:&lt;br /&gt;
      tmp = 256 + tmp&lt;br /&gt;
    uncrypt_content += chr(tmp)&amp;lt;br&amp;gt;&lt;br /&gt;
  uncrypt_file=open(&amp;quot;./encrypt1.png&amp;quot;,&amp;quot;w&amp;quot;)&lt;br /&gt;
  uncrypt_file.write(uncrypt_content)&lt;br /&gt;
  uncrypt_file.close()&lt;br /&gt;
&lt;br /&gt;
Le fichier caché est le même:&amp;lt;br&amp;gt;&lt;br /&gt;
[[Fichier: Simple1.png]]&lt;/div&gt;</summary>
		<author><name>Futex</name></author>
	</entry>
</feed>