
# Laboratoire CTF basé sur Docker démontrant CVE-2024-4577, une injection d'arguments PHP-CGI menant à une exécution de code à distance (RCE). Inclut un CGI PHP 5.4.1 vulnérable, des scripts d'exploitation et la récupération du flag.
Un lab Docker autonome, entièrement construit de zéro, qui démontre la primitive réelle
d'injection d'arguments → Exécution de code à distance derrière CVE-2024-4577.
Exploitez-la via http://localhost:8080, obtenez un shell, et lisez le flag depuis
l'intérieur du conteneur.
Il s'agit d'une vulnérabilité réelle, pas d'une simulation. Le conteneur compile un binaire PHP 5.4.1 CGI non patché et le connecte derrière Apache exactement comme les hôtes vulnérables réels sont configurés. Il n'y a aucun faux "if password == flag" nulle part — la seule façon d'obtenir le flag est de réellement parvenir à une exécution de code.
La charge utile signature de CVE-2024-4577 utilise %AD (un trait d'union conditionnel). Cette astuce
ne fonctionne que sur Windows, car l'encodage de caractères "Best-Fit" de Windows
convertit l'octet 0xAD en un vrai - (0x2D) après que le patch CVE-2012-1823 de PHP
ait déjà vérifié la chaîne de requête. Cette conversion d'encodage est effectuée par
Windows lui-même — elle ne se produit pas dans un conteneur Docker Linux normal.
Ainsi, un lab Linux fidèle et exécutable sur votre machine reproduit la même primitive
RCE exacte — injection d'options php-cgi via l'URL → -d auto_prepend_file=php://input → exécution de code — en utilisant la forme littérale -
(qui est le bug parent de CVE-2024-4577, CVE-2012-1823). La seule
différence par rapport à une cible Windows réelle de CVE-2024-4577 est la couche de
contournement d'encodage %AD→-, que ce README documente intégralement (voir
Comment ça fonctionne et
poc.http).
| Ce lab Linux | CVE-2024-4577 réel (Windows) | |
|---|---|---|
| Composant vulnérable | php-cgi | php-cgi |
| Primitive RCE | -d auto_prepend_file=php://input | identique |
| Délimiteur dans l'URL | - littéral | %AD (best-fit → -) |
| Contourne le patch de 2012 ? | N/A (PHP antérieur au patch) | Oui, via le best-fit Windows |
| Fonctionne sur Win 11 Home + Docker Desktop | ✅ | ❌ (nécessite des conteneurs Windows) |
Si vous avez spécifiquement besoin de la reproduction Windows bit pour bit avec %AD, vous
avez besoin d'un hôte Docker capable de conteneurs Windows (Windows Server / Win Pro + Hyper-V) —
cela ne fonctionnera pas sur Windows 11 Home. La charge utile Windows est incluse dans
poc.http pour référence.
CVE-2024-4577 — Injection d'arguments CGI PHP menant à une exécution de code à distance. Découverte par DEVCORE (Orange Tsai / Angelboy), divulguée le 2024-06-06.
Lorsque PHP est déployé en mode CGI (ou que le binaire php-cgi.exe est autrement
accessible) sur Windows avec certains paramètres régionaux du système (chinois
traditionnel/simplifié, japonais, et autres), le serveur web transmet la chaîne de requête HTTP à
php-cgi comme arguments de ligne de commande. Un attaquant peut faire passer en contrebande des
options de ligne de commande php-cgi (-d ...) dans cette chaîne de requête. La conversion de
page de codes best-fit de Windows transforme l'octet de trait d'union conditionnel 0xAD (%AD)
en trait d'union ASCII -, ce qui contourne le durcissement CVE-2012-1823 et permet à l'attaquant
de définir des directives INI PHP arbitraires — le plus utile étant
auto_prepend_file=php://input avec allow_url_include=1, ce qui exécute le
corps de requête fourni par l'attaquant comme du PHP. Résultat : exécution de code à distance
sans authentification. Elle a été exploitée dans la nature en quelques jours (par ex. le
rançongiciel TellYouThePass).
CGI transmet la chaîne de requête comme argv. Selon la RFC 3875, si la chaîne de
requête d'une requête CGI ne contient aucun = non encodé, le serveur la divise sur +,
décode chaque mot en URL, et transmet les mots au programme CGI comme
arguments de ligne de commande. php-cgi reçoit donc un argv contrôlé par l'attaquant.
php-cgi analyse ces argv comme des options. Historiquement, php-cgi interprétait
-d key=value, -T, etc. depuis cet argv. Fournir
-d allow_url_include=1 -d auto_prepend_file=php://input fait exécuter à PHP
le corps de la requête comme du code → CVE-2012-1823.
Le correctif de CVE-2012-1823 est incomplet sur Windows. Le patch de 2012 a ajouté
une protection dans sapi/cgi/cgi_main.c : en gros "si la chaîne de requête (brute) commence
par - et ne contient pas de =, ignorer l'analyse des options (skip_getopt)." Un attaquant
envoyant un - littéral est désormais bloqué.
L'encodage best-fit neutralise la protection (le bug de 2024). Sur Windows, PHP
convertit la ligne de commande en utilisant la page de codes locale avec le mappage best-fit
activé. L'attaquant envoie %AD (octet 0xAD, trait d'union conditionnel). Au
moment de la vérification de la protection, le premier octet est 0xAD, pas -, donc
skip_getopt n'est pas défini. Plus tard, lorsque PHP construit réellement l'argv,
le mappage best-fit de Windows convertit 0xAD → -, donc getopt voit maintenant -d. L'injection
d'options se déclenche après la vérification censée l'arrêter. Cet
ordre vérification-puis-conversion constitue l'intégralité de la vulnérabilité.
Dans ce lab Linux, les étapes 1–2 sont reproduites exactement avec un php-cgi antérieur au patch de l'étape 3, donc la forme littérale
-fonctionne et démontre la RCE identique. L'étape 4 est la couche propre à Windows, documentée mais non exécutée (Linux n'a pas de conversion best-fit).
Corrigée dans 8.3.8, 8.2.20, 8.1.29. Par conséquent, vulnérables :
Conditions : système d'exploitation Windows ; PHP fonctionnant en CGI ou php-cgi.exe exposé
(la configuration par défaut XAMPP sur Windows est vulnérable) ; un paramètre régional
affecté pour le chemin best-fit. (Le bug parent CVE-2012-1823 — la primitive
que ce lab exécute — affecte tout système d'exploitation exécutant un php-cgi antérieur au correctif de 2012 dans cette
configuration.)
cve-2024-4577-lab/ ├── Dockerfile # builds the lab: compiles unpatched PHP 5.4.1 CGI + Apache ├── Dockerfile.vulhub # fallback: prebuilt vulnerable base image (if compile fails) ├── docker-compose.yml # one-command build+run, maps localhost:8080 -> 80 ├── start.sh # container entrypoint (Apache foreground) ├── exploit.sh # one-shot RCE PoC (bash + curl) ├── poc.http # raw HTTP requests (Linux payload + real Windows %AD payload) ├── app/ │ └── index.php # ordinary web page (NOT itself vulnerable) ├── config/ │ ├── apache-vhost.conf # the vulnerable Apache <-> php-cgi wiring │ └── php.ini # minimal php.ini (cgi.force_redirect=0, etc.) ├── flag.txt # the flag (copied to /flag.txt in the container) └── README.md # this file
## 5. Prérequis
- **Docker Desktop** (Windows/macOS) ou Docker Engine (Linux).
Windows 11 Famille : installez Docker Desktop avec le backend **WSL 2** (par défaut).
→ https://www.docker.com/products/docker-desktop/
- `curl` pour l'exploitation (`curl.exe` est intégré à Windows 10/11 ; également dans
Git Bash / WSL / macOS / Linux).
- Accès Internet **pendant la construction** (télécharge le code source de PHP 5.4.1).
## 6. Instructions de construction
Ouvrez un terminal dans le dossier `cve-2024-4577-lab/`.