Buffer overflows: War FTP
                      =========================

Recoucou tous !
Hehe. Vous commencez … en avoir marre des buffer overflows hein ! ;)))
AprŠs l'article de __2, qui expliquait le principe de base du smashing stack,
puis aprŠs mon article pr‚c‚dent qui expliquait les techniques pratiques pour
programmer un exploit bas‚ sur un buffer overflow, y manquait encore un truc
pour ˆtre tout … fait complet !

Y manquait un beau petit exploit...
J'ai cherch‚ pas mal, aprŠs un programme relativement connu et r‚cent, qui
aurait pu servir d'exemple. En me renseignant un ti peu, j'ai apprit que
War FTPd version 1.65 finale contenait ce que nous cherchions ! ;)))

Je vais donc vous montrer ici en d‚tail comment programmer un petit exploit
pour les serveurs War FTP, en se servant de ce sacr‚ buffer overflow :)

Tout d'abord avant de commencer, je vous conseille d'aller chercher War-FTP
1.65, sur http://www.jgaa.com . Ensuite, je vous conseille aussi d'avoir les
outils suivants (pas que pour ce buffer overflow-ci, il vous servirons pour
en exploiter d'autres aussi ;)
Un petit ‚diteur hexad‚cimal: UltraEdit (http://www.idmcomp.com),
Un debugger-d‚sassembleur: Win32dASM
Un assembleur 386-Windows: MASM32
Et enfin, un outil formidable dont j'ai d‚j… parl‚ dans un article, … savoir
NetCat, un programme de gestion de sockets TCP/IP provenant de Unix, trŠs
puissant et trŠs facile d'emploi (http://www.l0pht.com/~weld/netcat).
N'oubliez pas aussi de relire un petit peu les 2 articles pr‚c‚dents si c'est
loin dans votre m‚moire hehe ;)


OU EST LE BUFFER OVERFLOW ?
===========================
Avant de commencer je vous conseille d'installer War-FTP chez vous, puis que
vous me mailiez avec votre IP, comme ca je pourrai tester l'exploit... lol :)
Non, pas besoin de me mailer l'IP, mais installer le quand mˆme, ca va ˆtre un
peu plus facile pour que vous compreniez ski va spasser :)

Alors l'exploit dans War FTP est assez bˆte, on se demande d'ailleurs comment
il n'est pas encore corrig‚...
C'est un buffer overflow dans les commandes USER et PASS, qui sont les 1Šres
commandes que vous envoyer … un serveur FTP quand vous vous connectez dessus.
On va essayer ca tout de suite.
On lance d'abord WarFTP, on oublie pas de l'activer (hehehe ;), puis on cr‚e
un petit fichier EXPLOIT1.BIN, qui contient ceci:
USER exploit

suivi de qq dizaines de lignes <ENTER>.

Ensuite, nous allons utiliser NetCat, pour envoyer ces commandes au serveur
FTP. Par exemple, si mon IP est 10.10.10.1, on lance:

nc 10.10.10.1 21 < exploit1.bin

(21 est le port FTP par d‚faut utilis‚ par WarFTP)
Voici le r‚sultat:
C:\>nc 10.10.10.1 21 < exploit1.bin
220- Jgaa's Fan Club FTP Service WAR-FTPD 1.65 Ready
220 Please enter your user name.
331 User name okay, Need password.

Donc le serveur FTP recoit bien notre commande USER, et il attend un password,
dont on a rien … foutre ici c justemment pour pas l'avoir qu'on bosse ;))
Maintenant rentrons de suite dans le vif du sujet.
On va recr‚er un petit fichier EXPLOIT2.BIN en faisant un buffer overflow.
Recr‚ons un 2Šme petit fichier, EXPLOIT2.BIN, contenant ceci:
USER xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
(pour ceux qui ont pas un bon ‚diteur, il y en a 1000+ ou - des "x" ;)))
Normalement si on a mit assez de caractŠres, on devrait bien faire un buffer
overflow. Lancons:  nc 10.10.10.1 21 < exploit2.bin
DŠs qu'on coupe NetCat (CTRL-C), Windows rame un petit peu, puis on a un beau
message d'erreur "Ce programme va ˆtre arrˆt‚ car il a effectu‚ une op‚ration
non conforme".
Donc pas de doute, il y a bien un problŠme qq part :)))))


ANALYSE DE WARFTP
=================
Maintenant il va s'agir d'analyser un peu WarFTP, pour essayer de mieux
comprendre d'ou vient ce buffer overflow, et aussi de chercher quelques
informations pour l'exploiter.

