Share
## https://sploitus.com/exploit?id=9E899FF8-ADEC-5A3D-B90C-1658DF69CA4D
# CVE-2026-33032 / MCPwn

[![CVE](https://img.shields.io/badge/CVE-2026--33032-c0392b.svg)](https://nvd.nist.gov/vuln/detail/CVE-2026-33032)
[![CVSS](https://img.shields.io/badge/CVSS-9.8%20Critical-c0392b.svg)](https://nvd.nist.gov/vuln/detail/CVE-2026-33032)
[![Status](https://img.shields.io/badge/Exploitation-Active%20in%20the%20Wild-e67e22.svg)]()
[![Affected](https://img.shields.io/badge/nginx--ui-%3C%202.3.4-informational.svg)](https://github.com/0xjacky/nginx-ui)
[![License](https://img.shields.io/badge/License-MIT-green.svg)](#license)
[![Python](https://img.shields.io/badge/Python-3.9%2B-blue.svg)](#requirements)

> Non-destructive detection tooling for the nginx-ui MCP authentication
> bypass known publicly as **MCPwn**. Ship a two-HTTP-request unauthenticated
> takeover of any nginx-ui instance running a vulnerable version.

## Table of Contents

1. [Quick Facts](#quick-facts)
2. [Vulnerability Overview](#vulnerability-overview)
3. [Technical Deep Dive](#technical-deep-dive)
4. [Detection Strategy](#detection-strategy)
5. [Installation](#installation)
6. [Usage](#usage)
7. [Example Output](#example-output)
8. [Chain with CVE-2026-27944](#chain-with-cve-2026-27944)
9. [Remediation](#remediation)
10. [Responsible Use](#responsible-use)
11. [References](#references)
12. [License](#license)

## Quick Facts

| Field                  | Value                                                         |
|------------------------|---------------------------------------------------------------|
| CVE ID                 | CVE-2026-33032                                                |
| Alias                  | MCPwn                                                         |
| CVSS 3.1               | 9.8 / Critical (AV:N / AC:L / PR:N / UI:N / S:U / C:H/I:H/A:H)|
| CWE                    | CWE-306 Missing Authentication for Critical Function          |
| Affected product       | nginx-ui (github.com/0xjacky/nginx-ui)                        |
| Affected versions      | All versions prior to 2.3.4                                   |
| Fixed version          | 2.3.4                                                         |
| Exploitation status    | Active in the wild (Picus Security, Recorded Future)          |
| Shodan exposure        | ~2,689 internet-facing instances                              |
| Publication date       | 2026-04-15                                                    |

## Vulnerability Overview

nginx-ui exposes a Model Context Protocol (MCP) interface that lets an
authenticated operator drive destructive tools such as nginx configuration
edits, restart commands and backup operations through JSON-RPC.

The `/mcp` endpoint is guarded by the `AuthRequired()` middleware, while
its paired `/mcp_message` endpoint, which actually receives the tool
invocations, was deployed **without** the middleware. Any client who can
reach the UI over the network can:

1. Open a Server Sent Events (SSE) stream to `/mcp` and receive a fresh
   `sessionID` without presenting any credential.
2. Use that `sessionID` to invoke any registered MCP tool by POSTing to
   `/mcp_message`, still unauthenticated.

The attacker gains complete control of the nginx process: edit server
blocks to redirect traffic, extract TLS private keys via path reads,
reload or stop nginx, and implant persistent backdoors.

## Technical Deep Dive

### Code-level root cause

```go
// vulnerable (pre-2.3.4)
r.GET("/mcp",          AuthRequired(), mcpHandler)
r.POST("/mcp_message", mcpMessageHandler)    // missing middleware

// fixed in 2.3.4
r.GET("/mcp",          AuthRequired(), mcpHandler)
r.POST("/mcp_message", AuthRequired(), mcpMessageHandler)
```

One missing function call on the route registration was enough to
turn the MCP interface into an unauthenticated RCE gateway.

### End-to-end attack sketch

```
  Attacker                              nginx-ui (  |
     |   2) event: endpoint data: /mcp_message?sessionID=XYZ
     |   |
     |   4) 200 OK; tool executed with full privileges
     |  Step 1  Fingerprint nginx-ui via
>         GET /               (HTML title, JS bundles)
>         GET /api/settings   (JSON referencing nginx-ui keys)
>         Extract version via header / body regex
> Step 2  Open SSE stream to /mcp
>         Parse the first sessionID from the "endpoint" event
> Step 3  POST /mcp_message?sessionID=
>         Body: {"jsonrpc":"2.0","method":"tools/list","params":{}}
>         No Authorization header
> Step 4  Vulnerable if status 200 and body contains a tool manifest
>         Patched if status 401 / 403 / 404
>         Inconclusive otherwise
```

### Why this is safe

The `tools/list` JSON-RPC method is read-only. It enumerates which
tools the MCP server knows about but invokes none of them. The script
refuses to POST any other method and never constructs payloads for
destructive tools.

## Installation

```bash
git clone https://github.com/your-org/CVE-2026-33032-detector.git
cd CVE-2026-33032-detector
python3 --version      # 3.9 or newer
# No third-party packages required.
```

For the Nmap NSE component, copy `nginx-ui-mcpwn.nse` into your local
scripts directory and refresh the script database:

```bash
cp nginx-ui-mcpwn.nse /usr/share/nmap/scripts/
sudo nmap --script-updatedb
```

## Usage

### Python detector

```bash
# Single target
python3 detect_nginx_ui_mcpwn.py --target https://nginx-ui.internal

# Bulk scan from file
python3 detect_nginx_ui_mcpwn.py --targets targets.txt --workers 20

# JSON (NDJSON) output suited for piping to jq
python3 detect_nginx_ui_mcpwn.py --target 10.0.0.5:9000 --json | jq .
```

Command line reference:

| Flag            | Purpose                                                |
|-----------------|--------------------------------------------------------|
| `--target`      | Single URL or host[:port]                              |
| `--targets`     | Newline separated target file                          |
| `--timeout`     | HTTP timeout, default 10 seconds                       |
| `--workers`     | Concurrent workers for bulk scans, default 10          |
| `--verify-tls`  | Enforce TLS certificate verification (off by default)  |
| `--json`        | Emit NDJSON, one record per target                     |
| `--no-banner`   | Suppress the ASCII banner                              |

### Nmap NSE

```bash
nmap -p 80,443,9000 --script nginx-ui-mcpwn 10.0.0.0/24
nmap -p 443 --script nginx-ui-mcpwn --script-args "nginx-ui-mcpwn.timeout=8" host.example.com
```

## Example Output

### Human readable

```
 _   _       _                  _    _  ___   __  __  ____ ____
| \ | | __ _(_)_ __ __  __     | |  | ||_ _| |  \/  |/ ___|  _ \__      ___ __
|  \| |/ _` | | '_ \\ \/ /_____| |  | | | |  | |\/| | |   | |_) \ \ /\ / / '_ \
| |\  | (_| | | | | |>   non-destructive

[!] VULNERABLE https://nginx-ui.internal version=2.3.2 evidence=status=200; body_preview={"jsonrpc":"2.0","id":"...","result":{"tools":[{"name":"edit_config",...
[+] patched https://nginx-ui-patched:9000 version=2.3.4 evidence=status=401; body_preview={"error":"unauthorized"}
[.] not nginx-ui https://example.com evidence=fingerprint negative

Summary: 1/3 targets flagged vulnerable
```

### NDJSON

```json
{"target":"https://nginx-ui.internal","reachable":true,"is_nginx_ui":true,"mcp_endpoint_present":true,"session_id_obtained":true,"mcp_message_unauthenticated":true,"vulnerable":true,"nginx_ui_version":"2.3.2","evidence":"status=200; body_preview=...","error":null}
```

### Nmap

```
PORT     STATE SERVICE
9000/tcp open  http
| nginx-ui-mcpwn:
|   status: VULNERABLE
|   version: 2.3.2
|   session_id: abc123
|_  evidence: tools/list accepted without credentials
```

## Chain with CVE-2026-27944

`CVE-2026-27944` (the unauthenticated `/api/backup` download that leaks
the AES key in the `X-Backup-Security` header) chains cleanly with
MCPwn: the backup archive exposes the `node_secret`, which can be
used to authenticate to `/mcp` even after the fix for 33032 lands,
until operators rotate the secret.

The companion detector for 27944 lives in a sibling directory of
this research project.

## Remediation

1. Upgrade nginx-ui to **2.3.4** or later.
2. Rotate `node_secret`, admin password hashes and any TLS private
   keys that were accessible to the nginx-ui process.
3. Restrict nginx-ui exposure to a management VLAN, VPN, or reverse
   proxy that enforces authentication before the `/mcp_message` route
   is reachable.
4. Review nginx configuration history (Git or backup) for unexpected
   upstream / proxy_pass / ssl_certificate directives introduced in
   the exposure window.

## Responsible Use

This tooling is published to help defenders identify unpatched
instances inside environments they are authorised to test. Do not use
it against systems you do not own or have explicit permission to
assess. The authors decline all responsibility for misuse.

## References

- NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-33032
- Picus Security (MCPwn writeup): https://www.picussecurity.com/resource/blog/cve-2026-33032-mcpwn-how-a-missing-middleware-call-in-nginx-ui-hands-attackers-full-web-server-takeover
- Security Affairs: https://securityaffairs.com/190841/hacking/cve-2026-33032-severe-nginx-ui-bug-grants-unauthenticated-server-access.html
- BleepingComputer: https://www.bleepingcomputer.com/news/security/critical-nginx-ui-auth-bypass-flaw-now-actively-exploited-in-the-wild/
- Upstream project: https://github.com/0xjacky/nginx-ui

## License

Released under the MIT License. See the individual script headers for
per-file notices.