
CVE-2026-35616(FortiClient EMS における事前認証 API バイパス)向けの検出ツールキットです。脆弱なバージョンの特定と修復ガイダンスを提供する Python スキャナと Nmap NSE スクリプトが含まれています。
Fortinet FortiClient EMS 7.4.5および7.4.6における重大な認証バイパスにより、完全に認証されていないリモート攻撃者が、単一のHTTPヘッダー(X-SSL-CLIENT-VERIFY)を偽装することでAPI認証をバイパスできます。この脆弱性は、Djangoミドルウェアが信頼できるリバースプロキシからのみではなく、ユーザー制御のヘッダーからのクライアント証明書メタデータを信頼するために存在します。これにより、攻撃者は完全な管理APIアクセスを取得でき、そこから企業全体の管理対象エンドポイント上で任意のコード実行が可能になります。
2026年3月31日以降、積極的に悪用されています。2026年4月6日にCISA KEVに追加されました。
| フィールド | 詳細 |
|---|---|
| CVE ID | CVE-2026-35616 |
| ベンダー | Fortinet |
| 製品 | FortiClient Enterprise Management Server (EMS) |
| 影響を受けるバージョン | 7.4.5、7.4.6 |
| 影響を受けないバージョン | 7.2.x系、7.4.4以前 |
| CVSS v3.1 | 9.1(重大) |
| CWE | CWE-284 - 不適切なアクセス制御 |
| 攻撃ベクトル | ネットワーク |
| 認証 | 不要 |
| ユーザー操作 | 不要 |
| 悪用の成熟度 | 実環境で悪用済み |
| CISA KEV | 2026年4月6日追加(期限:2026年4月9日) |
| パッチ | ホットフィックス利用可能。完全な修正は7.4.7で提供 |
| 発見者 | Simo Kohonen(Defused Cyber)、Nguyen Duc Anh |
FortiClient Enterprise Management Server(EMS)は、Fortinetの集中型エンドポイント管理プラットフォームです。組織全体でFortiClientエージェントを展開、構成、監視するためのコマンド&コントロール層として機能します。Fortinet管理環境におけるすべてのエンドポイントを統括する頭脳と考えてください:
攻撃者がEMSへの管理アクセスを取得すると、組織内のすべての管理対象エンドポイントへの鍵を実質的に掌握することになります。
FortiClient EMSは、舞台裏でかなり標準的なWebアプリケーションスタックを使用しています:
+----------------+ +----------------+ +----------------+
| Browser / | HTTPS | Apache | WSGI | Django |
| API Client | -------> | (mod_ssl) | -------> | Backend |
+----------------+ +----------------+ +----------------+
相互TLS(mTLS)が構成されている場合、Apacheのmod_sslがクライアント証明書の検証を処理します。証明書を検証した後、Apacheは検証結果を信頼されたWSGI環境変数を通じてDjangoに渡します:
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終端点ではないリバースプロキシ構成をサポートするために追加されました。しかし、ミドルウェアはこれら2つのソースを区別しません。最初にWSGI変数をチェックしますが、それらが存在しない場合(mTLSが構成されていない、または直接接続の場合)、任意のクライアントが設定できるHTTPヘッダーにフォールバックします。
概念的な内訳は次のとおりです:
安全なパス(意図されたもの):
Apache mod_sslが証明書を検証 --> WSGI環境変数を設定 --> Djangoが環境変数を読み取る [OK]
安全でないパス(脆弱性):
攻撃者がHTTPヘッダーを直接設定 --> Djangoがヘッダーを読み取る --> それらを信頼する [FAIL]
ミドルウェアは事実上、クライアント自身の証明書検証ステータスの自己申告を信頼しています。これは、警備員が誰かに「ねえ、他の警備員がもうあなたのIDを確認した?」と尋ねて、「はい」と言われたら入場を許可するようなものです。
ステップ1: 攻撃者がEMS APIエンドポイントにPOSTリクエストを送信
以下のヘッダーを付与:
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: ミドルウェアがリクエストを管理者IDで認証済みとして処理
ステップ4: 攻撃者が完全な管理APIアクセスを取得
ステップ5: 管理APIから攻撃者は以下が可能:
- すべての管理対象エンドポイントに悪意のあるポリシーをプッシュ
- 保存された認証情報と証明書を抽出
- ソフトウェア配布を介してペイロードを展開
- ZTNA構成を変更
- より広範なネットワークへのピボット
攻撃全体には単一のHTTPリクエストのみが必要です。ブルートフォースも、クレデンシャルスタッフィングも、ソーシャルエンジニアリングも不要です。偽造された1つのヘッダーだけです。
ここでの深刻度はサーバー自体を超えています。FortiClient EMSはフォースマルチプライヤー(力の増幅器)であり、それを侵害すると攻撃者はすべての管理対象エンドポイントに対する支配力を得ます:
即時的な影響:
下流への影響(管理対象エンドポイント経由):
企業リスク:
| バージョン | ステータス |
|---|---|
| FortiClient EMS 7.4.6 | 脆弱 |
| FortiClient EMS 7.4.5 | 脆弱 |
| FortiClient EMS 7.4.4以前 | 影響なし |
| FortiClient EMS 7.2.x | 影響なし |
| 日付 | イベント |
|---|---|
| 2026年3月下旬頃 | Simo Kohonen氏とNguyen Duc Anh氏によって脆弱性が発見・報告 |
| 2026年3月31日 | ハニーポット(Defused Cyber)に対する最初の悪用試行が記録 |
| 2026年4月4日 | Fortinetが7.4.5および7.4.6向け緊急ホットフィックスをリリース |
| 2026年4月6日 | CISAがCVE-2026-35616をKEVカタログに追加(期限:2026年4月9日) |
| 2026年4月13日 | 本検出ツールキット公開 |
Pythonスクリプトは、差分応答手法を使用して複数のAPIエンドポイントをテストします。
仕組み:
HTTP 401 Unauthorizedを期待)X-SSL-CLIENT-VERIFY: SUCCESSを注入した同じリクエストを送信401から他のコード(通常は500または200)に変化した場合、認証バイパスが確認される悪用ペイロードは一切送信されません。このテストは本番環境でも安全です。
使用方法:
# 依存関係のインストール(このスクリプトには標準ライブラリのみ必要)
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 | ターゲットを含むファイル(1行に1つ、#で始まる行はスキップ) | - |
-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