simota/nginx-rift-scanner
GitHub: simota/nginx-rift-scanner
用于检测NGINX Rift漏洞的Python 3扫描器。
Stars: 0 | Forks: 0
# nginx-rift-scanner
无依赖的 Python 3 扫描器,用于检测 **CVE-2026-42945 ("NGINX Rift")** — 在 `ngx_http_rewrite_module` 中存在一个 CVSS v4.0 **9.2 CRITICAL** 堆栈缓冲区溢出(CWE-122)。
## 检测内容
每次调用都会运行两个独立的检查:
| 检查 | 如何 |
|------|-----|
| **版本** | `nginx -V`,`dpkg`/`rpm`/`apk`,Dockerfile/compose 镜像标签 |
| **配置模式** | `nginx.conf` 的花括号感知解析 + 所有 `include` 文件 |
### 受影响版本
| 版本 | 易受攻击 | 已修复 |
|------------|---------------------------------|------------------------------|
| NGINX OSS | 0.6.27 – 1.30.1 | 1.31.0+(或 1.30.1 补丁) |
| NGINX Plus | R32 之前 R32P6 | R32P6+ |
| NGINX Plus | R36 之前 R36P4 | R36P4+ |
| NGINX Plus | R37+ | 未受影响 |
### 配置触发模式
当 **以下三个条件都满足** 时,将标记作用域块:
1. 一个 `rewrite`、`if` 或 `set` 指令使用一个 **未命名的 PCRE 捕获** 引用(`$1`–`$9`,包括花括号形式 `${1}`–`${9}`)。
2. 该指令的 **值/替换参数** 包含一个 `?` 字符(对于 `rewrite`/`set`,正则表达式模式参数被排除 — 那里的 `?` 是一个 PCRE 量词;`if` 条件是保守扫描的)。
3. 另一个 `rewrite`/`if`/`set` 指令 **在同一作用域中跟随**(`include` 被拼接到包含的作用域中,因此跨越 `include` 边界的对会被检测到)。
## 快速开始
```
# 克隆并运行
git clone https://github.com/simota/nginx-rift-scanner.git
cd nginx-rift-scanner
# 扫描本地 nginx(PATH 中的二进制文件,配置在 /etc/nginx/nginx.conf)
python3 scripts/scan_nginx_rift.py
# 自定义路径
python3 scripts/scan_nginx_rift.py \
--nginx-binary /usr/sbin/nginx \
--config /etc/nginx/nginx.conf \
--prefix /etc/nginx \
--scan-dir /app
# JSON 输出(CI / SIEM)
python3 scripts/scan_nginx_rift.py --json
# 使用包含的测试用例验证
python3 scripts/scan_nginx_rift.py --config fixtures/vulnerable.nginx.conf
python3 scripts/scan_nginx_rift.py --config fixtures/safe.nginx.conf
```
退出代码:`0` = 清洁,`1` = 被标记为易受攻击 / 可能易受攻击的版本或配置模式。
## 选项
| 标志 | 默认 | 描述 |
|------|---------|-------------|
| `--nginx-binary PATH` | `nginx` | nginx 可执行文件的路径 |
| `--config PATH` | `/etc/nginx/nginx.conf` | 扫描的根 nginx 配置 |
| `--prefix PATH` | `--config` 的目录 | nginx 配置前缀,用于解析相对 `include` 路径(nginx 使用前缀解析它们,而不是包含文件的目录) |
| `--scan-dir PATH` | `.` | 搜索 Dockerfile/compose 文件的目录 |
| `--json` | — | 将 JSON 报告输出到 stdout |
## 补救措施
**升级**(首选):
- OSS → NGINX ≥ 1.31.0(或应用 1.30.1 稳定补丁)
- Plus → R32P6+,R36P4+,或 R37+
**绕过方法** — 在每个包含 `?` 的 `rewrite`/`if`/`set` 指令中将未命名的捕获替换为命名捕获:
```
# 有漏洞
rewrite ^/api/(\w+)$ /new-api?path=$1 last;
# 安全
rewrite ^/api/(?\w+)$ /new-api?path=$action last;
```
## 假阳性说明
配置发现是 **启发式** 的。标记的指令并不保证可利用性 — `?` 可能不在 URI 构造路径中,或者捕获引用可能不会与导致溢出的分配交互。在优先考虑补救措施之前,每个发现都应该由人工审查。
## 要求
- Python 3.6+(stdlib 仅限 — 无 pip 安装)
- `nginx` 二进制文件(可选 — 如果不存在,则跳过版本检查)
## 固件
| 文件 | 预期结果 |
|------|----------------|
| `fixtures/vulnerable.nginx.conf` | 3 个配置发现,退出 1 |
| `fixtures/safe.nginx.conf` | 0 个配置发现,退出 0 |
## 测试
```
python3 -m unittest discover -s tests -v
```
## 参考
- NVD:
- F5 咨询 K000161019:
标签:CVE-2026-42945, CWE-122, NGINX Rift, Python, RuleLab, 反取证, 堆溢出, 子域名枚举, 安全响应, 安全扫描, 安全测试, 安全漏洞, 安全评估, 安全防护, 开源, 攻击向量, 攻击性安全, 无依赖, 无后门, 时序注入, 漏洞修复, 版本检测, 系统安全, 网络安全, 网络安全培训, 配置分析, 隐私保护