
라우트 등록 과정에서 함수 호출 하나가 누락된 것만으로 MCP 인터페이스가 인증 없는 RCE 게이트웨이로 변하기에 충분했다.
nginx-ui MCP 인증 우회 취약점으로 공개적으로 알려진 MCPwn에 대한 비파괴적 탐지 도구입니다. 취약한 버전을 실행 중인 모든 nginx-ui 인스턴스에 대해 두 개의 HTTP 요청만으로 인증 없이 완전한 장악이 가능합니다.
| 필드 | 값 |
|---|---|
| CVE ID | CVE-2026-33032 |
| 별칭 | 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 |
| 영향 제품 | nginx-ui (github.com/0xjacky/nginx-ui) |
| 영향 버전 | 2.3.4 이전의 모든 버전 |
| 수정 버전 | 2.3.4 |
| 악용 상태 | 실제 환경에서 활발히 악용 중 (Picus Security, Recorded Future) |
| Shodan 노출 | ~2,689개의 인터넷 노출 인스턴스 |
| 공개 날짜 | 2026-04-15 |
nginx-ui는 인증된 운영자가 JSON-RPC를 통해 nginx 설정 편집, 재시작 명령, 백업 작업과 같은 파괴적인 도구를 구동할 수 있게 해주는 Model Context Protocol(MCP) 인터페이스를 노출합니다.
/mcp 엔드포인트는 AuthRequired() 미들웨어로 보호되지만, 실제로 도구 호출을 수신하는 짝 엔드포인트인 /mcp_message는 미들웨어 없이 배포되었습니다. 네트워크를 통해 UI에 접근할 수 있는 모든 클라이언트는 다음을 수행할 수 있습니다:
/mcp에 Server Sent Events(SSE) 스트림을 열고 자격 증명을 제시하지 않고 새 sessionID를 수신합니다.sessionID를 사용하여 여전히 인증 없이 /mcp_message에 POST하여 등록된 모든 MCP 도구를 호출합니다.공격자는 nginx 프로세스에 대한 완전한 제어권을 얻습니다: 트래픽을 리디렉션하기 위해 server 블록을 편집하고, 경로 읽기를 통해 TLS 개인 키를 추출하고, nginx를 리로드하거나 중지하고, 영구 백도어를 심을 수 있습니다.
// 취약 (2.3.4 이전)
r.GET("/mcp", AuthRequired(), mcpHandler)
r.POST("/mcp_message", mcpMessageHandler) // 미들웨어 누락
// 2.3.4에서 수정됨
r.GET("/mcp", AuthRequired(), mcpHandler)
r.POST("/mcp_message", AuthRequired(), mcpMessageHandler)
라우트 등록에서 함수 호출 하나가 누락된 것만으로 MCP 인터페이스가 인증 없는 RCE 게이트웨이로 변했습니다.
공격자 nginx-ui (<2.3.4)
| 1) GET /mcp (인증 없음) |
| --------------------------------------> |
| 2) event: endpoint data: /mcp_message?sessionID=XYZ
| <-------------------------------------- |
| 3) POST /mcp_message?sessionID=XYZ |
| body: JSON-RPC call_tool "nginx_reload" 또는
| "edit_config {...}" |
| --------------------------------------> |
| 4) 200 OK; 전체 권한으로 도구 실행
| <-------------------------------------- |
| MCP 도구 | nginx 서버에 미치는 영향 |
|---|---|
edit_config | 임의의 server 블록 재작성, 공격자 upstream 삽입 |
reload_nginx | 수동 작업 없이 공격자 설정 적용 |
stop_nginx | 서비스 거부 |
read_file | 마운트된 경로에서 TLS 개인 키, 자격 증명 유출 |
create_cert | 공격자 통제 하에 TLS 인증서 재발급 |
list_backups / download | node_secret 및 해시를 포함한 전체 nginx-ui 백업 다운로드 |
이 저장소는 의도적으로 파괴적인 작업을 피합니다. 탐지기는 읽기 전용 MCP 메서드(tools/list)만 사용합니다. 로직:
> 단계 1 nginx-ui 핑거프린팅
> GET / (HTML 제목, JS 번들)
> GET /api/settings (nginx-ui 키를 참조하는 JSON)
> 헤더/본문 정규식을 통해 버전 추출
> 단계 2 /mcp에 SSE 스트림 열기
> "endpoint" 이벤트에서 첫 번째 sessionID 파싱
> 단계 3 POST /mcp_message?sessionID=<id>
> Body: {"jsonrpc":"2.0","method":"tools/list","params":{}}
> Authorization 헤더 없음
> 단계 4 상태 200이고 본문에 도구 매니페스트가 포함되면 취약
> 상태 401 / 403 / 404이면 패치됨
> 그 외에는 판정 불가
tools/list JSON-RPC 메서드는 읽기 전용입니다. MCP 서버가 알고 있는 도구를 열거할 뿐 어떤 도구도 호출하지 않습니다. 스크립트는 다른 메서드로 POST를 거부하며 파괴적인 도구에 대한 페이로드를 절대 구성하지 않습니다.
git clone https://github.com/your-org/CVE-2026-33032-detector.git
cd CVE-2026-33032-detector
python3 --version # 3.9 이상
# 타사 패키지 필요 없음.
Nmap NSE 구성 요소의 경우 nginx-ui-mcpwn.nse를 로컬 스크립트 디렉토리에 복사하고 스크립트 데이터베이스를 새로 고칩니다:
cp nginx-ui-mcpwn.nse /usr/share/nmap/scripts/
sudo nmap --script-updatedb
# 단일 대상
python3 detect_nginx_ui_mcpwn.py --target https://nginx-ui.internal
# 파일에서 대량 스캔
python3 detect_nginx_ui_mcpwn.py --targets targets.txt --workers 20
# jq로 파이프하기에 적합한 JSON (NDJSON) 출력
python3 detect_nginx_ui_mcpwn.py --target 10.0.0.5:9000 --json | jq .
명령줄 참조:
| 플래그 | 용도 |
|---|---|
--target | 단일 URL 또는 host[:port] |
--targets | 줄바꿈으로 구분된 대상 파일 |
--timeout | HTTP 타임아웃, 기본값 10초 |
--workers | 대량 스캔용 동시 작업자 수, 기본값 10 |
--verify-tls | TLS 인증서 검증 강제 (기본적으로 꺼짐) |
--json | 대상당 하나의 레코드로 NDJSON 출력 |
--no-banner | ASCII 배너 표시 억제 |
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 /| | | |
|_| \_|\__, |_|_| |_/_/\_\ |_____|_||___| |_| |_|\____|_| \_/\_/ |_| |_|
|___/
CVE-2026-33032 nginx-ui MCPwn 탐지기 > 비파괴적
[!] 취약 https://nginx-ui.internal version=2.3.2 evidence=status=200; body_preview={"jsonrpc":"2.0","id":"...","result":{"tools":[{"name":"edit_config",...
[+] 패치됨 https://nginx-ui-patched:9000 version=2.3.4 evidence=status=401; body_preview={"error":"unauthorized"}
[.] nginx-ui 아님 https://example.com evidence=fingerprint negative
요약: 3개 대상 중 1개가 취약으로 플래그됨
{"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: VULNERABLE
| version: 2.3.2
| session_id: abc123
|_ evidence: tools/list accepted without credentials
CVE-2026-27944(X-Backup-Security 헤더에서 AES 키를 유출하는 인증 없는 /api/backup 다운로드)는 MCPwn과 깔끔하게 연계됩니다: 백업 아카이브는 node_secret을 노출하며, 이는 운영자가 시크릿을 교체할 때까지 33032 수정이 적용된 후에도 /mcp에 인증하는 데 사용될 수 있습니다.
27944용 동반 탐지기는 이 연구 프로젝트의 형제 디렉토리에 있습니다.