Nous allons pour cela lancer Win32DASM, et d‚sassembler WarFTP.
(si vous ne savez pas vous servir de Win32DASM, lisez mon article sur le
Cracking, qui vous en expliquera assez bien les bases de fonctionnement)
Tout d'abord, nous allons essayer de localiser l'endroit ou la valeur de EIP
est r‚cup‚r‚e de la pile via le RET critique. C'est … cet endroit que nous
devrons en effet par la suite analyser l'ex‚cution et mettre une adresse EIP
qui permettra l'ex‚cution de notre exploit.

Une fois le d‚sassemblage termin‚ (menu "Disassembler", commande "Open file
to disassemble..."), on va donc dans le menu "Refs", commande
"String Data References". Nous allons chercher aprŠs la chaŒne
"User name okay", qui est affich‚e lorsque le username … bien ‚t‚ recu par le
serveur. En effet, c'est probablement aprŠs l'utilisation de cette chaŒne que
se produit le RET recherch‚.
Nous arrivons … l'adresse 0042363D. Nous notons cette adresse, puis nous
lancons le debugger "Debug","Load Process", et placons un breakpoint … cet
endroit, au moyen de la commande "Goto" "Goto Code Location" et de la touche
F2. Ensuite, nous lancons le debugging par "Run", nous activons le serveur,
minimisons sa fenˆtre, puis nous relancons notre nc 10.10.10.1 21 < exploit2.bin
Nous ex‚cutons ensuite pas … pas, en pressant sur F8, jusqu'… ce que nous
atteignons la fin de la proc‚dure (structure classique: probablement plusieurs
POP suivi d'un RET), car c'est l… que doit se passer le problŠme.

Nous arrivons ainsi … un RET … l'adresse 004232D0.
Nous allons continuer le pas … pas dans le programme, jusqu'au RET qui va
essayer d'ex‚cuter le saut vers l'adresse que nous avons overwrit‚ dans la
pile. Pour plus de facilit‚, nous allons recommencer, en r‚‚crivant un
EXPLOIT3.BIN, avec comme username des caractŠres 0FFh, comme ca nous saurons
que le RET qui sera ˆtre ex‚cut‚ sera un saut vers l'adresse 0FFFFFFFFh, qui
est un saut interdit par le systŠme (hors des adresses accessibles par le
programme), et nous aurons donc plus facile pour rep‚rer l'emplacement du RET
correspondant.
Nous allons donc parcourir le code en suivant les RET successif, jusqu'au RET
qui charge dans EIP la valeur 0FFFFFFFFh.
Le RET … l'adresse 004232D0 renvoie … l'adresse 0421A2Bh, le RET suivant
renvoie … 004219C1, puis le RET encore aprŠs nous renvoie … l'adresse
5F416294. Nous remarquons que cette adresse n'est plus dans l'espace de notre
programme, mais que c'est une adresse contenue dans une DLL: MFC42.DLL
Donc nous allons mettre un breakpoint … l'adresse du RET pr‚c‚dant ce saut,
puisque nous ne pouvons pas mettre un breakpoint sur des instructions ne se
trouvant pas dans le code. Nous mettons donc un breakpoint sur l'adresse
004219D7  RET 00000004

En continuant … partir de ce breakpoint, nous allons successivement aprŠs
chaque RET arriver aux adresses suivantes:
5F416294
5F4161E4
5F416176
5F402679
5F40233C
5F4022C6
5F402251
5F402208
Ensuite, en continuant encore un peu, nous arrivons enfin … un saut vers
l'adresse 0FFFFFFFFh, que nous attendions !


OFFSET DE LA VALEUR DE RETOUR
=============================
Nous avons donc cr‚er un buffer overflow avec des caractŠres 0FFh, qui
provoquent bien un saut vers l'adresse 0FFFFFFFFh. Nous allons donc maintenant
essayer de d‚terminer exactement l'endroit dans notre chaŒne ou se trouve
l'adresse de retour, de maniŠre … pouvoir aller y placer une adresse de retour
vers notre exploit :)))

Pour cela, nous allons proc‚der de la maniŠre suivante: nous allons cr‚er une
chaŒne de username dans EXPLOIT4.BIN de la forme suivante:
EEEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, et lancer
l'ex‚cution jusqu'… une des adresses suivantes:
0EEEEEEEEh: si nous avons cette adresse, cela veut dire que l'adresse de
 retour se trouve dans la partie ou nous avons des 0EEh, et donc, nous allons
 diminuer le nombre de caractŠres 0EEh, pour essayer de diminuer cette
 intervalle.
0FFFFFFFFh: si nous avons cette adresse, cela veut dire que l'adresse de
 retour se trouve dans l'autre partie (caractŠres 0FFh), et nous allons donc
 augmenter le nombre de caractŠres 0EEh, pour essayer de monter dans la pile.

