Problèmes De Corde De Format


  Share  
|


Les problèmes de corde de format sont l'une des quelques attaques véritablement nouvelles à apprêter ces dernières années. Une des premières mentions des bogues de corde de format avait lieu juin 23, 2000, dans un poteau par Lamagra Argamal (www.securityfocus.com/archive/1/66842) ; Le Pascal Bouchareine plus clair les a expliqués presque un mois plus tard (www.securityfocus.com/archive/1/70552). Un poteau plus tôt par Mark Slemko (www.securityfocus.com/archive/1/10383) a noté les fondations du problème, mais a manqué la capacité des bogues de corde de format d'écrire la mémoire.

Comme pour beaucoup de problèmes de sécurité, la cause de racine des bogues de corde de format fait confiance à l'entrée écrite par l'utilisateur sans validation. Dans C/C++, des bogues de corde de format peuvent être employés pour écrire aux endroits de mémoire arbitraires, et l'aspect le plus dangereux est que ceci peut se produire sans trifouiller les blocs contigus de mémoire. Ces possibilités à grain fin permettent à un attaquant de dévier des protections de pile, et modifient même les parties très petites de la mémoire. Le problème peut également se produire quand les cordes de format sont lues de l'untrusted l'endroit que l'attaquant commande. Ce dernier aspect du problème tend à être plus répandu sur des systèmes d'UNIX et de Linux. Sur des systèmes de Windows, des tables de corde d'application sont généralement gardées dans le programme exécutable, ou les bibliothèques de lien dynamiques de ressource (DLLs). Si un attaquant peut récrire l'exécutable principal ou la ressource DLLs, l'attaquant peut effectuer beaucoup plus d'attaques franches que des bogues de corde de format.

Même si vous’au sujet de ne pas traiter C/C++, attaques de corde de format pouvez encore mener aux problèmes considérables. Le plus évident est que des utilisateurs peuvent être trompés, mais dans certaines conditions, un attaquant pourrait également lancer des attaques scripting d'croix-emplacement ou d'injection de SQL. Celles-ci peuvent être employées pour corrompre ou transformer des données aussi bien.

Langues Affectées

La langue le plus fortement affectée est C/C++. Une attaque réussie peut mener immédiatement à l'exécution du code arbitraire, et à la révélation de l'information. L'autre t gagné’par langues permettent typiquement l'exécution du code arbitraire, mais d'autres types d'attaques sont possibles comme nous notons précédemment. L'isn t’de Perl directement vulnérable aux spécificateurs donné par l'entrée d'utilisateur, mais lui pourrait être vulnérables si les cordes de format sont lues dedans des données trifouillées.

Le Péché Expliqué

Les données de formatage pour l'affichage ou le stockage peuvent être quelque peu des difficiles chargent. Ainsi, beaucoup de langages de programmation incluent des routines pour restructurer facilement des données. Dans la plupart des langues, l'information de formatage est décrite en utilisant une certaine sorte d'une corde, appelée la corde de format. La corde de format est définie réellement en utilisant la langue informatique limitée que’s a conçu pour la rendre facile de décrire des formats de rendement. Mais beaucoup de réalisateurs font une erreur facile qu'—ils emploient des données de untrusted des utilisateurs comme corde de format. En conséquence, les attaquants peuvent écrire des cordes dans la langue informatique pour poser beaucoup de problèmes.

La conception de C/C++ fait ce particulièrement dangereux : La conception’de C/C++ s le rend plus dur pour détecter des problèmes de corde de format, et les cordes de format incluent quelques commandes particulièrement dangereuses (en particulier %n) qui n'existent pas dans quelques autres langues’ de corde de format de langues.

Dans C/C++, une fonction peut être déclarée pour prendre un nombre variable d'arguments en indiquant des points de suspension (…) comme dernier (ou seulement) argument. Le problème est que la fonction s'appelant n'a aucune manière de savoir juste combien d'arguments sont passés dedans. L'ensemble de fonctions le plus commun pour prendre des arguments de longueur variable est la famille de printf : printf, sprintf, snprintf, fprintf, vprintf, et ainsi de suite. Les fonctions larges de caractère qui exécutent la même fonction ont le même problème. Laissez’la prise de s un regard à une illustration :

# incluez < stdio.h >

