
استدعاء دالة واحد ناقص في تسجيل المسار كان كافياً لتحويل واجهة MCP إلى بوابة تنفيذ أوامر عن بُعد (RCE) غير مصادق عليها.
أداة كشف غير تخريبية لثغرة تجاوز المصادقة في واجهة MCP الخاصة بـ nginx-ui، المعروفة علنًا باسم MCPwn. تتيح الاستيلاء غير المصادق عليه عبر طلبي HTTP على أي مثيل nginx-ui يعمل بإصدار ثغري.
يكشف nginx-ui عن واجهة بروتوكول سياق النموذج (MCP) التي تتيح للمشغّل المصادَق عليه تشغيل أدوات تخريبية مثل تعديل إعدادات nginx، وأوامر إعادة التشغيل، وعمليات النسخ الاحتياطي عبر JSON-RPC.
نقطة النهاية /mcp محمية بوسيط AuthRequired()، بينما نقطة النهاية
المقترنة بها /mcp_message، التي تستقبل فعليًا استدعاءات الأدوات،
تم نشرها بدون الوسيط. أي عميل يمكنه الوصول إلى الواجهة عبر الشبكة
يمكنه:
/mcp واستلام
sessionID جديد دون تقديم أي بيانات اعتماد.sessionID لاستدعاء أي أداة MCP مسجلة عبر إرسال POST إلى
/mcp_message، دون مصادقة أيضًا.يحصل المهاجم على سيطرة كاملة على عملية nginx: تعديل كتل الخادم لإعادة توجيه حركة المرور، استخراج مفاتيح 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 للقراءة فقط (tools/list) فقط. المنطق:
> الخطوة 1 بصمة nginx-ui عبر
> GET / (عنوان HTML، حزم JS)
> GET /api/settings (JSON يشير إلى مفاتيح nginx-ui)
> استخراج الإصدار عبر الترويسة / تعبير regex في النص
> الخطوة 2 فتح تدفق SSE إلى /mcp
> تحليل أول sessionID من حدث "endpoint"
> الخطوة 3 POST /mcp_message?sessionID=<id>
> Body: {"jsonrpc":"2.0","method":"tools/list","params":{}}
> بدون ترويسة Authorization
> الخطوة 4 ثغري إذا كانت الحالة 200 ويحتوي النص على قائمة أدوات
> مُصحَّح إذا كانت الحالة 401 / 403 / 404
> غير حاسم بخلاف ذلك
طريقة JSON-RPC الخاصة بـ tools/list للقراءة فقط. إنها تُعدّد الأدوات
التي يعرفها خادم 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
# مخرجات JSON (NDJSON) مناسبة للأنابيب إلى jq
python3 detect_nginx_ui_mcpwn.py --target 10.0.0.5:9000 --json | jq .
مرجع سطر الأوامر:
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 Detector > غير تخريبي
[!] ثغري 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
الملخص: 1/3 أهداف تم الإبلاغ عنها كثغرية
{"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 (تنزيل /api/backup غير المصادق عليه الذي يُسرّب
مفتاح AES في ترويسة X-Backup-Security) يتسلسل بسلاسة مع
MCPwn: أرشيف النسخة الاحتياطية يكشف node_secret، الذي يمكن
استخدامه للمصادقة على /mcp حتى بعد تطبيق إصلاح 33032،
إلى أن يقوم المشغّلون بتدوير السر.
الكاشف المصاحب لـ 27944 موجود في دليل شقيق ضمن مشروع البحث هذا.
node_secret، وتجزئات كلمة مرور المسؤول، وأي مفاتيح TLS
خاصة كانت قابلة للوصول من عملية nginx-ui./mcp_message قابلًا للوصول.تُنشر هذه الأداة لمساعدة المدافعين على تحديد المثيلات غير المُصحَّحة داخل البيئات المصرّح لهم باختبارها. لا تستخدمها ضد أنظمة لا تملكها أو ليس لديك إذن صريح بتقييمها. يرفض المؤلفون أي مسؤولية عن سوء الاستخدام.
صدر بموجب رخصة MIT. راجع ترويسات السكربتات الفردية للإشعارات الخاصة بكل ملف.
| الحقل | القيمة |
|---|
| معرّف CVE | CVE-2026-33032 |
| الاسم المستعار | MCPwn |
| CVSS 3.1 | 9.8 / حرج (AV:N / AC:L / PR:N / UI:N / S:U / C:H/I:H/A:H) |
| CWE | CWE-306 غياب المصادقة لوظيفة حرجة |
| المنتج المتأثر | nginx-ui (github.com/0xjacky/nginx-ui) |
| الإصدارات المتأثرة | جميع الإصدارات قبل 2.3.4 |
| الإصدار المُصحَّح | 2.3.4 |
| حالة الاستغلال | نشط في البرية (Picus Security, Recorded Future) |
| التعرض عبر Shodan | ~2,689 مثيلًا مواجهًا للإنترنت |
| تاريخ النشر | 2026-04-15 |
| أداة MCP | التأثير على خادم nginx |
|---|
edit_config | إعادة كتابة كتل خادم عشوائية، إدراج upstream تابع للمهاجم |
reload_nginx | تطبيق إعدادات المهاجم دون إجراء يدوي |
stop_nginx | رفض الخدمة |
read_file | تسريب مفاتيح TLS الخاصة وبيانات الاعتماد من المسارات المثبتة |
create_cert | إعادة إصدار شهادات TLS تحت سيطرة المهاجم |
list_backups / download | سحب نسخة nginx-ui الاحتياطية كاملة بما فيها node_secret والتجزئات |
| العلم | الغرض |
|---|
--target | عنوان URL واحد أو host[:port] |
--targets | ملف أهداف مفصول بأسطر جديدة |
--timeout | مهلة HTTP، الافتراضي 10 ثوانٍ |
--workers | عمليات متزامنة للفحص الجماعي، الافتراضي 10 |
--verify-tls | فرض التحقق من شهادة TLS (معطّل افتراضيًا) |
--json | إصدار NDJSON، سجل واحد لكل هدف |
--no-banner | إخفاء الشعار ASCII |