Nous allons proc‚der comme ca plusieurs fois, en modifier le nombre de 0EEh,
jusqu'… ce que nous sautions … une adresse compos‚e de 0EEh et de 0FFh, ce qui
voudra dire que l'on est vraiment tout prŠs de l'endroit recherch‚ !
Allons-y: mettons des 0EEh jusqu'… l'offset 4FFh (avec UltraEdit).
Nous supprimons aussi les breakpoints, et lancons l'ex‚cution de WarFTP,
ensuite nous lancons l'ex‚cution de  nc 10.10.10.1 21 <  exploit4.bin
Nous fermons ensuite NetCat, avec CTRL-C, puis nous pressons sur "Pause"
dans le debugger. Nous voyons ainsi la valeur de saut 0EEEEEEEEh.
Nous allons ainsi continuer en rajoutant ou en supprimant des 0EEh, pour
diminuer l'intervalle dans laquelle nous sommes certains que se trouve la
valeur de retour:

0EEh jusqu'… l'offset:      valeur de retour (EIP):   => la zone devient:
 4FFh                       0EEEEEEEEh                   de 0h … 4FFh
 2FFh (milieu de 0h,4FFh)   0EEEEEEEEh                   de 0h … 2FFh
 1FFh (milieu de 0h,2FFh)   0FFFFFFFFh                   de 1FFh … 2FFh
 28Fh                       0EEEEEEEEh                   de 1FFh … 28Fh
 22Fh                       0FFFFFFFFh                   de 22Fh … 28Fh
 25Fh                       0EEEEEEEEh                   de 22Fh … 25Fh
 23Fh                       0FFFFFFFFh                   de 23Fh … 25Fh
 24Fh                       0EEEEEEEEh                   de 23Fh … 24Fh
 247h                       0EEEEEEEEh                   de 23Fh … 247h
 243h                       0FFFFEEEEh

Nous arrivons donc … une adresse qui contient des 0EEh et des 0FFh. Que cela
veut-il dire ? Cela veut dire que notre pile est comme ceci:
EE EE EE EE EE EE EE EE EE FF FF FF FF FF FF FF FF
                     || || || ||
                  adresse de retour
Donc, si nous supprimons 2 0EEh, puis que nous mettons par exemple 4 0DDh,
nous devrions avoir une pile comme ceci:
EE EE EE EE EE EE EE DD DD DD DD FF FF FF FF FF FF
                     || || || ||
Ou 0DDDDDDDDh repr‚senterait l'adresse de retour EIP. Nous mettons donc des
0EEh jusqu'… l'offset 241h compris, puis nous mettons DD DD DD DD, puis nous
laissons des 0FFh derriŠre. Normalement nous devrions donc maintenant sauter
… l'adresse 0DDDDDDDDh. Nous essayons, et...
Yessssssssssssssssss it works ! :)
Donc, l'adresse de retour que nous pouvons modifier se trouve … l'offset
242h dans le fichier EXPLOIT4.BIN .


