
كشف مجموعة أدوات لـ CVE-2026-35616، وهو تجاوز للمصادقة المسبقة في واجهة برمجة التطبيقات (API) في FortiClient EMS. يتضمن ماسحًا بلغة Python وسكربت Nmap NSE لتحديد الإصدارات المعرضة للخطر وتقديم إرشادات المعالجة.
ثغرة حرجة في تجاوز المصادقة في Fortinet FortiClient EMS 7.4.5 و 7.4.6 تسمح لمهاجم عن بُعد غير مصادق تمامًا بتجاوز مصادقة API عبر تزوير ترويسة HTTP واحدة (X-SSL-CLIENT-VERIFY). يكمن الخلل في أن برمجية Django الوسيطة تثق في بيانات وصف شهادة العميل القادمة من ترويسات يتحكم بها المستخدم، وليس فقط من الوكيل العكسي الموثوق. يمنح هذا المهاجمين وصولًا إداريًا كاملًا لواجهة API - ومن هناك، تنفيذ تعليمات برمجية عشوائية على نقاط النهاية المُدارة عبر المؤسسة.
تم استغلالها بنشاط منذ 31 مارس 2026. أُضيفت إلى كتالوج CISA KEV في 6 أبريل 2026.
| الحقل | التفاصيل |
|---|---|
| معرف CVE | CVE-2026-35616 |
| البائع | Fortinet |
| المنتج | خادم إدارة المؤسسات FortiClient (EMS) |
| الإصدارات المتأثرة | 7.4.5، 7.4.6 |
| غير المتأثرة | فرع 7.2.x، 7.4.4 والإصدارات الأقدم |
| CVSS v3.1 | 9.1 (حرجة) |
| CWE | CWE-284 - التحكم غير السليم في الوصول |
| متجه الهجوم | الشبكة |
| المصادقة | غير مطلوبة |
| تفاعل المستخدم | لا شيء |
| نضج الاستغلال | مُستغلة في البرية |
| CISA KEV | أُضيفت في 6 أبريل 2026 (الموعد النهائي: 9 أبريل 2026) |
| التصحيح | تصحيح عاجل متاح؛ الإصلاح الكامل في 7.4.7 |
| نسبة الفضل إلى | Simo Kohonen (Defused Cyber)، Nguyen Duc Anh |
خادم إدارة المؤسسات FortiClient (EMS) هو منصة إدارة نقاط النهاية المركزية من Fortinet. يعمل كطبقة القيادة والتحكم لنشر وتكوين ومراقبة وكلاء FortiClient عبر المؤسسة. اعتبره الدماغ الذي يحكم كل نقطة نهاية في بيئة مُدارة بواسطة Fortinet:
عندما يحصل مهاجم على وصول إداري إلى EMS، فإنه يمتلك فعليًا مفاتيح كل نقطة نهاية مُدارة في المؤسسة.
يستخدم FortiClient EMS حزمة تطبيقات ويب قياسية إلى حد ما خلف الكواليس:
+----------------+ +----------------+ +----------------+
| Browser / | HTTPS | Apache | WSGI | Django |
| API Client | -------> | (mod_ssl) | -------> | Backend |
+----------------+ +----------------+ +----------------+
عند تكوين TLS المتبادل (mTLS)، تتعامل وحدة mod_ssl الخاصة بـ Apache مع التحقق من شهادة العميل. بعد التحقق من الشهادة، يمرر Apache نتيجة التحقق إلى Django عبر متغيرات بيئة WSGI الموثوقة:
SSL_CLIENT_VERIFY - حالة التحقق (SUCCESS، NONE، FAILED)SSL_CLIENT_S_DN - الاسم المميز للموضوع من الشهادةSSL_CLIENT_SERIAL - الرقم التسلسلي للشهادةهذا هو النمط القياسي والآمن. المشكلة تكمن في كيفية قراءة برمجية Django الوسيطة لهذه البيانات.
في FortiClient EMS 7.4.5 و 7.4.6، تم تعديل برمجية Django الوسيطة للمصادقة لتقبل أيضًا هذه المعلومات نفسها من ترويسات طلبات HTTP:
X-SSL-CLIENT-VERIFYX-SSL-CLIENT-S-DNX-SSL-CLIENT-SERIALيُرجح أن هذا أُضيف لدعم نشر الوكيل العكسي حيث لا يكون Apache هو نقطة إنهاء TLS. ومع ذلك، لا تميز البرمجية الوسيطة بين هذين المصدرين. تتحقق من متغيرات WSGI أولًا، لكن إذا كانت غائبة (عدم تكوين mTLS، أو اتصال مباشر)، فإنها تتراجع إلى ترويسات HTTP - والتي يمكن لأي عميل تعيينها.
إليك التحليل المفاهيمي:
المسار الآمن (المقصود):
Apache mod_ssl يتحقق من الشهادة --> يعين متغيرات بيئة WSGI --> Django يقرأ متغيرات البيئة [موافق]
المسار غير الآمن (الثغرة):
المهاجم يعين ترويسات HTTP مباشرة --> Django يقرأ الترويسات --> يثق بها [فشل]
تثق البرمجية الوسيطة فعليًا بالعميل ليشهد بنفسه على حالة التحقق من شهادته. هذا يشبه حارسًا يسأل شخصًا "هل قام الحارس الآخر بفحص هويتك بالفعل؟" ويسمح له بالدخول عندما يقول "نعم".
الخطوة 1: يرسل المهاجم طلب POST إلى نقطة نهاية API في EMS
مع هذه الترويسات:
X-SSL-CLIENT-VERIFY: SUCCESS
X-SSL-CLIENT-S-DN: CN=admin
X-SSL-CLIENT-SERIAL: 0000000000000001
الخطوة 2: تتحقق برمجية Django الوسيطة من متغيرات بيئة WSGI → غير موجودة
تتراجع إلى ترويسات HTTP → تجد X-SSL-CLIENT-VERIFY: SUCCESS
الخطوة 3: تعامل البرمجية الوسيطة الطلب كمصادق عليه بهوية إدارية
الخطوة 4: يحصل المهاجم على وصول إداري كامل لواجهة API
الخطوة 5: من واجهة API الإدارية، يمكن للمهاجم:
- دفع سياسات خبيثة إلى جميع نقاط النهاية المُدارة
- استخراج بيانات الاعتماد والشهادات المخزنة
- نشر حمولات عبر توزيع البرامج
- تعديل تكوينات ZTNA
- الانتقال الجانبي إلى الشبكة الأوسع
يتطلب الهجوم بأكمله طلب HTTP واحدًا فقط. لا تخمين كلمات مرور، ولا حشو بيانات اعتماد، ولا هندسة اجتماعية. مجرد ترويسة واحدة مزورة.
تتجاوز الخطورة هنا الخادم نفسه. FortiClient EMS هو مضاعف قوة - اختراقه يمنح المهاجم نفوذًا على كل نقطة نهاية مُدارة:
الأثر المباشر:
الأثر اللاحق (عبر نقاط النهاية المُدارة):
مخاطر المؤسسة:
| الإصدار | الحالة |
|---|---|
| FortiClient EMS 7.4.6 | عرضة للثغرة |
| FortiClient EMS 7.4.5 | عرضة للثغرة |
| FortiClient EMS 7.4.4 والإصدارات الأقدم | غير متأثرة |
| FortiClient EMS 7.2.x | غير متأثرة |
| التاريخ | الحدث |
|---|---|
| ~أواخر مارس 2026 | اكتشاف الثغرة والإبلاغ عنها بواسطة Simo Kohonen و Nguyen Duc Anh |
| 31 مارس 2026 | تسجيل أولى محاولات الاستغلال ضد أنظمة honeypot (Defused Cyber) |
| 4 أبريل 2026 | إصدار Fortinet تصحيحات عاجلة طارئة لـ 7.4.5 و 7.4.6 |
| 6 أبريل 2026 | إضافة CISA لـ CVE-2026-35616 إلى كتالوج KEV (الموعد النهائي: 9 أبريل 2026) |
| 13 أبريل 2026 | نشر مجموعة أدوات الكشف هذه |
يختبر سكربت بايثون نقاط نهاية API متعددة باستخدام تقنية الاستجابة التفاضلية.
كيف يعمل:
HTTP 401 Unauthorized)X-SSL-CLIENT-VERIFY: SUCCESS401 إلى أي شيء آخر (عادةً 500 أو 200)، يتم تأكيد تجاوز المصادقةلا يتم إرسال أي حمولة استغلال أبدًا. الاختبار آمن للإنتاج.
الاستخدام:
# تثبيت التبعيات (مطلوبة مكتبة stdlib فقط لهذا السكربت)
pip install -r requirements.txt
# هدف واحد
python CVE-2026-35616_FortiClientEMS_detector.py -t 192.168.1.100
# منفذ مخصص
python CVE-2026-35616_FortiClientEMS_detector.py -t ems.corp.local -p 8443
# فحص جماعي من ملف
python CVE-2026-35616_FortiClientEMS_detector.py -f targets.txt
# حفظ مخرجات JSON إلى ملف
python CVE-2026-35616_FortiClientEMS_detector.py -t 192.168.1.100 --json -o results.json
# مع تفعيل التحقق من شهادة SSL
python CVE-2026-35616_FortiClientEMS_detector.py -t 192.168.1.100 --verify-ssl
# زيادة المهلة للشبكات البطيئة
python CVE-2026-35616_FortiClientEMS_detector.py -t 192.168.1.100 --timeout 20
الخيارات:
| العلم | الوصف | الافتراضي |
|---|---|---|
-t, --target | عنوان IP أو اسم المضيف للهدف | - |
-f, --file | ملف يحتوي على الأهداف، هدف واحد لكل سطر (يتم تخطي الأسطر التي تبدأ بـ #) | - |
-p, --port | منفذ الهدف | 443 |
--timeout | مهلة الاتصال بالثواني | 10 |
--verify-ssl | تفعيل التحقق من شهادة SSL | معطل |
--json | إخراج النتائج بتنسيق JSON | إيقاف |
-o, --output | حفظ النتائج إلى ملف | - |
مثال على المخرجات:
╔══════════════════════════════════════════════════════════════╗
║ CVE-2026-35616 - FortiClient EMS Auth Bypass Detector ║
║ Pre-Authentication API Access Bypass → Privilege Escalation║
║ CVSS: 9.1 (Critical) | CISA KEV: Active Exploitation ║
╚══════════════════════════════════════════════════════════════╝
[*] Scanning 192.168.1.100:443...
Target: 192.168.1.100:443
============================================================
[*] FortiClient EMS detected (Version: Unknown)
Vulnerability Test Results:
[VULNERABLE] /api/v1/auth/signin Baseline: 401 → Spoofed: 500
[VULNERABLE] /api/v1/system/status Baseline: 401 → Spoofed: 500
[NOT VULN] /api/v1/endpoints Baseline: 401 → Spoofed: 401
[!] TARGET IS LIKELY VULNERABLE TO CVE-2026-35616
Pre-authentication API bypass confirmed. Apply hotfix immediately!
Remediation: Upgrade to FortiClient EMS 7.4.7 or apply the hotfix
# تثبيت سكربت NSE
sudo cp CVE-2026-35616_FortiClientEMS.nse /usr/share/nmap/scripts/
sudo nmap --script-updatedb
# فحص أساسي
nmap -p 443 --script CVE-2026-35616_FortiClientEMS <target>
# فحص شبكة فرعية
nmap -p 443 --script CVE-2026-35616_FortiClientEMS 10.0.0.0/24
# فحص أهداف متعددة من ملف
nmap -p 443 --script CVE-2026-35616_FortiClientEMS -iL targets.txt
# مع اكتشاف إصدار الخدمة
nmap -sV -p 443 --script CVE-2026-35616_FortiClientEMS <target>
مثال على مخرجات Nmap:
PORT STATE SERVICE
443/tcp open https
| CVE-2026-35616_FortiClientEMS:
| VULNERABLE:
| FortiClient EMS Pre-Authentication API Bypass
| State: VULNERABLE
| IDs: CVE:CVE-2026-35616
| Risk factor: Critical (CVSS: 9.1)
| Disclosure date: 2026-04-04
| Extra information:
| Affected endpoints: 2
| Remediation: Apply hotfix for FortiClient EMS 7.4.5/7.4.6 or upgrade to 7.4.7
| CISA KEV deadline: April 9, 2026
| References:
| https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-35616
|_ https://www.cisa.gov/known-exploited-vulnerabilities-catalog
إذا كنت تريد التأكيد يدويًا باستخدام curl:
# الخطوة 1: خط الأساس - يجب أن يُرجع 401
curl -sk -X POST https://<TARGET>:443/api/v1/auth/signin \
-H "Content-Type: application/json" \
-d '{}' \
-o /dev/null -w "%{http_code}\n"
# الخطوة 2: المزيف - إذا أُرجع أي شيء غير 401، فمن المرجح أنه عرضة للثغرة
curl -sk -X POST https://<TARGET>:443/api/v1/auth/signin \
-H "Content-Type: application/json" \
-H "X-SSL-CLIENT-VERIFY: SUCCESS" \
-H "X-SSL-CLIENT-S-DN: CN=admin" \
-H "X-SSL-CLIENT-SERIAL: 0000000000000001" \
-d '{}' \
-o /dev/null -w "%{http_code}\n"
إذا أُرجع الأول 401 والثاني 500 أو 200، فإن المثيل عرضة للثغرة.
ابحث عن هذه العلامات في بيئتك:
X-SSL-CLIENT-VERIFY من مصادر غير وكيلةمصادر السجلات للمراجعة:
إجراءات فورية (قم بها الآن):
على المدى القصير (هذا الأسبوع):
على المدى الطويل:
X-SSL-CLIENT-VERIFY و X-SSL-CLIENT-S-DN و X-SSL-CLIENT-SERIAL من الطلبات الواردة عند حافة الشبكةKerem Oruç - مهندس أمن سيبراني