2008-12-30 11 views
3

Qu'est-ce qu'une «vulnérabilité de format de chaîne» dans un système Windows, comment cela fonctionne-t-il et comment puis-je me protéger contre cette vulnérabilité?Protection contre la vulnérabilité de format de chaîne

+0

Eh bien, savoir attaquer aide à savoir comment défendre/éviter la vulnérabilité. C'est l'idée de divulguer publiquement de telles vulnérabilités/exploits. – PhiLho

+0

Assez juste, peut-être que j'ai mal lu le ton de la question, merci à ctacke pour l'éditer.J'ai posté une réponse en supposant que cela mérite le bénéfice du doute. –

+0

J'ai édité la question, donc c'est maintenant vraiment demander la même information, mais dans un langage qui est plus approprié et convivial. Je ne suis pas certain de l'intention de l'auteur original, mais si ce n'est pas ce à quoi je l'ai changé, il était destiné à être supprimé de toute façon. – ctacke

Répondre

2

Dans ce code pseudo l'utilisateur entre des caractères à imprimer, comme « bonjour »

string s=getUserInput(); 
write(s) 

Cela fonctionne comme prévu. Mais puisque l'écriture peut mettre en forme des chaînes, par exemple

int i=getUnits(); 
write("%02d units",i); 

sorties: "03 unités". Qu'en est-il si l'utilisateur en premier lieu a écrit "% 02d" ... puisqu'il n'y a pas de paramètres sur la pile, quelque chose d'autre sera récupéré. Qu'est-ce que c'est, et si cela est un problème ou non dépend du programme.

Une solution facile est de dire le programme de sortie une chaîne:

write("%s",s); 

ou utiliser une autre méthode qui ne tentez pas de formater la chaîne:

output(s); 

un link wikipedia avec Plus d'informations.

4

Une attaque de chaîne de format, à sa plus simple, est la suivante:

char buffer[128]; 
gets(buffer); 
printf(buffer); 

Il y a une vulnérabilité de dépassement de mémoire tampon là aussi, mais le point est ceci: vous transmettre des données non fiables (de l'utilisateur) à printf (ou l'un de ses cousins) qui utilise cet argument comme une chaîne de format. C'est-à-dire: si l'utilisateur tape "% s", vous avez une vulnérabilité de divulgation d'informations, car printf traitera l'entrée de l'utilisateur comme une chaîne de format, et tentera d'imprimer la chose suivante sur la pile comme une chaîne. C'est comme si votre code disait printf("%s");. Puisque vous n'avez pas passé d'autres arguments à printf, cela affichera quelque chose d'arbitraire. Si l'utilisateur tape "% n", vous avez une potentielle élévation d'attaque de privilège (au moins une attaque par déni de service), car la chaîne de formatage% 0 fait printf écrire le nombre de caractères imprimés de façon à ce que loin à l'emplacement suivant sur la pile. Puisque vous ne lui avez pas donné une place pour mettre cette valeur, il écrira quelque part arbitrairement.

Tout cela est mauvais, et c'est une des raisons pour lesquelles vous devriez être extrêmement prudent lorsque vous utilisez printf et les cousins.

Ce que vous devez faire est la suivante:

printf("%s", buffer); 

Cela signifie que l'on n'a jamais traité l'entrée de l'utilisateur en tant que chaîne de format, de sorte que vous êtes en sécurité de ce vecteur d'attaque particulière.

En Visual C++, vous pouvez utiliser l'annotation __Format_string pour lui demander de valider les arguments à printf. %n n'est pas autorisé par défaut. Dans GCC, vous pouvez utiliser __attribute__(__printf__) pour la même chose.

Questions connexes