SHASHING DE EIP
===============
Nous avons donc maintenant trouver l'endroit ou aller mettre la valeur pour
revenir au d‚but de notre buffer. Cependant, nous arrivons ici … un cas
particulier, mais courant dans les programmes Windows. De quoi s'agit-il ?
L'adresse de notre buffer, est approximativement 00CCxxxx (en observant la
valeur de ESP le plus vite possible aprŠs l'ex‚cution du saut vers 0DDDDDDDDh).
Donc l'adresse de la pile contient un byte 00h, et le dernier byte que nous
allons mettre va nous poser problŠme: il ne sera pas ajouter dans le buffer,
et donc tout semble … refaire ! :((((((

Pour contourner ce problŠme, nous allons analyser la valeur des registres lors
de l'ex‚cution du RET, et observer ceux d'entre eux, qui pointent vers des
adresses trŠs proches de ESP (adresse de la pile). En effet, nous pourrions
alors essayer de proc‚der comme ceci:
par exemple, si la valeur du registre EDX est proche de l'adresse de ESP,
nous pouvons essayer de trouver une instruction "CALL EDX" cod‚e dans une DLL
charg‚e par le programme (… une adresse ne contenant pas de 00h), sauter vers
l'adresse de ce CALL via le RET que nous ‚crasons, qui s'ex‚cutera et
ressautera lui vers l'offset EDX, qui sera le plus prŠs possible de notre
buffer.

Nous relancons donc WarFTP, en r‚activant le breakpoint … l'adresse 
004219D7  RET 00000004,
et nous allons noter les registres ‚ventuels qui sont proches de notre buffer.
DŠs le saut vers 0DDDDDDDDh, nous avons les valeurs de registres suivantes:
EAX: 00CCFD6C
EBX: 00CCFD6C
ECX: 00CCF714
EDX: BFF76859
ESI: 81729ECC
EDI: 00CCF73C
EBP: 00CCF690
ESP: 00CCF670

Notre pile (ESP) est en 00CCF670, nous remarquons donc que les registres
EAX,EBX,ECX,EDI,EBP pointent tous des adresses proches de notre pile.

Dans Win32DASM, observons un peu plus attentivement notre pile:
A la valeur ESP+00000700, nous observons ceci:
ESP+000006F4  EEEEEEEE
ESP+000006F8  EEEEEEEE
ESP+000006FC  EEEEEEEE
ESP+00000700  DDDDDDDD <- notre adresse de retour
ESP+00000704  FFFFFFFF
ESP+00000708  FFFFFFFF
ESP+0000070C  FFFFFFFF

Comme ESP vaut 00CCF670, c'est Çquivalent Ö:
00CCFD6C  EEEEEEEE
00CCFD70  DDDDDDDD <- notre adresse de retour
00CCFD74  FFFFFFFF

Registres possÇdant des valeurs "intÇressantes":
EAX: 00CCFD6C
EBX: 00CCFD6C
ECX: 00CCF714
EDI: 00CCF73C
EBP: 00CCF690

Nous remarquons que tout ces registres pointent sur une valeur qui est avant
notre ESP. Cependant, la valeur de ces registres dÇpent peut-àtre d'une
exÇcution Ö une autre. Nous allons donc essayer de modifier notre buffer
overflow pour que màme si la valeur du registre soit lÇgärement modifiÇe, elle
n'empàche pas pour autant le saut. Nous allons donc placer comme instructions
dans les bytes prÇcÇdant notre valeur de retour toute une sÇrie de NOPs (90h)
, Ö la place des 0EEh que nous avions tantìt. Et nous placerons le code Ö
exÇcuter apräs notre adresse de retour. Cela ne pose pas un grand probläme.
C'est peut-àtre màme plus pratique, car nous disposerons ainsi de plus de
mÇmoire pour notre code assembleur, et nous pourrons aussi empiler sans
problämes des valeurs sur la pile, puisque celle-ci va continuer Ö descendre
et ne remontra pas venir Çcraser notre code.

Maintenant, nous allons essayer de trouver l'adresse d'un emplacement mÇmoire
ou on pourrait trouver une instruction de saut, qui pourrait sauter vers la
valeur d'un de ces registres. Nous allons commencer avec EAX, donc nous allons
essayer de trouver dans une des DLL chargÇes par WarFTP une instruction
"CALL EAX", qui soit Ö une adresse ne contenant pas de 00h.

Relancons Win32DASM. A partir de la ligne 663, nous avons la liste des
fonctions que WarFTP importe, donc la liste des fonctions qu'il appelle dans
des DLLs. Nous voyons par exemple qu'il appelle des fonctions de la DLL
MFC42.DLL .
Nous allons donc lancer avec Win32DASM le dÇsassemblage de MFC42.DLL.
Une fois le dÇsassemblage terminÇ, nous lancons dans le menu "Search" la
commande "Find Text", et nous spÇcifions comme texte "call eax".
Win32DASM nous indique la ligne 13057, Ö l'adresse 5F402C28.
Nous notons cette adresse sur un pti bout de papier ;))), puis nous
retournons dans UltraEdit, fichier EXPLOIT5.BIN et nous allons placer Ö la
place de 0DDDDDDh, les valeurs 28 2C 40 5F (dñ Ö l'inversion des bytes en
mÇmoire).
Nous modifions par la màme occasion les EEh en 90h, et nous remplacons juste
le 90h qui prÇcäde notre adresse de retour la valeur CCh.
Pourquoi ?
La valeur CCh reprÇsente l'instruction assembleur "INT 03", qui est une
exception, interdite dans un programme Windows normal. Donc, si nous lancons
WarFTP puis notre exploit, normalement nous allon avoir un message d'erreur
de Windows, qui prouvera que nous sommes bien en train d'exÇcuter le code
de notre buffer overflow.

Nous lancons WarFTP (plus besoin de le lancer sous Win32DASM), puis
nc 10.10.10.1 21 < exploit5.bin

Qu'est-ce que nous avons ?
Nous avons un message qui s'affiche dans NetCat, Invalid User Name !!!!
Cela veut dire qu'un des caractäres qui est utilisÇ dans notre adresse de
retour est reconnu comme invalide par WarFTP.

Nous allons aller chercher dans une autre librairie, qui sera situÇe Ö une
autre adresse en mÇmoire, apräs une autre instruction "CALL EAX".
Par exemple, dans MSVCRT.DLL, nous lancons la recherche, et nous trouvons:
780026B0  call eax
Nous continuons, jusqu'Ö ce que nous trouvions une instruction "CALL EAX",
dont l'adresse ne contienne pas de 00h et possäde des caractäres qui n'aient
pas l'air "bizarre".
Nous arrivons Ö l'adresse 780101DBh.

Nous rÇessayons donc, en codant cette adresse Ö la place de l'ancienne adresse
de retour ( DB 01 01 78 ). Nous rÇessayons, et nous un message d'erreur de
Windows, qui nous indique:
"WAR-FTPD a causÇ une exception 03H dans le module <inconnu> Ö 0000:00CCFD70."

Ca y est !
Donc, maintenant nous sommes certain que notre code est bien exÇcutÇ, puisque
Windows a dÇtectÇ l'appel de l'interruption 3h.
Si nous regardons plus en dÇtail, nous remarquons d'ailleurs que l'adresse
00CCFD70 est l'adresse du RET ! C'est logique, le processeur a exÇcutÇ notre
INT 03, puis il met Ö jour EIP, et enfin Windows provoque une erreur.
D'ailleurs, en regardant un peu plus bas dans la boåte de message de Windows,
nous trouvons:
"Octets Ö CS : EIP :
db 01 01 78 ff ff ff ff ff ff ff ff ff ff ff ..."
Donc c'est bien notre adresse que nous observons lÖ !

Maintenant, nous avons un petit probläme. En effet nous avons placÇ un INT 03,
et donc le processeur s'est arràtÇ juste avant d'exÇcuter les bytes suivants,
qui sont justement ceux de notre adresse !!! Nous allons donc recommencer, en
placant cette fois le CCh apräs l'adresse de retour. Nous verrons ainsi ce que
les instructions que reprÇsente notre adresse sont "dangereuses" ou pas.
Nous crÇons donc EXPLOIT6.BIN, avec le CCh apräs les bytes DB 01 01 78.
Cependant, nous rajoutons quelque 90h (NOP), avant le CCh. En effet, les 4
bytes qui codent notre adresse de retour reprÇsente des instructio, mais il
est fort possible que les instructions codÇes fasse plus de 4 bytes, et donc
que le processeur interpräte certains bytes derriäre comme les bytes de la fin
de l'instruction. En mettant 5 NOPs (90h), par exemple, nous sommes ainsi
certain que notre CCh ne fera pas partie d'une instruction prÇcÇdente et qu'il
codera bien un INT 3.

Qu'observons nous ? WarFTP plante toujours de la màme maniäre, mais maintenant
les Octets Ö CS : EIP ne contiennent plus notre adresse de retour.
C'est donc qu'elle a ÇtÇ interprÇtÇe comme une ou plusieurs instructions, qui
apparement sont sans danger pour nous...

Quelles sont les instructions qui pourraient àtre dangereuses ?
Ben il suffirait que notre adresse de retour code une instruction du style
jmp xxxx par exemple, et lÖ cela serait la catastrophe.
Cependant, il existe finalement assez peu d'instructions dangereuses:
les JUMP, CALL, PUSH, POP et c'est Ö peu präs tout...
Il est aussi important de noter que la valeur de EAX n'a pas ÇtÇ modifÇe par
cette instruction. En effet, nous allons nous resservir par la suite du EAX,
car il va nous aider Ö connaåtre plus ou moins l'adresse du buffer dans notre
exploit.
Dans un cas ou nous aurions eu une instruction qui foutait la merde, nous
aurions alors dñ faire prÇcÇder l'adresse de retour d'un JUMP qui sautait au
dessus (jump de +4 bytes). Cela est tout Ö fait faisable, mais inutile dans
ce cas-ci, mais c'est ptàt bon de le mentionner ;)

VoilÖ, donc maintenant, nous avons presque fait tout le boulot pour le buffer
overflow proprement dit. Nous avons smasher EIP, donc il exÇcute le code que
l'ont veut qu'il exÇcute ! N'est ce pas formidable ;)


UN EXPLOIT SOUS WINDOWS
=======================
Maintenant que nous pouvons exÇcuter le code que nous voulons, nous allons
essayer de programmer un petit exploit qui sera donc exÇcutÇ sur la machine
qui exÇcutait le serveur WarFTP. Jusqu'Ö prÇsent, la technique que nous avions
employÇe Çtait fort portable d'un systäme Ö un autre. Maintenant, Çtant donnÇ
que nous allons devoir faire appel Ö des fonctions du systäme pour programmer
l'exploit, nous allons nous concentrer un peu plus sur Windows.

Pour programmer l'exploit, il n'y a pas 36 solutions, il faut ressortir notre
bon vieil assembleur MASM32 ;)

Keskon va programmer comme exploit ? Ici on a l'embarras du choix.
D'habitude, on a envie de programmer quelque chose qui va nous permettre
d'accÇder au disque du serveur, d'y exÇcuter un programme, d'y charger
Çventuellement un fichier de mot de passe, etc...

Nous allons nous essayer de crÇer un exploit qui soit "portable", c'est Ö dire
qu'il pourra àtre exÇcutÇ sur une version quelconque (Windows 95/98), mais
aussi que nous pourrons reprendre son code en grande partie pour
Çventuellement l'utiliser dans un buffer overflow d'un autre programme.
Pour cela, nous allons donc programmer notre exploit complätement sur la pile.
Cela veut dire que nous allons devoir stocker les donnÇes dans le code màme,
et que nos variables elles-aussi devront àtre Ö des adresses dans le code.

Tout d'abord, la 1äre chose est de ne pas oublier que notre exploit ne doit
comporter aucun caractäre spÇcial. Pas de caractäre 00h, pas de caractäre 0Dh,
0Ah. Comme les APIs Windows nÇcessitent souvent le passage de constantes en
paramätres, constantes qui peuvent contenir des 00h, nous utiliserons donc
la commande assembleur NOT, qui permettra d'inverser la valeur juste au
moment de l'exÇcution, et donc d'Çviter les caractäres 00h dans le code.

2ämement, nous risquons aussi d'avoir des 00h dans le codage hexadÇcimal des
sauts relatifs. En effet, la valeur hexadÇcimale qui est codÇe est le nombre
de bytes Ö ajouter Ö l'EIP courant pour arriver Ö la nouvelle adresse.
Or quand on fait des sauts, on fait rarement des jump qui se dÇplacent de
6500000 octets. Ce sont plus souvent des sauts de quelques 10aines d'octets
au grand maximum. Donc nous risquons de voir apparaåtre des 00h dans le codage
de ces sauts. Pour l'Çviter, nous essayerons donc d'utiliser des Jx SHORT, qui
codent le dÇplacement du saut sur le moins d'octets possible.
Remarquons que dans le cas d'un saut "retour en arriäre", le dÇplacement est
nÇgatif, donc nous n'aurons pas de valeur 00h.

Voyons un peu comment appeler des fonctions systämes (APIs) sous Windows dans
notre exploit. Au dÇbut d'un fichier.EXE, par exemple de WAR-FTPD.EXE, on
trouve toutes les APIs qui sont importÇes par le programme. Ces APIs sont
importÇes dans une table, en mÇmoire (jump table), qui contient l'adresse
rÇelle de l'API. Cette table est gÇnÇrÇe au moment du chargement du programme,
et permet Ö l'API de se trouver Ö une adresse diffÇrente selon l'exÇcution,
selon la version du systäme,etc...
Cependant, les APIs que nous voulons Çventuellement utiliser dans notre
exploit ne sont pas forcÇment importÇes par le programme.
Windows met pourtant Ö notre disposition 2 fonctions, dans KERNEL32.DLL, qui
nous permettent de rÇaliser nous màme notre propre jump table.
Il s'agit des fonctions LoadLibraryA et GetProcAddress:
La fonction LoadLibrary recoit comme paramätre un pointeur sur la chaåne
contenant le nom de la DLL dans laquelle se trouve la fonction Ö importer, et
nous renvoie un Handle.
La fonction GetProcAddress recoit comme paramätres ce handle, et un pointeur
sur la chaåne contenant le nom de la fonction de la DLL.
Dans un programme exÇcutable, il est träs rare que ces 2 fonctions ne soient
pas importÇes. Donc, nous pouvons connaåtre l'adresse de ces 2 fonctions, et
les appeler pour charger d'autres fonctions et APIs que nous voulons utiliser.


OUTILS
======
Pour me faciliter la tÉche et faciliter la vìtre aussi, j'ai programmÇ un
petit fichier d'include pour MASM, qui va nous permettre de facilemment Çcrire
des exploits quelconques (EXPLOIT.INC).
Ce fichier se compose de 3 macros, appelables dans un code assembleur
classique.
Pourquoi des macros et pas des procÇdures ? Parce que des macros sont incluses
directemment au bon endroit dans le code, et qu'elles Çvitent donc d'utiliser
des instructions non nÇcessaires (PUSH,POP,CALL,RET,...), qui prennent des
bytes pour rien. On Çcrit ici un exploit qui doit àtre le plus petit possible,
pas un programme pour apprendre Ö faire de la programmation structurÇe ;)
Il y a 3 macros, mais 2 d'entre-elles sont complÇmentaires et doivent àtre
utilisÇes ensemble.
Voici comment utiliser les 2 premiäres:

DEBUTEXPLOIT:
 ExploitPrologue
 db "donnÇes",...
 ExploitEpilogue AddrLoadLibrary,AddrGetProcAddress,BytesVariables

Ou:
AddrLoadLibrary reprÇsente l'offset de la zone mÇmoire qui contient l'adresse
de l'API LoadLibrary.
AddrGetProcAddress reprÇsente l'offset de la zone mÇmoire qui contient
l'adresse de l'API GetProcAddress.
BytesVariables reprÇsente un nombre de bytes Ö rÇserver pour d'Çventuelles
variables (initialisÇes Ö 0).
Le format des donnÇes est le suivant:
Des chaånes de caractäres, suivie chaque fois d'un caractäre de contrìle:
255 indique la fin de la table de donnÇes
254 indique la fin d'un nom de librairie (qui va donc àtre chargÇe)
253 indique la fin d'un nom de fonction de la librairie courante
252 indique la fin d'une chaåne

Ces 2 macros vont donc balayer les donnÇes, et crÇer une table.
Cette table contiendra pour les fonctions, l'adresse de la fonction qui a
ÇtÇ chargÇe, et pour les chaåne, l'adresse de la chaåne.
Ces adresses seront accessibles via le registre ESI, en descendant.
L'adresse de la derniäre fonction ou chaåne sera en [ESI-4], l'avant derniäre
en [ESI-8],...
Ce codage est effectuÇ de maniäre nÇgative pour Çviter de nouveau d'avoir des
00h dans le codage hexadÇcimal.
Ensuite, si le paramätre BytesVariables est diffÇrent de 0, la macro va crÇer
autant de bytes initialisÇs Ö 0, accessibles via [EDI-1],[EDI-2],...

ATTENTION !!!
Pour Çconomiser de la place, la table d'adresses (ESI) et la table des
variables (EDI) sont crÇÇes par dessus la table des donnÇes. Pour les noms de
fonctions cela n'est pas important, puisque ceux-ci deviennent inutiles une
fois que l'on a l'adresse, par contre pour les chaånes, celles-ci ne doivent
pas àtre ÇcrasÇes, donc je vous conseille de les placer Ö la fin des donnÇes.

Il faut aussi chaque fois utiliser la macro ExploitPrologue, puis la procÇdure
ExploitEpilogue apräs, car la fin de la procÇdure ExploitPrologue contient un
jump vers le dÇbut de ExploitEpilogue, pour sauter au dessus des donnÇes.

La macro suivante, ExploitAlloc, vous permet de crÇer un espace pour les
variables sur le heap du programme. L'avantage est que vous disposez lÖ de
beaucoup plus de place pour crÇer des variables ou stocker des donnÇes,
l'inconvÇnient est qu'il faut quelques lignes de code en plus, et qu'il faut
avoir l'adresse d'une API particuliäre, l'API GlobalAlloc (plus ou moins
Çquivalente Ö un malloc en C).
On appelle donc la procÇdure ExploitAlloc comme ceci:
ExploitAlloc AddrGlobalAlloc,BytesVariables
ou:
AddrGlobalAlloc reprÇsente l'offset de la zone mÇmoire qui contient l'adresse
de l'API GlobalAlloc (prÇsente dans le programme, ou initialisÇe par les 2
macros prÇcÇdentes).
BytesVariables reprÇsente le nombre de bytes Ö rÇserver pour les variables
(initialisÇes Ö 0).
Apräs l'appel de cette macro, on accäde aux variables crÇÇes via [EBP-1],
[EBP-2],...

