Space attacks
Un article de HackaWiki.
Les services de messageries par web (web-based email services) ont toujours été sujets à des problèmes de sécurité liés au filtrages (sanitization) des messages et à leur rendu en html. Le risque, c'est que du code html arbitraire ou du javascript puisse être injecté par un expéditeur mal intentionné, via un email, dans les pages envoyées à l'utilisateur lorsqu'il consulte ses message. Ce genre d'attaque permet, entre autre, d'exploiter facilement les vulnérabilités du navigateur d'une victime particulière ; de prendre le contrôle de la session courante, par vol de cookie ou en pilotant l'interface depuis le navigateur de la victime, et donc d'usurper son identité, lire et effacer ses messages ; de maquiller les informations sur l'origine des messages, et d'augmenter la vraisemblance d'un faux message (phishing). D'une manière générale, le problème de sécurité principal que doivent gérer ces services de messagerie, mais aussi les logiciels de forums en lignes, ou tout système de publication qui transmet à un tiers un contenu d'origine inconnue (untrusted source), est de protéger en amont les navigateurs et les autres programmes clients des utilisateurs, contre des attaques potentielles. Il y a deux grandes difficultés à cela. D'abord, ces attaques sont difficiles à reconnaître objectivement, parce que leurs formes peuvent être très diverses et parce que de nouveaux vecteurs peuvent être découverts à tout moment. Ensuite, il n'est pas toujours possible de savoir a priori quels logiciels clients seront utilisés. Ceux-ci peuvent avoir des comportements différents envers un même contenu (par exemple, les parser html de certains navigateurs sont plus tolérants aux erreurs que d'autres).
Sommaire |
Space attacks
Début 2003, The Hackademy Audit mettait en évidence [THJ4] un type d'attaque particulièrement redoutable, capable de tromper les filtres de la plupart des webmails. Voici un exemple de code qui permettait d'exécuter du javascript via un mail, sur Hotmail :
<STYLE>
BODY {background:\xa0url('javascript:(...)');}
</STYLE>
Ce code n'était pas modifié par le filtrage, et était transmis tel quel au navigateur de la victime. Sans ce caractère spécial, inséré avant url, ce dernier aurait été detecté et transformé en nonurl. Or ce caractère chr(0xa0) est ignoré par Internet Explorer et traité comme un séparateur valide, ce qui entraîne l'exécution du script. Ce problème vient d'un déphasage entre les parsers du filtre et du navigateurs, qui ne reconnaissent pas les caractères d'espacement de la même manière. Cela entraîne que certains mot-clés dangereux ne sont pas identifiés par le filtre, mais bien interprétés par le navigateurs. Dans notre exemple, \xa0url est vu comme un seul identificateur inconnu par l'un et comme [espace] url par l'autre. Afin de limiter les risques, on peut prendre parti de supprimer tous les éléments et paramètres qui ne sont pas reconnus. La possibilité de supprimer par erreur du contenu légitime n'est pas toujours jugée comme acceptable. La sémentique de fonctions standard comme isspace(3) peut varier en fonction du système, de l'encodage utilisé et de la localisation, ou encore de l'implémentation. De plus certains parsers utilisent leurs propres fonctions de bas niveau. Ainsi, il n'est pas possible de s'appuyer sur une quelconque norme, ce qui rend cette approche de filtrage très empirique.
Situation actuelle
Les bugs spécifiques que nous avions identifiés en 2003 ont heureusement été corrigés depuis longtemps. Cependant, il semble que les correctifs proposés n'aient pas réglé le problème à la racine. Pour preuve, Rafel Ivgi annonçais sur bugtraq [FINJAN] en décembre 2004 de nouveaux problèmes de filtrage dans Hotmail et Yahoo!Mail lié à des caractères d'espacement. La faille de hotmail pouvait être exploitée de cette manière :
<img src="http://www.finjan.com/images/logo.gif" MCRC= onmouseover="alert(...)"><img>
Ici, le fait d'avoir un retour chariot juste après MCRC= donnait l'illusion au filtre que la valeur associée à cet attribut était '\nonmouseover="alert(...)"'. Par conséquent, onmouseover n'était pas modifié. Par contre, pour un navigateur, il y a là deux attributs, et le second entraîne bien l'exécution de code javascript. La faille de Yahoo!Mail était un peu différentes :
<div style="background: url(j	a	v	 a	s	c	r	i	p	 t:alert());"></div>
Au delà des webmails
Ces différences d'interprétation, notamment en ce qui concerne les séparateurs et espaces, peut causer des problèmes dans bien d'autres domaines que les webmails. Un bug de ce type était par exemple présent dans ircservices jusqu'à janvier 2003 [CASTAMAN]. Ircservices est implémentation des robots du genre Chanserv, capable de linker avec divers types de serveurs IRC. Le problème était qu'alors que la plupart des serveurs IRC parsent les commandes des utilisateurs en ne tenant compte que du caractère chr(32), ircservices utilisait isspace(). Ainsi, le nombre d'arguments calculés par un serveur pouvait différer du nombres d'arguments reconnus par les services. Un utilisateur pouvait par exemple émettre la commande suivante et crasher les services : /mode #channel +k \x09 Elle est considérée valide par un serveur (\x09 étant l'argument du mode +k) et donc retransmises aux services. Ceux-ci font confiance à ce qu'ils reçoivent des serveur, il n'y a donc pas de vérification supplémentaire. Mais, lorsque les arguments sont décomposés, \x09 était considéré comme un espace. En l'absence d'un argument pour +k, les services devaient donc crasher (null pointer).
Plus récemment, des techniques d'évasion de filtres (content filtering bypass techniques) publiée fin 2004 [3APA3A], ainsi que des advisories de Corsaire sur l'encapsulation MIME postés en janvier 2005 sur bugtraq [CORSAIRE] mettent également en évidence cette technique, ainsi que d'autres apparentées. Les antivirus placés sur les serveurs de messagerie afin d'éliminer les messages contenant des malware en attachement peuvent en effet rater la détection de certains contenus, lorsque ceux-ci sont encodés de manières particulières, sans pour autant empêcher certains clients de les extraire ou d'en déclencher éventuellement la charge (payload). En particuliers, des headers MIME erronés, ou même conformes aux standards mais ambïgus, peuvent produire cet effet. Voici un exemple représentatif. Les différentes parties d'un message multi-part son délimités par un identificateur donné dans les headers (afin d'éviter qu'il apparaisse accidentellement dans les données). Lorsque des espaces supplémentaires (additional space symbols) sont ajouté à la fin de ce header, il peuvent être interprétés de deux manières différentes. Par exemple : Content-Type: multipart/mixed; boundary=xxxx\r\r\n
Dans cette situation, certains programmes décideront que le délimiteur est 'xxxx', d'autres 'xxxx\r'. Si un filtre ne tient pas compte des deux interprétations, il risque de laisser passer des contenus malveillants.
Ces différences d'interprétation entre filtre et client causent des problèmes de sécurité similaires dans toutes sortes d'autres applications : les antivirus en général, les filtres anti-spam, les proxies http ou autre qui filtrent les contenus(anonimysers, anti-popups, child protection, etc. ), les IDS, ...
White-list based filtering
Il existe pourtant des éléments de solution. Les techniques que nous venons de décrire mettent en défaut les filtres de contenus, parce que ceux-ci tentent de supprimer des objets dangereux (black-list) qu'il ne pourront jamais parfaitement reconnaître. Une autre approche, plus sûre, consiste à refabriquer (refactoring) les contenus analysés à partir d'éléments dont on est sûr qu'ils sont sains et inoffensifs (white-list). Dans le cas de l'html, on peut tenir la liste précise des tags que l'on autorise, en précisant exactement la forme de leur paramètres. À l'aide d'un interpréteur tolérant certains écarts, on peut reconstruire le message original tel qu'il a été compris en ne se servant que de cette liste de tags. On est alors sur de n'introduire aucun élément étranger, à part certaines données courtes qui ne peuvent contenir de caractères spéciaux. Il existe notamment une implémentation en Perl de cette méthode [StripScripts] et en PHP [kses].
Cette manière de faire est la seule qui puisse garantir que le contenu sera interprété par un client de la même façon qu'il l'a été par le filtre.
Réfs
- 3APA3A
- Bypassing content filtering whitepaper
- http://www.security.nnov.ru/advisories/content.asp
- FINJAN
- http://www.securityfocus.com/archive/1/384708
- http://www.securityfocus.com/archive/1/384725
- http://www.securityfocus.com/archive/1/384723
- CORSAIRE
- See bugtraq posts from advisories@corsaire.com on 2004-09-13
- StripScripts
- http://search.cpan.org/~ncleaton/HTML-StripScripts/
- kses
- http://kses.sf.net
