Vulnérabilité "format string" en PERL
Date : 04 Janvier 2006
Les vulnérabilités de type "format string" sont connues depuis
longtemps pour le langage C (cf. l'article
du bulletin Cert-IST d'octobre 2000). En décembre 2005, il a été mis en
évidence que ce même type de faille concernait également le langage PERL.
Les vulnérabilités de type "format string"
Ce type de vulnérabilité se produit lorsque les programmeurs utilisent mal des
fonctions de traitement de chaîne de caractères telles que "printf"
ou "sprintf", et passent en premier argument de ses fonctions une
variable renseignée par l'utilisateur (au lieu d'une "chaîne de
format", comme par exemple "%s
"). Dans ce cas, un utilisateur
malicieux peut provoquer des dysfonctionnements dans le programme, en insérant
dans cette variable des caractères normalement réservés aux "chaînes de
format" (comme par exemple "%d", "%s" ou
"%f").
Tous les langages qui proposent des fonctions équivalentes au "printf"
du langage C sont, elles aussi, vulnérables à ce type d'attaque. Les
discussions récentes (décembre 2005) se sont focalisées sur le langage PERL,
mais en les extrapolant, les mêmes problèmes pourraient aussi survenir en PHP,
ou dans d'autres langages.
Le cas du langage PERL
Dans le cas du PERL, une première vulnérabilité de type "format
string" a été mise en évidence début décembre 2005 sur le logiciel
d'administration "webmin" (cf. l'avis CERT-IST/AV-2005.458).
Depuis, des vulnérabilités de ce type ont également été mises en évidence
sur les produits suivants (non significatifs pour le Cert-IST) :
- "TN3270 Resource Gateway" (CVE-2005-4511)
- "CP+" (CVE-2005-4261)
- "ftplogcheck" (script PERL pour "Wu-Ftpd")
- "perl-nocem" (script PERL pour "INN")
- "WASD OpenVMS web server"
En PERL, cette vulnérabilité peut se produire avec :
- les fonctions natives "printf" et "sprintf",
- mais aussi avec les modules d'extension qui implémentent des fonctions utilisant elles aussi les chaînes de format, comme "sscanf" (module "String::Scanf") et "syslog" (module "Sys::Syslog").
La liste des modules d'extension potentiellement vulnérables donnée ici
n'est pas exhaustive. L'exemple du module "syslog" montre en
particulier que l'on ne doit pas limiter sa recherche (lors de l'analyse d'un
code) à la simple famille des fonctions "printf".
Exemples de codes PERL vulnérables :
- Exemple 1 : Vulnérable :
printf "Filename in format string: $file ";
Ici, il faut utiliser "print", plutôt que "printf". Non vulnérable :
print "Filename in format string: $file ";
- Exemple 2 : Vulnérable :
syslog("crit", "invalid login : $user ");
Non vulnérable :
syslog("crit", "invalid login : %s ", $user);
Conséquences possibles d'une attaque "format string"
L'article de "Steven M. Christley" (cité ci-dessous dans la rubrique
"Pour plus d'information") donne une description détaillée des
impacts possibles lorsqu'une vulnérabilité de type "format string"
existe dans un programme PERL. De façon schématique, nous retiendrons que ce
type de vulnérabilité permet de provoquer :
- de façon triviale, un déni de service sur l'application PERL. Par
exemple, une chaine de caractère comme "%999999999s" est
suffisante pour provoquer l'allocation d'un espace mémoire de 1Go par le
programme PERL lors de l'exécution d'un "printf" mal codé.
- ou même, mais cela est beaucoup plus complexe, de prendre le contrôle du programme PERL, au moyen d'une chaine du type "%n". Le format "%n" permet en effet d'écrire des données dans une variable passée à la fonction "printf". Il peut être détourné pour écrire à une adresse arbitraire de l'espace d'adressage du processus.
L'attaque universelle pour le "format string" en PERL
La société "dyadsecurity.com"
(qui a découvert la vulnérabilité "webmin" mentionnée plus haut) a
analysé en profondeur les possibilités de prise de contrôle d'un programme
PERL. A cette occasion, elle a découvert qu'une vulnérabilité existait dans
l'interpréteur PERL lui même (cf. l'avis CERT-IST/AV-2005.482).
Cette vulnérabilité se produit lorsqu'une chaines de format telle que "%123$n"
doit être interprétée par PERL (ce format – appelé "explicit
parameter" - spécifie que PERL doit effectuer un formatage
"%n"sur le "123"ème paramètre passé lors de
l'appel "printf"). Si la valeur "123" (donnée ici en
exemple) est habilement choisie, il est possible de prendre le contrôle de
l'interpréteur PERL. L'intérêt de cette "découverte" est que la
faille :
- concerne une "chaîne de format". Si une application présente une vulnérabilité de type "format string", il est donc possible d'activer cette faille.
- et est présente dans l'interpréteur PERL lui-même. En conséquence, elle est présente dans tous les scripts PERL (puisqu'ils s'appuient tous sur cet interpréteur).
Les détails pour exploiter cette "découverte" n'ont pas été
donnés à ce jour, et à la vue de l'universalité de l'attaque, on peut s'en
réjouir. De plus les correctifs pour cette faille de l'interpréteur PERL sont
disponibles (se reporter à l'avis du Cert-IST).
Recommandation
On le voit dans cet article, les failles de type "format string"
(découvertes en 2000) ont trouvé ce mois-ci une nouvelle jeunesse. Pour se
protéger, les configurations utilisant PERL doivent appliquer le correctif pour
la faille CERT-IST/AV-2005.482. Si cela limite le risque induit en cas d'attaque, cela ne supprime pas le risque
qu'une vulnérabilité de type "format string" existe dans les
applications PERL développées. Pour écarter ce risque, une revue attentive du
code PERL développé est nécessaire. Une sensibilisation des équipes de
développement sur ce type de faille est également indispensable. Enfin, il est
important de retenir que les failles de type "format string" ne sont
pas exclusivement un problème du langage C (ni PERL) : tout les langages
disposant de fonctions utilisant les "chaînes de format" (fonctions
de type "printf") sont également concernés.
Pour plus d'information :
- Article de Steven M. Christley sur les failles "format string" en PERL : http://archives.neohapsis.com/archives/fulldisclosure/2005-12/0066.html
- Description détaillé de la faille de l'interpréteur PERL : http://dyadsecurity.com/perl-0002.html