共计 3373 个字符,预计需要花费 9 分钟才能阅读完成。
文章目录[显示]
加群领脚本:本文检测脚本及微信群关注本微信公众号,见文末即可立即获得检测脚本,无需关注其他账号,第一时间收到漏洞预警和一手分析。
上周我的工作群突然炸了。
十几条消息连着进来,都在转同一篇文章——「紧急!nginx 惊现 18 年高危漏洞,CVSS 9.2 分,数亿服务器遭 RCE 攻击风险」。
群里有人开始问要不要今晚就重启服务器,有人已经在拉升级方案,还有人直接在生产环境里把 nginx 停了……
我看着这些消息,翻了一遍那些刷屏的文章,发现一个共同点:每篇都在复读厂商公告,没一篇说清楚你的机器到底安不安全。
所以我认真研究了下漏洞原理,实际跑了一遍。
先说结论,省得你看完还不知道该怎么办
- 用 Ubuntu / Debian / CentOS 官方仓库装的 nginx,90% 的情况下不需要恐慌
- 自己从源码编译的 nginx,且配置了特定的 rewrite 规则,需要认真对待
- 所有人都应该升级,但 大多数人可以等下次维护窗口,不用今晚连夜动
具体怎么判断自己在哪个情况里,往下看。
漏洞是什么
这个漏洞编号 CVE-2026-42945,研究人员给它起了个名字叫「Nginx Rift」,发现于 nginx 的 URL 重写模块(ngx_http_rewrite_module),从 2008 年就埋在代码里了。
用生活化的方式解释:
nginx 处理 URL 改写(rewrite)时,内部有个两步走的流程——先量尺寸,再填内容。就像搬家前先量好家具尺寸,再订合适的包装箱。
问题是 " 量尺寸 " 和 " 填内容 " 用的不是同一把尺子。量尺寸的时候,某个状态变量是 0(忽略 URL 参数符号 ?),填内容的时候,同一个变量变成了 1(需要对特殊字符做转义,一个字符变三个字节)。
结果就是:量出来的箱子装不下实际要塞的东西,溢出了。这个溢出发生在堆内存上,理论上攻击者可以借此覆盖相邻内存,执行任意代码。
漏洞是真实的,代码缺陷切实存在。但接下来这段话才是关键——
9.2 分这个数字,有多少水分
NVD 官方公告里有一句很关键的话,刷屏的文章几乎没人引用:
"Code execution possible on systems without ASLR protection"
翻译过来:只有在 ASLR 关闭的系统上,才存在代码执行的可能。
ASLR(地址空间随机化)是现代操作系统的标配。每次程序启动,内存地址都是随机的,攻击者就算知道漏洞存在,也不知道要往哪里打——就像你知道对方的金库有漏洞,但每天早上金库都会随机传送到城里某个位置,你找都找不到。
所有现代 Linux 发行版默认开启 ASLR。你可以现在就验证:
cat /proc/sys/kernel/randomize_va_space
输出 2 就是完整开启。几乎所有生产服务器都是这个状态。
官方 POC 之所以能打成 RCE,是因为作者在 Docker 测试环境里 专门手动关掉了 ASLR,相当于把金库固定在了一个位置,然后说 " 你看,打进去了 "。
要打成 RCE,需要同时凑齐三把钥匙
我实际分析 POC 代码后发现,要从 " 存在漏洞 " 到 " 执行任意命令 ",攻击者需要同时满足三个条件。少一个,攻击链就断了。
钥匙一:nginx 必须有特定的配置组合
不是所有用了 rewrite 指令的 nginx 都中招,触发漏洞的扳机是这样的配置:
location ~ ^/api/(.*)$ {rewrite ^/api/(.*)$ /internal?migrated=true; # 替换串里含 ?
set $original_endpoint $1; # 同块内用捕获组赋值
}
rewrite 和 set 单独用没事,合在一起、且替换串含 ? 才会触发那个 " 量短尺填长数据 " 的 bug。这是 nginx 在做 URL 迁移或参数透传时才会写的配置,默认安装的 nginx 完全不涉及。
钥匙二:关闭 ASLR
如上所说,现代 Linux 默认开启,你的生产服务器大概率不满足这个条件。
钥匙三:堆地址字节恰好全部是 URL 安全字符
这个条件最 " 刁钻 "。POC 的攻击方式是把目标内存地址藏在 URL 里发过去,但 URL 里有些字节是非法的(比如空字节 \x00、高位字节 \xd7 等),nginx 收到会直接做转义处理。
攻击者需要目标堆地址的每一个字节都恰好是 URL 安全字符。在 POC 的 Docker 环境里,堆落在 0x5555xxxxxxxx(全是 0x55,安全)。我在本机 Ubuntu 上实测,堆在 0x603cd7xxxxxx,含有 0x3c、0xd7 等非法字节,POC 直接报错:
[!] No safe heap addresses found — adjust HEAP_BASE
打不进去。即使我手动关了 ASLR,也打不进去。
发行版打包的 nginx,还有额外的护城河
Ubuntu 官方打包的 nginx 在编译时加了一批安全选项,这是自行编译没有的:
-fcf-protection ← Intel CET,硬件级别拦截非法跳转
-D_FORTIFY_SOURCE=3 ← 增强内存函数溢出检测
-Wl,-z,now ← Full RELRO,函数地址表锁死为只读
-fstack-protector-strong ← 栈保护
这些不是 nginx 官方加的,是发行版打包时加的。自行从源码 ./configure && make 编译的 nginx 没有这些,风险高得多——这也是为什么 POC 在 Docker(自行编译)里能跑通,在 Ubuntu 系统包上跑不通。
三种情况,三个结论
| 情况 | 实际风险 |
|---|---|
默认安装,没有 rewrite+set 组合配置 |
无影响,CVE 和你没有关系 |
| 有触发配置,用发行版官方包(Ubuntu/Debian/CentOS) | DoS 风险:攻击者可让 worker 进程崩溃,nginx 会自动拉起,用户感知约为请求超时 1-2 秒 |
| 有触发配置,自行编译,ASLR 关闭 | RCE 风险:条件苛刻但理论成立,需立即处理 |
「DoS 风险」的意思是:你的服务可能被人打崩溃后自动重启,但服务器不会被人拿走。跟「RCE 风险」(服务器被人接管)是完全不同的量级。
一分钟自查
把下面这个脚本放到你的服务器上跑(需要 sudo 权限),它会逐项检查版本、配置、ASLR、编译加固,最后给出低 / 中 / 高三档结论:
sudo bash check_cve_2026_42945.sh
脚本输出示例(有漏洞配置但 ASLR 开启的情况):
[!] 版本 1.24.0 在受影响范围内,继续检查触发条件...
[!] 发现漏洞触发配置:→ location ~ ^/api/(.*)$ {[✓] ASLR 已启用(级别 2,完整随机化)→ RCE 可靠利用所需前提不满足,最坏情况为 worker 进程崩溃(DoS)[✓] 检测到 -fcf-protection(Intel CET 控制流保护)[✓] 检测到 FORTIFY_SOURCE=3
[✓] 检测到 Full RELRO(GOT 只读)风险等级:低
建议:在下次维护窗口升级到 nginx 1.30.1 / 1.31.0
该怎么处理
升级是正确的,但节奏要根据你的实际风险来定:
没有触发配置的: 正常排期,下次例行维护时顺手升一下。
有触发配置、用系统包的: 可以等官方仓库更新,Ubuntu 的 apt update && apt install nginx 到位后升级。这期间最坏的情况是偶发的 worker 崩溃(有人专门来打你的话),nginx 会自动重启,可用性有轻微影响。
有触发配置、自行编译的: 建议尽快。临时措施是把触发漏洞的 rewrite+set 组合改写成等价的 map 或 if 实现,不需要停服。
修复版本:
- nginx 开源版:1.30.1(稳定版)/ 1.31.0(主线版)
- NGINX Plus:R36 P4 / R35 P2 / R32 P6
官方公告:https://nvd.nist.gov/vuln/detail/CVE-2026-42945
写在最后
漏洞是真实的,但 9.2 分是在 " 关闭 ASLR、有特定配置、堆地址恰好合法 " 这个理想化靶场环境下打出来的分数。你的生产服务器大概率不在那个环境里。
我不是说不用管,是说要用事实判断风险,而不是被一个分数吓到连夜停服务器。
安全这件事,跟看病一样——同样是 " 发烧 ",37.5 度和 40 度的处理方式完全不同。分清楚自己是哪种,比一看到标题就开始恐慌有用得多。
👇 扫码加入安全技术交流群
漏洞预警 · 一手分析 · 检测脚本直取
群内不定期同步高危 CVE 进展,不转发未经验证的二手信息。
人满加微信 Linux0127。
脚本及加群获取方式:搜索关注 风叶林 公众号,回复42945 即可立即获得检测脚本。