New Nginx Exploit
443 points • 4 days agoArticle Link

该仓库包含针对 CVE-2026-42945 的概念验证利用代码。该漏洞存在于 NGINX 的 `ngx_http_rewrite_module` 中,可追溯到 2008 年,是一起严重的堆缓冲区溢出问题。使用 `rewrite` 和 `set` 指令的服务器可被未认证地远程执行任意代码。与另外三个内存损坏问题(CVE-2026-42946 、 CVE-2026-40701 、 CVE-2026-42934)一起,该漏洞由 DepthFirst 的安全分析系统在一次接入 NGINX 源代码后自动发现。

漏洞源于 NGINX 双遍脚本引擎处理过程中的不一致:先进行长度计算以确定所需缓冲区大小,再执行数据复制。当 `rewrite` 的替换字符串包含 `?` 时,主引擎会设置 `is_args` 标志,但长度计算是在一个全新且已清零的子引擎上进行的。因此长度遍看到 `is_args = 0` 并返回原始捕获长度,而复制遍看到 `is_args = 1`,并以 `NGX_ESCAPE_ARGS` 调用 `ngx_escape_uri`,把每个可转义字节扩展为 3 字节。结果复制操作会用攻击者控制的 URI 数据溢出分配不足的堆缓冲区。

攻击利用跨请求的堆布局(heap feng shui)来破坏相邻 `ngx_pool_t` 结构的 `cleanup` 指针。由于 URI 字节不能包含空字节,攻击者通过 POST 请求体进行喷射以污染该指针,从而把执行流重定向到伪造的 `ngx_pool_cleanup_s`,在内存池销毁时触发对 `system()` 的调用,进而实现远程代码执行。

受影响的 NGINX Open Source 版本为 0.6.27 到 1.30.0,已在 1.31.0 和 1.30.1 中修复;NGINX Plus 受影响的版本为 R32 到 R36,已在 R36 P4 、 R35 P2 和 R32 P6 中修复。

仓库包含可在 Ubuntu 24.04.3 LTS 上测试的部署脚本和 Python 概念验证代码。用户可以用 `./setup.sh` 构建容器,运行 `docker compose -f env/docker-compose.yml up` 启动易受攻击的 NGINX 服务器,并使用 `python3 poc.py --shell` 弹出 shell 。该项目在 GitHub 上获得了 422 颗星和 76 个 fork,主要贡献者为 Zhenpeng Lin (Markakd) 。

101 comments • Comments Link

• 已发布的漏洞利用为了简化演示禁用了 ASLR,但完整的技术文章描述了如何利用该漏洞本身绕过 ASLR,使其在启用 ASLR 的系统上依然构成严重威胁。 ASLR 只是纵深防御的一环,而 LLM 辅助的漏洞利用开发正在迅速降低制作武器化利用的门槛。优先应当修补根本原因,而非单纯依赖缓解措施。

• ASLR 在没有信息泄露的情况下可以完全缓解单个漏洞,但当多个漏洞被串联利用时仍然存在风险。读者有责任对安全声明保持批判性,不能在没有证据的情况下盲信自信的结论。

• 该漏洞需要不寻常的先决条件:在替换字符串中含有问号的 rewrite 指令,后面又跟着引用正则捕获组的 set 指令。许多常见的 nginx 配置(例如在 proxy_set_header 中使用 $host)不受影响,只有那些依赖未命名捕获(如 $1)的配置会受到影响。

• 主流 Linux 发行版并不默认禁用 ASLR,默认通常是模式 1(仅对 PIE 可执行启用 ASLR),而非模式 2(对所有内容强制启用 ASLR)。可以使用 checksec 等工具审计运行中的进程,检查是否缺失必要的加固选项。

• F5 已发布修补版本 1.31.0 和 1.30.1,OpenResty 已发布针对 1.27 和 1.29 的补丁。建议的缓解措施是在重写定义中使用命名捕获而非未命名捕获。

• 由于工作进程通过 fork 共享相同的内存布局,持续触发崩溃可以作为潜在的读取预言机,至少可以可靠地造成拒绝服务。 PoC 假设在演示时禁用了 ASLR,但对有动机的攻击者来说仍然存在真实威胁。

• 虽然像 Caddy 和 Jetty 这样的内存安全替代方案减少了某些类型的漏洞,但它们也有各自的漏洞历史,说明成熟度和安全实现比单纯的语言选择更重要。 Caddy 的静态编译模型对自由软件项目更为简单,但也缺乏传统的插件生态。

• 该漏洞在 nginx 中存在已久,版本号并不总是能准确反映实际的代码变更或安全状态。 Debian 12 和 Ubuntu 24.04 已有可用补丁,用户应通过 apt list nginx 等命令核实具体版本信息。

总体讨论揭示了依赖纵深防御与修补根本原因之间的紧张关系:ASLR 是有价值的屏障,但可以被绕过,前提是攻击者付出足够努力。特定利用链需要不常见的配置,从而降低了大多数用户的攻击面,但漏洞在 nginx 中长期存在凸显了基于 C 的成熟软件中内存安全问题的持久性。内存安全语言虽然带来优势,但并不能免疫其他类别的缺陷,这表明安全开发实践和项目成熟度与语言选择同样重要。社区的响应强调了可行的实际步骤,如使用命名捕获并检查发行版的补丁级别,而不是假定版本号就等同于安全状态。