La traversée de répertoires, également appelée directory traversal ou path traversal (et identifiée par CWE-22), est une vulnérabilité des applications web qui permet aux hackers d’accéder à des fichiers non surveillés sur un système de fichiers sous-jacent. En fonction de la manière et de l’endroit où la traversée se produit, cela peut permettre à un hacker de lire ou d’écrire des fichiers arbitraires sur le serveur web, ce qui peut lui permettre de lire des données ou des fichiers sensibles, de modifier les données de l’application ou de prendre le contrôle complet du serveur web.
Les vulnérabilités de traversée sont généralement décrites selon qu’elles permettent de lire ou d’écrire des fichiers. Nous allons démontrer l’impact de chacune d’entre elles dans les sous-sections suivantes.
Prenons l’exemple d’une application qui permet à un utilisateur de stocker des photos et de les récupérer ultérieurement par le biais d’une requête GET utilisant un paramètre de nom de fichier pour spécifier le fichier à récupérer. Si l’application n’inclut pas de protection contre la traversée de répertoires et crée le chemin du fichier en utilisant le paramètre de nom de fichier fourni, il pourrait être possible de récupérer des fichiers arbitraires à partir du serveur d’applications sous-jacent. La Fgure 1 illustre cette séquence dans la pratique :
Même si l’application est vulnérable à la traversée de répertoires, il existe d’autres limitations à prendre en compte, comme les autorisations de l’application. Par exemple, si un modèle de moindre privilège est appliqué pour limiter l’accès des applications sur le serveur web, ses autorisations peuvent limiter les fichiers auxquels le hacker peut accéder via cette vulnérabilité. C’est l’une des raisons pour lesquelles les charges utiles (payloads) de traversée utilisent fréquemment /etc/passwd comme cible ; le fichier doit être lisible par tous les utilisateurs. Il existe d’autres moyens de mettre en place un sandboxing et de limiter l’accès aux applications. Nous les aborderons plus en détail dans la section consacrée à la prévention.
Prenons la même application de stockage de photos, mais elle permet désormais à l’utilisateur de donner un nom à chacune des photos qu’il stocke. Lors de l’enregistrement du fichier sur le disque, l’application utilise le nom fourni pour créer le chemin d’accès au fichier photo. En l’absence de protections suffisantes, un hacker peut ajouter des séquences de traversée (par exemple, ../) au nom fourni, contrôlant ainsi le répertoire dans lequel le fichier est stocké.
Bien que cela puisse sembler inoffensif puisqu’il s’agit simplement de stocker une photo, il existe des moyens d’approfondir cette exploit. Si le type de fichier n’est pas validé (par exemple, JPEG, PNG), un hacker peut télécharger n’importe quel type de fichier, ce qui conduit à plusieurs scénarios d’exploit différents, tels que :
Ajouter la clé publique du hacker au fichier authorized_keys d’un utilisateur (par exemple, /root/.ssh/authorized_keys) pour obtenir un accès permanent.
Écraser les fichiers de l’application pour modifier le comportement de cette dernière.
Télécharger un shell web dans la racine web.
Provoquer un déni de service en écrasant des fichiers système nécessaires.
Télécharger de fichiers exécutables (par exemple, des malwares, des ransomwares).
Selon le niveau d’accès de l’application, l’impact d’une écriture de fichier arbitraire à partir d’une traversée de répertoires peut être dévastateur.
Maintenant que nous avons abordé les principes de base de la traversée de répertoires, examinons quelques exemples récents d’exploitation de cette vulnérabilité dans le monde réel.
Dans la version 16.0.0 de Gitlab, il existe une vulnérabilité de traversée de répertoires qui permet la lecture de fichiers arbitraires. Le téléchargement d’un fichier en tant que pièce jointe à un Problème dans une installation Gitlab par défaut fait que Gitlab stocke le fichier à 10 répertoires de profondeur selon le modèle suivant :
/var/opt/gitlab/gitlab-rails/uploads/@hashed/<directory>/<directory>/<directory>/<directory>/<filename>
Après le téléchargement, Gitlab fournit également un endpoint pour récupérer le fichier téléchargé dans le répertoire
/<repo-name>/uploads/<file-id>/<filename>
Dans les requêtes vers cet endpoint, Gitlab n’analyse pas ou ne valide pas le paramètre « filename », ce qui permet une attaque par traversée de répertoires. Pour exploiter cette traversée, le registre doit être imbriqué dans au moins 5 groupes, le nombre de groupes étant directement corrélé à la quantité de répertoires que l’on peut traverser en utilisant cette vulnérabilité.
Dans une installation standard, cela signifie que l’on doit imbriquer le registre dans 11 groupes pour pouvoir atteindre la racine du système de fichiers. Dans ce scénario, le payload d’une attaque pour récupérer le fichier /etc/passwd ressemblerait à ceci :
GET /Groupe-1/Groupe-2/Groupe-3/Groupe-4/Groupe-5/Groupe-6/Groupe-7/Groupe-8/Groupe-9/Groupe-10/Groupe-11/<repo-name>/uploads/<file-id>/..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd
Les hackers non authentifiés ne peuvent exploiter cette vulnérabilité que si un registre public remplit l’exigence des groupes imbriqués. Cela est peu probable. Aussi, il est plus probable que cette attaque vienne d’un utilisateur authentifié disposant de privilèges pour créer des groupes imbriqués et des registres. Une chaîne d’attaque complète peut d’abord créer les groupes et le registre nécessaires, télécharger un fichier, et ensuite exploiter la traversée pour lire des fichiers arbitraires, comme vu dans le PoC ici.
Dans les versions de ManageEngine Desktop Central antérieures à la version 10.1.2127.1, une traversée de répertoires dans la fonctionnalité de téléchargement de fichiers permettait d’écrire des fichiers arbitraires en manipulant le paramètre « computerName » (ou quelques autres) pour inclure des séquences de traversée.
Au moment de sa découverte, cette vulnérabilité était activement exploitée et combinée à un contournement d’authentification (CVE-2021-44515) pour permettre l’exécution de code à distance. Par souci de concision, nous nous concentrerons sur la partie de l’attaque concernant la traversée de répertoires, car elle permet l’écriture d’un fichier et contourne la validation libre.
Dans une fonction nommée « doPost », Desktop Central traite plusieurs paramètres dans le cadre d’un téléchargement de fichier, notamment « computerName » et « filename ». Cette fonction est à l’origine de deux vulnérabilités qui conduisent à une traversée de répertoires permettant l’écriture de fichiers :
seul le paramètre « filename » est vérifié pour les séquences de traversée. Les autres paramètres tels que « domainName », « computerName » ou « customerId » sont utilisés pour créer le chemin absolu du fichier, mais ne sont pas vérifiés pour les séquences de traversée. « computerName » est le dernier paramètre utilisé dans la chaîne concaténée. Il s’agit donc de l’endroit idéal pour saisir une séquence de traversée, car il n’y aura pas de contenu supplémentaire ajouté à ce paramètre.
Le téléchargement de fichiers autorise les fichiers portant les extensions zip, 7z et gz. À première vue, cela peut sembler sûr. Cependant, comme Desktop Central est une application Java et que les fichiers JAR sont construits sur le format zip, cela permet l’exécution de code à distance. En téléchargeant un fichier zip dans le répertoire C:\Program Files\DesktopCentral_Server\lib
et en forçant un redémarrage, un hacker avisé peut écraser les fichiers de classe dans l’application pour inclure son propre code et l’exécuter.
Cette vulnérabilité met en évidence l’impact sévère qu’une vulnérabilité de traversée peut avoir, tout en montrant comment une prévention incomplète peut involontairement entraîner une traversée de répertoires.
La traversée de répertoires est l’une des techniques d’attaque les plus couramment observées, comme le souligne notre rapport sur les menaces Network Effect du deuxième trimestre 2023.
Cela peut s’expliquer par plusieurs raisons, notamment la gravité de l’impact en cas de succès ou la taille des listes de charges utiles que les hackers et les scanners peuvent utiliser. Par exemple, un extrait de l’une des listes de traversée de répertoires de PayloadsAllTheThings tente de lire le même fichier avec différentes profondeurs de traversée, comme indiqué ci-dessous :
../../../../../../../../../etc/passwd
../../../../../../../../etc/passwd
../../../../../../../etc/passwd
../../../../../../etc/passwd
../../../../../etc/passwd
../../../../etc/passwd
../../../etc/passwd
Dans la plupart des cas, les hackers ne savent probablement pas où se trouve l’application sur le système de fichiers lorsqu’ils testent une vulnérabilité de traversée. Cependant, les applications ne vont pas au-delà de la racine du système (c’est-à-dire /). Les hackers utilisent donc des séquences « ../ » plus longues pour s’assurer que la racine est atteinte, tout en incluant des séquences plus courtes au cas où les séquences plus longues seraient bloquées ou briseraient la fonctionnalité de l’application.
D’autres types d’attaques, comme le Cross-Site Scripting (XSS), peuvent utiliser des payloads polyglottes qui combinent plusieurs techniques en un même payload. Cela conduit les hackers et les scanners à envoyer beaucoup plus de charges utiles pour tester la traversée que pour tester le XSS. Notre fichier d’exemple de PayloadsAllTheThings contient 140 payload, alors que le fichier XSS_Polyglots n’en contient que 16. Le fichier de payload le plus volumineux pour la traversée dans PayloadsAllTheThings contient plus de 21 000 entrées, contre plus de 600 pour le XSS, plus de 400 pour SQLi (bien qu’il faille supposer que ce chiffre serait plus élevé dans la pratique si le type de base de données est inconnu, étant donné que plusieurs types devraient être testés), et plus de 400 pour l’injection de commandes système.
La taille des listes de payloads de traversée est l’une des hypothèses qui expliquent que cette technique soit aussi largement utilisée. Mais la gravité de l’impact de ce type d’attaque en est une autre, comme le montre la discussion sur CVE-2022-48362 ci-dessus, qui permettait l’exécution de code à distance et qui, lors de sa découverte, s’était avérée avoir déjà été exploitée.
Plusieurs stratégies peuvent être utilisées pour prévenir les vulnérabilités de traversée, y compris des modifications de conception pour empêcher la construction de chemins de fichiers avec des entrées utilisateur, une validation stricte des entrées, l’utilisation de la canonisation des chemins et la limitation des accès des applications. Nous aborderons chacune de ces stratégies ci-dessous.
Plutôt que d’utiliser les entrées de l’utilisateur pour créer le chemin d’accès au fichier, envisagez d’utiliser un nom ou un identifiant de fichier correspondant pour référencer le fichier. Ensuite, associez les identifiants de fichier au chemin de stockage correspondant. Lorsqu’un utilisateur demande ce fichier ou télécharge un fichier, il ne peut contrôler que son identifiant, ce qui l’empêche d’accéder au contenu utilisé pour créer le chemin d’accès au fichier. Cela supprime entièrement la possibilité de traversée, puisque l’entrée de l’utilisateur n’est plus utilisée pour créer le chemin d’accès au fichier récupéré.
La validation stricte et l’assainissement sont deux concepts différents. Plutôt que de nettoyer les entrées en essayant de supprimer les séquences de traversée (par exemple, ../), qui peuvent être contournées d’innombrables façons, il s’agit de valider uniquement le contenu attendu qui se trouve dans les entrées utilisateur et de rejeter tout ce qui ne passe pas cette validation stricte. Exemples de validation qui peuvent aider à empêcher la traversée de répertoires :
Valider un nom de fichier ne contenant que des valeurs alphanumériques
Valider que le nom de fichier fourni ne contient qu’un seul caractère « . »
Valider qu’aucun caractère non désiré ne se trouve dans l’entrée fournie (par exemple, /, \)
Valider le type de fichier des fichiers téléchargés (autrement que par son extension, laquelle peut être facilement contournée)
En bref, la canonisation des chemins raccourcit le chemin d’accès du fichier à son chemin réel, en supprimant les liens symboliques, les séquences ../ et autres contenus symboliques. Après avoir obtenu un chemin canonique, vous pouvez vérifier qu’il commence toujours par le répertoire de base prévu (par exemple, uploads/photos/). Voici quelques exemples de fonctions permettant d’obtenir un chemin canonique :
Java : getCanonicalPath
PHP : realpath
C : realpath
ASP.NET : GetFullPath
En général, une application ne devrait avoir accès qu’aux fichiers et aux répertoires dont elle a besoin pour fonctionner correctement. Cela permet, dans certains cas de traversée de répertoires, de limiter l’impact d’une vulnérabilité si elle est découverte. Par exemple, une application web ne devrait jamais être exécutée sous l’utilisateur root, et son accès devrait idéalement être limité aux fichiers dont elle a besoin pour fonctionner.
La traversée de répertoire, également appelée directory traversal ou path traversal, est une vulnérabilité des applications web qui permet à des hackers d’accéder à des fichiers non-surveillés sur un système de fichiers sous-jacent. Selon la vulnérabilité de traversée, cela peut permettre à un hacker de lire des données ou des fichiers sensibles, de modifier les données des applications ou de prendre le contrôle complet du serveur web. Les vulnérabilités de traversée peuvent avoir de graves répercussions et, comme le montrent nos exemples réels et les données du WAF de nouvelle génération, elles constituent un vecteur d’attaque de premier plan. Cependant, les applications peuvent prévenir les vulnérabilités de traversée de répertoires en mettant en place les solutions que nous avons décrites. Si vous avez des difficultés à éviter les traversées de répertoires, ou si vous utilisez un produit qui a été victime de ces vulnérabilités dans le passé, le WAF de nouvelle génération de Fastly peut vous protéger contre ces hackers et bien plus encore.