Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2025-55182-research — CVE-2025-55182的技术概念验证与深度分析,这是React Flight协议中一个严重的RCE漏洞,涉及路径遍历、伪造chunk注入以及$B处理器滥用。 | Kitploit
工具/GitHubGitHub/ejpir/cve-2025-55182-research
漏洞分析漏洞利用Web应用程序漏洞利用WAF绕过论文与研究学习与教育Payload 开发
GitHubejpir/cve-2025-55182-research

CVE-2025-55182-research

CVE-2025-55182的技术概念验证与深度分析,这是React Flight协议中一个严重的RCE漏洞,涉及路径遍历、伪造chunk注入以及$B处理器滥用。

查看仓库
795202279个月前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2025-55182 - React Server Components RCE

NOTE: Written by AI/Claude

https://github.com/ejpir/CVE-2025-55182-bypass

TL;DR

CVE-2025-55182 是 React 的 Flight Protocol 中的一个严重 RCE 漏洞。该攻击链结合 路径遍历 + 伪造 chunk 注入 + $B 处理器滥用 来执行 Function(attacker_code)。

衷心感谢 maple3142 提供了可用的利用链!


The Exploit

Attack Overview

该漏洞利用三个表单字段来构造恶意负载:

  1. 创建一个带有自引用 then 的伪造 chunk 对象(字段 1 $@0 → 字段 0)
  2. 嵌入一个伪造的 _response,其中 _formData.get 设置为 $1:constructor:constructor
  3. 触发 $B 处理器,它会调用 response._formData.get(response._prefix + id)
  4. 路径遍历将 _formData.get 解析为 Function,从而执行 Function(code)

Exploitation Flow```

┌─────────────────────────────────────────────────────────────────────┐ │ 1. Attacker sends multipart form with fake chunk object │ │ → decodeReply() parses form fields 0, 1, 2 │ │ → Object has: then, status, value, _response │ └─────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ 2. Self-reference makes object thenable with real function │ │ → then: "$1:proto:then" → Chunk.prototype.then │ │ → Chunk.prototype.then(this) calls initializeModelChunk(this) │ │ → Uses this._response (attacker's fake _response) │ └─────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ 3. parseModelString() handles "$B1337" reference │ │ → case "B": return response._formData.get(response._prefix+id) │ │ → Calls _formData.get with attacker's _prefix + "1337" │ └─────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ 4. getOutlinedModel() resolves _formData.get (lazy evaluation): │ │ → "$1:constructor:constructor" traverses prototype chain │ │ → Returns Function constructor │ │ → Function(code + "1337") → RCE │ └─────────────────────────────────────────────────────────────────────┘

### 关键组件

| 组件 | 用途 |
|-----------|---------|
| `then: "$1:__proto__:then"` | 自引用 thenable;块 1(`$@0`)指回块 0 |
| `status: "resolved_model"` | 使对象看起来像有效的 React 块 |
| `reason: -1` | 将 rootReference 设置为 undefined(避免引用冲突) |
| `value: '{"then":"$B1337"}'` | 触发 `$B` 处理器的嵌套载荷 |
| `_response._prefix` | 包含 RCE 代码字符串 |
| `_response._chunks: "$Q2"` | 空 Map,用于防止块处理期间崩溃 |
| `_response._formData.get` | 通过 `$1:constructor:constructor` 指向 `Function` |

### 组件深入解析

#### 表单字段结构

该漏洞利用三个具有循环引用的表单字段:```
Field 0: {"then":"$1:__proto__:then", "status":"resolved_model", ...}
Field 1: "$@0"    ← references back to field 0
Field 2: []       ← empty array for _chunks Map

自引用 Thenable(then)

