
Comprobador seguro no autenticado del estado de parcheo para Check Point CPM RCE CVE-2026-93616; sondea el inicio de sesión SOAP de UpgradeSvcRemote en TCP 19009 sin explotarlo.
Una comprobación no autenticada del estado de parcheo para CVE-2026-93616, el directory
traversal no autenticado en el servidor Check Point Security Management (CPM) que alcanza
Runtime.exec(), corregido en
sk1000171 el 2026-09-22. CWE-22,
CVSS 9.8 Crítico (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H), explotado en el
mundo real. Check Point es el CNA; el problema se identificó a partir de la explotación
en el mundo real en lugar de un informe externo.
El servidor CPM expone servicios web SOAP en TCP 19009. El método de inicio de sesión
loginAsApplicationReadOnlyPublicSession de UpgradeSvcRemote reenvía su parámetro
targetVersion a una ruta del sistema de archivos pasada a Runtime.exec sin validación,
por lo que un llamador no autenticado puede redirigir la ejecución a un script elegido por
el atacante. La corrección añade un patrón de Bean Validation a targetVersion que rechaza
un separador de ruta.
El script informa si esa corrección está presente en cada objetivo. Envía un carácter
ilegal en targetVersion, nunca una secuencia de traversal, y no se autentica, no sube un
archivo ni ejecuta nada en el objetivo. Un resultado distinto de VULNERABLE no indica por
sí mismo que un objetivo esté parcheado; véase
Interpretación de resultados no vulnerables.
Las compilaciones en fin de soporte se manejan explícitamente. En ramas anteriores a
R81.10 el método de inicio de sesión toma menos parámetros, por lo que la sonda principal
es rechazada por el unmarshalling de XML antes de que se pueda leer el estado de parcheo.
Cuando un servidor Check Point rechaza la sonda de esa manera, el script envía una llamada
de seguimiento con la forma de parámetros antigua. Si el método de inicio de sesión
entonces se despacha, el objetivo es una compilación afectada para la que Check Point nunca
publicó una corrección, y el veredicto es VULNERABLE con la razón affected-eos-no-fix.
La llamada de seguimiento no lleva mode ni targetVersion, por lo que tampoco envía nada
que validar ni nada que recorrer. Esto cierra una brecha en la que un servidor heredado de
otro modo se leería como no identificable.
# 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+, solo biblioteca estándar — sin paquetes de terceros.
Ejecute la herramienta contra los servidores de gestión (Security Management, Multi-Domain Management, Log, Multi-Domain Log y SmartEvent), no contra las pasarelas. La comprobación se dirige al listener SOAP de CPM en TCP 19009, que las pasarelas no ejecutan.
| Flag | Descripción |
|---|---|
TARGET | Uno o más objetivos HOST[:PORT]; el puerto por defecto es 19009 |
-f, --targets-file FILE | Leer objetivos de un archivo (uno por línea; comentarios #) |
-p, --port PORT | Puerto por defecto cuando un objetivo omite uno (por defecto: 19009) |
--timeout SECS | Tiempo de espera por sonda (por defecto: 15) |
--workers N | Objetivos concurrentes (por defecto: 16); la salida permanece en el orden de entrada |
-b, --brief | Una línea alineada por objetivo, para escanear muchos hosts |
--json | Emitir JSON estructurado, incluyendo los marcadores de sonda por objetivo |
--no-color | Deshabilitar la salida con color (también respeta NO_COLOR y no-TTY) |
Servidor vulnerable (salida por defecto; el marcador [!] y VULNERABLE se muestran en
rojo en un 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
Servidor parcheado:
$ ./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)
Un servidor de gestión Check Point que respondió pero no despachó el método de inicio de sesión, por lo que no se pudo leer el estado de parcheo:
$ ./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
Múltiples objetivos con --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
Salida JSON con --json. Los marcadores de sonda se incluyen para que el veredicto pueda
comprobarse contra lo que realmente contenía la respuesta:
$ ./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": ""
}
}
]
La comprobación está pensada para usarse contra sistemas de producción:
!) en targetVersion; ese único carácter es suficiente para activar la
validación de la compilación parcheada, y no puede escapar de un directorio como lo haría
un separador de ruta. La sonda de seguimiento heredada no lleva targetVersion en
absoluto.domainId, por lo que en un
servidor sin parchear el método lanza una NullPointerException mientras construye sus
parámetros, antes de que ReflectionUtils alcance Runtime.exec. Incluso sin eso, el
valor de la sonda resuelve a un directorio que no existe, por lo que no hay script que
ejecutar. La sonda heredada envía solo un nombre de aplicación y un tiempo de espera, por
lo que no tiene nada con lo que construir una ruta.