Nous pensons souvent qu’un pare-feu suffisamment restrictif protège l’accès aux services non ouverts. Nous croyons aussi que seule une machine compromise peut donner accès au reste du réseau interne.
Et bien nous avons tort, et c’est ce que nous allons voir avec une vulnérabilité des applications web : le Server-Side Request Forgery (SSRF).
Qu’est-ce que les SSRF ?
A partir d’une application web vulnérable, les SSRF permettent d’interagir avec le serveur, afin d’en extraire des fichiers et de trouver ses autres services actifs. Mais cela ne s’arrête pas là. Il est également possible de scanner le réseau interne afin d’en cartographier les IP et Ports ouverts.
Mais d’où vient cette brèche ?
L’idée générale est la suivante : si une fonctionnalité permet d’interagir avec des ressources (exemple : chargement d’une image dans l’application ou redirection vers une page), alors l’attaquant pourra tenter de soumettre une requête au serveur de telle sorte que la ressource recherchée soit interne au serveur (fichiers, services, ressources disponibles en localhost seulement) ou à son réseau.
Prenons pour exemple la fonctionnalité suivante permettant à un utilisateur de changer sa photo de profil :
On remarque deux choses. D’une part, le paramètre url n’est pas contrôlé avant son utilisation dans file_get_contents($url), et d’autre part, le contenu est écrit (echo $content;) alors qu’une redirection a lieu.
Cette fonctionnalité est donc vulnérable au SSRF. Voici certaines exploitations possibles :
- Accès à une fonctionnalité apache du serveur (non exposée) :
http://vaadata.test/ssrf.php?url=http://localhost/server-status - Accès à un service web du serveur (non exposé) :
http://vaadata.test/ssrf.php?url=http://localhost:8080 - Accès à un fichier du serveur (LFI : Local File Inclusion) :
http://vaadata.test/ssrf.php?url=file:///etc/passwd - Accès à un serveur web du réseau interne :
http://vaadata.test/ssrf.php?url=http://10.0.0.15/ - Interface du routeur : http://vaadata.test/ssrf.php?url=http://10.0.0.1/
On voit ici que la vulnérabilité SSRF donne potentiellement de nombreuses possibilités à un attaquant. En fait, il ne s’agit ici que d’exemples appliqués à notre serveur de tests mais bien d’autres exploitations pourraient être réalisées en fonction des cas : XML External Entity (XXE), Cross-Site Scripting (XSS), injection de commande, etc.
Dans notre exemple ci-dessus, c’est la fonction file_get_contents qui ouvre la brèche. Cependant, d’autres fonctions (ici PHP) peuvent également en être la source, les plus classiques étant :
- file_get_contents()
- fopen()
- fread()
- fsockopen()
- curl_exec()
Cette vulnérabilité SSRF ne se limite bien sûr pas à PHP et le même principe peut être retrouvé avec chaque technologie web.
Différents types de SSRF
Nous avons vu un cas particulier de SSRF, car le contenu de la ressource chargée est retourné par le serveur (echo $content;). Pour cette raison, cette SSRF est appelée Content-Based. Ce type de SSRF est potentiellement le plus dangereux, car permettant d’extraire rapidement des données.
Dans d’autres cas, seuls des indices, directs ou indirects, peuvent permettre de déduire des informations sur le serveur ou le réseau interne :
- Boolean-Based : la réponse du serveur est différente que la ressource existe ou non
- Error-Based : une erreur, HTTP (404 ou 500) par exemple, permettant de déduire les ressources existantes ou non
- Time-Based : dans le cas où la réponse du serveur reste la même que la ressource existe ou non, le temps de réponse peut quant à lui varier de manière significative
Avec ces trois types d’indices, et bien qu’aucune donnée ne soit extraite, il reste possible de cartographier les ressources existantes sur le serveur et dans le réseau interne.
Remédiation
Il est indispensable de mettre en place des règles sur les ressources à charger.
Comme pour toute vulnérabilité faisant intervenir un contrôle sur les paramètres envoyés par le client, l’utilisation d’une liste noire n’est PAS recommandée, parce qu’il existera toujours une manière de contourner ce filtre. Préférez donc une liste blanche, c’est-à-dire n’autoriser que les ressources explicitées et refuser tout le reste. Il faudra alors définir :
- Les noms DNS et/ou adresses IP autorisées
- En l’absence de localhost et 127.0.0.1, cela empêchera l’accès aux services/fichiers du serveur.
- L’accès illégitime au réseau interne sera empêché.
- Les protocoles autorisés
- L’utilisation de file://, sftp://, sera alors empêché.
Dans cet article suivant, nous montrons qu’il existe de nombreuses manières de contourner des filtres via l’utilisation d’URL et nous présenterons un outil pour exploiter plus facilement les SSRF.