VoilÖ. Pour mieux comprendre ce qui se passe, je vous conseille de jeter un
petit coup d'oeil Ö ces macros, dans le fichier EXPLOIT.INC.
J'ai Çcrit ces macros en essayant d'optimiser le plus possible la taille du
code, ce qui fait que leur structure est peut-àtre un peu complexe, mais
rappelez vous qu'on a pas 1Mg de mÇmoire pour coder notre exploit ;)


L'EXPLOIT
=========
Au dÇbut, je voulai programmer un exploit qui active le partage de fichiers
NetBIOs de l'ordinateur sur lequel WarFTP Çtait exÇcutÇ. Pour rÇaliser cela,
j'allai Çcrire quelques informations dans la base des registres. Le probläme
Çtait que pour que ces informations soient validÇes, il fallait absolumment un
redÇmarrage du systäme sur la machine. Ce n'est pas träs compliquÇ Ö faire,
mais ce qui m'embàtait beaucoup est que dans le cas d'un IP dynamique, on perd
ainsi la trace de l'ordinateur dont on avait activÇ le partage de fichiers.
Finalement, j'ai programmÇ un autre exploit, qui ouvre un port TCP sur la
machine exÇcutant le serveur FTP, et qui attend une connection sur ce port.
Il nous suffit ensuite d'envoyer un fichier exÇcutable sur ce port (par
exemple un trojan ;), pour que celui-ci soit exÇcuter sur la machine distante.
Pour programmer cet exploit, j'ai utilisÇ les fonctions Winsock 1.1, assez
puissantes et pas trop compliquÇes Ö programmer en assembleur.

