
CVE-2026-11374-check — Updated!
Скрипт обнаружения для CVE-2026-11374
CVE-2026-11374 Сценарий обнаружения предусловия для ManageEngine AD360
Скрипт обнаружения предусловия эксплуатации CVE-2026-11374 — предсказуемой уязвимости SSO-билетов, которая приводит к неаутентифицированному захвату учётных записей во всём комплексе ManageEngine AD360. Четыре продукта, попадающие в область действия, используют общий ManageEngineADSFramework:
| Продукт | Затронутая сборка | Исправленная сборка |
|---|---|---|
| ADSelfService Plus | ≤ 6528 | 6529 |
| RecoveryManager Plus | ≤ 6320 | 6321 |
| M365 Manager Plus | ≤ 4816 | 4817 |
| ADAudit Plus | ≤ 8702 | 8703 |
В затронутых сборках SSO-билет — это просто System.currentTimeMillis() (предсказуемая метка времени), снятая при входе жертвы, поэтому его можно воспроизвести через cookie CUSTOM_SSO_TICKET, чтобы перехватить эту сессию. Исправление заменяет билет на UUID.randomUUID() (достаточно случайный идентификатор). Путь воспроизведения доступен только когда продукт интегрирован с AD360: ADSFilter допускает его при условии isProductIntegrated(). Это условие и есть предусловие, которое проверяет данный инструмент.
ПРИМЕЧАНИЕ: этот детектор подтверждает предусловие, а не саму уязвимость. Результат
POTENTIALLY_AFFECTED— это не вердикт «подтверждённо уязвим»; подробнее см. ниже.
Безопасно ли его запускать?
Да. Он предназначен для использования в производственной среде и при оценке безопасности.
- Ничего не эксплуатируется. Зонд отправляет недействительный SSO-билет (
1700000000000— значение в миллисекундах, достаточно старое, чтобы никогда не оказаться в кэше), поэтому ни одна сессия не восстанавливается. Сервер лишь просит очистить отправленные нами cookie. - Состояние цели не меняется. Каждый запрос — обычный
GET, и единственные затронутые cookie — одноразовые, которые отправляет инструмент. - Никакого перебора или разрешения сессий. Инструмент не предпринимает активное разрешение билета по метке времени, которое доказало бы эксплуатируемость; это уже эксплуатация, а не обнаружение, и она вне рамок данного инструмента (см. Ограничения).
Что этот инструмент может и чего не может сказать
Патч CVE-2026-11374 изменил только способ генерации билета (с миллисекунд на UUID); он не менял путь воспроизведения cookie, который проверяет этот зонд. В результате исправленная установка отвечает побайтово идентично уязвимой на любой неаутентифицированный запрос.
Что инструмент может сделать без аутентификации и без разрушающих воздействий:
- Подтвердить, что у доступного продукта из области действия активен путь воспроизведения cookie CustomSSO (то есть он интегрирован с AD360), что является предусловием эксплуатации CVE-2026-11374.
- Определить, какой именно из четырёх продуктов отвечает, по cookie сессии, уникальной для каждого продукта.
- По возможности извлечь номер сборки актива как подсказку. Это доступно для ADSelfService Plus, ADAudit Plus и M365 Manager Plus; недоступно для RecoveryManager Plus.
Чего он не может:
- Отличить уязвимую версию от исправленной. Для этого не существует безопасного, пассивного, неаутентифицированного сигнала. Результат
POTENTIALLY_AFFECTEDозначает, что предусловие выполнено, и вам следует проверить уровень патча, а не то, что хост подтверждённо уязвим. - Подтвердить эксплуатируемость. Доказательство фактической эксплуатируемости хоста требует наблюдения за форматом выданного билета (13-значное число — уязвимо, UUID — исправлено; для обоих нужен аутентифицированный доступ или доступ к хосту), локального чтения
conf/product.confлибо активного разрешения действующего билета (реальная эксплуатация, намеренно не реализована здесь). - Полностью доверять номеру сборки ADSelfService Plus ниже исправленной. Параметр
?build=у ADSSP иногда показывает реальную сборку, а иногда — замороженное значение-заглушку, которое оказывается ниже исправленной сборки, поэтому значение ниже исправленной неоднозначно, и инструмент помечает его как неопределённое. Значение на уровне исправленной сборки или выше по-прежнему является надёжным признаком установки патча, поскольку заглушка всегда слишком низкая, чтобы достичь его.
Требования
- Python 3.7+ и библиотека
requests. Установка:pip install requests.
Использование
# single host (prefer a URL or host:port; ports differ per product)
./cve_2026_11374_check.py https://adssp.example.com:8888
# multiple hosts (scheme optional: https is tried first, then http)
./cve_2026_11374_check.py host-a:8081 host-b:8365
# scan a list, one target per line ('#' comments allowed), compact output
./cve_2026_11374_check.py -f targets.txt --brief
# machine-readable output for pipelines
./cve_2026_11374_check.py -f targets.txt --json > results.json
Порты по умолчанию различаются для каждого продукта (ADSelfService Plus 8888, ADAudit Plus 8081, M365 Manager Plus 8365, RecoveryManager Plus 8090), поэтому передавайте URL или host:port. Для адреса без порта по умолчанию используется 8888.
Параметры
| Флаг | Описание |
|---|---|
targets | Один или несколько адресов host, host:port или https://host:port |
-f, --targets-file FILE | Читать цели из файла (по одной на строку; комментарии #) |
--brief | Одна выровненная строка на цель, удобно при сканировании многих хостов |
--json | Выдавать структурированные результаты в JSON |
--timeout SECS | Таймаут на запрос (по умолчанию: 15) |
--no-build | Пропускать дополнительный запрос номера сборки при положительном результате |
--no-color | Отключить цветной вывод (также учитывает NO_COLOR и не-TTY) |
Примеры
Интегрированная с AD360 консоль (подробный режим, используется по умолчанию). Во второй строке поясняется, что это предусловие, а не вердикт об уязвимости; третья — полученная по возможности подсказка о сборке:
$ ./cve_2026_11374_check.py https://adssp.example.com:8888
[!] https://adssp.example.com:8888: POTENTIALLY_AFFECTED
ADSelfService Plus: AD360-integrated, CustomSSO replay path active - precondition met. Not confirmed vulnerable; verify patch level (fixed build 6529).
build: 6519 (below fixed 6529 - inconclusive: ?build= may be a stale placeholder or a hotfix)
Автономная установка того же продукта, где путь воспроизведения неактивен:
$ ./cve_2026_11374_check.py https://adssp.example.com:8888
[+] https://adssp.example.com:8888: UNAFFECTED
ADSelfService Plus: standalone / not AD360-integrated (no cleanup), so the replay path isn't reachable here. Verify build >= 6529 regardless.
Сканирование списка с одной выровненной строкой на хост (--brief). Код возврата равен 1, если хотя бы один хост — POTENTIALLY_AFFECTED, иначе 0; это удобно в скриптах. Завершающая пометка показывает определённый продукт, а при находке — номер сборки:
$ ./cve_2026_11374_check.py -f targets.txt --brief; echo "exit: $?"
POTENTIALLY_AFFECTED https://host-a:8888 ADSelfService Plus 6519
POTENTIALLY_AFFECTED http://host-b:8081 ADAudit Plus 8530
UNAFFECTED http://host-c:8365 M365 Manager Plus
UNAFFECTED https://host-d:443
INCONCLUSIVE http://host-e:8888 ADSelfService Plus
ERROR host-f:8888 timeout
exit: 1
Машиночитаемый вывод (--json). Каждый результат содержит verdict, а также state и detail, лежащие в его основе, определённый product и — при находке — объект build: build — найденный номер, fixed_build — порог для этого продукта, patch_hint — направленная оценка (likely_patched на уровне исправленной сборки или выше, иначе inconclusive), а note — краткое пояснение:
$ ./cve_2026_11374_check.py https://host-b:8081 --json
[
{
"target": "https://host-b:8081",
"state": "potentially_affected",
"detail": "ADAudit Plus: AD360-integrated, CustomSSO replay path active - precondition met ...",
"product": "ADAudit Plus",
"build": { "build": "8530", "fixed_build": "8703", "patch_hint": "inconclusive", "note": "below fixed 8703 - inconclusive: may be a hotfix" },
"verdict": "POTENTIALLY_AFFECTED"
}
]
Вердикты
| Вердикт | Значение |
|---|---|
POTENTIALLY_AFFECTED | Продукт из области действия интегрирован с AD360; путь воспроизведения cookie CustomSSO активен, поэтому предусловие эксплуатации CVE-2026-11374 выполнено. Это не вердикт «подтверждённо уязвим»; проверьте уровень патча (см. дальнейшие шаги). |
UNAFFECTED | Путь воспроизведения недоступен. Варианты: автономный продукт из области действия (не интегрирован с AD360 — хотя он станет доступен при последующей интеграции, поэтому всё равно проверьте сборку); продукт ManageEngine на базе ADS-framework, не входящий в число четырёх; или в ответе вообще нет продукта из области действия (не один из четырёх продуктов CVE-2026-11374, либо прокси, удаляющий cookie сессии). |
INCONCLUSIVE | HTTP 400 — вероятно, блокировка из-за ограничения частоты запросов IAM маскирует сигнал; повторите попытку примерно через 60 с. |
ERROR | Ошибка соединения/таймаута/TLS. |
Коды возврата
| Код | Значение |
|---|---|
0 | Ни одна цель не вернула POTENTIALLY_AFFECTED |
1 | Хотя бы одна цель получила POTENTIALLY_AFFECTED |
2 | Ошибка использования (неверные аргументы / нечитаемый файл целей) |
Как это работает
Отправьте недействительный билет и метку приложения на любой URL CustomSSO (*.do):
GET /AppsHome.do
Cookie: CUSTOM_SSO_TICKET=1700000000000; CUSTOM_SSO_APP_TAG_NAME=AD360
На установке, интегрированной с AD360, цепочка ADSFilter → CustomSSOFilter → CookieSSOImpl выполняет ветвь разрешения (метка указывает на другой продукт, поэтому appName != prodName), не может разрешить поддельный билет и выдаёт заголовки ответа с очисткой cookie:
Set-Cookie: CUSTOM_SSO_TICKET=removed; Max-Age=0; ...
Set-Cookie: CUSTOM_SSO_APP_NAME=removed; Max-Age=0; ...
Set-Cookie: CUSTOM_SSO_APP_TAG_NAME=removed; Max-Age=0; ...
Автономная установка никогда не выполняет этот путь и не выдаёт очистку cookie. Продукт определяется по фиксированной для каждого продукта cookie сессии Tomcat (JSESSIONIDADSSP для ADSelfService Plus и т. д.), которая устанавливается в каждом ответе. Проверка опирается на заголовки, а не на код состояния, поскольку интегрированный ADSSP возвращает 302, а ADAudit, M365 и RMP на тот же зонд отвечают 200.
| Ответ на зонд | Вердикт |
|---|---|
| заголовки очистки и известная cookie продукта из области действия | POTENTIALLY_AFFECTED |
| cookie продукта, без очистки, статус ≠ 400 | UNAFFECTED (автономный / не интегрирован) |
| нет cookie продукта из области действия, статус ≠ 400 | UNAFFECTED (не один из четырёх продуктов) |
| заголовки очистки, но неизвестная cookie продукта | UNAFFECTED (ManageEngine, вне области действия) |
HTTP 400 | INCONCLUSIVE (вероятно, блокировка из-за ограничения частоты IAM; см. Ограничения) |
Ограничения
POTENTIALLY_AFFECTED— это не «подтверждённо уязвим». Это предусловие эксплуатации. Поскольку патч не затрагивал этот код, исправленная сборка отвечает идентично, поэтому уровень патча нужно подтверждать вне полосы (см. дальнейшие шаги). Это верхняя граница того, что может знать неаутентифицированный наблюдатель.- Нет активного подтверждения. Инструмент никогда не пытается разрешить реальный билет, действительный на текущий момент. Этот метод может положительно доказать уязвимость хоста, но это активная эксплуатация (перехват живой сессии), он ограничен троттлингом и вероятностный, и требует активной сессии жертвы, поэтому он исключён из этого детектора.
HTTP 400может быть блокировкой из-за ограничения частоты запросов, а не реальным ответом. Zoho IAM применяет скользящее ограничение по URL, которое ограничивает исходный IP примерно 40 запросами за 60 с, а затем блокирует этот путь на ~60 с. Во время блокировки запросы возвращаютHTTP 400, и сигнал интеграции маскируется. Инструмент сообщает об этом какINCONCLUSIVE; повторите попытку с этого IP примерно через минуту.- За обратным прокси консоль, которая удаляет или переписывает cookie сессии, может быть ошибочно помечена как
UNAFFECTED. Если вы ожидаете там продукт ManageEngine, подтвердите напрямую. - Номера сборок — это подсказки, а не вердикты. ADAudit (
?v=) и M365 (?bN=) всегда показывают реальную сборку;?build=у ADSSP иногда реальный, а иногда замороженная заглушка, которая показывает значение ниже исправленной сборки, поэтому значение ADSSP ниже исправленной неоднозначно; RMP не раскрывает никакой. В любом случае сборка на уровне исправленной или выше с большой вероятностью означает установку патча, а ниже — неопределённость.
Дальнейшие шаги для защитников
Если цель вернула POTENTIALLY_AFFECTED, считайте её открытой и требующей подтверждения. Далее:
-
Подтвердите уровень патча напрямую (инструмент не может). Прочитайте
conf/product.conf(build_number) на хосте и сравните с исправленной сборкой для этого продукта (ADSelfService Plus 6529, RecoveryManager Plus 6321, M365 Manager Plus 4817, ADAudit Plus 8703). Интерпретируйте направленно: сборка на уровне исправленной или выше — сильный признак того, что хост запропатчен, поскольку исправление с UUID находится в этом дереве. Сборка ниже исправленной неопределённа, а не доказательство уязвимости, потому что внешние горячие исправления и бэкпорты могут применить UUID-фикс без увеличения номера сборки; в этом случае прибегните к проверке формата билета ниже. -
Проверьте формат выданного билета, если можете войти. Cookie
CUSTOM_SSO_TICKETне являетсяHttpOnly, поэтому после аутентификации вы можете прочитать её значение: 13-значное число означает уязвимость, UUID — патч. Это самая чёткая положительная проверка. -
Обновите до исправленной сборки (или более поздней) на любом хосте, который уязвим или который вы не можете подтвердить как запропатченный. Исправление заменяет предсказуемый билет на случайный UUID.
-
Ищите попытки эксплуатации. На хосте
serverOut_<date>.txtфиксирует троттлинг как всплески:IAMSecurityException ErrorCode: URL_ROLLING_THROTTLES_LIMIT_EXCEEDED, RequestURI: "/showLogin.cc", RemoteAddr: <source IP>Всплеск
URL_ROLLING_THROTTLES_LIMIT_EXCEEDEDна путях диспетчеризации SSO/входа с одного исходного IP — сильный признак перебора билетов. Также просмотрите недавние успешные входы и активность сессий на предмет признаков захвата. -
Тем временем снизьте подверженность риску. Ограничьте сетевой доступ к комплексу AD360 (он не должен быть доступен из интернета), а если путь воспроизведения не нужен, отключение интеграции CustomSSO полностью устраняет предусловие.
Устранение
Обновите затронутый продукт как минимум до исправленной сборки (ADSelfService Plus 6529, RecoveryManager Plus 6321, M365 Manager Plus 4817, ADAudit Plus 8703) или более поздней. Исправление заменяет предсказуемый SSO-билет System.currentTimeMillis() на UUID.randomUUID().
Лицензия
Этот код распространяется по лицензии MIT.
Юридический отказ от ответственности
Использование этого инструмента для атак на цели без предварительного взаимного согласия незаконно. Ответственность за соблюдение всех применимых местных, государственных и федеральных законов лежит на конечном пользователе. Разработчики не несут ответственности и не отвечают за любое неправомерное использование или ущерб, причинённый этой программой.
См. также
- NVD: CVE-2026-11374
- Пакеты обновления ManageEngine: ADSelfService Plus · RecoveryManager Plus · M365 Manager Plus · ADAudit Plus
- Блог Bishop Fox: Полный технический анализ