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

Recoucou tous !
Hehe. Vous commencez  en avoir marre des buffer overflows hein ! ;)))
Aprs l'article de __2, qui expliquait le principe de base du smashing stack,
puis aprs mon article prcdent 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, aprs un programme relativement connu et rcent, 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 dtail 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 hexadcimal: UltraEdit (http://www.idmcomp.com),
Un debugger-dsassembleur: Win32dASM
Un assembleur 386-Windows: MASM32
Et enfin, un outil formidable dont j'ai dj parl dans un article,  savoir
NetCat, un programme de gestion de sockets TCP/IP provenant de Unix, trs
puissant et trs facile d'emploi (http://www.l0pht.com/~weld/netcat).
N'oubliez pas aussi de relire un petit peu les 2 articles prcdents si c'est
loin dans votre mmoire 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 mme, ca va tre un
peu plus facile pour que vous compreniez ski va spasser :)

Alors l'exploit dans War FTP est assez bte, 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 1res
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 cre
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 dfaut utilis par WarFTP)
Voici le rsultat:
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 recrer un petit fichier EXPLOIT2.BIN en faisant un buffer overflow.
Recrons un 2me 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 caractres, on devrait bien faire un buffer
overflow. Lancons:  nc 10.10.10.1 21 < exploit2.bin
Ds qu'on coupe NetCat (CTRL-C), Windows rame un petit peu, puis on a un beau
message d'erreur "Ce programme va tre arrt car il a effectu une opration
non conforme".
Donc pas de doute, il y a bien un problme 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 dsassembler 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 rcupre de la pile via le RET critique. C'est  cet endroit que nous
devrons en effet par la suite analyser l'excution et mettre une adresse EIP
qui permettra l'excution de notre exploit.

Une fois le dsassemblage termin (menu "Disassembler", commande "Open file
to disassemble..."), on va donc dans le menu "Refs", commande
"String Data References". Nous allons chercher aprs la chane
"User name okay", qui est affiche lorsque le username  bien t recu par le
serveur. En effet, c'est probablement aprs l'utilisation de cette chane 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 fentre, puis nous relancons notre nc 10.10.10.1 21 < exploit2.bin
Nous excutons ensuite pas  pas, en pressant sur F8, jusqu' ce que nous
atteignons la fin de la procdure (structure classique: probablement plusieurs
POP suivi d'un RET), car c'est l que doit se passer le problme.

Nous arrivons ainsi  un RET  l'adresse 004232D0.
Nous allons continuer le pas  pas dans le programme, jusqu'au RET qui va
essayer d'excuter le saut vers l'adresse que nous avons overwrit dans la
pile. Pour plus de facilit, nous allons recommencer, en rcrivant un
EXPLOIT3.BIN, avec comme username des caractres 0FFh, comme ca nous saurons
que le RET qui sera tre excut sera un saut vers l'adresse 0FFFFFFFFh, qui
est un saut interdit par le systme (hors des adresses accessibles par le
programme), et nous aurons donc plus facile pour reprer 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 aprs 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 prcdant 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 aprs
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 crer un buffer overflow avec des caractres 0FFh, qui
provoquent bien un saut vers l'adresse 0FFFFFFFFh. Nous allons donc maintenant
essayer de dterminer exactement l'endroit dans notre chane ou se trouve
l'adresse de retour, de manire  pouvoir aller y placer une adresse de retour
vers notre exploit :)))

Pour cela, nous allons procder de la manire suivante: nous allons crer une
chane de username dans EXPLOIT4.BIN de la forme suivante:
EEEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, et lancer
l'excution 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 caractres 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 (caractres 0FFh), et nous allons donc
 augmenter le nombre de caractres 0EEh, pour essayer de monter dans la pile.