ATTENTION !!! Ne pas lancer EXPLOIT.EXE Ö la ligne de commande, sa conception
est assez particuliäre, vu qu'il n'y a pas de segment de donnÇes, pas de pile
(puisqu'il va s'exÇcuter sur la pile), et l'appel des fonctions APIs de
Windows est lui aussi particulier, donc cela ne ferait que planter votre
ordinateur...

L'exploit utilise les fonctions classique de Winsock version 1.1 (plus faciles
Ö utiliser que les fonctions de Winsock 2.2 etc...), et utilise les vieilles
fonctions de gestion de fichiers _lwrite, etc..., qui sont plus faciles Ö
utiliser aussi. Le nom du fichier Çcrit qui sera exÇcutÇ est le plus court
possible, et le port ouvert 4444, a ÇtÇ choisi pour àtre facile a retenir et
pour àtre un port qui est habituellement ouvrable sans probläme (màme derriäre
pas mal de firewalls).

Il est bon de remarquer que le fichier est chargÇ sur l'ordinateur distant,
ensuite il est exÇcutÇ, puis le process WarFTP est killÇ, pour Çviter
d'alerter la personne qui est sur la machine, ou pour Çviter un message
d'erreur de Windows (qui se produirait si le programme continerai Ö exÇcuter
des instructions codÇes par les bytes sur la pile).

