4.8.16 Tester l'HTTP Splitting Smuggling (OTG-INPVAL-016)

Sommaire
Cette section illustre des exemples d'attaques utilisant des fonctionnalités spécifiques du protocol HTTP, soit en exploitant des faiblesses de l'application web, soit en exploitant des particularités dans la façon dont les différents agents interprêtent les messages HTTP.

Cette section va analyser deux attaques différentes qui cibles des entêtes HTTP specifiques :
 * HTTP splitting
 * HTTP smuggling.

La première attaque exploite un manque de validation des entrées qui permet à un intrus d'insérer des caractères CR et LF dans les entêtes des réponses de l'application et donc de 'splitter' cette réponse en deux message HTTP différents. Le but de cette attaque peut varier du cache poisoning au cross site scripting.

Dans la seconde attaque, l'attaquant exploite le fait que certains messages HTTP spécialement construits peuvent être analysés et interprêtés de différentes manières selon l'agent qui les reçoit. L'HTTP smuggling requiert une certaine connaissance des différents agents traitant les messages HTTP (serveur web, proxy, pare-feu), et ne sera donc dcrite que dans la section boite grise.

HTTP Splitting
Certaine applications web utilisent une partie des entrées utilisateur pour générer les valeurs de certaines entête de leurs réponses. L'exemple le plus simple sont les redirections dans lesquelles l'URL cible dépend de valeurs fournies par les utilisateurs. Par exemple, le cas d'un utilisateur choisissant une interface web standard ou avancée. Le choix sera passé comme paramètre qui sera utilisé dans l'entête de la réponse pour déclencher une redirection vers la page correspondante.

Plusspécifiquement, si le paramètre 'interface' a la valeur 'advanced', l'application répondra :

HTTP/1.1 302 Moved Temporarily Date: Sun, 03 Dec 2005 16:22:19 GMT Location: http://victim.com/main.jsp?interface=advanced

En recevant ce message, le navigateur renvoie l'utilisateur vers la page indiquée dans l'entête Location. Cependant, si l'application ne filtre pas les entrées utilisateurs, il sera possible d'insérer dans le paramètre 'interface' une séquence %0d%0a, qui représente la séquence CRLF utilisée pour séparer différentes lignes. A ce moment, les testeurs vont pouvoir déclencher une réponse qui sera interprêtée comme deux réponses par quiconque l'analysera, par exemple un cache web, situé entre nous et l'application. Cela peut être utilisé par un attaquant pour empoisonner ce cache afin qu'il fournisse un contenu faalsifié à toute les requêtes suivantes.

Supposons que dans l'exemple précédent le testeur passe les données suivantes comme paramètre 'interface' : advanced%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent- Type:%20text/html%0d%0aContent-Length:%2035%0d%0a%0d%0a Sorry,%20System%20Down

La réponse resultantes de l'application vulnérable sera la suivante : HTTP/1.1 302 Moved Temporarily Date: Sun, 03 Dec 2005 16:22:19 GMT Location: http://victim.com/main.jsp?interface=advanced Content-Length: 0

HTTP/1.1 200 OK Content-Type: text/html Content-Length: 35

Sorry,%20System%20Down

Le cache web verra deux réponses différentes, donc si l'attaquant envoie, immédiatement après la première requête, une seconde requpete demandant /index.html, le cache fera correspondre cette requête avec la seconde réponse et stockera son contenu, donc toutes les requêtes suivantes dirigées vers victim.com/index.html passant par ce cache web recevront le message "system down". De cette manière, un attaquant pourra effectivement defacer le site pour tous les utilisateurs utilisant ce cache web (tout Internet; si ce cache est un reverse proxy pour l'application web).