argc de main(int, char internes * argv[ ])
{
if(argc > 1)
printf(argv[1 ]) ;

retour 0 ;
}

Substance assez simple. Laissez maintenant’s regarder ce qui peut tourner mal. Le programmeur s'attend à ce que l'utilisateur écrive quelque chose de bénin, comme bonjour le monde. Si vous lui donnez un essai, vous’ll récupérez bonjour le monde. Laissez maintenant’le changement de s l'entrée—l'essai %x %x. Sur un système de Windows.xp en utilisant la ligne de commande de défaut (cmd.exe), vous’ll obtenez maintenant ce qui suit :

E:\projects\19_sins\format_bug>format_bug.exe "%x %x"
12ffc0 4011e5

Notez que si vous’au sujet d'exploiter un logiciel d'exploitation différent, ou employez une ligne de commande différente interprète, vous pouvez devoir faire quelques changements pour obtenir cette corde exacte introduite dans votre programme, et les résultats seront probablement différents. Pour la facilité d'utilisation, vous pourriez mettre les arguments dans un manuscrit de coquille ou un fichier séquentiel.

Que s'est produit ? La fonction de printf a pris une corde d'entrée qui l'a faite s'attendre à ce que deux arguments poussent sur la pile avant d'appeler la fonction. Les spécificateurs de %x vous ont permis de lire la pile, quatre bytes à la fois, jusque vous’d comme. Il isn’t dur pour imaginer que si vous aviez une fonction plus complexe qui a stocké un secret dans une variable de pile, l'attaquant pourrait alors lire le secret. Le rendement ici est l'adresse de l'endroit de pile (0x12ffc0), suivie de l'endroit de code dans lequel la fonction de main() retournera. Comme vous pouvez imaginer, tous les deux sont les informations extrêmement importantes qui sont fuies à un attaquant.

Vous pouvez maintenant vous demander juste comment l'attaquant emploie un bogue de corde de format pour écrire la mémoire. Un des moindres spécificateurs utilisés de format est %n, qui écrit le nombre de caractères qui devraient avoir été écrits jusqu'ici dans l'adresse de la variable que vous avez donnée comme argument correspondant. Ici’s comment il devrait être employé :

bytes internes non signés ;
printf("%s%n\n", argv[1 ], &bytes) ;
l'entrée de printf("Your était long\n, bytes de caractères de %d") ;

Le rendement serait :

E:\projects\19_sins\format_bug>format_bug2.exe une "certaine entrée aléatoire"

Une certaine entrée aléatoire

Votre entrée était 17 caractères longs

Sur une plateforme avec des nombres entiers de quatre octets, le spécificateur de %n écrira quatre bytes immédiatement, et %hn écrira deux bytes. Maintenant les attaquants seulement doivent figurer hors de la façon les obtenir à l'adresse’d comme en la position appropriée dans la pile, et tordent les spécificateurs de largeur de champ jusqu'à ce que soit le nombre de bytes écrits ce qu'elles’d aiment.

Pour maintenant, laissez’s juste supposer que si vous permettez à des attaquants de commander la corde de format dans un programme de C/C++, c'est une question de temps avant qu'ils figurent hors de la façon vous inciter à courir leur code. Un aspect particulièrement méchant de ce type d'attaque est celui avant de lancer l'attaque, ils peuvent sonder la pile et corriger l'attaque en marche. En fait, la première fois que l'auteur a démontré cette attaque l'en public, il a employé une ligne de commande différente interprète que lui’d employé pour créer la démonstration, et elle travail’du didn t. En raison de la flexibilité unique de cette attaque, il était possible de corriger le problème et d'exploiter l'application d'échantillon avec l'observation d'assistances.

La plupart des autres langues mettent’l'appui de t l'équivalent d'un spécificateur de format de %n, et elles aren’t directement vulnérable à l'exécution facile du code attaquant-fourni, mais vous pouvez course immobile dans des problèmes. Il y a autre, des variantes plus complexes sur ceci attaque que d'autres langues sont vulnérables à. Si les attaquants peuvent indiquer une corde de format pour le rendement à un dossier ou à une base de données de notation, ils peuvent causer les notations incorrectes ou fallacieuses. En plus, l'application lisant les notations peut considérer elles entrée de confiance, et une fois que cette prétention est violée, des faiblesses du fait l'analyseur’de l'application s peut mener à l'exécution du code arbitraire. Un problème relatif inclut des caractères de commande dans des dossiers de notation que—des espacements arrière peuvent être employés pour effacer des choses ; rayez les terminateurs peut assombrir ou même éliminer les traces’de l'attaquant s.