Nous assemblons l'exploit (EXPLOIT.EXE), puis nous lancons Win32Dasm sur
EXPLOIT.EXE, pour aller voir ou commence le code de l'exploit dans le fichier
.EXE.
On remarque que le point d'entrÇe du programme est Ö l'offset 200h dans le
fichier EXPLOIT.EXE. Nous lancons donc UltraEdit, et nous allons Ö l'offset
200h du fichier EXPLOIT.EXE. En descendant un petit peu, nous observons un peu
plus bas une suite de 00h, qui indique vraissemblablement la fin de l'exploit.
Vous remarquez au passage que l'exploit est assez court, on peut àtre fier de
nous ! ;))) On y observe aussi les chaånes qui sont utilisÇes dans l'exploit
(noms de librairies, etc...). Il pourrait àtre intÇressant de crypter ces
chaånes, par un NOT, ou un XOR... Mais ici ce n'est pas trop important.
Maintenant, nous copions collons tout ces bytes dans EXPLOIT7.BIN, derriäre
les NOPs qui se trouvent apräs notre adresse de retour, et nous supprimons
tout les bytes FFh apräs, qui prennent de la place inutile.

Voici maintenant de maniäre pratique, comment utiliser l'exploit:
Nous trouvons un serveur WarFTP 1.65.
Nous lancons l'exploit avec NetCat, en tapant:

