alexb616/SessionReaper-CVE-2025-54236

GitHub: alexb616/SessionReaper-CVE-2025-54236

针对 Magento 2 CVE-2025-54236 PHP 反序列化漏洞的 Python PoC,通过三种 REST API 向量实现未认证远程代码执行。

Stars: 0 | Forks: 0

# SessionReaper — CVE-2025-54236 **Magento 2 / Adobe Commerce 中的 PHP 对象反序列化 → RCE** ``` ____ _ ____ / ___| ___ ___ ___(_) ___ _ __ | _ \ ___ __ _ _ __ ___ _ __ \___ \ / _ \/ __/ __| |/ _ \| '_ \| |_) / _ \/ _` | '_ \ / _ \ '__| ___) | __/\__ \__ \ | (_) | | | | _ < __/ (_| | |_) | __/ | |____/ \___||___/___/_|\___/|_| |_|_| \_\___|\__,_| .__/ \___|_| |_| ``` 针对 CVE-2025-54236 实现了**三种不同反序列化攻击向量**的统一 Python PoC —— 这是一个严重 (CVSS 9.1) 的 Magento `ServiceInputProcessor` 输入验证不当漏洞,允许在使用基于文件的会话存储的实例上进行未经认证的远程代码执行。 ## 目录 - [概述](#overview) - [攻击原理 — 攻击链](#how-it-works--the-attack-chain) - [反序列化方法](#deserialization-methods) - [方法 1 — `address` (通过 addressConfig 的 estimate-shipping-methods)](#method-1--address) - [方法 2 — `checkmo` (通过 paymentData 的 set-payment-information)](#method-2--checkmo) - [方法 3 — `order` (PUT guest-carts/order — 官方 PoC 向量)](#method-3--order) - [为什么 SKU 和 Cart ID 很重要](#why-sku-and-cart-id-matter) - [Payload — 写入内容及位置](#the-payload--what-gets-written-and-where) - [环境要求](#requirements) - [使用方法](#usage) - [受影响版本](#affected-versions) - [参考链接](#references) - [时间线](#timeline) - [免责声明](#disclaimer) - [许可证](#license) ## 概述 CVE-2025-54236 针对的是 `Magento\Framework\Webapi\ServiceInputProcessor` 类 —— 具体来说是 `getConstructorData()` 方法 —— 该方法将通过 REST API 端点接收的嵌套 JSON 对象递归反序列化为完整的 PHP 对象图,**且未验证目标类型是否仅限于 Magento API Data 接口**。 这意味着攻击者可以向深度对象链中注入任意构造函数参数,触及 `Magento\Framework\Session\Config` 等类,并覆盖 `savePath`,将 PHP 的会话处理程序指向攻击者控制的目录 —— 通常是 `media/customer_address/`,恶意序列化会话文件已事先上传至此。 当 Magento 的 `SessionManager` 从重定向的路径加载被投毒的会话文件时,PHP 原生的 `session_start()` 会对攻击者的 payload 触发 `unserialize()`,从而完成 gadget chain 并实现任意文件写入 → RCE。 ### 前置条件 - **基于文件的会话存储** (`var/session/`) —— 基于 Redis/数据库的会话不受此 RCE 链影响(通过其他向量仍可能实现会话接管)。 - **未经认证** —— 无需凭据或客户账户。 - **`/customer/address_file/upload`** 端点可访问 —— 用于在磁盘上植入序列化会话文件。 ## 攻击原理 — 攻击链 无论使用哪种反序列化方法,该漏洞利用都遵循一致的五个阶段序列: ``` ┌─────────────────────────────────────────────────────────────────┐ │ Stage 1 — Gadget chain generation (phpggc) │ │ phpggc -se -a Guzzle/FW1 │ │ → Produces a serialized PHP object that, when deserialized, │ │ writes to on the server. │ ├─────────────────────────────────────────────────────────────────┤ │ Stage 2 — Upload fake session file │ │ POST /customer/address_file/upload │ │ → Uploads the serialized payload as sess_ into │ │ media/customer_address/s/e/ on disk. │ ├─────────────────────────────────────────────────────────────────┤ │ Stage 3 — Redirect session savePath (deserialization) │ │ REST API request with nested JSON that constructs: │ │ SessionConfig::__construct(savePath: "media/customer_...") │ │ → Magento's ServiceInputProcessor builds the full object │ │ graph, overriding the session save path for this request. │ ├─────────────────────────────────────────────────────────────────┤ │ Stage 4 — Trigger session load │ │ GET // with Cookie: PHPSESSID= │ │ → PHP's session_start() reads the malicious file from the │ │ redirected path, triggering unserialize() on the payload. │ ├─────────────────────────────────────────────────────────────────┤ │ Stage 5 — Payload executes │ │ The Guzzle/FW1 gadget chain writes the PHP payload to the │ │ target path (e.g. /pub/errors/404.php), achieving RCE. │ └─────────────────────────────────────────────────────────────────┘ ``` ## 反序列化方法 这三种方法共享相同的核心机制:**注入一个能够触及 `Session\Config` 构造函数并覆盖 `savePath` 的嵌套 JSON 结构**。它们的区别在于**使用哪个 REST API 端点以及哪个参数树**来传递该嵌套对象。 ### 方法 1 — `address` **端点:** `POST /rest/{api_store}/V1/guest-carts/{cart_id}/estimate-shipping-methods` **注入路径:** ``` address → addressConfig → addressHelper → context → urlBuilder → session → sessionConfig → savePath ``` 此方法滥用接受 `address` 对象的 `estimate-shipping-methods` 端点。`ServiceInputProcessor` 沿着构造函数链从地址配置助手一直向下追溯到 `SessionConfig`,并在那里设置 `savePath`。 **关键细节:** 此方法**需要有效的 `cart_id`** —— 端点在处理地址对象之前会验证购物车是否存在。如果你传入一个像 `abc` 这样的虚拟购物车 ID,Magento 会在到达反序列化逻辑之前返回 404。这就是为什么存在 `--sku` 标志:它创建一个包含商品的真实访客购物车,为请求提供有效的 `cart_id`。 ### 方法 2 — `checkmo` **端点:** `POST /rest/{api_store}/V1/guest-carts/abc/set-payment-information` **注入路径:** ``` paymentMethod → method: "checkmo" → paymentData → context → urlBuilder → session → sessionConfig → savePath ``` 使用 `set-payment-information` 端点,并以 Check/Money Order 作为支付方式。`paymentData` 字段通过 `ServiceInputProcessor` 处理,并接受同样的可触及 `SessionConfig` 的嵌套对象链。 **关键细节:** 此方法适用于**虚拟购物车 ID `abc`** —— `set-payment-information` 端点在验证购物车之前处理 `paymentMethod` 对象反序列化。方法名 `checkmo` 必须对应一个已启用的支付方式,但在大多数 Magento 安装中默认是启用的。 ### 方法 3 — `order` **端点:** `PUT /rest/{api_store}/V1/guest-carts/abc/order` **注入路径:** ``` paymentMethod → paymentData → context → urlBuilder → session → sessionConfig → savePath ``` 这是**原版 Searchlight Cyber (Assetnote) PoC** 中发布的向量。它使用向 `order` 端点发出的 `PUT` 请求。与 `checkmo` 一样,它在验证购物车之前处理 `paymentMethod` 对象,因此虚拟 `cart_id` `abc` 有效。 **关键细节:** 服务器通常会对虚拟购物车返回 404 或 500 —— 这是**预期行为并表明反序列化成功**。错误发生在 `ServiceInputProcessor` 已经构建了完整对象图(包括会话路径覆盖)*之后*。 ## 为什么 SKU 和 Cart ID 很重要 此漏洞利用有两种操作模式,这种区别很重要: ### 虚拟购物车模式 (`abc`) — 无 `--sku` 标志 `checkmo` 和 `order` 方法在验证引用的购物车是否实际存在**之前**,就通过 `ServiceInputProcessor` 处理 `paymentMethod` JSON。这意味着: - 无需创建访客购物车 - 目标上无需存在产品 SKU - 使用 `abc` 作为占位符购物车 ID - 服务器返回错误 (404 或 500) —— 但反序列化已经执行 这是最简单、最隐蔽的方法,也是官方 PoC 所使用的。 ### 真实购物车模式 — 提供了 `--sku ` `address` 方法 在处理地址对象**之前**验证购物车。如果购物车不存在,Magento 会短路返回 404,反序列化永远不会发生。对于此向量: 1. 通过 Magento 的 GraphQL 端点验证 SKU(信息性,非阻塞) 2. 通过 `POST /rest/{store}/V1/guest-carts` 创建真实的访客购物车 3. 通过 `POST /rest/{store}/V1/guest-carts/{cart_id}/items` 将 SKU 添加到购物车 4. 在反序列化请求中使用真实的 `cart_id` 此模式对于**支付端点可能受限的目标**(WAF 规则、禁用模块等)但购物车/配送端点仍可访问的情况也很有用。 ## Payload — 写入内容及位置 该漏洞利用使用 `Guzzle/FW1` phpggc gadget chain,它在反序列化时执行**任意文件写入**。`--payload-out` 标志控制服务器上的哪个文件将被你的 payload 覆盖。 ### 为什么要覆盖现有的 PHP 文件? 将新的 `.php` 文件放入 `pub/media/` 等可写目录**通常在生产环境中会失败** —— 不是因为写入失败,而是因为文件永远不会被执行。许多 Magento 部署在 Web 服务器级别限制 PHP 执行: - **Nginx** 规则拒绝在 `pub/media/`、`pub/static/` 和上传目录中执行 PHP - **Apache** `.htaccess` 规则在这些相同路径中禁用 PHP 处理程序 - **反向代理** (Varnish, CDN, 负载均衡器) 可能阻止对意外 PHP 文件的请求 - **云 WAF** (Fastly, Cloudflare, Akamai) 拦截对不匹配已知应用路由的路径的请求 文件落在了磁盘上,但没有 HTTP 请求能到达它。解决方案:**覆盖一个 Magento 在其正常运行中已经执行的 PHP 文件** —— 一个 PHP 解释器*必须*处理的文件,因为应用程序本身包含了它。 | 目标文件 | 生效原因 | |---|---| | **`pub/index.php`** | 应用程序入口点。对商店的每一个请求都经过它。无法通过代理规则阻止 —— 如果你阻止 `index.php`,商店就会瘫痪。| | **`pub/health_check.php`** | 负载均衡器、正常运行时间监控器和云基础设施用于健康探测。必须可访问且可执行 —— 阻止它会导致编排失败和错误的停机警报。 | | **`pub/errors/404.php`** | 当发生 404 时由 Magento 的错误渲染管道在内部加载。在任何缺失的页面上触发 —— 在任何活跃的商店上极其频繁。 | | **`pub/errors/503.php`** | 同样的原理 —— Magento 的维护模式处理程序。 | | **`pub/errors/report.php`** | 异常报告处理程序 —— 当 Magento 记录错误时执行。 | 原理始终相同:选择一个服务器**必须解释**为 PHP 的文件,因为它是应用程序核心路由、健康检查或错误处理的一部分。 ### 此 PoC:裸 `phpinfo()` 包含的 `payload.php` 是一个最小的、非破坏性的执行证明: ``` ``` 它故意保持简单 —— `phpinfo()` 在不造成损害的情况下确认代码执行。**对于真正的授权渗透测试,请将 `payload.php` 替换为你自己的 payload** (webshell, 反向 shell, 回调等),并为环境将 `--payload-out` 指向适当的目标。 ### 示例:后门 `404.php` ``` python3 session_reaper.py --host https://target.com --method order --payload-out /var/www/html/pub/errors/404.php ``` 漏洞利用后,访问 `https://target.com/errors/404.php` 或 `https://target.com/pub/errors/404.php`,如果你看到 `phpinfo()` 输出,则漏洞利用成功。 ## 环境要求 - **Python 3.8+** 及 `requests` 库 - **phpggc** —— 按以下顺序自动解析: 1. `--phpggc` 标志(显式路径) 2. 系统 `PATH` 中的 `phpggc` 3. 常见安装路径 (`/opt/phpggc/`, `~/phpggc/` 等) 4. Docker 镜像 `ambionics/phpggc` (自动拉取) - **`payload.php`** 位于脚本同目录(或通过 `--payload-in` 指定) ### 安装 phpggc ``` git clone https://github.com/ambionics/phpggc /opt/phpggc ``` 或通过 Docker: ``` docker pull ambionics/phpggc ``` ## 使用方法 ``` python3 session_reaper.py --host --method [options] ``` ### 示例 **方法 `order` (官方 PoC 向量) — 最简单,无需购物车:** ``` python3 session_reaper.py --host https://target.com --method order ``` **方法 `checkmo` — 无需购物车,滥用支付端点:** ``` python3 session_reaper.py --host https://target.com --method checkmo --api-store es ``` **方法 `address` — 需要有效的 SKU 和真实购物车:** ``` python3 session_reaper.py --host https://target.com --method address --sku PROD-001 --api-store all ``` **使用自定义商店代码并禁用代理:** ``` python3 session_reaper.py --host https://target.com --method order --store es --api-store default --no-proxy ``` ### 完整选项 | 标志 | 默认值 | 描述 | |------|---------|-------------| | `--host` | *(必填)* | 目标基础 URL | | `--method` | *(必填)* | `address`, `checkmo`, 或 `order` | | `--store` | `default` | 购物车/触发请求的商店代码 | | `--api-store` | `default` | 反序列化端点的商店代码 (`all`/`es`/`default`/自定义) | | `--sku` | *(无)* | 产品 SKU —— 启用真实购物车模式 | | `--payload-in` | `./payload.php` | PHP payload 路径 | | `--payload-out` | `/var/www/html/pub/errors/404.php` | 远程写入路径 | | `--save-path` | `media/customer_address/s/e/` | 会话 savePath 覆盖 | | `--phpggc` | *(自动检测)* | 显式 phpggc 路径 | | `--proxy` | `http://127.0.0.1:8081` | HTTP 代理 (Burp Suite) | | `--no-proxy` | `false` | 禁用代理 | | `--username` | *(无)* | 客户用户名 (可选 Bearer token) | | `--password` | *(无)* | 客户密码 | ## 受影响版本 所有 **2025 年 9 月补丁之前**的 Adobe Commerce 和 Magento Open Source 版本均受影响: - Adobe Commerce ≤ 2.4.9-alpha2, ≤ 2.4.8-p2, ≤ 2.4.7-p7, ≤ 2.4.6-p12, ≤ 2.4.5-p14, ≤ 2.4.4-p15 - Adobe Commerce B2B ≤ 1.5.3-alpha2, ≤ 1.5.2-p2, 1.4.2-p7, ≤ 1.3.4-p14, ≤ 1.3.3-p15 - Magento Open Source ≤ 2.4.9-alpha2, ≤ 2.4.8-p2, ≤ 2.4.7-p7, ≤ 2.4.6-p12, ≤ 2.4.5-p14 - Custom Attributes Serializable 模块 0.1.0 → 0.4.0 **补丁:** VULN-32437-2-4-X-patch via [APSB25-88](https://helpx.adobe.com/security/products/magento/apsb25-88.html) ## 参考链接 | 来源 | 链接 | |--------|------| | **Adobe 公告 (APSB25-88)** | https://helpx.adobe.com/security/products/magento/apsb25-88.html | | **Sansec — SessionReaper 披露** | https://sansec.io/research/sessionreaper | | **Searchlight Cyber (Assetnote) — 原版 RCE PoC & 技术深入分析** | https://slcyber.io/research-center/why-nested-deserialization-is-still-harmful-magento-rce-cve-2025-54236/ | | **Pentest-Tools.com — 漏洞利用开发文章** | https://pentest-tools.com/blog/sessionreaper-cve-2025-54236-exploit | | **Akamai — 野外利用分析** | https://www.akamai.com/blog/security-research/grim-sessionreaper-cve-2025-54236-comes-collect-halloween | | **Flare — 暗网 & Telegram 追踪** | https://flare.io/learn/resources/blog/sessionreaper-cve-2025-54236-dark-web-and-telegram | | **NVD** | https://nvd.nist.gov/vuln/detail/CVE-2025-54236 | | **CISA KEV** | 2025 年 10 月 24 日添加 — 截止日期 2025 年 11 月 14 日 | ## 时间线 | 日期 | 事件 | |------|-------| | 2025 年 8 月 | Blaklis 发现 CVE-2025-54236 | | 8 月 19 日 | Sansec 为 Shield 添加 SessionReaper 防护 | | 8 月 22 日 | Adobe 意外泄露紧急修复 | | 9 月 4 日 | Adobe 向特定客户私下宣布修复 | | 9 月 9 日 | Adobe 发布公开补丁 — APSB25-88 | | 10 月 22 日 | Searchlight Cyber 发布首个公开 RCE PoC;大规模攻击开始 | | 10 月 24 日 | CISA 将 CVE-2025-54236 添加到 KEV 目录 | | 12 月 2 日 | Searchlight Cyber & Pentest-Tools 发布详细技术文章 | ## 免责声明 ## 许可证 [MIT](LICENSE)
标签:Adobe Commerce, CISA项目, CVE-2025-54236, CVSS 9.1, Magento 2, Maven, PHP对象反序列化, PoC, Python, RCE, ServiceInputProcessor, Web安全, 反序列化漏洞, 安全测试, 攻击性安全, 文件会话存储, 无后门, 暴力破解, 漏洞验证, 电商安全, 编程工具, 蓝队分析, 输入验证不当, 远程代码执行