Ceci devrait aller de soi, mais si un attaquant peut indiquer la corde de format alimentée au scanf ou aux fonctions semblables, le désastre est sur le chemin.

C/C++ pécheur

À la différence de beaucoup d'autres pailles il examine’, celui-ci est assez facile nous repèrer ll comme défaut de code. Il’s très simple :

printf(user_input) ;
est faux, et

printf("%s", user_input) ;
est correct.

Une variante sur le problème que la négligence de beaucoup de programmeurs est qu'il n'est pas suffisant de faire ceci correctement seulement une fois. Il y a un certain nombre de constructions communes de code où vous pourriez employer le sprintf pour placer une corde composée dans un amortisseur, et puis glisse vers le haut et fait ceci :

fprintf(STDOUT, err_msg) ;
L'attaquant alors seulement doit ouvrer l'entrée de sorte que les spécificateurs de format soient échappés, et dans la plupart des cas, c'est une version beaucoup plus facilement exploitée parce que l'amortisseur d'err_msg fréquemment sera assigné sur la pile. Une fois que les attaquants parviennent à marcher support la pile, ils’ll puissent commander l'endroit qui est écrit en utilisant l'entrée d'utilisateur.

Péchés Relatifs

Bien que l'attaque la plus évidente soit liée à un défaut de code, il est dans des habitudes courants de mettre des cordes d'application dans les dossiers externes pour l'internationalisation. Si votre application a sinned par ne protège pas le dossier correctement, alors un attaquant peut fournir des cordes de format en raison d'un manque d'accès approprié de dossier.

Un autre péché relatif ne valide pas correctement l'entrée d'utilisateur. Sur quelques systèmes, une variable d'environnement indique l'information de lieu, et le lieu, alternativement, détermine l'annuaire où des dossiers spécifiques à une langue seront trouvés. Sur quelques systèmes, l'attaquant pourrait même faire regarder l'application dans les annuaires arbitraires.

Repèrer le modèle de péché

N'importe quelle application qui prend l'utilisateur entrent et passages il à une fonction de formatage est potentiellement en danger. Un exemple très commun de ce péché se produit en même temps que les applications qui notent l'entrée d'utilisateur. En plus, quelques fonctions peuvent mettre en application la composition intérieurement.

Repèrer le péché pendant la revue de code

Dans C/C++, recherchez les fonctions de la famille de printf. Les problèmes à rechercher sont

printf(user_input) ;  
fprintf(STDOUT, user_input) ;

Si vous voyez une fonction qui ressemble à ceci :

fprintf(STDOUT, msg_format, arg1, arg2) ;

puis vous le besoin de vérifier où la corde référencée par le msg_format est stockée et à quel point il est protégé.

Il y a beaucoup d'autres appels de système et APIs qui sont également sgf—vulnérable est un exemple. Quand vous voyez une définition de fonction qui inclut … dans la liste d'argument, vous’au sujet de regarder quelque chose qui est susceptible d'être un problème.

Beaucoup de modules de balayage de code source, même les lexicologiques aiment des RATS et le flawfinder, peut détecter ceci. Là’s PScan égal (www.striker.ottawa.on.ca/~aland/pscan/), qui a été conçu spécifiquement pour ceci.

Là parent également les outils qui peuvent être construits dans le processus de compilation. Par exemple, là’s Crispin Cowan’s FormatGuard : http://lists.nas.nasa.gov/archives/ext/linux-security-audit/2001/05/msg00030.html

Méthodes d'essai pour trouver le péché

Passez les spécificateurs de formatage dans l'application et voyez si des valeurs hexadécimales sont retournées. Par exemple, si vous avez une application qui s'attend à un nom de fichier et renvoie un message d'erreur contenant l'entrée quand le dossier ne peut pas être trouvé, alors l'essai lui donnant le dossier appelle comme NotLikely%x%x.txt. Si vous recevez un message d'erreur le long des lignes de "NotLikely12fd234104587.txt ne peut pas être trouvé," alors vous a juste trouvé une vulnérabilité de corde de format.

