React服务端组件RCE漏洞更新(CVE-2025-55182 / CVE-2025-66478)
自React服务端组件(RSC)远程代码执行漏洞被披露以来,攻击态势持续演变。关于最初的漏洞概念验证、改进的检测方法、在野观察到的利用机制以及快速增长的攻击活动,均出现了新的信息。本文更新了我们在Wallarm客户环境中观察到的变化和发现。
首个PoC漏洞利用并非真实
漏洞披露后不久,一个早期的PoC开始在GitHub上流传。随后证实,该PoC并非针对CVE-2025-55182的真实漏洞利用。相反,它代表了一次不准确的研究尝试,通过手动注册如fs、child_process和vm等危险模块,无意中模拟了一个存在漏洞的服务器,而现实中的RSC应用程序绝不会这样做。
即使在该PoC无效已被公开澄清之后,使用此PoC格式的漏洞利用尝试仍在继续增长。Wallarm在12月3日至4日期间,观察到了大量基于此模板的自动化攻击。
由于许多攻击者只是简单地复用或自动化任何标记为"PoC"的内容,错误或过于简化的代码库仍然会引发大规模的恶意流量。
用于扫描易受攻击部署的实用工具涌现
12月4日,Assetnote Security的研究人员发布了该漏洞的详细技术分析,并介绍了一款用于检测易受攻击的RSC和Next.js部署的Python实用工具。
该工具的发布极大地提高了从业者社区和攻击者识别易受攻击的软件包及服务器配置的能力。
与此前PoC的发布类似,这些扫描工具的发布也引发了一波攻击活动的激增。在最初几小时内,Wallarm记录了超过5500次新的漏洞利用尝试,其中许多直接模仿了扫描工具的结构。
这种扫描方法迅速被改编为:
- 独立的社区扫描器
- Nuclei模板
- 从Assetnote代码分叉出来的自定义脚本
这些变体迅速传播开来,并在12月4日和5日被大量使用,在许多情况下其数量甚至超过了真实的漏洞利用尝试,如下文图表所示。
CVE-2025-55182的首个真实RCE漏洞利用
虽然最初的PoC无效,但CVE-2025-55182的实际RCE漏洞利用链后来得以公开。它基于滥用RSC操作反序列化过程中的不安全导出解析机制。
该载荷利用了React服务端组件如何反序列化和解析元数据字段,允许攻击者遍历JavaScript原型链,最终在服务器上执行任意代码。载荷中的每个字段都用于塑造对象,使其既能被RSC运行时接受,又能触发求值器。其核心组件包括:
then: "$1:__proto__:then"— 建立一个自引用的thenable结构,强制反序列化器遍历__proto__链,暴露继承的属性,而不是将解析限制在安全的操作引用上。status: "resolved_model"— 将对象标记为有效的React服务端组件模型块,使其通过结构验证而不会被拒绝。reason: -1— 通过使根引用以某种方式解析来操纵内部引用处理,以避免在反序列化过程中发生冲突。value: "{\"then\":\"$B1337\"}"— 嵌入一个嵌套载荷,旨在调用$B处理程序,这会影响模型数据的解释方式,并允许进一步控制反序列化流程。_response._prefix— 包含实际的远程代码执行片段。在此示例中,注入的代码使用process.mainModule.require('https')向攻击者控制的域发出出站请求,作为成功执行代码的带外确认。_response._chunks: "$Q2"— 提供一个空的块映射,防止反序列化错误,并确保载荷在结构上被视为有效。_response._formData.get: "$1:constructor:constructor"— 通过遍历原型链(constructor → constructor),将get访问器重定向到Function构造函数。这是将_prefix中攻击者提供的字符串转换为可执行JavaScript的关键步骤。
这些元素共同利用RSC模型解析管道中的漏洞,使攻击者能够将无害的元数据转换为在Node.js运行时内完全执行的JavaScript载荷。其结果是产生一个可靠的、内存中的RCE原语,它不需要向磁盘写入文件,并且仅在进程重启前持续存在。
数据窃取技术
随着漏洞利用技术的成熟,载荷也发展到通过多种渠道返回命令结果。以下是三种主要方法及其背后的技术机制。
响应体输出
载荷将命令输出直接嵌入到序列化的RSC digest字段中,例如:
|
|
反序列化后,服务器将命令结果发送回HTTP响应体中。这提供了直接的、交互式的输出,且载荷复杂度最低。
某些变体将命令输出注入到Next.js内部重定向使用的错误对象中:
|
|
由于框架将digest值反映到特定的HTTP头部中,这允许即使在响应体被覆盖或清理的情况下也能进行数据窃取。
OAST / DNSLog回调
为了进行完全带外的数据窃取,载荷利用Node内部机制来读取和传输数据:
process.mainModule.require('fs')→ 读取文件或命令输出process.mainModule.require('https')→ 将数据发送到攻击者控制的OAST/DNSLog端点
运行时内存Webshell
另一种有趣的技术被公开,演示了攻击者如何通过滥用JavaScript原型行为,利用RSC反序列化缺陷来创建内存中的Webshell。该方法无需向磁盘写入任何内容即可执行任意代码,既隐蔽又有效。
技术原理:
- 使用精心构造的RSC元数据访问原型链属性,如
__proto__和constructor.constructor。 - 这将访问权限提升到能够执行任意代码的强大JavaScript构造函数。
- 注入的脚本导入核心Node.js模块(
http,url,child_process)以获得更深入的控制。 - 重写
http.Server.prototype.emit以拦截所有传入的HTTP请求。 - 添加一个隐藏的端点,如
/exec?cmd=<command>,该端点使用child_process.execSync执行命令。 - 结果形成一个内存中的Webshell,该shell会一直存在直到服务器进程重启,并且不会在磁盘上留下任何痕迹。
Wallarm观察结果与漏洞利用统计数据
Wallarm持续监控客户环境中的漏洞利用活动。主要观察结果包括:
- 无效PoC流量:尽管被证实无效,但在12月4日,错误PoC格式的使用量相比12月3日翻了一番,并持续到12月5日。
- 扫描器衍生的攻击:在Assetnote发布其扫描工具后,社区迅速进行了改编,导致在最初几小时内出现了约5500次攻击,12月4日至5日的扫描流量超过了真实的漏洞利用尝试。
- 真实RCE载荷:一旦准确的技术细节公开,真正的RCE漏洞利用开始出现,包括将扫描器逻辑与利用模式相结合的混合攻击(所有这些都被Wallarm使用现有和更新的RSC特定防护措施成功检测和阻止)。
使用WAF/WAAP绕过技术的漏洞利用尝试
虽然大多数漏洞利用尝试只是简单地模仿原始PoC格式,但Wallarm也观察到一些更高级的尝试,旨在绕过安全控制。例如:
- 填充载荷:用大量不相关的数据填充载荷,以逃避仅检查请求前一部分或难以处理过大载荷的WAF/WAAP产品。
- 轻微结构变异:例如将
["$1:a:a"]改为["$1:aa:aa"],这可以绕过依赖静态签名的WAF。 - 添加二进制数据到多部分请求:在某些漏洞利用请求中,攻击者将高熵二进制数据插入到多部分正文的第一个段。该技术利用了这样一个事实:许多WAF/WAAP解决方案会减少或跳过对二进制载荷的检查以避免误报,从而允许后续的恶意内容绕过更深层次的分析。
这些变体突显出攻击者已经在尝试规避策略,这强化了基于行为检测而非简单签名匹配的必要性。
Wallarm对混淆技术的抵抗能力
Wallarm的WAAP能够抵抗所有这些规避方法。其基于"印记"的攻击检测超越了静态签名匹配,并避免了基于正则表达式方法的性能问题,允许以低延迟快速检查大型或混淆的载荷。
Wallarm专有的基于印记的检测比简单的静态字符串匹配更灵活,即使攻击者修改或重新排列载荷,系统也能识别利用模式。同时,在许多规则必须并发评估时,印记的运行速度也显著快于传统的正则表达式。虽然许多WAF难以(或干脆无法)检查大型请求,有些甚至无法处理超过64KB或8KB的载荷,但Wallarm旨在高效处理大型和高度混淆的输入,在高负载下保持最低延迟。
此外,Wallarm对所有传入请求进行深度递归解析,确保每个组件无论其结构或编码如何都能被分析。检测准确性始终保持高位,因为基于印记的逻辑应用于每个参数和嵌套元素中。
Wallarm对常见的WAF绕过技术也具有高度抵抗力。多重编码和混淆层在检查前会自动进行规范化和解码,防止攻击者通过转换技巧隐藏恶意载荷。
最后,Wallarm提供跨多种API协议(包括REST、GraphQL、SOAP、gRPC和WebSockets)的全面覆盖,并检查所有请求参数,如URI、头部、正文、多部分段甚至JWT,确保无论载荷在何处引入,都能提供一致的保护。
Wallarm检测能力
尽管在流量层面检测并阻止了漏洞利用尝试,Wallarm还使用其他方法来揭示易受攻击的实例和漏洞利用证据:
- 攻击面管理:采用主动扫描方法,识别面向互联网的主机上的易受攻击技术,包括那些未受Wallarm过滤保护的主机。
- 被动检测系统:被动分析应用程序流量,以检测成功漏洞利用尝试的指标,帮助发现可能被忽视的安全事件。