
بيئة مختبرية قابلة للتكرار لـ CVE-2026-46716، وهو ثغرة RCE حرجة عبر المستأجرين في Nezha Monitoring من خلال تجاوز تفويض API cron. يتضمن قالب كشف Nuclei ومجموعات متضررة/مصححة قائمة على Docker.
بيئة مختبرية لإعادة إنتاج واكتشاف CVE-2026-46716، وهي ثغرة أمنية خطيرة في Nezha Monitoring حيث يفتقر نقطة النهاية POST /api/v1/cron إلى فحوصات صلاحية المشرف، مما يسمح لمستخدمي RoleMember بتحقيق تنفيذ الأوامر عن بُعد عبر المستأجرين.
| الحقل | التفاصيل |
|---|---|
| CVE ID | CVE-2026-46716 |
| GHSA | GHSA-99gv-2m7h-3hh9 |
| CVSS | 9.9 (حرجة) — AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H |
| الإصدارات المتأثرة | nezhahq/nezha >= 1.4.0, < 1.14.15-0.20260517022419-d7526351cf97 |
| الإصدار المُصحَّح | v1.14.15-0.20260517022419-d7526351cf97 (الالتزام d7526351cf97, 2026-05-17) |
| CWE | CWE-862 (تغيب التفويض), CWE-269 (إدارة صلاحيات غير سليمة), CWE-78 (حقن أوامر نظام التشغيل) |
المسار المعرض للخطر:
POST /api/v1/cron → commonHandler (مصادقة JWT فقط، بدون فحص دور)
→ CheckPermission(servers=[])
→ يتكرر على قائمة فارغة → يعيد true بدون شرط
→ CronTrigger يرسل الأمر إلى جميع الخوادم عبر ServerShared map
❌ لا فحص مشرف، لا تحقق ملكية → تنفيذ أوامر عبر المستأجرين
المسار المُصحَّح:
POST /api/v1/cron → commonHandler (نفس الشيء — لا يزال HTTP 200 يُعاد للأعضاء)
→ CheckPermission(servers=[]) → true (بدون تغيير)
→ CronTrigger: cronCanSendToServer(cr, s) يتحقق من cr.UserID == s.UserID
✅ يتم إرسال الأوامر فقط إلى الخوادم المملوكة لمنشئ الكرون
| # | الشرط | التفاصيل |
|---|---|---|
| 1 | إصدار Nezha المتأثر | < 1.14.15-0.20260517022419 |
جهاز المضيف
├── localhost:8008 ──→ Docker: nezha-vuln (v1.14.14 ⚠ عرضة)
└── localhost:8009 ──→ Docker: nezha-patched (الالتزام d7526351cf97 ✓ مُصحَّح، مبني من المصدر)
| الأداة | التثبيت |
|---|---|
| Docker Desktop | docker.com |
| nuclei | brew install nuclei |
| curl, python3 | مثبت مسبقًا على macOS |
bash scripts/01-setup.sh
عند الانتهاء:
══════════════════════════════════════════════════════
المختبر جاهز!
══════════════════════════════════════════════════════
عرضة (v1.14.14) : http://localhost:8008
مُصحَّح (الأحدث) : http://localhost:8009
المشرف : admin / admin
العضو : member / Memberpass123!
══════════════════════════════════════════════════════
ملاحظة: إذا اختلفت واجهة إنشاء حساب العضو عن المتوقع، فأنشئه يدويًا عبر واجهة Nezha UI على
http://localhost:8008(الإعدادات ← المستخدمون).
bash scripts/03-trigger-cve.sh
المخرجات المتوقعة — الإصدار العرضة (v1.14.14):
HTTP 200 — تم إنشاء الكرون (id: 1)
⚠ النتيجة: تم تجاوز فحص المشرف — عرضة
المخرجات المتوقعة — الإصدار المُصحَّح:
HTTP 403 — تم رفض الوصول
✓ النتيجة: تم تطبيق فحص المشرف — مُصحَّحة
# المجموعة المعرضة → يجب أن تنتج [حرجة]
nuclei -duc -t nuclei/CVE-2026-46716.yaml \
-u http://localhost:8008 \
-var username=admin \
-var password=admin
# المجموعة المُصحَّحة → يجب ألا تنتج أي نتائج
nuclei -duc -t nuclei/CVE-2026-46716.yaml \
-u http://localhost:8009 \
-var username=admin \
-var password=admin
bash scripts/99-teardown.sh
nezha-cve-2026-46716-lab/
├── README.md
├── LAB_SETUP_GUIDE.md # دليل إعداد المختبر (الإنجليزية)
├── VULNERABILITY_ANALYSIS.md # تحليل الثغرة على مستوى الكود (الإنجليزية)
├── NUCLEI_TEMPLATE_GUIDE.md # دليل قالب Nuclei ونتائج الاختبار (الإنجليزية)
├── docker-compose.yaml
│
├── REPORT/ # تقارير بالكورية
│ ├── LAB_REPORT_KR.md
│ ├── Nuclei_Template_Report_KR.md
│ └── Vulnerability_Analysis_KR.md
│
├── nuclei/
│ └── CVE-2026-46716.yaml # قالب الكشف Nuclei
│
└── scripts/
├── 01-setup.sh # تشغيل الحاويات، إنشاء حساب العضو
├── 03-trigger-cve.sh # PoC: تشغيل تجاوز الصلاحية، التحقق من النتيجة
└── 99-teardown.sh # إيقاف وإزالة جميع موارد المختبر
الخطوة 1 POST /api/v1/login (بيانات المشرف)
→ المصادقة واستخراج رمز JWT
الخطوة 2 GET /api/v1/setting
→ مطابقة حقل الإصدار مع النطاق المعرض (1.4.x – 1.14.14)
→ تطابق → اكتشاف: إصدار عرضة
→ لا تطابق (>= 1.14.15 أو "debug") → لا اكتشاف
كلا الإصدارين العرضة والمُصحَّحة يعيدان HTTP 200 لـ POST /api/v1/cron مع
servers:[], cover:1 — الكشف السلوكي غير ممكن. الإصلاح يضيف فقط التحقق من
الملكية داخل CronTrigger وقت التنفيذ، وليس على مستوى API. بيانات المشرف مطلوبة
لأن GET /api/v1/setting يُعيد حقل version فقط لمستخدمي RoleAdmin.
تحذير: جميع بيانات الاعتماد في هذا المختبر هي بيانات اختبار وهمية لأغراض البحث الأمني فقط. لا تستخدمها في الإنتاج.
| 2 | حساب مصادق عليه | RoleMember (أدنى مستوى صلاحية) |
| 3 | قائمة خوادم فارغة | "servers":[], "cover":1 يتجاوز CheckPermission |