
Безопасный неаутентифицированный чекер состояния патча для Check Point CPM RCE CVE-2026-93616; проверяет SOAP-логин UpgradeSvcRemote на TCP 19009 без эксплуатации.
Проверка состояния патча без аутентификации для CVE-2026-93616 — неаутентифицированного обхода каталогов в сервере Check Point Security Management (CPM), приводящего к Runtime.exec(), исправленного в
sk1000171 2026-09-22. CWE-22,
CVSS 9.8 Critical (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H), эксплуатируется в
реальных атаках. Check Point является CNA; проблема была выявлена в результате
эксплуатации в реальных атаках, а не по внешнему отчёту.
Сервер CPM предоставляет SOAP-веб-сервисы на TCP 19009. Метод входа UpgradeSvcRemote
loginAsApplicationReadOnlyPublicSession передаёт свой параметр targetVersion
в путь файловой системы, передаваемый в Runtime.exec, без проверки, поэтому
неаутентифицированный вызывающий может перенаправить выполнение на выбранный
атакующим скрипт. Исправление добавляет шаблон Bean Validation к targetVersion,
который отклоняет разделитель пути.
Скрипт сообщает, присутствует ли это исправление на каждой цели. Он отправляет один
недопустимый символ в targetVersion, никогда не последовательность обхода, и не
аутентифицируется, не загружает файл и ничего не выполняет на цели. Результат, отличный
от VULNERABLE, сам по себе не означает, что цель пропатчена; см.
Интерпретация результатов, отличных от уязвимых.
Сборки с завершённой поддержкой обрабатываются явно. На ветках старше R81.10 метод
входа принимает меньше параметров, поэтому первичная проверка отклоняется при
XML-демаршалинге до того, как можно прочитать состояние патча. Когда сервер Check Point
отклоняет проверку таким образом, скрипт отправляет один дополнительный вызов в старой
форме параметров. Если метод входа затем выполняется, цель является затронутой сборкой,
для которой Check Point никогда не публиковал исправление, и вердикт —
VULNERABLE с причиной affected-eos-no-fix. Дополнительный вызов не содержит ни mode,
ни targetVersion, поэтому он также не отправляет ничего для проверки и ничего для
обхода. Это закрывает пробел, при котором устаревший сервер иначе определялся бы как
неидентифицируемый.
# single target (port defaults to 19009)
./cve_2026_93616_check.py mgmt.example.com
# explicit port
./cve_2026_93616_check.py mgmt.example.com:19009
# several targets
./cve_2026_93616_check.py mds-a.example.com mds-b.example.com
# scan a list, one target per line ('#' comments allowed), compact output
./cve_2026_93616_check.py -f targets.txt --brief
# machine-readable output for pipelines
./cve_2026_93616_check.py -f targets.txt --json > results.json
Python 3.8+, только стандартная библиотека — без сторонних пакетов.
Запускайте инструмент против серверов управления (Security Management, Multi-Domain Management, Log, Multi-Domain Log и SmartEvent), а не против шлюзов. Проверка нацелена на SOAP-слушатель CPM на TCP 19009, который шлюзы не запускают.
| Флаг | Описание |
|---|---|
TARGET | Одна или несколько целей HOST[:PORT]; порт по умолчанию — 19009 |
-f, --targets-file FILE | Читать цели из файла (по одной в строке; комментарии #) |
-p, --port PORT | Порт по умолчанию, когда цель его не указывает (по умолчанию: 19009) |
--timeout SECS | Тайм-аут на проверку (по умолчанию: 15) |
--workers N | Одновременных целей (по умолчанию: 16); вывод сохраняется в порядке ввода |
-b, --brief | Одна выровненная строка на цель, для сканирования множества хостов |
--json | Вывод структурированного JSON, включая маркеры проверки для каждой цели |
--no-color | Отключить цветной вывод (также учитывает NO_COLOR и не-TTY) |
Уязвимый сервер (вывод по умолчанию; маркер [!] и VULNERABLE отображаются красным
на TTY):
$ ./cve_2026_93616_check.py mgmt.example.com
[!] mgmt.example.com:19009: VULNERABLE [dispatched-without-validation]
loginAsApplicationReadOnlyPublicSession accepted an illegal targetVersion and dispatched it; the fix's input validation is absent
Пропатченный сервер:
$ ./cve_2026_93616_check.py mgmt-dr.example.com
[+] mgmt-dr.example.com:19009: PATCHED [validation-constraint-present]
the server rejected an illegal targetVersion with the input-validation constraint added by the fix (Jumbo Hotfix R82.10 Take 45 or equivalent)
Сервер управления Check Point, который ответил, но не выполнил метод входа, поэтому состояние патча не удалось прочитать:
$ ./cve_2026_93616_check.py log.example.com
[?] log.example.com:19009: INCONCLUSIVE [cpm-no-dispatch]
a Check Point management fault came back, but the UpgradeSvcRemote login method did not dispatch, so patch state could not be read
Несколько целей с --brief:
$ ./cve_2026_93616_check.py -f targets.txt --brief; echo "exit: $?"
VULNERABLE mgmt.example.com:19009 dispatched-without-validation
PATCHED mgmt-dr.example.com:19009 validation-constraint-present
INCONCLUSIVE log.example.com:19009 cpm-no-dispatch
UNAFFECTED web.example.com:19009 not-cpm
ERROR offline.example.com:19009 unreachable
exit: 1
Вывод JSON с --json. Маркеры проверки включены, чтобы вердикт можно было сверить
с тем, что фактически содержал ответ:
$ ./cve_2026_93616_check.py mgmt.example.com mgmt-dr.example.com --json
[
{
"target": "mgmt.example.com:19009",
"verdict": "VULNERABLE",
"reason": "dispatched-without-validation",
"detail": "loginAsApplicationReadOnlyPublicSession accepted an illegal targetVersion and dispatched it; the fix's input validation is absent",
"http_status": 500,
"probe": {
"http_status": 500,
"saw_validation": false,
"saw_dispatch": true,
"saw_cpm": true,
"note": ""
}
},
{
"target": "mgmt-dr.example.com:19009",
"verdict": "PATCHED",
"reason": "validation-constraint-present",
"detail": "the server rejected an illegal targetVersion with the input-validation constraint added by the fix (Jumbo Hotfix R82.10 Take 45 or equivalent)",
"http_status": 500,
"probe": {
"http_status": 500,
"saw_validation": true,
"saw_dispatch": true,
"saw_cpm": true,
"note": ""
}
}
]
Проверка предназначена для использования против производственных систем:
!) в targetVersion; этого одного символа достаточно, чтобы
сработала проверка пропатченной сборки, и он не может выйти из каталога так, как это
сделал бы разделитель пути. Дополнительная проверка для устаревших сборок вообще не
содержит targetVersion.domainId, поэтому на
непатченном сервере метод вызывает NullPointerException при построении своих
параметров, прежде чем ReflectionUtils достигнет Runtime.exec. Даже без этого
значение проверки разрешается в несуществующий каталог, поэтому запускать нечего.
Проверка для устаревших сборок отправляет только имя приложения и тайм-аут, поэтому
ей не из чего строить путь.