Alternativement, l'attaquant peut passer à tous ces utilisateurs un morceau de code JavaScript menant une attaque XSS, par exemple pour voler les cookies. Remarquons que bien que la vulnérabilité soit dans l'application, ce sont les utilisateurs qui sont ciblés. Donc pour chercher cette vulnérabilité, le testeur doit identifier toutes les entrées contrôlées par l'utilisateur qui influencent une ou plusieurs entêtes de la réponse, et vérifier qu'il peut injecter une séquence CR+LF dedans.

Les entêtes les plus évidents pour cette attaque sont :


 * Location
 * Set-Cookie

Il faut remarquer qu'une exploitation réussie de cette vulnérabilité dans un scénario réel peut être très complexe, car plusieurs facteur doivent être pris en compte :


 * 1) Le testeur doit modifier correctement les entêtes dans la fausse réponse pour qu'elle soit mise en cache correctement (Ex : une entête Last-Modified avec une date dans le futur). Il peut aussi avoir à détruire les versions de la page cible précédemment mises en cache, en envoyant au préalable des requêtes avec "Pragma: no-cache".
 * 2) L'application, bien qu'elle ne filtre pas les séquences CR+LF, peut filtrer d'autres caractères nécessaire à une attaque réussie (par exemple "<" et ">"). Dans ce cas, le testeur peut essayer d'autres encodages (ex : UTF-7).
 * 3) Certaines cibles (ex : ASP) vont encoder en format URL la partie chemin de l'entête Location (ex : www.victim.com/redirect.asp), rendant une séquence CRLF inutile. Cependant, elles n'encodent pas la section requête (ex : ?interface=advanced), donc un point d'interrogation au début contournera le filtrage.

Pour une discussion plus détaillée sur cette attaque et d'autres information sur les scénarii et applications possibles, voir les articles référencés à la fin de cette section.

HTTP Splitting
Une connaissance assez détaillée de l'application web et de la cible de l'attaque est d'une grande aide pour une exploitation réussie d'HTTP Splitting. Par exemple, différentes cibles peuvent utiliser différentes méthodes pour décider quand un message HHTP se termine et qu'un second commance. Certaines vont utiliser les séparateurs de messages, comme dans l'exemple précédent. D'autres cibles vont considérer que différents messages seront transportés dans différents paquets. D'autres encore vont allouer des blocks mémoire pour chaque message ; dans ce cas, le second message devra commencer exactement au début d'un block et le testeur devra faire du remplissage (padding) entre deux messages.Cela peut causer quelques problèmes quand le paramètre vulnérable doit être envoyé dans l'URL, puisque des URLs très longues sont suceptibles d'être tronquées ou filtrées. Un scénario en boite grise peut aider l'attaquant à trouver un contournement : plusieurs serveurs d'application, par exemple, autoriseront les requêtes à être envoyées en POST plutôt qu'en GET.

HTTP Smuggling
Comme signalé en introduction, l'HTTP Smuggling utilise les différentes manières dont un message HTTP peut être analysé et interprêté par différents agents (navigateurs, caches web, pare-feux applicatifs). Ce genre d'attaques relativement nouveau a été découvert par Chaim Linhart, Amit Klein, Ronen Heled et Steve Orrin en 2005. Il permet différentes applications et nous allons analyser la plus spectaculaire : le contournement d'un pare-feu applicatif. Voir l'article original référencé en bas de page pour plus de détails et d'autres scenarii.

Contournement d'un pare-feu applicatif