then: "$1:__proto__:then" 创建了一个自引用,该引用解析为一个 真实函数:``` $1:proto:then ↓ $1 → chunk 1 → "$@0" → getChunk(0) → Chunk object ↓ Chunk.proto.then → Chunk.prototype.then (actual function!)

**为什么这至关重要:**

1. `then` 解析为 `Chunk.prototype.then` —— 一个真实的可调用函数
2. 这使得伪对象成为合法的 thenable
3. 当被 await 时,JS 会调用 `obj.then(resolve, reject)`
4. `Chunk.prototype.then` 以伪对象作为 `this` 执行:```javascript
Chunk.prototype.then = function (resolve, reject) {
  switch (this.status) {  // this.status = "resolved_model" ✓
    case "resolved_model":
      initializeModelChunk(this);  // fake object passed!
  1. initializeModelChunk(this) 使用 this._response - 攻击者伪造的 _response:```javascript value = reviveModel( chunk._response, // ← attacker's fake _response! ... );
**没有自引用**,伪造的 `_response` 将永远不会被使用。自引用使得 `Chunk.prototype.then` 将攻击者的对象视为真正的 Chunk。

#### 两阶段 Thenable 触发(`value`)

`value` 字段包含一个嵌套的 JSON 字符串,其中含有另一个 thenable:```json
{"then":"$B1337"}

Stage 1: 外部对象的自引用 then 触发分块处理

Stage 2: 当 React 解析模型时,它会解析 value 并遇到另一个带有 then: "$B1337" 的 thenable。$B 前缀触发处理器:```javascript case "B": return response._formData.get(response._prefix + obj); // obj = "1337"

`_formData.get` 的值是 `"$1:constructor:constructor"` → `getOutlinedModel()` 解析为 `Function`。

这变成了:`Function(code + "1337")` → 有效的 JS,因为 `1337` 只是一个尾随表达式。

#### 防御性填充(`_chunks`)

伪造的 `_response` 需要一个有效的 `_chunks` 属性以防止崩溃:```
Form field "2": []           ← empty array
_chunks: "$Q2"               ← $Q = Map type, creates new Map([])

React 的内部代码在处理过程中可能会访问 response._chunks.get() 或 response._chunks.has()。空的 Map 可以无错误地满足这些调用,从而使执行流到达存在漏洞的 $B 处理器。


易受攻击的代码路径

路径函数在漏洞利用中的用途
路径遍历getOutlinedModel()解析 $1:constructor:constructor → Function
伪造 _response 注入initializeModelChunk()使用攻击者的 chunk._response
$B 处理器parseModelString()调用 _formData.get(_prefix + id) → RCE

decodeReply() 是入口点,本身并不易受攻击。

路径遍历(getOutlinedModel()):```javascript for (key = 1; key < reference.length; key++) parentObject = parentObject[reference[key]]; // No validation!

**伪造响应用法** (`initializeModelChunk()`):```javascript
value = reviveModel(
  chunk._response,  // Uses chunk._response directly!
  { "": rawModel },
  ...
);

$B 处理器 RCE (parseModelString()):```javascript case "B": return response._formData.get(response._prefix + obj); // RCE!

---

## 修复(19.2.1)

该补丁包含多项修复:

1. **`RESPONSE_SYMBOL` 在 `initializeModelChunk()` 中** - 关键修复   ```javascript
   // BEFORE: chunk._response (attacker can set via JSON)
   value = reviveModel(chunk._response, ...);

   // AFTER: Symbol lookup (cannot be forged via JSON)
   var response = chunk.reason[RESPONSE_SYMBOL];
   value = reviveModel(response, ...);
  1. getOutlinedModel() 中的 hasOwnProperty 检查 - 阻止原型链遍历 ```javascript hasOwnProperty.call(value, name) && (value = value[name]);
  2. __proto__ 在 reviveModel() 中的处理 - 防止原型污染 ```javascript void 0 !== parentObj || "proto" === i ? (value[i] = parentObj) : delete value[i];
  3. 在 initializeModelChunk() 中进行类型检查 - 验证监听器 ```javascript "function" === typeof listener ? listener(value) : fulfillReference(response, listener, value);

影响与版本

影响评估

能力状态备注
原型链遍历✓ 已确认通过 $1:constructor:constructor
访问 Function 构造器✓ 已确认无需 manifest
完全远程代码执行(RCE)✓ 已确认通过伪造 chunk + $B 处理器

受影响版本

  • react-server-dom-webpack:19.0.0、19.1.0、19.1.1、19.2.0
  • react-server-dom-turbopack:相同版本
  • Next.js:15.x、16.x(补丁发布前),14.3.0-canary.77+ 及之后的 canary 版本

修复版本

  • React:19.0.1+、19.1.2+、19.2.1+
  • Next.js:15.0.5、15.1.9、15.2.6、15.3.6、15.4.8、15.5.7、16.0.7+

为什么基于特征签名的 WAF 检测会失效

本节解释为什么传统的模式匹配 WAF 规则无法可靠地检测此漏洞。了解这些局限性对于安全团队评估其防御态势至关重要。

核心问题:多层编码

攻击载荷会经过多个解析器,每个解析器支持不同的编码方式。检查原始 HTTP 字节的 WAF 看到的是编码后的字符串,但服务器在处理前会对它们进行解码:

层解析器解码内容
JSON 结构JSON.parse()\uXXXX Unicode 转义
JavaScript 代码Function() 构造函数\uXXXX、\xXX、八进制、fromCharCode()

这造成了根本性的不匹配:WAF 看到的是编码字节,而应用程序看到的是解码后的字符串。

签名需要匹配的内容

一个简单的 WAF 可能会查找类似 constructor、__proto__、resolved_model 或 child_process 的模式。然而,JSON 允许对任何字符使用 Unicode 转义:

字面模式Unicode 等价形式WAF 检测
constructor\u0063onstructor已绕过
__proto__\u005f\u005fproto\u005f\u005f已绕过
resolved_model\u0072esolved_model已绕过
$@(循环引用)$\u0040已绕过

载荷中的 JavaScript 代码拥有更多编码选项:

下载工具