BishopFox/CVE-2026-34908-check
GitHub: BishopFox/CVE-2026-34908-check
一款安全检测脚本,用于安全地探测 UniFi OS Server 是否存在由路径遍历和命令注入组成的未授权远程代码执行漏洞链。
Stars: 32 | Forks: 4
# UniFi OS Server 未授权 RCE 链检测脚本
针对 Ubiquiti 在 [安全公告 064](https://community.ui.com/releases/Security-Advisory-Bulletin-064-064/84811c09-4cf4-42ab-bd61-cc994445963b) 中披露的 UniFi OS Server ≤ 5.0.6 未授权远程代码执行链的安全检测脚本:
| CVE | 类别 | 在利用链中的作用 |
|-----|-------|-------------------|
| CVE-2026-34908 / CVE-2026-34909 | 访问控制不当 / 路径遍历 | Auth-gateway 绕过(初始突破口) |
| CVE-2026-34910 | 输入验证不当 → 命令注入 | 通过绕过实现的未授权 RCE |
已在 UniFi OS Server 5.0.8 版本中修复。
## 运行安全吗?
是的。该检测脚本专为生产环境和评估测试设计:
- **不会执行任何命令。** 探测请求在未提供必要参数的情况下访问易受攻击的 endpoint,因此处理程序会因缺少输入而拒绝请求,我们通过该校验错误来确认漏洞。
- **不会改变目标状态。** 每个请求均为普通的 `GET` 请求。
- **防误报机制。** 得出 `VULNERABLE`(存在漏洞)结论的前提是:auth-bypass 已成功触达易受攻击的处理程序,并且基准请求(访问同一 endpoint 且不进行绕过)被正确地以 `401` 状态码拒绝。
## 工作原理
UniFi OS 使用 nginx 作为其服务前端,并通过子请求强制进行身份验证。该身份验证检查会将 **原始 (raw)** URI 以 `/api/auth/validate-sso/` 开头的任何请求视为公开请求,但 nginx 在路由到后端时使用的是 **归一化 (normalized)** 后的 URI(它会将 `%2f` 解码为 `/` 并折叠 `../`)。因此,类似下面的请求:
```
GET /api/auth/validate-sso/..%2f..%2f..%2fproxy/users/api/v2/ucs/update/latest_package
```
会被视为公开请求(根据原始前缀),但实际却被路由到了需要授权的内部 package-update endpoint(根据归一化路径)。由于没有提供 `pkg_name` 参数,该 endpoint 会回复 `query param pkg_name required` —— 这证明了绕过机制有效,且能够触达易受攻击的处理程序。
| 探测响应 | 判定结果 |
|----------------|---------|
| `200` + 处理程序错误标记 | `VULNERABLE` |
| `400` (nginx 拒绝了路径差异) | `PATCHED` (5.0.8+) |
| `401`,存在 UniFi OS 指纹 | `INCONCLUSIVE` (已强制认证 / 绕过被阻止) |
| `401`,无 UniFi OS 指纹 | `UNAFFECTED` (非 UniFi OS Server) |
| 其他任何情况,且无 UniFi OS 指纹 | `UNAFFECTED` (非 UniFi OS Server) |
| 其他任何情况,且存在 UniFi OS 指纹 | `INCONCLUSIVE` (异常响应) |
检测程序还会向同一 endpoint 发送不包含绕过尝试的基准请求,并且要求该请求必须返回 `401`,然后才会宣告目标主机存在漏洞。此项检查直接测试了漏洞行为 —— 得出 `VULNERABLE` 判定结果意味着绕过机制确实触达了命令执行点 (sink)。
### 在做出任何“未受漏洞影响”的判定前,先确认目标是否为 UniFi OS
每当探测未能明确确认目标为 `VULNERABLE` 或 `PATCHED` 时,检测程序都会抓取根页面并寻找 UniFi OS 管理面板指纹(`UniFi OS `, `window.UNIFI_OS_MANIFEST`, `id="portal-root"`, `id="site-manager_portal-container"`)。这也适用于返回 `401` 的情况:如果在绕过时强制要求认证的 UniFi OS 主机,判定为 `INCONCLUSIVE`;但如果是一个仅仅对所有请求都返回 `401` 的非 UniFi 代理,由于不包含指纹,将被报告为 `UNAFFECTED`。因此,每一个“未受漏洞影响”的结论都是基于指纹得出的:存在标记 → `INCONCLUSIVE`;缺少标记 → `UNAFFECTED` (该 CVE 不适用)。
## 环境要求
- Python 3.7+,仅使用标准库 —— 无需任何第三方包。
## 用法
```
# 单个主机(默认端口 11443)
./cve_2026_34908_check.py 192.168.1.10
# 显式端口 / URL 格式
./cve_2026_34908_check.py host-a:11443 https://host-b
# 扫描列表,每行一个目标(允许 '#' 注释),紧凑输出
./cve_2026_34908_check.py -f targets.txt --brief
# 用于 pipelines 的机器可读输出
./cve_2026_34908_check.py -f targets.txt --json > results.json
```
### 选项
| 参数 | 描述 |
|------|-------------|
| `targets` | 一个或多个 `host`、`host:port` 或 `https://host:port` |
| `-f, --targets-file FILE` | 从文件中读取目标(每行一个;支持 `#` 注释) |
| `--brief` | 每个目标输出单行对齐结果 —— 适合扫描大量主机 |
| `--json` | 输出结构化的 JSON 结果 |
| `--timeout SECS` | 单次请求超时时间(默认:10) |
| `--no-color` | 禁用彩色输出(同时支持 `NO_COLOR` 环境变量及非 TTY 环境) |
### 示例
**存在漏洞的控制台**(详细模式,默认)。第二行是判定结果的详细信息;在 TTY 环境下,`[!]` 标记和 `VULNERABLE` 会以红色显示:
```
$ ./cve_2026_34908_check.py 192.168.1.10
[!] 192.168.1.10:11443: VULNERABLE
auth bypass reached the vulnerable handler (no command executed); baseline correctly 401
```
**已修复的控制台** (5.0.8+):
```
$ ./cve_2026_34908_check.py 192.168.1.11
[+] 192.168.1.11:11443: PATCHED
nginx rejected the normalized-path divergence (HTTP 400) — 5.0.8+ behavior
```
**确认是 UniFi OS 主机但探测无法分类** → `INCONCLUSIVE`。详细信息行区分了这两种情况(强制认证 vs 异常响应):
```
$ ./cve_2026_34908_check.py 192.168.1.12 192.168.1.13
[?] 192.168.1.12:11443: INCONCLUSIVE
bypass blocked / auth enforced (HTTP 401) on a confirmed UniFi OS host — not confirmed vulnerable
[?] 192.168.1.13:11443: INCONCLUSIVE
UniFi OS detected, but probe returned an unexpected response: HTTP 302 text/html
```
**根本不是 UniFi OS 的主机** → `UNAFFECTED`(安全公告不适用):
```
$ ./cve_2026_34908_check.py 203.0.113.9:443
[-] 203.0.113.9:443: UNAFFECTED
no UniFi OS web fingerprint on / (probe HTTP 404) — target is not a UniFi OS Server
```
**扫描列表,每个主机输出单行对齐结果** (`--brief`)。如果存在任何 `VULNERABLE` 主机,退出状态码为 `1`,否则为 `0` —— 非常适合在脚本中使用:
```
$ ./cve_2026_34908_check.py -f targets.txt --brief; echo "exit: $?"
VULNERABLE 192.168.1.10:11443
PATCHED 192.168.1.11:11443
INCONCLUSIVE 192.168.1.12:11443
UNAFFECTED 203.0.113.9:443
ERROR 10.0.0.1:11443 timeout
exit: 1
```
**用于流水线的机器可读输出** (`--json`)。每个结果都包含 `verdict` 以及背后的 `bypass.state`/`bypass.detail`;`ERROR` 结果包含 `error` 字段而不是 `bypass`:
```
$ ./cve_2026_34908_check.py 192.168.1.10 192.168.1.11 10.0.0.1 --json
[
{
"target": "192.168.1.10:11443",
"bypass": {
"state": "vulnerable",
"detail": "auth bypass reached the vulnerable handler (no command executed); baseline correctly 401"
},
"verdict": "VULNERABLE"
},
{
"target": "192.168.1.11:11443",
"bypass": {
"state": "patched",
"detail": "nginx rejected the normalized-path divergence (HTTP 400) — 5.0.8+ behavior"
},
"verdict": "PATCHED"
},
{
"target": "10.0.0.1:11443",
"verdict": "ERROR",
"error": "timeout"
}
]
```
## 判定结果说明
| 判定结果 | 含义 |
|---------|---------|
| `VULNERABLE` | 未授权的 Auth bypass 触达了易受攻击的处理程序。请更新至 5.0.8+ 版本。 |
| `PATCHED` | nginx 拒绝了归一化路径的分歧(5.0.8+ 版本的行为)。 |
| `UNAFFECTED` | 根页面上没有 UniFi OS 门户指纹 —— 该目标不是 UniFi OS Server,因此安全公告不适用。包括那些在无指纹的情况下返回 `401` 的主机(例如,拒绝所有请求的不相关代理)。 |
| `INCONCLUSIVE` | 已确认是 UniFi OS 主机但无法分类 —— 请手动核实版本。判定结果的详细信息行说明了具体情况:(a) 绕过被阻止 / 强制认证 (`401`),或者 探测返回了异常响应。 |
| `ERROR` | 连接 / 超时 / TLS 故障。 |
## 退出代码
| 代码 | 含义 |
|------|---------|
| `0` | 没有目标返回 `VULNERABLE` |
| `1` | 至少有一个目标为 `VULNERABLE` |
| `2` | 使用错误(参数错误 / 目标文件无法读取) |
## 局限性
- `INCONCLUSIVE` 并不保证绝对安全 —— 它确认了目标是 UniFi OS 主机,但无法对其进行分类(在尝试绕过时要求强制认证,或返回了异常响应)。经过严格过滤或位于异常代理之后的主机可能无法仅通过网络层面进行分类。请尽可能确认实际运行的版本。
- `UNAFFECTED` 意味着根页面不包含 UniFi OS 门户指纹(包括在无指纹情况下返回 `401` 的主机)。因此,如果 UniFi OS 控制台隐藏在会剥离或重写门户 HTML 的反向代理后面,可能会导致误报;如果预期目标应当是 UniFi OS,请直接确认。
- 检测程序仅报告漏洞行为的可触达性。
## 修复方案
将 UniFi OS Server 更新至 5.0.8 或更高版本。该修复增加了 nginx 原始 URI 与归一化 URI 的比对(修复了 auth bypass),并在 package-update 路径中增加了输入校验(修复了命令注入)。
## 许可证
此代码在 [MIT 许可证](LICENSE) 下分发。
## 免责声明
在未事先获得双方同意的情况下,使用此工具攻击目标是违法的。最终用户有责任遵守所有适用的地方、州和联邦法律。开发者不承担任何责任,也不对任何因滥用本程序而造成的损害负责。
## 另请参阅
- [Ubiquiti 安全公告 064](https://community.ui.com/releases/Security-Advisory-Bulletin-064-064/84811c09-4cf4-42ab-bd61-cc994445963b)
- [Bishop Fox 博客:完整技术分析](https://bishopfox.com/blog/popping-root-on-unifi-os-server-unauthenticated-rce-chain-detection-analysis)
标签:CISA项目, Python, Ubiquiti UniFi, 命令注入, 无后门, 路径遍历, 逆向工具