2012-03-03 4 views
3

J'ai simple programme C:Format vulnérabilité de chaîne

char user_input[100]; 
scanf("%s", user_input); 
printf(user_input); 

Je crois comprendre ce qui représente la vulnérabilité de la sécurité; par exemple. l'entrée d'un groupe de% x affichera le contenu de la pile. Mais comment peut-on imprimer un emplacement de mémoire choisi?

Je lis que:

\x10\x01\x48\x08_%08x.%08x.%08x.%08x.%08x|%s| 

Si le dumping contenu de la mémoire à l'emplacement 0x08480110 de this paper. Mais à la place, il imprime les 4 octets suivants à la chaîne de format de la pile. J'essaie de comprendre pourquoi.

+6

Il s'agit d'une question de forêt d'arbres, entrez plus de 99 caractères pour invoquer un débordement de tampon. L'histoire de Little Bobby Tables de ne pas désinfecter les entrées. –

Répondre

1

La chaîne de format elle-même sera sur la pile (comme vous l'avez déclaré user_input en tant que variable locale). Donc, si vous marchez assez loin dans la pile (ce que fait la force printf), alors vous arriverez au début de la chaîne de format. %s indique à printf de lire une adresse de la pile, puis d'imprimer la chaîne trouvée à cet emplacement. Il lit donc les 4 premiers octets de la chaîne de format et les utilise comme adresse.

Bien sûr, pour que cela fonctionne, vous devez savoir exactement jusqu'où lire la pile pour atteindre la chaîne de format. Donc, vous devrez peut-être ajuster le nombre de %08x.

En outre, un utilisateur entrant \x10 au moment de l'exécution n'est pas la même que celle d'une chaîne de caractères dans votre code source contenant \x10 ...

+0

Est-ce que la chaîne de format n'est pas plus faible en mémoire que user_input? De plus, je comprends que% x "marche sur la pile", est-il possible de ne pas imprimer tout le contenu de la pile, c'est-à-dire de parcourir la pile jusqu'à la chaîne de format qui utilisera les 4 premiers octets adresse il doit lire de la pile, mais, sans imprimer tout entre les deux? –

+0

@Pi_: Cela dépend. Sur x86, la pile se développe généralement vers le bas (donc la trame de la pile 'printf' sera à une adresse inférieure à celle de la pile de l'appelant). –

+0

NOTE: J'ai trouvé que l'entrée "% n $ x" où n est un nombre entier passe par les premières itérations n-1 sans imprimer le résultat (c'est-à-dire que les itérations n-1 passent directement à l'itération n) –