NETCAT -vv ip_du_serveur 21 <exploit7.bin

Une fois que le message de username correct apparaåt, on peut couper la
connection (CTRL-C).
Puis on envoie le fichier Ö exÇcuter sur la machine distante:

NETCAT -vv ip_du_serveur 4444 <trojan.exe

On attend ensuite que l'envoi soit terminÇ (regarder les lampiottes de votre
modem, ou attendez 5minutes pour àtre sñr ;)), puis on coupe NetCat (CTRL-C).
Et le tour est jouÇ ! :)))))))
Trojan.exe n'est pas un vrai trojan, c'est juste un programme qui affiche
une petite guirlande sur l'Çcran de la machine, et que j'ai utilisÇ pour faire
les tests, pas dpanik les gars ! :)))
Pour couper la guirlande au fait, vous allez dans la barre des applications,
partie droite (tray), et vous avez un petit truc rouge sur lequel vous
cliquez pour couper la belle guirlande :)))
Par contre, si vous voulez envoyer un trojan, rien ne vous en empàche :)))

VoilÖ j'espäre que vous avez bien compris le principe...
J'espäre aussi que vous allez nous coder pleins de beaux exploits hein ! :)))
Vous pourrez looker maintenant dans la rubrique Advisories sur la homepage
de IGA ou nous allons essayer de programmer d'autres buffer overflows :)
Bye bye,
                                                           Rix-Agressor-Shogun