
Uma única chamada de função ausente no registro de rotas foi suficiente para transformar a interface MCP em um gateway de RCE não autenticado.
Ferramenta de detecção não destrutiva para a bypass de autenticação MCP do nginx-ui conhecida publicamente como MCPwn. Permite a tomada de controlo não autenticada de qualquer instância nginx-ui a executar uma versão vulnerável, através de dois pedidos HTTP.
O nginx-ui expõe uma interface Model Context Protocol (MCP) que permite a um operador autenticado acionar ferramentas destrutivas, como edições de configuração do nginx, comandos de reinício e operações de backup, através de JSON-RPC.
O endpoint /mcp é protegido pelo middleware AuthRequired(), enquanto
o seu endpoint emparelhado /mcp_message, que na realidade recebe as
invocações das ferramentas, foi implementado sem o middleware.
Qualquer cliente que consiga alcançar a interface através da rede pode:
/mcp e receber um
sessionID novo sem apresentar qualquer credencial.sessionID para invocar qualquer ferramenta MCP registada,
fazendo POST para /mcp_message, ainda sem autenticação.O atacante obtém controlo total do processo nginx: editar blocos de servidor para redirecionar tráfego, extrair chaves privadas TLS através de leituras de caminhos, recarregar ou parar o nginx, e implantar backdoors persistentes.
// vulnerável (pré-2.3.4)
r.GET("/mcp", AuthRequired(), mcpHandler)
r.POST("/mcp_message", mcpMessageHandler) // middleware em falta
// corrigido em 2.3.4
r.GET("/mcp", AuthRequired(), mcpHandler)
r.POST("/mcp_message", AuthRequired(), mcpMessageHandler)
Uma única chamada de função em falta no registo da rota foi suficiente para transformar a interface MCP num portal de RCE não autenticado.
Atacante nginx-ui (<2.3.4)
| 1) GET /mcp (sem auth) |
| --------------------------------------> |
| 2) event: endpoint data: /mcp_message?sessionID=XYZ
| <-------------------------------------- |
| 3) POST /mcp_message?sessionID=XYZ |
| body: JSON-RPC call_tool "nginx_reload" ou
| "edit_config {...}" |
| --------------------------------------> |
| 4) 200 OK; ferramenta executada com privilégios totais
| <-------------------------------------- |
Este repositório evita intencionalmente qualquer ação destrutiva. O
detetor usa apenas métodos MCP de leitura (tools/list). A lógica:
> Passo 1 Identificar nginx-ui através de
> GET / (título HTML, bundles JS)
> GET /api/settings (JSON com referências a chaves do nginx-ui)
> Extrair versão via regex no cabeçalho / corpo
> Passo 2 Abrir stream SSE para /mcp
> Analisar o primeiro sessionID do evento "endpoint"
> Passo 3 POST /mcp_message?sessionID=<id>
> Body: {"jsonrpc":"2.0","method":"tools/list","params":{}}
> Sem cabeçalho Authorization
> Passo 4 Vulnerável se status 200 e o corpo contiver um manifesto de ferramentas
> Corrigido se status 401 / 403 / 404
> Inconclusivo caso contrário
O método JSON-RPC tools/list é apenas de leitura. Enumera as
ferramentas que o servidor MCP conhece, mas não invoca nenhuma delas. O
script recusa-se a fazer POST de qualquer outro método e nunca constrói
payloads para ferramentas destrutivas.
git clone https://github.com/your-org/CVE-2026-33032-detector.git
cd CVE-2026-33032-detector
python3 --version # 3.9 ou mais recente
# Não são necessários pacotes de terceiros.
Para o componente Nmap NSE, copie nginx-ui-mcpwn.nse para o seu
diretório local de scripts e atualize a base de dados de scripts:
cp nginx-ui-mcpwn.nse /usr/share/nmap/scripts/
sudo nmap --script-updatedb
# Alvo único
python3 detect_nginx_ui_mcpwn.py --target https://nginx-ui.internal
# Análise em massa a partir de ficheiro
python3 detect_nginx_ui_mcpwn.py --targets targets.txt --workers 20
# Saída JSON (NDJSON) adequada para canalizar para jq
python3 detect_nginx_ui_mcpwn.py --target 10.0.0.5:9000 --json | jq .
Referência da linha de comandos:
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
_ _ _ _ _ ___ __ __ ____ ____
| \ | | __ _(_)_ __ __ __ | | | ||_ _| | \/ |/ ___| _ \__ ___ __
| \| |/ _` | | '_ \\ \/ /_____| | | | | | | |\/| | | | |_) \ \ /\ / / '_ \
| |\ | (_| | | | | |> <|_____| |__| | | | | | | | |___| __/ \ V V /| | | |
|_| \_|\__, |_|_| |_/_/\_\ |_____|_||___| |_| |_|\____|_| \_/\_/ |_| |_|
|___/
Detetor CVE-2026-33032 nginx-ui MCPwn > não destrutivo
[!] VULNERÁVEL https://nginx-ui.internal versão=2.3.2 evidência=status=200; body_preview={"jsonrpc":"2.0","id":"...","result":{"tools":[{"name":"edit_config",...
[+] corrigido https://nginx-ui-patched:9000 versão=2.3.4 evidência=status=401; body_preview={"error":"unauthorized"}
[.] não é nginx-ui https://example.com evidência=identificação negativa
Resumo: 1/3 alvos sinalizados como vulneráveis
{"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}
PORT STATE SERVICE
9000/tcp open http
| nginx-ui-mcpwn:
| status: VULNERÁVEL
| version: 2.3.2
| session_id: abc123
|_ evidence: tools/list aceite sem credenciais
CVE-2026-27944 (o download não autenticado de /api/backup que expõe
a chave AES no cabeçalho X-Backup-Security) encadeia-se perfeitamente
com o MCPwn: o arquivo de backup expõe o node_secret, que pode ser
usado para autenticar em /mcp mesmo depois de a correção para 33032
ser aplicada, até os operadores rodarem o segredo.
O detetor complementar para 27944 vive num diretório irmão deste projeto de investigação.
node_secret, os hashes das palavras-passe de administrador
e quaisquer chaves privadas TLS que estivessem acessíveis ao
processo nginx-ui./mcp_message ser
alcançável.Esta ferramenta é publicada para ajudar defensores a identificar instâncias sem correção dentro de ambientes que estão autorizados a testar. Não a utilize contra sistemas que não possui ou para os quais não tem permissão explícita de avaliação. Os autores declinam toda a responsabilidade por uso indevido.
Publicado sob a Licença MIT. Consulte os cabeçalhos individuais dos scripts para avisos por ficheiro.
| Campo | Valor |
|---|
| ID CVE | CVE-2026-33032 |
| Alias | MCPwn |
| CVSS 3.1 | 9.8 / Crítico (AV:N / AC:L / PR:N / UI:N / S:U / C:H/I:H/A:H) |
| CWE | CWE-306 Falta de Autenticação para Função Crítica |
| Produto afetado | nginx-ui (github.com/0xjacky/nginx-ui) |
| Versões afetadas | Todas as versões anteriores a 2.3.4 |
| Versão corrigida | 2.3.4 |
| Estado de exploração | Ativa no terreno (Picus Security, Recorded Future) |
| Exposição no Shodan | ~2.689 instâncias expostas à Internet |
| Data de publicação | 2026-04-15 |
| Ferramenta MCP | Efeito no servidor nginx |
|---|
edit_config | Reescrever blocos de servidor arbitrários, inserir upstream do atacante |
reload_nginx | Aplicar configuração do atacante sem ação manual |
stop_nginx | Negação de serviço |
read_file | Exfiltrar chaves privadas TLS, credenciais de caminhos montados |
create_cert | Reemitir certificados TLS sob controlo do atacante |
list_backups / download | Descarregar o backup completo do nginx-ui, incluindo node_secret e hashes |
| Flag | Finalidade |
|---|
--target | URL único ou host[:porta] |
--targets | Ficheiro de alvos separados por nova linha |
--timeout | Timeout HTTP, padrão 10 segundos |
--workers | Trabalhadores concorrentes para análises em massa, padrão 10 |
--verify-tls | Impor verificação do certificado TLS (desativada por padrão) |
--json | Emitir NDJSON, um registo por alvo |
--no-banner | Suprimir o banner ASCII |