C'est évidemment quelque peu selon chaque langue ; vous devriez passer dans les spécificateurs de formatage qui sont employés par la langue d'exécution vous’au sujet d'employer au moins. Cependant, puisque beaucoup de temps d'exécution de langue sont mis en application dans C/C++, il soit’sage introduire également vous d des commandes de corde de formatage de C/C++ de détecter des cas où votre bibliothèque fondamentale a une vulnérabilité dangereuse.

Notez que si l'application est enchaînement basé et fait écho votre utilisateur entré de nouveau à vous, un autre souci serait des attaques scripting d'croix-emplacement

Péchés D'Exemple

Les entrées suivantes dans les vulnérabilités et les expositions communes (CVE) à http:// cve.mitre.org sont des exemples d'injection de SQL. Hors des 188 entrées de CVE qui les cordes de format de référence, ceci est juste un prélèvement.

CVE-2000-0573

De la description de CVE : “Lreply la fonction dans le wu-ftpd 2.6.0 et plus tôt ne nettoie pas correctement untrusted la corde de format, qui permet aux attaquants à distance d'exécuter des commandes arbitraires par l'intermédiaire de la commande de l'EMPLACEMENT EXEC.”

C'est la première exploit publiquement connue pour un bogue de corde de format. Le titre du poteau de BUGTRAQ souligne la sévérité du problème : “Fournir * extérieur * enracinez depuis au moins 1994.”

CVE-2000-0844

De la description de CVE : “Quelques fonctions qui mettent en application le sous-ensemble de lieu sur UNIX ne nettoient pas correctement les cordes utilisateur-injectées de format, qui permet aux attaquants locaux d'exécuter des commandes arbitraires par l'intermédiaire des fonctions telles que le gettext et catopen.”

L'à texte intégral du bulletin de renseignements original peut être trouvé à www.securityfocus.com/archive/1/80154, et ce problème est particulièrement intéressant parce qu'il affecte le système APIs de noyau pour la plupart des variantes d'UNIX (Linux y compris), excepté des variantes de schéma étant donné que la variable de NLSPATH est ignorée pour l'application privilégiée de suid dans le schéma. Ce bulletin de renseignements, comme beaucoup de bulletins de renseignements du NOYAU SDI, est particulièrement écrite et instructif bons et donne une explication très complète du problème global

Étapes De Rachat

La première étape n'est jamais utilisateur de passage entré directement dans une fonction de formatage, et soit également sûre de faire ceci à chaque niveau de manipuler le rendement composé. Comme note additionnelle, les fonctions de formatage ont des frais généraux significatifs. Regardez la source pour _ produit s'il pourrait’être commode—écrire vous au sujet d'intéressé il :

fprintf(STDOUT, buf) ;

La ligne précédente de l'isn t’de code juste dangereux, mais lui consomme également beaucoup de cycles supplémentaires d'unité centrale de traitement.

La deuxième étape à prendre est de s'assurer que les cordes de format vos utilisations d'application sont seulement lues des endroits de confiance, et que les chemins aux cordes ne peuvent pas être commandés par l'attaquant. Si vous’au sujet du code d'écriture pour UNIX et Linux, après l'exemple des variantes et d'ignorer de schéma la variable de NLSPATH, qui peut être employée pour indiquer le dossier employiez pour les messages localisés, pouvez fournir une certaine défense détaillée.

Rachat de C/C++

Là isn’t beaucoup plus à lui que ceci :

printf("%s", user_input) ;

Mesures Défensives Supplémentaires

Vérifiez et limitez le lieu aux valeurs valides. (pour plus d'information, voir le rouleur s’de David “l'écrire bloqué : Composez les cordes et le filtrage de lieu” énuméré dans “l'autre section” de ressources ci-dessous). Mettez’l'utilisation de t la printf-famille des fonctions si vous pouvez l'éviter. Par exemple, si vous’au sujet d'employer C++, opérateurs de jet d'utilisation à la place :

# incluez l'< iostream >  
/
std::cout < < user_input
/

D'Autres Ressources

c'est un article supplémentaire par Hendra Fang


Share  

© 2005-2010 E-articles.info All Rights Reserved - Terms and conditions