Nous allons procder comme ca plusieurs fois, en modifier le nombre de 0EEh,
jusqu' ce que nous sautions  une adresse compose de 0EEh et de 0FFh, ce qui
voudra dire que l'on est vraiment tout prs de l'endroit recherch !
Allons-y: mettons des 0EEh jusqu' l'offset 4FFh (avec UltraEdit).
Nous supprimons aussi les breakpoints, et lancons l'excution de WarFTP,
ensuite nous lancons l'excution 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 reprsenterait 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 derrire. 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 dbut 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 aprs l'excution 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 problme: il ne sera pas ajouter dans le buffer,
et donc tout semble  refaire ! :((((((

Pour contourner ce problme, nous allons analyser la valeur des registres lors
de l'excution du RET, et observer ceux d'entre eux, qui pointent vers des
adresses trs proches de ESP (adresse de la pile). En effet, nous pourrions
alors essayer de procder 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" code dans une DLL
charge 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'excutera et
ressautera lui vers l'offset EDX, qui sera le plus prs possible de notre
buffer.

Nous relancons donc WarFTP, en ractivant le breakpoint  l'adresse 
004219D7  RET 00000004,
et nous allons noter les registres ventuels qui sont proches de notre buffer.
Ds 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 possdant des valeurs "intressantes":
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 dpent peut-tre d'une
excution  une autre. Nous allons donc essayer de modifier notre buffer
overflow pour que mme si la valeur du registre soit lgrement modifie, elle
n'empche pas pour autant le saut. Nous allons donc placer comme instructions
dans les bytes prcdant notre valeur de retour toute une srie de NOPs (90h)
,  la place des 0EEh que nous avions tantt. Et nous placerons le code 
excuter aprs notre adresse de retour. Cela ne pose pas un grand problme.
C'est peut-tre mme plus pratique, car nous disposerons ainsi de plus de
mmoire pour notre code assembleur, et nous pourrons aussi empiler sans
problmes 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 mmoire
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 charges 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 dsassemblage de MFC42.DLL.
Une fois le dsassemblage termin, nous lancons dans le menu "Search" la
commande "Find Text", et nous spcifions 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
mmoire).
Nous modifions par la mme occasion les EEh en 90h, et nous remplacons juste
le 90h qui prcde notre adresse de retour la valeur CCh.
Pourquoi ?
La valeur CCh reprsente 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'excuter 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 caractres qui est utilis dans notre adresse de
retour est reconnu comme invalide par WarFTP.

Nous allons aller chercher dans une autre librairie, qui sera situe  une
autre adresse en mmoire, aprs 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 possde des caractres qui n'aient
pas l'air "bizarre".
Nous arrivons  l'adresse 780101DBh.

Nous ressayons donc, en codant cette adresse  la place de l'ancienne adresse
de retour ( DB 01 01 78 ). Nous ressayons, 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 excut, puisque
Windows a dtect l'appel de l'interruption 3h.
Si nous regardons plus en dtail, nous remarquons d'ailleurs que l'adresse
00CCFD70 est l'adresse du RET ! C'est logique, le processeur a excut notre
INT 03, puis il met  jour EIP, et enfin Windows provoque une erreur.
D'ailleurs, en regardant un peu plus bas dans la bote 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 problme. En effet nous avons plac un INT 03,
et donc le processeur s'est arrt juste avant d'excuter les bytes suivants,
qui sont justement ceux de notre adresse !!! Nous allons donc recommencer, en
placant cette fois le CCh aprs l'adresse de retour. Nous verrons ainsi ce que
les instructions que reprsente notre adresse sont "dangereuses" ou pas.
Nous crons donc EXPLOIT6.BIN, avec le CCh aprs 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 reprsente des instructio, mais il
est fort possible que les instructions codes fasse plus de 4 bytes, et donc
que le processeur interprte certains bytes derrire 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 prcdente et qu'il
codera bien un INT 3.

Qu'observons nous ? WarFTP plante toujours de la mme manire, mais maintenant
les Octets  CS : EIP ne contiennent plus notre adresse de retour.
C'est donc qu'elle a t interprte 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 prs tout...
Il est aussi important de noter que la valeur de EAX n'a pas t modife par
cette instruction. En effet, nous allons nous resservir par la suite du EAX,
car il va nous aider  connatre 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 prcder 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 ptt 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 excute le code que
l'ont veut qu'il excute ! N'est ce pas formidable ;)


UN EXPLOIT SOUS WINDOWS
=======================
Maintenant que nous pouvons excuter le code que nous voulons, nous allons
essayer de programmer un petit exploit qui sera donc excut sur la machine
qui excutait le serveur WarFTP. Jusqu' prsent, la technique que nous avions
employe tait fort portable d'un systme  un autre. Maintenant, tant donn
que nous allons devoir faire appel  des fonctions du systme 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'accder au disque du serveur, d'y excuter un programme, d'y charger
ventuellement un fichier de mot de passe, etc...

Nous allons nous essayer de crer un exploit qui soit "portable", c'est  dire
qu'il pourra tre excut 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 compltement sur la pile.
Cela veut dire que nous allons devoir stocker les donnes dans le code mme,
et que nos variables elles-aussi devront tre  des adresses dans le code.

Tout d'abord, la 1re chose est de ne pas oublier que notre exploit ne doit
comporter aucun caractre spcial. Pas de caractre 00h, pas de caractre 0Dh,
0Ah. Comme les APIs Windows ncessitent souvent le passage de constantes en
paramtres, constantes qui peuvent contenir des 00h, nous utiliserons donc
la commande assembleur NOT, qui permettra d'inverser la valeur juste au
moment de l'excution, et donc d'viter les caractres 00h dans le code.

2mement, nous risquons aussi d'avoir des 00h dans le codage hexadcimal des
sauts relatifs. En effet, la valeur hexadcimale qui est code 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 dplacent de
6500000 octets. Ce sont plus souvent des sauts de quelques 10aines d'octets
au grand maximum. Donc nous risquons de voir apparatre des 00h dans le codage
de ces sauts. Pour l'viter, nous essayerons donc d'utiliser des Jx SHORT, qui
codent le dplacement du saut sur le moins d'octets possible.
Remarquons que dans le cas d'un saut "retour en arrire", le dplacement est
ngatif, donc nous n'aurons pas de valeur 00h.

Voyons un peu comment appeler des fonctions systmes (APIs) sous Windows dans
notre exploit. Au dbut d'un fichier.EXE, par exemple de WAR-FTPD.EXE, on
trouve toutes les APIs qui sont importes par le programme. Ces APIs sont
importes dans une table, en mmoire (jump table), qui contient l'adresse
relle de l'API. Cette table est gnre au moment du chargement du programme,
et permet  l'API de se trouver  une adresse diffrente selon l'excution,
selon la version du systme,etc...
Cependant, les APIs que nous voulons ventuellement utiliser dans notre
exploit ne sont pas forcment importes par le programme.
Windows met pourtant  notre disposition 2 fonctions, dans KERNEL32.DLL, qui
nous permettent de raliser nous mme notre propre jump table.
Il s'agit des fonctions LoadLibraryA et GetProcAddress:
La fonction LoadLibrary recoit comme paramtre un pointeur sur la chane
contenant le nom de la DLL dans laquelle se trouve la fonction  importer, et
nous renvoie un Handle.
La fonction GetProcAddress recoit comme paramtres ce handle, et un pointeur
sur la chane contenant le nom de la fonction de la DLL.
Dans un programme excutable, il est trs rare que ces 2 fonctions ne soient
pas importes. Donc, nous pouvons connatre 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 tche et faciliter la vtre 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 procdures ? Parce que des macros sont incluses
directemment au bon endroit dans le code, et qu'elles vitent donc d'utiliser
des instructions non ncessaires (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 structure ;)
Il y a 3 macros, mais 2 d'entre-elles sont complmentaires et doivent tre
utilises ensemble.
Voici comment utiliser les 2 premires:

DEBUTEXPLOIT:
 ExploitPrologue
 db "donnes",...
 ExploitEpilogue AddrLoadLibrary,AddrGetProcAddress,BytesVariables

Ou:
AddrLoadLibrary reprsente l'offset de la zone mmoire qui contient l'adresse
de l'API LoadLibrary.
AddrGetProcAddress reprsente l'offset de la zone mmoire qui contient
l'adresse de l'API GetProcAddress.
BytesVariables reprsente un nombre de bytes  rserver pour d'ventuelles
variables (initialises  0).
Le format des donnes est le suivant:
Des chanes de caractres, suivie chaque fois d'un caractre de contrle:
255 indique la fin de la table de donnes
254 indique la fin d'un nom de librairie (qui va donc tre charge)
253 indique la fin d'un nom de fonction de la librairie courante
252 indique la fin d'une chane

Ces 2 macros vont donc balayer les donnes, et crer une table.
Cette table contiendra pour les fonctions, l'adresse de la fonction qui a
t charge, et pour les chane, l'adresse de la chane.
Ces adresses seront accessibles via le registre ESI, en descendant.
L'adresse de la dernire fonction ou chane sera en [ESI-4], l'avant dernire
en [ESI-8],...
Ce codage est effectu de manire ngative pour viter de nouveau d'avoir des
00h dans le codage hexadcimal.
Ensuite, si le paramtre BytesVariables est diffrent de 0, la macro va crer
autant de bytes initialiss  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 cres par dessus la table des donnes. 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 chanes, celles-ci ne doivent
pas tre crases, donc je vous conseille de les placer  la fin des donnes.

Il faut aussi chaque fois utiliser la macro ExploitPrologue, puis la procdure
ExploitEpilogue aprs, car la fin de la procdure ExploitPrologue contient un
jump vers le dbut de ExploitEpilogue, pour sauter au dessus des donnes.

La macro suivante, ExploitAlloc, vous permet de crer un espace pour les
variables sur le heap du programme. L'avantage est que vous disposez l de
beaucoup plus de place pour crer des variables ou stocker des donnes,
l'inconvnient est qu'il faut quelques lignes de code en plus, et qu'il faut
avoir l'adresse d'une API particulire, l'API GlobalAlloc (plus ou moins
quivalente  un malloc en C).
On appelle donc la procdure ExploitAlloc comme ceci:
ExploitAlloc AddrGlobalAlloc,BytesVariables
ou:
AddrGlobalAlloc reprsente l'offset de la zone mmoire qui contient l'adresse
de l'API GlobalAlloc (prsente dans le programme, ou initialise par les 2
macros prcdentes).
BytesVariables reprsente le nombre de bytes  rserver pour les variables
(initialises  0).
Aprs l'appel de cette macro, on accde aux variables cres 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 mmoire pour coder notre exploit ;)


L'EXPLOIT
=========
Au dbut, je voulai programmer un exploit qui active le partage de fichiers
NetBIOs de l'ordinateur sur lequel WarFTP tait excut. Pour raliser cela,
j'allai crire quelques informations dans la base des registres. Le problme
tait que pour que ces informations soient valides, il fallait absolumment un
redmarrage du systme sur la machine. Ce n'est pas trs compliqu  faire,
mais ce qui m'embtait 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 excutant le serveur FTP, et qui attend une connection sur ce port.
Il nous suffit ensuite d'envoyer un fichier excutable sur ce port (par
exemple un trojan ;), pour que celui-ci soit excuter sur la machine distante.
Pour programmer cet exploit, j'ai utilis les fonctions Winsock 1.1, assez
puissantes et pas trop compliques  programmer en assembleur.

ATTENTION !!! Ne pas lancer EXPLOIT.EXE  la ligne de commande, sa conception
est assez particulire, vu qu'il n'y a pas de segment de donnes, pas de pile
(puisqu'il va s'excuter 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 excut 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 problme (mme derrire
pas mal de firewalls).

Il est bon de remarquer que le fichier est charg sur l'ordinateur distant,
ensuite il est excut, 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  excuter
des instructions codes 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'entre 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 chanes qui sont utilises dans l'exploit
(noms de librairies, etc...). Il pourrait tre intressant de crypter ces
chanes, par un NOT, ou un XOR... Mais ici ce n'est pas trop important.
Maintenant, nous copions collons tout ces bytes dans EXPLOIT7.BIN, derrire
les NOPs qui se trouvent aprs notre adresse de retour, et nous supprimons
tout les bytes FFh aprs, qui prennent de la place inutile.

Voici maintenant de manire 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 apparat, on peut couper la
connection (CTRL-C).
Puis on envoie le fichier  excuter 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 sr ;)), 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 empche :)))

Voil j'espre que vous avez bien compris le principe...
J'espre 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
