
PoC fonctionnel de CVE-2026-64638 (XSS2Shell) : chaîne XSS pre-auth vers RCE dans WordPress Core. Laboratoire Docker + serveur attaquant Python + analyse technique et atténuation.
Preuve de concept éducative de la chaîne XSS2Shell (CVE-2026-64638), vulnérabilité pré-authentification XSS → RCE dans WordPress Core découverte de manière autonome par pwn.ai et divulguée le 7 août 2026.
CVE-2026-64638 est une vulnérabilité de type cross-site scripting (XSS)
réfléchi, pré-authentification, dans l'écran de connexion de WordPress
(wp-login.php). Elle affecte toutes les versions de WordPress sous
maintenance antérieures à la 7.0.3, publiée le 6 août 2026 en tant que
security release d'urgence. Un score CVSS v4.0 de 8.9 lui a été attribué.
La chaîne baptisée XSS2Shell démontre comment, à partir uniquement d'une tentative de login échouée avec un username manipulé, un attaquant peut :
strip_tags) et de
WordPress (wp_kses_post).user-profile.js) pour effectuer une requête REST JSONP vers la même origine.jQuery.globalEval().Le résultat est l'exécution de code à distance (RCE) sur le serveur
WordPress, sous l'utilisateur du processus web (typiquement www-data), à
partir d'un unique click de l'administrateur sur un lien contrôlé par
l'attaquant.
Ce dépôt contient du matériel strictement éducatif et défensif.
La PoC est fournie avec un environnement Docker autonome dont l'unique finalité est de servir de cible locale et reproductible.
┌─────────────────────────────────────────────────────────────────────┐
│ 1. XSS pré-auth dans wp-login.php │
│ log=< area id=ajaxurl href=/?rest_route=/&_jsonp=...> │
│ (divergence strip_tags ↔ wp_kses_post) │
└──────────────────────────────────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 2. user-profile.js déclenche .trigger('click') │
│ DOM clobbering de ajaxurl → requête POST vers l'origine │
└──────────────────────────────────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 3. REST JSONP répond application/javascript │
│ jQuery.globalEval() exécute le callback dans l'origine WP │
└──────────────────────────────────────────┬──────────────────────────┘
│ callback = window.opener
│ .approve.click
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 4. SOME : click() franchit la frontière opener→admin │
│ authorize-application.php#approve est cliqué dans la session admin │
└──────────────────────────────────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 5. WP crée Application Password → redirige vers success_url │
│ L'attaquant capture user_login + password dans callback.php │
└──────────────────────────────────────────┬──────────────────────────┘
│ HTTP Basic REST
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 6. POST /wp-json/wp/v2/pages → publie une page avec <script> │
│ L'admin visite la page → JS dans l'origine WP avec session admin │
└──────────────────────────────────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 7. fetch update.php?action=upload-plugin → téléverse payload.zip │
│ Le PHP du plugin est accessible directement sans l'activer │
└──────────────────────────────────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 8. RCE confirmée : GET /wp-content/plugins/payload/shell.php │
└─────────────────────────────────────────────────────────────────────┘
La PoC est conçue pour fonctionner sur macOS ou Linux avec :
zip (pour construire le payload
manuellement, optionnel ; le ZIP déjà construit est inclus dans payload/).Il n'est pas nécessaire d'installer WordPress manuellement : le
docker-compose.yml démarre un WordPress 7.0.2 vulnérable (la dernière version
antérieure au correctif) avec MariaDB.
POC XSS2Shell (CVE-2026-64638)/
├── README.md ← Ce fichier
├── docker-compose.yml ← Cible : WordPress 7.0.2 + MariaDB
├── .env.example ← Variables de configuration
├── exploit.py ← Orchestrateur en Python (optionnel)
├── attacker/ ← Infrastructure de l'attaquant
│ ├── index.html ← Page leurre avec la chaîne SOME
│ ├── callback.php ← Récepteur de l'Application Password
│ └── server.py ← Serveur statique + PHP embarqué
├── payload/ ← Plugin ZIP malveillant
│ ├── build_payload.py ← Générateur du ZIP
│ ├── shell.php ← Webshell minimal
│ └── payload.zip ← ZIP préconstruit (prêt à l'emploi)
└── docs/
├── ANALISIS.md ← Analyse technique détaillée
└── MITIGACION.md ← Guide de mitigation et de durcissement
cp .env.example .env
docker compose up -d
WordPress sera accessible sur http://localhost:8080. Suivez l'assistant
d'installation et créez un utilisateur administrateur (par exemple admin /
admin-password).
Le Dockerfile ancre l'image sur
wordpress:7.0.2-php8.2-apache, qui est la dernière version antérieure au correctif 7.0.3.
# Dans un autre terminal, dans attacker/
python3 server.py
Le serveur attaquant écoute sur http://localhost:9000 et expose :
/ → index.html (la page leurre)./callback.php → récepteur de l'Application Password.Dans le terminal où tourne server.py, une ligne du type suivant apparaîtra :
[+] Application Password reçue pour l'utilisateur 'admin' :
XXXX XXXX XXXX XXXX XXXX XXXX
La crédential est également enregistrée dans
attacker/captured_credentials.txt.
Après quelques secondes, l'orchestrateur de index.html aura :
payload.zip dans wp-content/plugins/payload/.Vérifiez l'exécution de code avec :
curl -sI http://localhost:8080/wp-content/plugins/payload/shell.php
Un en-tête Hacked: true et un corps JSON confirment le RCE.
Une fois la chaîne terminée, les endpoints suivants servent de preuve :
| Ressource | Preuve attendue |
|---|---|
GET /wp-content/plugins/payload/shell.php | En-tête Hacked: true + JSON {"rce":true,"user":"www-data"} |
docs/ANALISIS.md — Analyse technique détaillée de
chaque phase de la chaîne, avec références au code source de WordPress.docs/MITIGACION.md — Mitigations recommandées,
durcissement et vérification du patch 7.0.3.Distribué sous licence MIT. Consultez le fichier LICENSE pour plus de détails.
attacker/captured_credentials.txt | Application Password capturée |
wp-admin → Applications → Mots de passe d'application | Une nouvelle entrée nommée « SomeApp » |