
Инструментарий обнаружения для 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 года.
| Поле | Детали |
|---|---|
| ID CVE | 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 | Добавлена 6 апреля 2026 года (крайний срок: 9 апреля 2026 года) |
| Патч | Горячий фикс доступен; полное исправление в 7.4.7 |
| Авторы обнаружения | Симо Кохонен (Defused Cyber), Нгуен Дык Ань |
FortiClient Enterprise Management Server (EMS) — это централизованная платформа управления конечными точками от Fortinet. Она служит уровнем управления и контроля (C2) для развёртывания, настройки и мониторинга агентов FortiClient в организации. Представьте её как мозг, который управляет каждой конечной точкой в среде под управлением Fortinet:
Когда злоумышленник получает административный доступ к EMS, он фактически получает ключи от каждой управляемой конечной точки в организации.
FortiClient EMS использует довольно стандартный стек веб-приложений за кулисами:
+----------------+ +----------------+ +----------------+
| Браузер / | HTTPS | Apache | WSGI | Django |
| API-клиент | -------> | (mod_ssl) | -------> | Бэкенд |
+----------------+ +----------------+ +----------------+
Когда настроен взаимный TLS (mTLS), модуль mod_ssl Apache обрабатывает проверку клиентского сертификата. После проверки сертификата Apache передаёт результат проверки в Django через доверенные переменные окружения WSGI:
SSL_CLIENT_VERIFY — статус проверки (SUCCESS, NONE, FAILED)SSL_CLIENT_S_DN — Subject Distinguished Name из сертификата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 — это мультипликатор силы: его компрометация даёт злоумышленнику рычаги воздействия на каждую управляемую конечную точку:
Непосредственное воздействие:
Каскадное воздействие (через управляемые конечные точки):