
Ein einziger fehlender Funktionsaufruf bei der Routenregistrierung genügte, um die MCP-Schnittstelle in ein nicht authentifiziertes RCE-Gateway zu verwandeln.
Nicht-destruktives Erkennungswerkzeug für die nginx-ui MCP-Authentifizierungs- Umgehung, die öffentlich als MCPwn bekannt ist. Ermöglicht die Übernahme jeder nginx-ui-Instanz mit einer verwundbaren Version durch zwei HTTP-Anfragen ohne Authentifizierung.
| Feld | Wert |
|---|---|
| CVE-ID | CVE-2026-33032 |
| Alias | MCPwn |
| CVSS 3.1 | 9.8 / Kritisch (AV:N / AC:L / PR:N / UI:N / S:U / C:H/I:H/A:H) |
| CWE | CWE-306 Fehlende Authentifizierung für kritische Funktion |
| Betroffenes Produkt | nginx-ui (github.com/0xjacky/nginx-ui) |
| Betroffene Versionen | Alle Versionen vor 2.3.4 |
| Behobene Version | 2.3.4 |
| Ausnutzungsstatus | Aktiv in freier Wildbahn (Picus Security, Recorded Future) |
| Shodan-Exposition | ~2.689 internetzugängliche Instanzen |
| Veröffentlichungsdatum | 2026-04-15 |
nginx-ui stellt eine Model Context Protocol (MCP)-Schnittstelle bereit, die einem authentifizierten Bediener ermöglicht, destruktive Werkzeuge wie nginx-Konfigurationsänderungen, Neustartbefehle und Sicherungsoperationen über JSON-RPC auszuführen.
Der /mcp-Endpunkt wird durch die Middleware AuthRequired() geschützt,
während der zugehörige Endpunkt /mcp_message, der die Werkzeugaufrufe
tatsächlich empfängt, ohne die Middleware bereitgestellt wurde. Jeder
Client, der die Benutzeroberfläche über das Netzwerk erreichen kann, kann:
/mcp öffnen und eine neue
sessionID erhalten, ohne irgendeine Anmeldeinformation vorzulegen.sessionID verwenden, um jedes registrierte MCP-Werkzeug durch
einen POST an /mcp_message aufzurufen – weiterhin ohne Authentifizierung.Der Angreifer erhält vollständige Kontrolle über den nginx-Prozess: Er kann Serverblöcke bearbeiten, um Datenverkehr umzuleiten, TLS-Private-Keys über Pfadlesevorgänge extrahieren, nginx neu laden oder stoppen und persistente Hintertüren implantieren.
// verwundbar (vor 2.3.4)
r.GET("/mcp", AuthRequired(), mcpHandler)
r.POST("/mcp_message", mcpMessageHandler) // fehlende Middleware
// behoben in 2.3.4
r.GET("/mcp", AuthRequired(), mcpHandler)
r.POST("/mcp_message", AuthRequired(), mcpMessageHandler)
Ein einziger fehlender Funktionsaufruf bei der Routenregistrierung genügte, um die MCP-Schnittstelle in ein Gateway für nicht authentifizierte RCE zu verwandeln.
Angreifer nginx-ui (<2.3.4)
| 1) GET /mcp (ohne Auth) |
| --------------------------------------> |
| 2) event: endpoint data: /mcp_message?sessionID=XYZ
| <-------------------------------------- |
| 3) POST /mcp_message?sessionID=XYZ |
| body: JSON-RPC call_tool "nginx_reload" oder
| "edit_config {...}" |
| --------------------------------------> |
| 4) 200 OK; Werkzeug mit vollständigen Rechten ausgeführt
| <-------------------------------------- |
| MCP-Werkzeug | Auswirkung auf den nginx-Server |
|---|---|
edit_config | Beliebige Serverblöcke neu schreiben, Angreifer-Upstream einfügen |
reload_nginx | Angreiferkonfiguration ohne manuelles Eingreifen anwenden |
stop_nginx | Denial of Service |
read_file | TLS-Private-Keys, Anmeldeinformationen aus gemounteten Pfaden exfiltrieren |
create_cert | TLS-Zertifikate unter Kontrolle des Angreifers neu ausstellen |
list_backups / download | Vollständige nginx-ui-Sicherung inklusive node_secret und Hashes abrufen |
Dieses Repository vermeidet absichtlich jede destruktive Aktion. Der
Detektor verwendet ausschließlich schreibgeschützte MCP-Methoden
(tools/list). Die Logik:
> Schritt 1 nginx-ui per Fingerabdruck identifizieren über
> GET / (HTML-Titel, JS-Bundles)
> GET /api/settings (JSON mit nginx-ui-Schlüsseln)
> Version über Header-/Body-Regex extrahieren
> Schritt 2 SSE-Stream zu /mcp öffnen
> Erste sessionID aus dem "endpoint"-Event parsen
> Schritt 3 POST /mcp_message?sessionID=<id>
> Body: {"jsonrpc":"2.0","method":"tools/list","params":{}}
> Kein Authorization-Header
> Schritt 4 Verwundbar, wenn Status 200 und Body ein Werkzeugmanifest enthält
> Behoben, wenn Status 401 / 403 / 404
> Andernfalls unklar
Die JSON-RPC-Methode tools/list ist schreibgeschützt. Sie listet auf,
welche Werkzeuge der MCP-Server kennt, ruft jedoch keines davon auf. Das
Skript weigert sich, andere Methoden per POST zu senden, und erstellt
niemals Payloads für destruktive Werkzeuge.
git clone https://github.com/your-org/CVE-2026-33032-detector.git
cd CVE-2026-33032-detector
python3 --version # 3.9 oder neuer
# Keine Drittanbieter-Pakete erforderlich.
Für die Nmap-NSE-Komponente kopieren Sie nginx-ui-mcpwn.nse in Ihr
lokales Skriptverzeichnis und aktualisieren Sie die Skriptdatenbank:
cp nginx-ui-mcpwn.nse /usr/share/nmap/scripts/
sudo nmap --script-updatedb
# Einzelnes Ziel
python3 detect_nginx_ui_mcpwn.py --target https://nginx-ui.internal
# Massenscan aus Datei
python3 detect_nginx_ui_mcpwn.py --targets targets.txt --workers 20
# JSON (NDJSON)-Ausgabe für die Weiterleitung an jq
python3 detect_nginx_ui_mcpwn.py --target 10.0.0.5:9000 --json | jq .
Kommandozeilenreferenz: