4.8.14.3 Tester les format string

Sommaire
Cette section décrit comment tester les attaques sur les format string qui peuvent être utilisées pour faire planter un programme ou exécuter du code hostile. Le problème vient de l'utilisation d'entrées utilisateur comme paramètre de format string dans certains fonctions C qui font du formatage, telles que printf.

Différents langages de la famille C fournissent des fonctions de formatage comme printf, fprintf, etc. Le format est piloté par un paramètre de ces fonctions nommé spécification de type de format, typiquement %s, %c, etc. La vulnérabilité survient quand les fonctions de formatage sont appelées avec une validation des paramètres inadéquate et avec des données contrôlées par l'utilisateur.

printf(argv[1]) seraint un exemple simple. Dans ce cas, la spécification de type n'a pas été explicitement déclarée, permettant à un utilisateur de passer ds caractères tels que %s, %n, %x dans l'application au moyen de l'argument de ligne de commande argv[1].

Cette situation devient précaire puisqu'un utilisateur qui peut fournir des spécifications de format peut faire les actions malicieuses suivantes :

Enumérer la pile du processus : Cela permet à un adversaire de visualiser l'organisation de la pile du processus vulnérable en fournissant des format strings, telles que %x ou %p, qui peuvent causer une fuite d'information sensibles. Cela peut aussi être utilisé pour extraire des valeurs canary quand une application est protégée par un mécanismede protection de la pile. Couplé avec une débordement de pile, cette information peut être utilisée pour contourner la protection de la pile.

Controler le flux d'exécution : Cette vulnérabilité peut aussi faciliter l'exécution de code arbitraire puisqu'elle permet d'écrire 4 octets de données sur une adresse fournie par l'adversaire. Le spécificateur %n est pratique pour écraser divers pointeurs de fonctions en mémoire avec l'adresse de la charge utile malicieuse. Quand ces fonctions écrasées sont appelées, le code malicieux est exécuté.

Deni de service : Si l'adversaire n'est pas en position de fournir du code malicieux à exécuter, l'application vulnérable peut être plantée en fournissant une séquence de %x suivie par %n.

Test en boite noire
La clef pour tester les vulnérabilités de format string et de founir des spécificateur de type de format dans les entrées de l'application.

Par exemple, considérons une application qui traite des chaînes d'URL. http://xyzhost.com/html/en/index.htm ou accepte des entrée de formulaires. Si une vulnérabilité de format string est présente dans une des routines traitant cette information, fournir une URL comme http://xyzhost.com/html/en/index.htm%n%n%n ou entrer %n dans un des champs de formulaire peut planter l'application en créant un core dump dans le répertoire hôte.

Les vulnérabilité de format string se manifestent surtout sur les serveurs web, serveurs applicatifs ou les applications web utilisant du code basé sur C/C++ ou des CGI écrites en C. Dans la plupart de ces cas, un rapport d'erreur ou une fonction comme syslog a été appelée de manière non sécurisée.

Quand on test des scripts CGI pour les vulnérabilité de format string, les paramètres d'entrée peuvent être manipulés pour contenir les spécificateurs %x ou %n. Par exemple ue nrequête légitime comme

 http://hostname/cgi-bin/query.cgi?name=john&code=45765 

peut être modifiée en

 http://hostname/cgi-bin/query.cgi?name=john%x.%x.%x&code=45765%x.%x 

Si une vulnérabilité de format string est présente dans la routine traitant la requête, le testeur pourra voir les données de la pile s'afficher dans le navigateur.

Si le code n'est pas disponible, le processus de revue des fragments assembleur (aussi connu sous le nom d'ingénierie inverse des binaires) remontera des informations substantielles sur les bogues de format string.

Prenons l'instance de code (1) :

int main(int argc, char **argv) { printf("The string entered is\n"); printf(“%s”,argv[1]); return 0; }

quand le code désassemblé est examiné dans IDA Pro, l'adresse d'une format string poussée sur la pile est clairement visible avant qu'un appel à printf soit effectué.



D'autre part, quand le même code est compilé sans "%s" comme argument, la variation dans l'assembleur est apparente. Comme on le voit ci-dessous, il n'y a pas d'offset poussé sur la pile avant l'appel à printf.



Test en boite grise
Lors des revues de code, presque toutes les vulnérabilités de format string peuvent être détectées en utilisant des outils d'analyse de code statique. Soumettre le code montré en (1) a ITS4, qui est un analyseur de code statique, donnera la sortie suivante.



Les fonctions qui sont principalement responsables des vulnérabilités de format string sont celles qui traitent les spécifications de format comme optionelles. Donc, lors d'une revue de code manuelle, l'accent peut être mis sur des fonctions telles que :

printf fprintf sprintf snprintf vfprintf vprintf vsprintf vsnprintf

Il peut exister des fonction de formatage spécifiques à certaines plateformes de développement. Il faut aussi vérifier l'absence de format string une fois que l'utilisation dfde leurs arguments a été comprise.

Outils

 * ITS4: "A static code analysis tool for identifying format string vulnerabilities using source code" - http://www.cigital.com/its4
 * An exploit string builder for format bugs - http://seclists.org/lists/pen-test/2001/Aug/0014.html

Références
Whitepapers
 * Format functions manual page - http://www.die.net/doc/linux/man/man3/fprintf.3.html
 * Tim Newsham: "A paper on format string attacks" - http://comsec.theclerk.com/CISSP/FormatString.pdf
 * Team Teso: "Exploiting Format String Vulnerabilities" - http://www.cs.ucsb.edu/~jzhou/security/formats-teso.html
 * Analysis of format string bugs - http://julianor.tripod.com/format-bug-analysis.pdf