Titre: Stack overflow sous Ubuntu 10.10 (noyau 2.6.35-22-generic) Posté par: Ge0 le 30 Novembre 2010 à 21:06:15 Salut,
Ce sujet a pour but d'éclaircir un point qui me titille dans l'exploitation d'un débordement de pile dans un programme lambda - prévu à cet usage - compilé sous un environnement comme cité dans le titre. On considère le programme suivant : Code: geo@ubuntu:~/C/vuln$ cat vuln.c On remarque que le programme va faire appel à la procédure copy, qui, elle-même, va faire appel à la fonction strcpy sans prudence... Le tableau de caractères "dest" étant limité. Je désactive l'option "ASLR" pour ne pas être perturbé par le secouement des adresses mémoires au niveau de la pile - elles sont différentes à chaque exécution. Un simple '0' à écrire dans /proc/sys/kernel/randomize_va_space fait l'affaire. Je compile mon programme avec la ligne de commande suivante : Code: geo@ubuntu:~/C/vuln$ gcc -o vuln vuln.c -fno-stack-protector -ggdb Cela me permettra d'ôter la protection de la pile que gcc insère pour éviter les débordements de tampons et l'option -ggdb facilite le débogage. Je débogue le programme sans tarder et je parviens vite à localiser la sauvegarde du pointeur d'instruction de main que je vais écraser par un pointeur sur mon shellcode. Je fais d'abord quelques manipulations préalables : Code: (gdb) disass copy Je lance avec mon schéma d'exploitation : Code: (gdb) r `perl -e 'print "a" x 140 . "\x40\xf3\xff\xbf" . "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80"'` C'est ce fameux signal SIGSEGV qui me stoppe. Mais voyons tout de même l'état des registres... Code: (gdb) x/i $eip Si ce fameux signal SIGSEGV n'intervenait pas, je réussirais théoriquement à exécuter mon shellcode. Comme vous pouvez le voir, l'instruction qui devrait s'exécuter est le "ret", qui a pour effet de dépiler la valeur au sommet de la pile d'exécution et de la placer dans le pointeur d'instructions. En l'occurrence, cette valeur est une adresse mémoire qui fait référence à mon shellcode. Donc je pense être bon. Je me suis dit qu'il fallait peut-être que je fasse attention à la sauvegarde du pointeur sur la base de la pile ainsi qu'à la valeur originale de mon argument unique ? Seul problème, l'adresse de la source de mes données (src) varie à chaque exécution du programme ; et même si j'arrive à la réecrire pour la faire pointer sur un espace mémoire qui existe, j'ai toujours un signal SIGSEGV. Un exemple : Code: (gdb) r `perl -e 'print "a" x 136 . "\x59\xf3\xff\xbf" . "\x44\xf5\xff\xbf" . "\xb0\xf5\xff\xbf" . "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80" . "\x44\xf5\xff\xbf"'` Le "\x59\xf3\xff\xbf" est la sauvegarde d'ebp et pointe sur le second "\x44\xf5\xff\xbf" - car il y en a deux et le premier était là au cas où - qui, lui-même, pointe sur mon shellcode. C'est une adresse mémoire accessible, et pourtant, ça ne marche pas. Peut-être que l'environnement d'exécution - si c'est correct à dire - détecte un écrasement des arguments passés à la fonction ? Je suis perdu... Si quelqu'un a la patience de m'aider, alors je lui en serai très reconnaissant car je reconnais que tout cela n'est pas une partie de plaisir et qu'il n'y a aucun intérêt véritable derrière si ce n'est comprendre pourquoi ça ne fonctionne pas. Merci d'avance. Titre: Re : Stack overflow sous Ubuntu 10.10 (noyau 2.6.35-22-generic) Posté par: Ge0 le 30 Novembre 2010 à 22:31:49 Bon, en fait, c'était une histoire de pile non-exécutable.
Les versions d'Ubuntu émulent, depuis 10.04, la présence du bit "NX" - Non eXecutable - qui interdit l'exécution de code dans des régions mémoires non appropriées telles que la pile, le tas, ... Ce bit est présent dans les processeurs récents et si tel est le cas, il se désactive dans le BIOS. Par contre, si vous n'avez pas cette fonctionnalité dans votre processeur, c'est que votre version d'Ubuntu l'émule. Pour cela, il suffit de charger le noyau avec l'option "noexec=off". Si vous avez grub, une petite modification de son fichier de configuration suffit. Problème résolu. ;) |