结合 PoolSlip 堆越界读取泄漏(CVE-2026-9256)与 rift 溢出(CVE-2026-42945)的 ASLR 无关 nginx RCE 链 PoC,可在原版 nginx 上到达 system()。
首个公开的利用链,将两个近期披露的 nginx rewrite 引擎漏洞串联为针对 官方原版 nginx:1.30.0 Docker 镜像
(Debian 13,glibc 2.41)的单个 与 ASLR 无关的远程 system() —— 无硬编码地址,无需重启 nginx,每个新 worker 约 90% 成功率。
$args 堆越界读取 → 泄露实时的 libc + 堆 地址。is_args 堆溢出(仅限 URL 安全字节)→ 对 limit_conn 清理指针进行 2 字节部分覆写 → ngx_destroy_pool 遍历该指针 → system(cmd)。两者都是 同一个 is_args 两遍处理不匹配问题指向两个不同的利用点。完整技术分析:Writeup
披露与安全
- 两个 CVE 均 已修复,且 正在被积极利用。请升级到 nginx 1.30.2(稳定版)或 1.31.1(主线版) —— 注意
1.30.1修复了 rift,但 仍然 受 PoolSlip 影响,因此只有1.30.2能同时关闭两者。NGINX Plus:R36 P5 / R32 P7 / R37.0.1.1。- 本文仅出于 教育和授权测试目的 发布。它针对的是 捆绑的本地 Docker 实验环境 —— 切勿 将其指向你不拥有或未获得书面许可测试的基础设施。
| CVE | 代号 | 受影响版本 | 修复版本(nginx OSS) |
|---|---|---|---|
| CVE-2026-42945 | rift | 0.6.27 – 1.30.0 | 1.30.1 / 1.31.0 |
| CVE-2026-9256 | PoolSlip | 0.1.17 – 1.30.1 + 1.31.0 | 1.30.2 / 1.31.1 |
| 文件 | 用途 |
|---|---|
nginx.conf | 一个可信的 API 网关配置(即 目标 —— 包含 limit_conn、v1→v2 迁移 rewrite、上传代理、降级搜索页面)。无分配器调优。 |
run.sh | 搭建本地实验环境:原版 nginx:1.30.0 提供 nginx.conf 服务,外加一个慢速上游,监听主机 :19322。 |
exp_official.py | 完整利用链:PoolSlip 泄露 → 推导 libc/堆 → 喷射 → 布局整理 → rift 部分覆写 → system()。 |
exp_official.py)、curl、Linux x86-64。run.sh 使用 perl(原版 nginx 镜像中已包含)实现慢速上游,因此无需额外软件包、无需 slow_backend 文件、无需联网。nginx 二进制文件本身保持原版。WRITEUP.md 中的 gdb 调试会话,可 docker exec 进入容器并 apt-get install gdb file binutils,然后加载 gef。git clone https://github.com/y198nt/Nginx-chain-Rift-Poolslip
cd Nginx-chain-Rift-Poolslip
bash run.sh # stock nginx:1.30.0 on http://127.0.0.1:19322
python3 exp_official.py --cmd 'id > /tmp/rce_proof' # leak → overwrite → system()
docker exec nginx-rift-official cat /tmp/rce_proof # → uid=101(nginx) ...
exp_official.py 是 一次性 的(每个新 worker 约 90% 成功率):它只泄露一次、只触发一次。如果
证明文件为空,说明布局整理偏差了一个槽位 —— 重新运行即可。
docker rm -f nginx-rift-official # tear the lab down
rewrite ^/search/((.*))$ /lookup?$1$2 使复制过程将
r->args.len 设置得 超出 缓冲区;降级的 /search 页面将 $args 反射到相邻堆内存中。
经过短暂预热后,一个 libpcre-cluster 指针(位于 libc 下方固定偏移 0xb0ad08)和一个堆
指针会稳定在固定偏移处 → 得到 libc_base 和 heap_base,无任何硬编码。limit_conn 清理指针的 低 2 字节 —— ASLR 随机的高字节原封不动地保留 →
与 ASLR 无关。ngx_pool_cleanup_t{handler=&system, data=cmd, next=0};关闭受害者连接会触发 ngx_destroy_pool 的清理遍历 →
system(cmd)。完整推导、gdb 调试会话以及死胡同/转向过程见 Writeup。
rewrite 触发:其替换内容包含 ? 且 引用了 PCRE
捕获组($1/$2),或类似 ^/x/((.*))$ → /y?$1$2 的嵌套捕获模式。请审计配置中
此类写法,并在打补丁前重写有问题的 rewrite/set。$args(或任何回显的请求派生变量)是将越界读取转化为信息泄露的关键 —— 不要逐字反射请求参数。%2B/+ 洪水(GET /search/+++…)、降级页面回显长 $args 导致的 503,以及 worker SIGSEGV/重启风暴。