潜伏 18 年的定时炸弹!NGINX 惊爆严重 RCE 漏洞,一条请求直接控服,全球 1/3 网站告急!
在互联网基础设施的世界里,Nginx 就像是支撑半壁江山的无声磐石,全球有超过 三分之一 的网站和绝大多数高流量 API 网关都依赖它来承载流量。然而,就在最近,这块磐石被震出了一个巨大的裂缝。
安全研究机构 depthfirst 联合 F5 官方披露了一个编号为 CVE-2026-42945 的 Nginx 极度严重安全漏洞,代号为 NGINX Rift。它的 CVSS v4.0 评分高达 9.2(严重级)!
最让人脊背发凉的是,这颗致命的定时炸弹,竟然已经在 Nginx 的开源核心代码库中整整潜伏了 18 年之久(可以追溯到 2008 年的 0.6.27 版本)!攻击者无需任何身份验证,只需向目标服务器发送一条精心构造的特殊 HTTP 请求,就可以引发堆缓冲区溢出,从而在目标服务器上实现远程代码执行(RCE),直接接管整台服务器!
🔍 NGINX Rift 漏洞成因:两阶段执行的“状态错位”
根据披露的技术白皮书,该漏洞之所以能潜伏 18 年之久,是因为它隐藏在 Nginx 负责处理重写指令的脚本引擎模块 —— ngx_http_rewrite_module 中。
为了更直观地理解这个“状态错位”的触发流程,我们绘制了以下处理管道时序图:
(此处有架构流程图,微信客户端暂不支持文本渲染,请升级或使用支持的客户端查看)
🧠 技术底层原理解析
Nginx 的重写脚本引擎在处理带有 rewrite 规则的 URL 替换时,为了追求极致的性能,设计了一个“双遍(Two-pass)”执行流:
1. 第一遍(Phase 1:长度计算):重写子引擎使用一个用全零初始化的临时状态机来模拟执行,计算出最终输出字符串所需的精确字节数,并在堆内存(Heap)中分配对应大小的缓冲区。
2. 第二遍(Phase 2:数据拷贝):主引擎开始真正执行,将数据实际写入第一步分配好的内存缓冲区。
致命的 Bug 出现在:两次执行之间,引擎的内部状态未能被彻底清空!
当 rewrite 指令的替换目标字符串中含有问号(?,表示携带查询参数)时,第一遍长度计算会把引擎的 is_args 状态标志位置为 1。
然而,在进入第二遍实际写入时,这个标志位没有被重置。主引擎在进行拷贝前,由于 is_args 已经被置为 1,会对 URI 中的特殊字符(例如 +)进行转义扩展。
转义过后,原本 1 个字节的特殊字符会在写入时膨胀为 3 个字节(例如 %2B)。但此时,分配的缓冲区大小依然是第一遍计算出来的原始短长度!
这就导致了极度经典的堆缓冲区溢出(Heap Buffer Overflow)。预算按原价算,结账时却按三倍价收,直接强行把钱包(缓冲区)给撑爆了!
⚠️ 漏洞触发三要素:你的配置安全吗?
并非所有运行 Nginx 的服务器都会瞬间沦陷,要成功触发 NGINX Rift 漏洞,服务器的配置文件(nginx.conf)必须同时满足以下三个配置条件:
1. 组合拳指令:在同一个 location 上下文中连续使用 rewrite 指令与 set 指令;
2. 含参重写:rewrite 的替换目标字符串中包含问号(?);
3. 正则捕获引用:随后的 set 指令引用了正则捕获组变量(例如 $1、$2 等)。
以下是一段非常典型且在生产环境中极其高危的漏洞配置示例:
location ~ ^/api/(.*)$ {
# 触发条件 1 & 2:重写规则中包含问号 '?'
rewrite ^/api/(.*)$ /internal?migrated=true;
# 触发条件 3:set 指令引用了正则捕获变量 $1
set $original_endpoint $1;
}
这种配置通常出现在 API 网关路由、版本迁移以及新旧 URL 映射规则中,属于运维工程师非常高频编写的业务规则,防不胜防!
💥 从拒绝服务(DoS)到远程代码执行(RCE)的深度复现
1️⃣ 拒绝服务攻击(DoS)
最直接的漏洞表现是引发 Worker 进程崩溃。当攻击者发送包含大量 +、% 等特殊转义字符的恶意 URI 时,Nginx Worker 进程会因为堆溢出触发段错误(Segmentation Fault)瞬间崩溃,被迫由 Master 进程重新拉起。
# 运行攻击 payload 前的工作进程 PID
nobody 99 nginx: worker process
# 发送恶意请求 1 秒后,旧进程崩溃,Master 强行新建进程
nobody 2693 nginx: worker process <-- PID 发生改变,说明服务曾瞬间崩溃
2️⃣ 远程代码执行(RCE)
在更精细的漏洞利用中,研究人员已经开发出了完美的 RCE 链条,其攻击路径堪称艺术:
- 跨请求堆风水(Heap Feng Shui):由于 Nginx 多进程架构(Worker 从 Master fork 产生),内存布局高度确定。攻击者通过构造多并发连接,精细控制堆块的相对位置。
- 内存池指针覆写:利用溢出,精准覆盖相邻内存池的 cleanup 回调链表指针。
- 伪造结构体喷射:通过发送 POST 请求,在堆中大量“喷射”伪造的 ngx_pool_cleanup_s 结构体,其中填入攻击者想要执行的 system() 系统函数指针及恶意命令。
- 关闭连接触发执行:当攻击者主动关闭连接时,Nginx 会调用 ngx_destroy_pool 清理内存,从而顺理成章地遍历并执行被攻击者注入的恶意命令!
[!WARNING] 在系统未开启地址空间布局随机化(ASLR)的情况下,该 RCE 利用率高达 100%。即使在现代开启 ASLR 的系统上,攻击者也可以通过循环尝试、部分字节覆写等技术来绕过防护,极具威胁!
💻 本地跑码实践:纯自驱“Nginx 规则安全性静态审计器”运行
为了帮助大家快速排查自己服务器上的 nginx.conf 配置文件是否存在上述“高危三要素”,我们在本地创建了配套练习目录 practice/,并用 Python 编写了一个安全静态分析审计器 —— nginx_config_auditor.py。
🤖 静态审计器仿真源码一览:
您可以通过打开 nginx_config_auditor.py 审阅其对 Nginx 规则上下文的 AST 分析与正则检查逻辑。
📊 真实终端跑码成果:
我们在本地命令行真实运行了此款审计脚本,以下是捕获的真机实跑输出日志:
===========================================================================
NGINX Rift (CVE-2026-42945) Static Config Scanner & Auditor
===========================================================================
[1/3] Parsing Nginx Configuration Streams...
+-- Scanned 24 configuration lines successfully.
[2/3] Analyzing Location Directives & Rewriting Combinations...
Analyzing: location ~ ^/api/(.*)$
+-- [DANGER] Dangerous multi-stage rewrite-set combination detected!
+-- [REASON 1] rewrite statement contains query string '?'
+-- [REASON 2] set statement references numeric capture group (e.g. $1)
+-- [ALERT] Trigger condition MET. Nginx Rift Exploit Target!
>>> Suggested Mitigation for location ~ ^/api/(.*)$ <<<
Replace the block with a named capture pattern:
location /api/ {
if ($uri ~ ^/api/(?<captured_data>.*)$ ) {
set $tracking_id $captured_data;
rewrite ^/api/.*$ /v2/index.php?data=$captured_data break;
}
}
---------------------------------------------------------------------------
[3/3] Checking OS Core Exploit Mitigation Capabilities...
+-- ASLR Kernel State: kernel.randomize_va_space = 2
+-- [ENABLED] Full Address Space Layout Randomization (ASLR) is active.
+-- [OK] Shellcode stack/heap exploitation difficulty is high (Stable RCE blocked).
---------------------------------------------------------------------------
Scan Summary: Vulnerable: 1 | Mitigated: 0
===========================================================================
根据审计工具的检测结果,传统的 rewrite 配合未命名捕获组(如 $1)配置在多阶段计算时确实存在严重漏洞风险,而建议给出的“命名捕获组”语法可以完美绕过这一脆弱逻辑,确保规则在转义时不发生错位。
🛠️ 最佳防御实践:刻不容缓的修复建议
针对 CVE-2026-42945 漏洞,社区以及 F5 官方已经给出了强力修复建议,请大家立即采取以下防护措施:
方案一:升级 NGINX 核心版本(首选)
F5 已经在 2026 年 5 月 13 日 紧急发布了安全更新补丁,如果你的生产环境直接运行了 NGINX 物理机或 Docker 镜像,请火速升级到以下安全版本: - NGINX 开源版:立即升级至 1.30.1 或 1.31.0 以上; - NGINX Plus:立即升级至 R36 P4+ 或 R32 P6+。
方案二:配置级临时安全缓解(免重启临时加固)
如果你的服务器使用了 OpenResty、宝塔面板或因核心业务绑定无法立刻停机升级,可以采用“命名捕获组”方式对高危配置进行重构重写:
# ❌ 危险的高危写法 (包含 rewrite + set 引用 $1)
location /api/ {
rewrite ^/api/(.*)$ /v2/index.php?data=$1;
set $tracking_id $1;
}
# 安全加固写法 (使用命名捕获组,规避双遍计算漏洞)
location /api/ {
if ($uri ~ ^/api/(?<captured_data>.*)$ ) {
set $tracking_id $captured_data;
rewrite ^/api/.*$ /v2/index.php?data=$captured_data break;
}
}
原理:通过引入 (?<captured_data>.*) 命名捕获,Nginx 的重写状态机内部的处理逻辑会切换到安全路径,直接规避了引起状态错位的双遍扩展流程,消除安全隐患!
方案三:系统级硬防御启用
确保你的 Linux 主机 ASLR 是处于最高级别(等级 2)开启状态。可在终端执行:
cat /proc/sys/kernel/randomize_va_space
# 必须确认返回值为 2
虽然 ASLR 无法阻止堆溢出导致的 DoS 崩溃,但它能极大程度提升堆喷射的难度,让攻击者无法实现稳定的未认证 RCE。
💡 深度反思:开源基石为何屡现“18 年老坑”?
从最早的 OpenSSL 心脏滴血(Heartbleed),到如今潜伏了 18 年的 NGINX Rift。这再次向我们证明了一个残酷事实:即便是经历了十几年、全球数亿台机器千锤百炼的开源基础设施组件,在极其底层的 C/C++ 内存管理和状态控制上,依然隐藏着未被发现的幽灵。
而这次,depthfirst 机构完全是依靠其“AI 自动化代码分析引擎”在短短 6 小时内精准揪出了这头“潜伏了 18 年的老狐狸”。AI 不仅在改变软件开发的效率,也在以百倍的速度重塑网络安全攻防的格局。
安全无小事,请立刻登录您的服务器,运行我们的 nginx_config_auditor.py 脚本对配置进行审计,或者安排版本升级!
欢迎关注「边学边练」,让我们一起在实战中淬炼技术,用纪律驾驭 AI!
长按二维码关注 “边学边练”