
# Erkennungs-Toolkit für CVE-2026-35616, eine Pre-Authentication-API-Umgehung in FortiClient EMS. Enthält Python-Scanner und Nmap-NSE-Skript zur Identifizierung verwundbarer Versionen sowie Anleitungen zur Behebung.
Eine kritische Authentifizierungsumgehung in Fortinet FortiClient EMS 7.4.5 und 7.4.6 ermöglicht es einem vollständig nicht authentifizierten, entfernten Angreifer, die API-Authentifizierung durch das Fälschen eines einzigen HTTP-Headers (X-SSL-CLIENT-VERIFY) zu umgehen. Der Fehler besteht darin, dass die Django-Middleware Metadaten von Client-Zertifikaten aus benutzerkontrollierten Headern vertraut, nicht nur aus dem vertrauenswürdigen Reverse-Proxy. Dies gibt Angreifern vollen administrativen API-Zugriff – und von dort aus die Möglichkeit zur Ausführung beliebigen Codes auf verwalteten Endpunkten im gesamten Unternehmen.
Aktiv ausgenutzt seit dem 31. März 2026. Aufgenommen in den CISA-KEV am 6. April 2026.
| Feld | Detail |
|---|---|
| CVE-ID | CVE-2026-35616 |
| Anbieter | Fortinet |
| Produkt | FortiClient Enterprise Management Server (EMS) |
| Betroffene Versionen | 7.4.5, 7.4.6 |
| Nicht betroffen | 7.2.x-Zweig, 7.4.4 und früher |
| CVSS v3.1 | 9.1 (Kritisch) |
| CWE | CWE-284 - Unzureichende Zugriffskontrolle |
| Angriffsvektor | Netzwerk |
| Authentifizierung | Keine erforderlich |
| Benutzerinteraktion | Keine |
| Exploit-Reifegrad | In freier Wildbahn ausgenutzt |
| CISA-KEV | Hinzugefügt am 6. April 2026 (Frist: 9. April 2026) |
| Patch | Hotfix verfügbar; vollständige Korrektur in 7.4.7 |
| Gemeldet von | Simo Kohonen (Defused Cyber), Nguyen Duc Anh |
FortiClient Enterprise Management Server (EMS) ist Fortinets zentrale Endpunktverwaltungsplattform. Sie dient als Befehls- und Kontrollebene für die Bereitstellung, Konfiguration und Überwachung von FortiClient-Agenten in einer Organisation. Stellen Sie es sich als das Gehirn vor, das jeden Endpunkt in einer von Fortinet verwalteten Umgebung steuert:
Wenn ein Angreifer administrativen Zugriff auf EMS erlangt, besitzt er im Wesentlichen die Schlüssel zu jedem verwalteten Endpunkt in der Organisation.
FortiClient EMS verwendet hinter den Kulissen einen recht standardmäßigen Webanwendungs-Stack:
+----------------+ +----------------+ +----------------+
| Browser / | HTTPS | Apache | WSGI | Django |
| API Client | -------> | (mod_ssl) | -------> | Backend |
+----------------+ +----------------+ +----------------+
Wenn gegenseitiges TLS (mTLS) konfiguriert ist, übernimmt das mod_ssl von Apache die Überprüfung des Client-Zertifikats. Nach der Validierung des Zertifikats übergibt Apache das Überprüfungsergebnis über vertrauenswürdige WSGI-Umgebungsvariablen an Django weiter:
SSL_CLIENT_VERIFY - Der Überprüfungsstatus (SUCCESS, NONE, FAILED)SSL_CLIENT_S_DN - Der Distinguished Name des Antragstellers aus dem ZertifikatSSL_CLIENT_SERIAL - Die Seriennummer des ZertifikatsDies ist das standardmäßige und sichere Muster. Das Problem liegt darin, wie die Django-Middleware diese Daten liest.
In FortiClient EMS 7.4.5 und 7.4.6 wurde die Django-Authentifizierungs-Middleware so geändert, dass sie diese Informationen auch aus HTTP-Anfrage-Headern akzeptiert:
X-SSL-CLIENT-VERIFYX-SSL-CLIENT-S-DNX-SSL-CLIENT-SERIALDies wurde wahrscheinlich hinzugefügt, um Reverse-Proxy-Bereitstellungen zu unterstützen, bei denen Apache nicht der TLS-Terminierungspunkt ist. Die Middleware unterscheidet jedoch nicht zwischen diesen beiden Quellen. Sie prüft zuerst die WSGI-Variablen, aber wenn diese fehlen (kein mTLS konfiguriert oder eine direkte Verbindung), greift sie auf die HTTP-Header zurück – die jeder Client setzen kann.
Hier ist die konzeptionelle Aufschlüsselung:
SICHERER PFAD (beabsichtigt):
Apache mod_ssl validiert Zertifikat --> setzt WSGI-Umgebungsvariablen --> Django liest Umgebungsvariablen [OK]
UNSICHERER PFAD (die Schwachstelle):
Angreifer setzt HTTP-Header direkt --> Django liest Header --> Vertraut ihnen [FEHLER]
Die Middleware vertraut im Wesentlichen darauf, dass der Client seinen eigenen Zertifikatsüberprüfungsstatus selbst bestätigt. Das ist, als würde ein Türsteher jemanden fragen: „Hey, hat der andere Türsteher deinen Ausweis schon geprüft?" und ihn hereinlassen, wenn er „ja" sagt.
Schritt 1: Angreifer sendet eine POST-Anfrage an einen EMS-API-Endpunkt
mit diesen Headern:
X-SSL-CLIENT-VERIFY: SUCCESS
X-SSL-CLIENT-S-DN: CN=admin
X-SSL-CLIENT-SERIAL: 0000000000000001
Schritt 2: Django-Middleware prüft auf WSGI-Umgebungsvariablen → nicht vorhanden
Greift auf HTTP-Header zurück → findet X-SSL-CLIENT-VERIFY: SUCCESS
Schritt 3: Middleware behandelt Anfrage als authentifiziert mit Admin-Identität
Schritt 4: Angreifer hat vollen administrativen API-Zugriff
Schritt 5: Über die Admin-API kann der Angreifer:
- Bösartige Richtlinien an alle verwalteten Endpunkte verteilen
- Gespeicherte Anmeldeinformationen und Zertifikate extrahieren
- Payloads über die Softwareverteilung bereitstellen
- ZTNA-Konfigurationen ändern
- In das breitere Netzwerk vordringen
Der gesamte Angriff erfordert eine einzige HTTP-Anfrage. Kein Brute-Forcing, kein Credential Stuffing, kein Social Engineering. Nur ein einziger gefälschter Header.
Die Schwere geht hier über den Server selbst hinaus. FortiClient EMS ist ein Kraftverstärker – die Kompromittierung gibt einem Angreifer Einfluss auf jeden verwalteten Endpunkt:
Unmittelbare Auswirkungen:
Nachgelagerte Auswirkungen (über verwaltete Endpunkte):
Unternehmensrisiko:
| Version | Status |
|---|---|
| FortiClient EMS 7.4.6 | Verwundbar |
| FortiClient EMS 7.4.5 | Verwundbar |
| FortiClient EMS 7.4.4 und früher | Nicht betroffen |
| FortiClient EMS 7.2.x | Nicht betroffen |
| Datum | Ereignis |
|---|---|
| ~Ende März 2026 | Schwachstelle entdeckt und von Simo Kohonen und Nguyen Duc Anh gemeldet |
| 31. März 2026 | Erste Ausnutzungsversuche gegen Honeypots aufgezeichnet (Defused Cyber) |
| 4. April 2026 | Fortinet veröffentlicht Notfall-Hotfixes für 7.4.5 und 7.4.6 |
| 6. April 2026 | CISA fügt CVE-2026-35616 zum KEV-Katalog hinzu (Frist: 9. April 2026) |
| 13. April 2026 | Dieses Erkennungs-Toolkit veröffentlicht |
Das Python-Skript testet mehrere API-Endpunkte mit einer Differential-Response-Technik.
So funktioniert es:
HTTP 401 Unauthorized)X-SSL-CLIENT-VERIFY: SUCCESS401 zu etwas anderem ändert (typischerweise 500 oder 200), ist die Authentifizierungsumgehung bestätigtEs wird niemals ein Exploit-Payload gesendet. Der Test ist für die Produktion sicher.
Verwendung:
# Abhängigkeiten installieren (nur stdlib für dieses Skript benötigt)
pip install -r requirements.txt
# Einzelnes Ziel
python CVE-2026-35616_FortiClientEMS_detector.py -t 192.168.1.100
# Benutzerdefinierter Port
python CVE-2026-35616_FortiClientEMS_detector.py -t ems.corp.local -p 8443
# Massenscan aus Datei
python CVE-2026-35616_FortiClientEMS_detector.py -f targets.txt
# JSON-Ausgabe in Datei gespeichert
python CVE-2026-35616_FortiClientEMS_detector.py -t 192.168.1.100 --json -o results.json
# Mit aktivierter SSL-Zertifikatsüberprüfung
python CVE-2026-35616_FortiClientEMS_detector.py -t 192.168.1.100 --verify-ssl
# Erhöhtes Timeout für langsame Netzwerke
python CVE-2026-35616_FortiClientEMS_detector.py -t 192.168.1.100 --timeout 20
Optionen:
| Flag | Beschreibung | Standard |
|---|---|---|
-t, --target | Ziel-IP oder Hostname | - |
-f, --file | Datei mit Zielen, eines pro Zeile (Zeilen, die mit # beginnen, werden übersprungen) | - |
-p, --port | Zielport | 443 |
--timeout | Verbindungs-Timeout in Sekunden | 10 |
--verify-ssl | SSL-Zertifikatsüberprüfung aktivieren | Deaktiviert |
--json | Ergebnisse im JSON-Format ausgeben | Aus |
-o, --output | Ergebnisse in einer Datei speichern | - |
Beispielausgabe:
╔══════════════════════════════════════════════════════════════╗
║ 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-Skript installieren
sudo cp CVE-2026-35616_FortiClientEMS.nse /usr/share/nmap/scripts/
sudo nmap --script-updatedb
# Basisscan
nmap -p 443 --script CVE-2026-35616_FortiClientEMS <target>
# Subnetz scannen
nmap -p 443 --script CVE-2026-35616_FortiClientEMS 10.0.0.0/24
# Mehrere Ziele aus einer Datei scannen
nmap -p 443 --script CVE-2026-35616_FortiClientEMS -iL targets.txt
# Mit Service-Versionserkennung
nmap -sV -p 443 --script CVE-2026-35616_FortiClientEMS <target>
Beispiel-Nmap-Ausgabe:
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
Wenn Sie dies manuell mit curl bestätigen möchten:
# Schritt 1: Baseline - sollte 401 zurückgeben
curl -sk -X POST https://<TARGET>:443/api/v1/auth/signin \
-H "Content-Type: application/json" \
-d '{}' \
-o /dev/null -w "%{http_code}\n"
# Schritt 2: Gefälscht - wenn etwas anderes als 401 zurückgegeben wird, wahrscheinlich verwundbar
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"
Wenn die erste 401 und die zweite 500 oder 200 zurückgibt, ist die Instanz verwundbar.
Achten Sie in Ihrer Umgebung auf diese Anzeichen:
X-SSL-CLIENT-VERIFY-Header von Nicht-Proxy-Quellen enthaltenZu überprüfende Protokollquellen:
Sofortmaßnahmen (jetzt durchführen):
Kurzfristig (diese Woche):
Langfristig:
X-SSL-CLIENT-VERIFY, X-SSL-CLIENT-S-DN und X-SSL-CLIENT-SERIAL-Header aus eingehenden Anfragen am Netzwerkrand entfernenKerem Oruç - Cybersicherheitsingenieur