4.8.9 Tester les injections SSI (OTG-INPVAL-009)

Sommaire
Les serveur web donnent souvent aux développeurs la possibilité d'ajouter de petites parties de code dynamique dans une page HTML statique, sans avoir à manipuler un langage complet côté serveur ni côté client. Cette fonctionnalité s'appelle Server-Side Includes (SSI). Pour tester les injections SSI, nous allons voir s'il est possible d'injecter dans l'application des données qui seront interprêtées par les mécanismes SSI. Une exploitation réussie permettra à un attaquant d'injecter du code dans les pages HTML et même d'exécuter du code à distance.

Les Server-Side Includes sont des directives que le serveur web analyse avant de servir la page à l'utilisateur. Ils sont une alternative à l'écriture de programmes CGI ou de code embarqué utilisant des langages de script côté serveur, pour des tâches très simples. Les implémentations SSI communes fournissent des commandes pour inclure des fichiers externes, affecter ou afficher des variables d'environnement CGI, et pour exécuter des scripts CGI ou des commandes systèmes.

Insérer une directive SSI dans un document HTML statique est aussi simple que le code suivant :

pour afficher la date et heur actuelle.

pour inclure la sortie d'un script CGI.

pour inclure le contenu d'un fichier ou d'une liste de fichiers dans un répertoire.

pour inclure la sortie d'une commande système.

Ensuite, si le support SSI est activé sur le serveur web, ce dernier va analyser ces directives. Généralement, dans la configuration par défaut de la plupart des serveurs web, l'utilisation de la directive exec pour exécuter des commandes systèmes n'est pas autorisée.

Comme dans tous les cas de mauvaise validation d'entrées, les problèmes surviennent quand l'utilisateur d'une application web est autorisé à fournir des données qui vont provoquer un comportement inattendu de l'application ou du serveur web. Dans le cas des SSI, l'attaquant peut fournir une entrée qui, si elle est insérée dans une page générée dynamiquement par l'application (ou directement par le serveur), sera interprêtée comme une ou plusieurs directives SSI.

Cettte vulnérabilité est très similaire à une vulnérabilité classique d'injection dans un langage de script. Elle peut être mitigée par le fait qu'elle nécessite que le serveur web soit configuré pour autoriser SSI. Par contre, les vulnérabilités d'injection SSI sont souvent plus simples à exploiter, puisque les directives SSI sont simples à comprendre, et en même temps très puissantes, par exemple pour afficher le contenu de fichiers et pour exécuter des commandes systèmes.

Test en boite noire
La première chose à faire dans un test en boite noire, est de vérifier si le serveur web supporte réellement les directives SSI. Souvent la réponse est oui, puisque le support des SSI est très fréquent. Pour le découvrir, il suffit de détecter quel type de serveur web tourne sur la cible, en utilisant les techniques de reconnaissance classiques

Que l'on réussisse ou non à découvrir cette information, on peut deviner si les SSI sont supportées simplement en regardant le conteu du site web ciblé. S'il contient des fichiers .shtml, alors les SSI sont probablement supportées, puisque cette extension est utilisée pour identifier les pages contenant ces directives. Malheureusement, l'utilisation de l'extension .shtml n'est pas obligatoire, donc l'absence de tels fichiers ne signifie pas forcément que la cible n'est pas vulnérable aux attaques par injection SSI.

L'étape suivante consiste à déterminer si une injection SSI est vraiment possible et, si oui, quels sont les points d'entrées que l'on peut utiliser pour injecter du code malicieux.

Les actions nécessaires à ces tests sont exactement les même que pour les autres vulnérabilités d'injection de code. Notamment, il faut vérifier chaque page acceptant des entrées utilisateur, et vérifier que l'application valide ces entrées correctement. Si le nettoyage est insuffisant, on doit tester si l'on peut fournir des données qui seront affichées sans mofdification (par exemple, dans un message d'erreur ou dans un forum). En plus des entrées utilisateur, il faut aussi prendre en compte les vecteurs d'entrée comme les entêtes de requêtes HTTP et le contenu des cookies, qui peuvent facilement être manipulés.

Une fois qu'lon a une liste des points d'injection potentiels, on peut vérifier si les entrées sont validées correctement, et trouver où elles sont stockées. On doit s'assurer que l'on peut injecter des caractères utilisés dans des directives SSI :

< ! # = / . " - > and [a-zA-Z0-9]

Pour tester si la validation est insuffisante, on peut entrer, par exemple, une chaîne comme celle-ci dans un formulaire :

Ceci est similaire à un test de vulnérabilité XSS :

alert("XSS")

Si l'application est vulnérable, la directive est injectée et sera interprêtée par le serveur lors du prochain affichage de la page, ainsi le contenu du fichier standard de mots de passe Unix sera inséré dans la page.

L'injection peut aussi être faite dans les entêtes HTTP, si l'application web utilise ces données pour construire une page dynamique :

GET / HTTP/1.0 Referer: User-Agent:

Test en boite grise
Si l'on a accès au code source de l'application, on peut facilement vérifier :
 * 1) Si les directives SSI sont utilisées. Si elles le sont, alors le support des SSI est activé dans le serveur web, rendant ainsi les injections SSI au moins potentiellement possible, et donc à investiguer.
 * 2) Où les entrées utilisateur, le contenu des cookies et les entêtes HTTP sont traités. La liste complète des vecteurs d'entrée est ainsi rapidement déterminée.
 * 3) Comment les entrées sont traitées, wuel type de filtrage est en place, quels caractères l'application ne laisse pas passer, et combien de types d'encodages sont pris en compte.

Effectuer ces étapes est surtout une question d'utilisation de grep pour trouver les bons mots clefs dans le code source (directives SSI, variables d'environnement CGI, affectation de variables impliquant des entrées utilisateur, fonctions de filtrage, etc.).

Outils

 * Web Proxy Burp Suite - http://portswigger.net
 * Paros - http://www.parosproxy.org/index.shtml
 * WebScarab
 * String searcher: grep - http://www.gnu.org/software/grep

Références
Whitepapers
 * Apache Tutorial: "Introduction to Server Side Includes" - http://httpd.apache.org/docs/1.3/howto/ssi.html
 * Apache: "Module mod_include" - http://httpd.apache.org/docs/1.3/mod/mod_include.html
 * Apache: "Security Tips for Server Configuration" - http://httpd.apache.org/docs/1.3/misc/security_tips.html#ssi
 * Header Based Exploitation - http://www.cgisecurity.net/papers/header-based-exploitation.txt
 * SSI Injection instead of JavaScript Malware - http://jeremiahgrossman.blogspot.com/2006/08/ssi-injection-instead-of-javascript.html
 * IIS: "Notes on Server-Side Includes (SSI) syntax" - http://blogs.iis.net/robert_mcmurray/archive/2010/12/28/iis-notes-on-server-side-includes-ssi-syntax-kb-203064-revisited.aspx