Plusieurs produits permettent à un administrateur système de détecter et de bloquer un requête web hostile, selon les schémas malicieux connus intégrés à la requêete. Par exemple, considérons la célèbre et ancienne attaque 'Unicode directory traversal' contre les serveur IIS (http://www.securityfocus.com/bid/1806), dans laquelle un attaquant peut sortir de l'arborescence www en envoyant une requête telle que : http://target/scripts/..%c1%1c../winnt/system32/cmd.exe?/c+

Il est bien sûr très facile de repérer et filtrer cette attaque grâce à la présence de chaînes comme ".." et "cmd.exe" dans l'URL. Cependant, IIS 5.0 est très sensible pour les requêtes POST dont le corps fait jusqu'à 48K et tronque tout contenu au de-là de cette limite quand l'entête Content-Type est différent de application/x-www-form-urlencoded. Le testeur peut tirer avantage de cela en créant une très grand requête, structurée comme suit : POST /target.asp HTTP/1.1       <-- Request #1 Host: target Connection: Keep-Alive Content-Length: 49225  POST /target.asp HTTP/1.0       <-- Request #2 Connection: Keep-Alive Content-Length: 33  POST /target.asp HTTP/1.0       <-- Request #3 xxxx: POST /scripts/..%c1%1c../winnt/system32/cmd.exe?/c+dir HTTP/1.0  <-- Request #4 Connection: Keep-Alive 

La première requête #1 est composée de 49223 octets, incluant les lignes de la requête #2. Un pare-feu (ou tout autre agent excepté IIS 5.0) va voir la requête #1 mais pas la requête #2 (ses données sont juste une partie de la requête #1), va voir la requête #3 et manquer la requête #4 (puisque le POST est une partie de l'entête falsifié xxxx).

Ensuite, que se passe-t-il dans IIS 5.0 ? Il va arrêter d'analyser la requête #1 après les 49152 octets de remplissage (puisqu'il aura atteinte la limite de 48K=49152 octets) et va ainsi analyser la requête #2 comme une nouvelle requête séparée. La requête #2 prétend que son contenu des de 33 octets, ce qui inclut tout le contenu jusqu'à "xxxx: ", faisant en sorte que IIS manque la requête #3 (interprêtée comme une partie de la requête #2), mais va voir la requête #4, puisque son POST commence après le 33e octet de la requête #2. Cela semble un peu compliqué, mais l'important est que l'URL d'attaque ne sera pas détectée par le pare-feu (interprêtée comme le corps de la requête précédente) mais sera analysée correectement (et exécutée) par IIS.

Quand la technique précédente est utilisée pour exploiter un bogue dans un serveur web, plusieurs autres scenarii vont bénéficier des différentes manières dont différents devices HTTP vont analyser les messages non conformes à la RFC 1005. Par exemple, le protocol HTTP ne permet qu'une seule entête Content-Length, mais ne spécifie pas comment traiter une message qui en contient deux instances. Certaines implémentations vont utiliser la première, d'autres vont préférer la seconde, permettant ainsi des attaques d'HTTP smuggling. Un autre exemple est l'utilisation de l'entête Content-Length dans un message GET.

Il faut remarquer que l'HTTP Smuggling n'exploit *pas* de vulnérabilité dans l'application ciblée. Il peut donc être difficile, lors d'un test d'intrusion, de convaincre le client que des contre-mesures doivent tout de même être recherchées et appliquées.

Références
Whitepapers
 * Amit Klein, "Divide and Conquer: HTTP Response Splitting, Web Cache Poisoning Attacks, and Related Topics" - http://www.packetstormsecurity.org/papers/general/whitepaper_httpresponse.pdf
 * Chaim Linhart, Amit Klein, Ronen Heled, Steve Orrin: "HTTP Request Smuggling" - http://www.watchfire.com/news/whitepapers.aspx
 * Amit Klein: "HTTP Message Splitting, Smuggling and Other Animals" - http://www.owasp.org/images/1/1a/OWASPAppSecEU2006_HTTPMessageSplittingSmugglingEtc.ppt
 * Amit Klein: "HTTP Request Smuggling - ERRATA (the IIS 48K buffer phenomenon)" - http://www.securityfocus.com/archive/1/411418
 * Amit Klein: “HTTP Response Smuggling” - http://www.securityfocus.com/archive/1/425593
 * Chaim Linhart, Amit Klein, Ronen Heled, Steve Orrin: "HTTP Request Smuggling" - http://www.cgisecurity.com/lib/http-request-smuggling.pdf