From a17a401f00f432b11f04b60f131568f827fe07d5 Mon Sep 17 00:00:00 2001 From: Yorick Barbanneau Date: Thu, 21 Sep 2023 01:09:30 +0200 Subject: [PATCH 1/3] Add system security introduction --- content/secu_systeme/1_introduction/index.md | 265 +++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 content/secu_systeme/1_introduction/index.md diff --git a/content/secu_systeme/1_introduction/index.md b/content/secu_systeme/1_introduction/index.md new file mode 100644 index 0000000..dcb23ad --- /dev/null +++ b/content/secu_systeme/1_introduction/index.md @@ -0,0 +1,265 @@ +--- +title: "Sécurité système : introduction" +date: 2023-09-07 +tags: ["bibliothèque", ".got"] +categories: ["Sécurité système", "Cours"] +--- + +## Définition : un exécutable + +C'est un fichier contenant un programme et identifié par le système +d'exploitation en tant que tel ([définition par Wikipédia][l_execwiki]). Il +existe plusieurs format d'exécutable en fonction du système d'exploitation. + +Il ne faut pas confondre programme et scripts, le premier contenant le code +**exécutable**, le second est **interprété** (par un programme) et passe +éventuellement par du code intermédiaire ou [bytecode][l_bytecode] : *Portable +Executable* Pour Microsoft Windows, *Match Object* pour Apple MacOS / iOS, +*Executable and Linkable Format* pour beaucoup de système Unix. + +Pourquoi compiler du code? Plusieurs avantages : + + * un programme compilé est moins consommateur de ressources et par conséquent + plus rapide à l'exécution; + * pour protéger sa propriété intellectuelle (par la possibilité d'obfuscation + du code machine généré); + * pour se passer de l'**interpréteur** et ainsi éviter une étape + (complexification de la pile d'exécution). + +Le code interprété a aussi ses avantages : + * il est indépendant de la plate-forme d'exécution; + * en général il existe une multitude de bibliothèques utilisable rapidement + (coucou Python); + * le développement est simplifié et plus interactif, le langage est alors plus + accessible et le développement peut-être plus rapide (langage de plus haut + niveau) + + +[l_bytecode]: https://fr.wikipedia.org/wiki/Bytecode +[l_execwiki]: https://fr.wikipedia.org/wiki/Fichier_ex%C3%A9cutable + +## La compilation + +Un exécutable contient donc du code machine, le code source qui le défini est +alors **compilé** en code machine. Mais la compilation est en fait plus +compliquée que cette simple *"traduction"*. Elle se compose en fait de 4 grande +phases : + + 1. le préprocessing; + 2. la compilation; + 3. l'assemblage; + 4. l'édition de liens + +### le préprocessing + +Chargé de modifier le code source avant la compilation. Ici le moteur de +préprocessing se charge de remplacer les macro (`#define`), les constantes +[^f_const], les inclusion d'entêtes (`#include`) par le code effectif; + +[^f_const]: Voici quelques exemples de constantes de bases : + - `__FILE__` : affiche le nom du fichier source; + - `__LINE__` : affiche le numéro de la ligne atteinte; + - `__DATE__` : affiche la date de compilation du code source; + - `__TIME__` : affiche l'heure de compilation de la source. + +### la compilation + +C'est à cette étape que le code (`C`, `C++`, `Rust` etc.) est transforme en +assembleur. Cette étape se compose elle-même de plusieurs parties. + +#### L'analyse lexicale + +Lors de cette étape, le compilateur analyse le texte du code source. Il est +découpé en *mots* ou *tokens* définis par des **expressions rationnelles** et +**des automates à états finis**. + +Il revient à **l'analyseur lexical** de réaliser cette opération. Lors de +cette étape, les *"bruits"* sont ignorés : commentaires et espaces. Les +*lexèmes* -- représentant une instance de la petite unité de signification -- +sont ainsi définis. Si l'analyseur syntaxique rencontre un lexème inconnu, il +lèvera une erreur. + +Il existe plusieurs analyseur lexicaux : flex, lex[^n_lex] etc. + +Il ne revient pas à l'analyseur syntaxique de vérifier que l'enchainement des +lexème est correct, il transmets juste le résultat de son analyse à l'étape +suivante. + +[^n_lex]: analyseur en *C* co-écrit par Eric Schmidt, cofondateur de Google. + +#### L'analyse syntaxique + +Réalisée par **l'analyseur syntaxique** qui traite les informations reçues par +l'analyseur lexical. Contrairement à l'étape précédente, il est question ici de +se focaliser sur la validités syntaxique *d'une phrase*. + +C'est un processus itératif dont le résultat est un *Arbre Syntaxique Abstrait* +construit en fonction de la **grammaire du langage**.Il est construit au fur et +à mesure que l'analyseur avance dans le code source. Deux outils d'analyse +syntaxique sont principalement utilisés : + +#### L'analyse sémantique + +Lors de cette étape le compilateur vérifie la cohérence du code, certaines +erreurs relevant de la grammaire seront détectées comme par par exemple : + +```c +// erreur sur les types +int my_integer = "a string"; + +// Accès à une variable en dehors de son scope +{ int x = 3;} x = 4; +``` +Lors de l'analyse syntaxique, l'*Arbre Syntaxique Abstrait* est enrichi +d'information sur le sens des phrases du code. + +#### La production de code intermédiaire + +Cette étape, le code est transformé dans un langage intermédiaire entre le +langage de haut niveau (*C*, *C++*) et le langage machine. C'est à partir de ce +code que le compilateur appliquera des optimisations. C'est aussi lors de cette +étape que le code peut être offusqué afin de rendre son analyse plus complexe +(dans le logiciel privateur, ça va de soit). + +#### Les optimisations + +Ici, le compilateur réalise des optimisations sur le code intermédiaire. La +plupart de ces optimisations effectué sur le code de plus haut niveau le +rendraient moins compréhensible et pourrait se révéler plus fastidieux à écrire. + +#### La génération de code assembleur + +Ici le code intermédiaire optimisé est transformé en assembleur. Le compilateur +créé les fichiers `*.S`. On appelle aussi cette étape **génération de code +natif**. Lors de cette étape, le code généré est spécifique à une architecture +donnée et ce afin de profiter des instructions disponible sur celle-ci (*MMX*, +*SSE*, *NEON* etc.). + +#### L'assemblage + +Le compilateur créé un fichier objet `*.o` par fichier source. Ces fichiers +objets sont bien des binaires, il contienne déjà les segments nécessaires +(`.text`, `.data` ...) dans un format dépendant du système cible (PE pour +Microsoft Windows©, Mach-O pour Apple MacOS©, ELF pour Linux). + +Lors de cette étape, le compilateur enlève tous les *labels*, mais afin de +pouvoir résoudre les symboles (fonctions, variables, etc.) il va créer la +**table des symboles**. + +Cette table contenu dans chacun des fichiers objets générés fait référence à la +position des élément dans ce fichier. Le compilateur résout ces symboles **lors +de l'édition de liens**. + +#### L'édition de liens + +C'est le moment ou le compilateur agrège les différents fichiers objets en un +seul exécutable. Le *linker* responsable de cette étape doit résoudre les +symboles et les liers aux différents fichiers objets et bibliothèques. + +C'est aussi lors de cette étape que les différents segments composants le +programme sont créés et que la **table de relocation** est créée (très utile +pour les mécanismes d'ALSR). + +Il existe deux type d'édition de liens : + + * **statique** : les éléments issus de bibliothèques sont inclus dans le + binaire final. Dans ce cas la résolution des symboles **est totale**; + * **dynamique** : les bibliothèques partagées ne sont pas incluses dans le + binaire. La résolution des symboles ne peut-être que partielle. + +Dans le cas de la compilation **dynamique**, le *linker* doit identifier les +symboles appartenant aux bibliothèques partagées. Leur résolution se fera alors +au moment de l'exécution. + +## Exécution + +L'exécution d'un programme se passe en plusieurs étapes : + + 1. le noyau est averti que qu'il doit charger le fichier binaire; + 2. l'élément chargé du chargement de notre binaire se charge de l'analyser; + 3. le noyau alloue de la mémoire pour notre programme; + 4. il *map* la mémoire allouée avec les éléments du programme; + 5. il est maintenant temps de passer le flot d'exécutions au programme. + +Bien évidement le binaire n'est pas chargé tel quel en mémoire, d'où l'étape +*d'analyse*. Sous Linux et les système Unix en général, le format d'exécutable +utilisé est ELF. ce format, largement documenté, sert de base pour le *loader* + +### Segments et sections + +C'est deux éléments qui composent un fichier binaire au format ELF sont souvent +source de confusion. + +*Les segments* contiennent des éléments nécessaires à l'exécution alors que *les +sections* contiennent des informations utiles pour les liens, la relocation et la +résolution de symboles. + +Les *sections* sont des composantes des *segments*. Prenons l'exemple du segment +`LOAD` qui contient des sections `.data`, `.got`, `.bss` ... Elles contiennent +soit des données brutes: + + * `.text` : du code; + * `.data` : des données initialisées comme par exemple: + ```c + int x = 42; + ``` + * `.bss` : des données non initialisées + * `.rodata` : des données en lecture seule comme les constantes statiques + +### Le format ELF + +Comme nous le disions, c'est le format binaire d'enregistrement de code compilé +utilisé par la plupart des systèmes de type *Unix*. Il commence par les nombres +magiques[^n_magic] `0x7fELF`. Il se compose ensuite d'un entête fixe. Celui ci +contient (entre autres) l'*endianess* (big ou little), l'ABI, le type +(bibliothèque, exécutable), l'architecture cible. + +Après viens le *Program Header Table* qui contient des segments et informations +nécessaire à la création du processus en mémoire. + +Ensuite la *Section Header Table* référençant et décrivant les sections + +Enfin le fichier ELF contient les données référencées par ces deux tables. + +[^n_magic]: dans notre cas, ensemble de caractères utilisés pour désigner un + format de fichier. + +## Pratique + +### Propriété de `ls` + +Le plus simple pour obtenir des information est d'utiliser le programme `file`. + +```shell +$ file /bin/ls +ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, +interpreter /usr/lib/ld-linux-x86-64.so.2, +BuildID[sha1]=4d53da289d128a5ccee3f944db35244bf91c7a99, +for GNU/Linux 3.10.0, not stripped +``` + +Nous apprenons donc que cet exécutable est un ELF 64bits pour uns architecture +*Intel x86_64*, lié dynamiquement, chargé par la bibliothèque `ld-linux-x86-64`. +Ici le binaire est *not stripped* : les différents *labels* ne sont pas +supprimés (ici pour NixOS). + +Il est aussi possible de récolter plus d'informations avec `readelf` notamment +la version de la *libc* utilisée. Ce genre d'information peut permettre de mener +une attaque. + +### Segments et sections avec `realelf` + +#### Le segment `GNU_STACK` + +Il permet la configuration de la pile lorsque le binaire est charge. Il sert par +exemple à la mise en place de protection (pile non exécutable par exemple). + +#### Le segment `GNU_RELRO` + +Il indique quelles régions de la mémoire doivent être marquées en lecture seule +une fois la résolution des symboles effectuée. Il existe deux type : + + * **full**: `.got` et `.got.plt` sont passés en lecture seule + * **partiel**: seule la `.got` est en lecture seule. + +*[ELF]: Executable and Linkable Format From 324179092e21e8e82618388a21d0fd5f7f2fde66 Mon Sep 17 00:00:00 2001 From: Yorick Barbanneau Date: Sun, 24 Sep 2023 23:58:52 +0200 Subject: [PATCH 2/3] Add Win PE format --- content/secu_systeme/1_introduction/index.md | 80 +++++++++++++++++++- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/content/secu_systeme/1_introduction/index.md b/content/secu_systeme/1_introduction/index.md index dcb23ad..e34b8b5 100644 --- a/content/secu_systeme/1_introduction/index.md +++ b/content/secu_systeme/1_introduction/index.md @@ -206,7 +206,7 @@ soit des données brutes: * `.bss` : des données non initialisées * `.rodata` : des données en lecture seule comme les constantes statiques -### Le format ELF +## Le format ELF Comme nous le disions, c'est le format binaire d'enregistrement de code compilé utilisé par la plupart des systèmes de type *Unix*. Il commence par les nombres @@ -224,7 +224,7 @@ Enfin le fichier ELF contient les données référencées par ces deux tables. [^n_magic]: dans notre cas, ensemble de caractères utilisés pour désigner un format de fichier. -## Pratique +## ELF : Pratique ### Propriété de `ls` @@ -247,11 +247,35 @@ Il est aussi possible de récolter plus d'informations avec `readelf` notamment la version de la *libc* utilisée. Ce genre d'information peut permettre de mener une attaque. +### les sections `.plt` et `.got` + +Ces différentes sections permette la résolution de symboles. `.plt` signifie +*Procedure Linkag Table* et `.got` *Global Offset Table*. On parle alors de +relocation. + +Pour la section `.plt`, toutes ses entrées sont initialisées pour pointr vers +l'editeur du lien et non l'adresse de la bonne fonction. C'est lors de premier +appel de la fonction en question que sont adresse sera résolue - elle st donc +effectuée au *runtime* - et mise à jour. On parle alors de *lazy symbols +binging* + +La section `.got` fait plus office d'annuaire référençant juste les adresss de +fonctions mais aussi de variables globales des bibliothèques). + +#### `.got` et `plt.got + +Ces deux sections sont utilisés pour les symboles ayant besoin d'être résolus +**au moment du chargement du binaire en mémoire**. + +#### `.plt` et `.got.plt` + +Ces deux sections se chargent de la résolution fainéante. + ### Segments et sections avec `realelf` #### Le segment `GNU_STACK` -Il permet la configuration de la pile lorsque le binaire est charge. Il sert par +Il permet la configuration de la pile lorsque le binaire est chargé. Il sert par exemple à la mise en place de protection (pile non exécutable par exemple). #### Le segment `GNU_RELRO` @@ -263,3 +287,53 @@ une fois la résolution des symboles effectuée. Il existe deux type : * **partiel**: seule la `.got` est en lecture seule. *[ELF]: Executable and Linkable Format + +## Le format PE + +PE pour *Portable Execution* est le format de binaire utilisé par Microsoft +Windows. Comme pour Linux, un *loader* réalise l'analyse et le chargement du +binaire en mémoire. Dans ce format, la notion de segment n'existe pas, mais il +se compose de 3 entêtes : + + * un reliquat de l'ère MS DOS avec comme *magic number* `MZ`. cette section + affiche un message d'erreur du style *Ce programme ne n'exécute pas en mode + MSDOS* lors de son exécusion en mode DOS; + * une entête *PE* avec comme *magic number* `PE`; + * une entête optionnelle. + +Il se compose aussi: + + * une partie *data directories*; + * une table des sections (`text`, `data`, etc.); + * les sections en questions (avec leurs entêtes). + +### CFF explorer + +Ce programme disponible uniquement pour Windows permet d'analyser les fichiers +binaires (exécutable, bibliothèques, etc.). + +### Entête optionnelle + +Elle est quasiment tout le temps présente et permet notamment de définir le +point d'entrée (*entrypoint*), d'activer les protections comme l'ASLR ou autre +mécanismes de sécurité. + +### Entête *data directories* + +Elle contient la localisation et la taille de chaque `directory`. Ces +*directories* sont de plusieurs natures : + + * signatures cryptographiques; + * icônes; + * configurations; + * *export-table* : référençant les fonctions exportées par le binaire; + * *import-table* : référençant les DLL importées par le binaire, les fonctions + issues de ces DLL sont référencées dans l'*Imports Address Table*; + * *relocation table* : table référençant les relocations. + +Plusieurs *directories* peuvent appartenir à une section. + +### Entêtes de sections + +Elles contiennent les information relatives à leurs sections respectives : nom, +adresse virtuelle, taille, droit d'accès. From 359c629860df693afe62538f2951b30b5ca5796e Mon Sep 17 00:00:00 2001 From: Yorick Barbanneau Date: Wed, 27 Sep 2023 22:49:01 +0200 Subject: [PATCH 3/3] Update reverse engineering article --- content/secu_systeme/2_initiation_re/index.md | 329 ++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 content/secu_systeme/2_initiation_re/index.md diff --git a/content/secu_systeme/2_initiation_re/index.md b/content/secu_systeme/2_initiation_re/index.md new file mode 100644 index 0000000..192bf3d --- /dev/null +++ b/content/secu_systeme/2_initiation_re/index.md @@ -0,0 +1,329 @@ +--- +title: "Sécurité système : initiation au reverse engeneering" +date: 2023-09-21 +tags: ["ingénieurie inverse", "assembleur"] +categories: ["Sécurité système", "Cours", "TD"] +--- + +Nous avons revu dans le cours précédents les bases du fonctionnement d'un +binaire de la compilation à son exécution. Dans cette partie nous allons +appréhender les bases de l'ingénierie inverse. À l'issue de celle-ci nous +devrions être en mesure de réaliser de petits *crackme*. + +L'étape de compilation est en quelque sorte destructrice : Il n'est plus +possible à partir du binaire compilé de retrouver le code source correspondant. +Mais il est tout de même possible de **désassembler** : on reconstitue un code +assembleur. + +Ainsi afin de faire du reverse engineering, il est nécessaire de **comprendre la +compilation**, de savoir de quoi se **compose un binaire** et comment **il est +exécuté**. + +Une compréhension de l'assembleur, des type de structures qu'il manipule est +primordiale. Il est aussi nécessaire de maîtriser les outils à notre +disposition, de savoir coder un minimum (en *C*, *Python*). + +## La gestion de la mémoire + +Les sections `.rodata`, `.bss` et `.data` contiennent des données mémoires. Deux +structures existent pour les manipuler : la pile et le tas. + +### La pile + +Elle manipule des données statiques. C'est une structure de type LIFO (*Last In +First Out) qui croit vers le bas : plus on descend plus les adresse augmentent. +Sa taille est alignées sur un *int32* ou *int64* en fonction de l'architecture +(32 ou 64 bits). + +*Deux "fonctions"* permettent de la manipuler : `push()` afin de placer un +élément -- la pile descend alors d'une case -- et `pop()` pour reprendre un +élément -- la pile remonte d'un élément. + +Elle se situe **dans l'espace mémoire d'un processus**, ainsi chaque processus a +sa pile. Elle a une structure linéaire; son accès est **rapide** (pas +d'allocation de mémoire à effectuer) mais la **taille des éléments que l'on peut +y stockée est limitée**. + +### Le tas + +Il manipule des données dynamiques représentées par une structure de données +hiérarchisée. Le tas est lui aussi positionné dans l'espace mémoire d'un +processus. + +Il n'est pas limité en taille (enfin presque pas...) mais nécessite de coûteuses +allocations mémoire qui le rend plus lent. Le développeur peut lui même allouer +de la mémoire sur le tas avec la présence de fonctions comme `malloc()` (et ne +pas oublier de les libérer avec `free()`). L'implémentation de ces mécanismes +mémoire dépendent de **l'allocateur**. + +## Initiation au reverse Engineering + +### L'assembleur + +C'est un langage de bas niveau mais encore compréhensible par un humain +(initié...). Il est dépendant de l'architecture, prenons par exemple le code *C* +suivant: + +```c +int sum (int a, int b ){ + return a +b; +} +``` + +Voici ce code en assembleur *x86_64* : + +```asm +sum(int, int): + push rbp + mov rbp, rsp + mov DWORD PTR [rbp-4], edi + mov DWORD PTR [rbp-8], esi + mov edx, DWORD PTR [rbp-4] + mov eax, DWORD PTR [rbp-8] + add eax, edx + pop rbp + ret +``` + +Et en assembleur *ARM64*: + +```asm +sum(int, int): + sub sp, sp, #16 + str w0, [sp, 12] + str w1, [sp, 8] + ldr w1, [sp, 12] + ldr w0, [sp, 8] + add w0, w1, w0 + add sp, sp, 16 + ret +``` + +On parle alors d'ISA pour *Instruction Set Architecture*, cela représente le jeu +d'instruction disponible. Nous y trouvons les opérations élémentaires : +addition, soustraction, multiplication, division, et / ou (exclusifs ou non) +etc. Ici mon manipule les registres et la mémoire directement. Une *ISA* ne +contient pas d'opérateur avancés comme les structures de contrôles que nous +pouvons trouver dans les langages de haut niveau (`while ...`, `if ... +else ...`, `for ...`). + +### L'assembleur x86 (32 et 64 bits) + +Tout comme pour le cours de sécurité logicielle, nous utiliserons principalement +l'assembleur *x86_32* pour ce cours (et quelques fois sa version 64). Mais par +contre nous utiliserons **la syntaxe *Intel*** majoritairement utilisée dans le +monde de l'ingénierie inverse. Cette syntaxe est plus simple : + + * les suffixes de mnémoniques pour n'existes pas en syntaxe Intel, ainsi + `movl`, `movw` ou encore `movb` deviennent **`mov`**; + * les préfixes sur les registres et immédiats disparaissent : `%eax`, `$1`, + `$0x0ff` deviennent **`eax`, `1` et `0x0ff`**; + * l'ordre des opérandes est inversé : ce n'est plus `source, destination` mais + **`destination, source`**. `movl $1, %eax` devient **`mov eax, 1`** + * les accès indirect à la mémoire sont aussi plus simple : `(%eax)` devient + `[eax]` et `3(%eax)` devient `[eax + 3]` voir le cours [accès à la mémoire de + sécurité logicielle]({{}}) + +Le vocablulaire reste le même que celui vu lors des cours [d'introduction de +sécurité logicielle]({{ref "secu_logicielle/1_introduction/index.md"}}) + +### L'assembleur x86 : les registres + +LEs registres sont de petits espace memoire directement intégrés au processeur. +Ce sont les espace mémoires les plus rapides disponible sur un ordinateur, mais +aussi les plus petits. Il sont dédiés entre autres au stockage de données. + +Certains de ces registres ont des **rôles bien déterminés** par exemples : + + * `eip` pour *extended instruction pointer* pointe vers la prochaine + instruction à exécuter[^eip], il porte aussi le nom de *Compteur Ordinal*. + **il ne peut être modifié** contrairement à tous les autres registres; + * `ebp` pour `extended base pointeur` pointe vers le bas de la pile; + * `esp` pour `extented stack pointer` pointe lui vers le haut de la pile. + +Tous ces registres sont noté *extended* dans leurs versions **32 bits** + +Certains autres ont des spécificité, mais il est tout à fait possible pour le +programmeur de les utiliser à sa guise : + + * `ecx` par exemple est utilisé comme compteur dans certaines instructions de + repétition(typiquement les boucles); + * `esi` et `edi` utilisés comme source (*extended source index*) et destination + (*extended destination index*) pour certaines instructions de copie. + +Les registres peuvent être découpés en sous registres : + +> `a` 8 bits -> `ax` 16 bits -> `eax` 32 bits -> `rax` 64 bits + +Il est d'ailleurs possible de découper `ax` en deux registes de 8bits : `al` +(bits 0 à 7) et `ah` (bits 8 à 15). Ces découpes permettent certaines +optimisations comme par exemple le **stockage de deux entiers 16 bits** dans un +registre 32bits ou encore pour les instruction se basant sur **l'interprétation +du contenu** des registres. + +Il existe aussi des registes d'états, mais nous les avons vu [en sécurité +logicielle]({{}}) +DAs le cadre de ce cours, le *Zero Flag*, *Sign Flag* et *Carry flag* sont +importants. Le carry flag correspond à la présence d'une retenue [voir sur +Wikipedia][carry_flag]. + +Pour rappel, voici un exemple d'utilisation du *Zero flag* : + +```asm + +start: + mov eax, 1 + dec eax ; décrémente eax + + ; comme le résultat de la précédente instruction est 0 + ; alors notre programme va forcément brancher... + jz hell + +; [...] + +hell: +``` + +[^eip]: en x86, dans certaine ISA, il pointe l'instruction en cours). + +[carry_flag]:https://fr.wikipedia.org/wiki/Indicateur_de_retenue + +## Pratique + +### IDA Free + +C'est un outils gratuit et multi plate-forme d'analyse de binaire. Il existe +aussi plusieurs versions payantes (pro, home, corporate ...). La version free +comporte un desassembleur, un décompilateur "cloud" pour x86_64 seulement. Il +permet la manipulation de binaire au formats différents (ELF, PE Mach-O). Il +s'interface aussi avec des débogueras notamment GDB. + +C'est un outil puissant mais difficile à prendre en main. + +### Étudions `ls` (binaire ELF) + +Nous ouvrons notre binaire ls modifié avec `lift` lors du précédent TD pour +l'étudier avec *IDA Free*. + +#### question b + +`strcpy` se trouve dans la section `.dynsym`, section des symboles résolus +dynamiquement lors de son premier appel. + +#### question c + +Dans IDA, le code couleur utilisé entre autres dans la section `.dynsym` +correspond aux éléments fournis à l'extérieur de notre binaire, comme dans les +bibliothèques partagées. + +#### question d + +Les chiffres hexadécimaux dans ne nom de la fonction `sub_xxxxxx` correspondent +aus décalage (*offset*) de celle-ci par rapport à l'adresse de chargement de +notre binaire. + +### Les raccourcis clavier + +Ils sont une part importante de l'utilisation d'IDA, en voici quelques-uns: + +| raccourcis | fonction | commentaires | +|------------|----------|--------------| +| crtl + w | sauvegarder la base de données | très utile cat IDA est instable +| ctrl + shitf + w | effectuer un snapshot de la base de données | CF au dessus +| ctrl + z | annuler | | +| n | renommer un objet (variable, fonction, etc.) | hexrays | +| y | modifier le type d'un objet (variable, fonction, etc.) | asm / hexrays | +| alt + a | interpréter l'objet comme une chaine de caractères | | +| h | interpréter la selection comme un décimal / hexadécimal | asm / hexrays | +| r | interpréter la selection comme un caractère | asm / hexrays | +| c | interpréter la portion comme du code asm | asm | +| d | interpréter la portion comme data | asm | +| u | retirer l'interprétation | asm | +| : ou ;|ajouter un commentaire au niveau de l'instruction | visualiseur | +| insert | ajouter un commentaire avant l'instruction | asm / hexrays | +| espace | cycle entre la vue graph et linéaire | hexrays | +| F5 | décompiler (si possible) | | +| entrée ou double-clic | su un symbole -> aller où pointe le symbole | asm / hexrays | +| echap | revenir à la position précédente - en arrière | asm / hexrays | +| ctrl + entrée | revenir à la position précédente - en avant | asm / hexrays | +| x | afficher les cross références *xref* d'un objet | asm / hexrays | +| alt + t | recherche de texte | | +| alt + b | recherche de motif binaire | | +| alt + i | rechetche un *immédiat* | | +| tab | passer de la vue *asm* à la vue hexrays | | +| ctrl + e | afficher les points d'entrées du binaire | | +| maj + F1 | afficher la fenêtre des types locaux | | +| maj + F12 | afficher la fenêtre des chaîne de caractères | | + +Il faut voir IDA comme un bloc note accompagnant le travail d'ingénierie inverse +Il faut **absolument** documenter au fur et à mesure des investigations et faire +autant d'instantanés que possible (stabilité...). + +### Analyse du binaire `mysecrets` + +#### Question 1 + +Dans IDA, lorsque nous faisons `ctrl+e` nous atterrissons dans la liste des points +d'entrées du binaire chargé. Dans le cas de `mysecret`, nous atterrissons dans +la fonction `main:`. Ce qui est normal pour un binaire ELF. + +#### Question 2 + +Pou trouver la section `.rodata`, il suffit de trouver la liste des segments +(mais pas au sens ELF...) avec le raccourci clavier `ctrl+s`. Cette section +contient les données en lecture seule, ici toutes les *strings* de notre +binaire. + +#### Question 3-a + +Dasn le code assembleur, il semble y avoir 3 arguments. IDA nous les donne en +commentaire : + +```asm +ebp + arg0 +ebp + arg4 +ebp + arg8 +``` + +#### Question 3-b + +La convention d'appel utilisées ici est `__cdecl` (pour *C declaration*), c'est +la convention utilisés par le langage C et C++ -- la convention d'appel dépend +aussi de l'ABI système, du compilateur ). Ici les arguments sont placés sur la +pile par la fonction appelante (*caller*). Il sont placé dans l'ordre inverse, +prenons comme exemple le programme *C* suivant : + +```c +int add_3 ( int a, int b, int c){ + // [...] +} +main() { + add_3 (1, 2, 3); +} +``` + +Ce qui donnera en assembleur : + +```asm + +main: + push ebp ; backup current base pointer + mov ebp, esp ; get the new base pointer + + push 3 + push 2 + push 1 + call add_3 + ; [...] +``` + +#### Question 3-c + +Les instructions `push epb` et `mov epb, esp` permettent de mettre en place le +*base pointer* après l'avoir sauvegardé pour assurer sa remise en place lors du +retour de notre fonction `secrets`. + +#### Question 3-d + +La décente de `0x18` dans la pile permet à la fonction apellée de mettre en +place un espace pour les variables locales.