
Lab basé sur Docker démontrant la vulnérabilité d'analyse d'URI de Nginx CVE-2013-4547 avec une exploitation étape par étape pour le contournement de privilèges et l'exécution de code.
Versions concernées : Nginx 0.8.41 ~ 1.4.3 / 1.5.0 ~ 1.5.7
Liens de référence :
Cette vulnérabilité n’a en fait pas grand-chose à voir avec l’exécution de code ; sa cause principale est une analyse incorrecte de l’URI de la requête, qui conduit à récupérer de manière erronée le nom de fichier demandé par l’utilisateur, entraînant des conséquences telles que le contournement des autorisations ou l’exécution de code.
Par exemple, lorsque Nginx trouve une requête se terminant par .php, il l’envoie à fastcgi pour analyse. Une configuration courante est la suivante :
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT /var/www/html;
}
Normalement (lorsque pathinfo est désactivé), seuls les fichiers avec l’extension .php sont envoyés à fastcgi pour analyse.
Cependant, en présence de CVE-2013-4547, si nous demandons 1.gif[0x20][0x00].php, cet URI correspond à l’expression régulière \.php$ et peut entrer dans ce bloc location ; mais une fois à l’intérieur, Nginx considère à tort que le fichier demandé est 1.gif[0x20] et définit cette valeur comme SCRIPT_FILENAME qu’il envoie à fastcgi.
fastcgi analyse ensuite la valeur de SCRIPT_FILENAME, ce qui entraîne finalement une vulnérabilité d’analyse.
Ainsi, il suffit de télécharger un fichier dont le nom se termine par un espace pour que PHP l’analyse.
Un autre exemple : de nombreux sites limitent l’accès à l’interface d’administration en fonction de l’IP :
location /admin/ {
allow 127.0.0.1;
deny all;
}
Nous pouvons alors demander l’URI suivante : /test[0x20]/../admin/index.php. Cet URI ne correspond pas au /admin/ du location, ce qui contourne la vérification IP ; mais le fichier final demandé est /test[0x20]/../admin/index.php, c’est-à-dire /admin/index.php, permettant ainsi d’accéder à l’interface d’administration. (Cette astuce nécessite qu’un répertoire nommé test existe : c’est une particularité des systèmes Linux ; si le répertoire n’existe pas, même en remontant d’un niveau, une erreur de fichier inexistant se produira. Sous Windows, cette contrainte n’existe pas.)
Démarrez l’environnement vulnérable :
docker-compose build
docker-compose up -d
Une fois l’environnement lancé, accédez à http://your-ip:8080/ pour voir une page de téléchargement.
Cet environnement utilise une liste noire : nous ne pouvons pas télécharger de fichiers avec l’extension .php. Nous devons donc utiliser CVE-2013-4547. Téléchargez un fichier nommé 1.gif (notez l’espace à la fin) :

Accédez à http://your-ip:8080/uploadfiles/1.gif[0x20][0x00].php ; vous constaterez que PHP a été analysé :

Notez que [0x20] est un espace et [0x00] est \0. Ces deux caractères n’ont pas besoin d’être encodés.