Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-93616-check — Safe unauthenticated patch-state checker for Check Point CPM RCE CVE-2026-93616; probes the UpgradeSvcRemote SOAP login on TCP 19009 without exploiting. | Kitploit
Tools/GitHubGitHub/bishopfox/cve-2026-93616-check
Defensive ToolsVulnerability ScannersVulnerability AnalysisExploitationNetwork SecurityPenetration TestingRemote Access Tool
GitHubbishopfox/cve-2026-93616-check

CVE-2026-93616-check

Safe unauthenticated patch-state checker for Check Point CPM RCE CVE-2026-93616; probes the UpgradeSvcRemote SOAP login on TCP 19009 without exploiting.

View Repository
1 day agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

Check Point Security Management Unauthenticated RCE — Vulnerability Detection Script

An unauthenticated patch-state check for CVE-2026-93616, the unauthenticated directory traversal in the Check Point Security Management (CPM) server that reaches Runtime.exec(), fixed in sk1000171 on 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), exploited in the wild. Check Point is the CNA; the issue was identified from in-the-wild exploitation rather than an external report.

The CPM server exposes SOAP web services on TCP 19009. The UpgradeSvcRemote login method loginAsApplicationReadOnlyPublicSession forwards its targetVersion parameter into a filesystem path passed to Runtime.exec without validation, so an unauthenticated caller can redirect execution to an attacker-chosen script. The fix adds a Bean Validation pattern to targetVersion that rejects a path separator.

The script reports whether that fix is present on each target. It sends one illegal character in targetVersion, never a traversal sequence, and does not authenticate, upload a file, or execute anything on the target. A result other than VULNERABLE does not by itself indicate that a target is patched; see Interpreting non-vulnerable results.

End-of-support builds are handled explicitly. On trains older than R81.10 the login method takes fewer parameters, so the primary probe is rejected by XML unmarshalling before patch state can be read. When a Check Point server rejects the probe that way, the script sends one follow-up call in the older parameter shape. If the login method then dispatches, the target is an affected build for which Check Point never published a fix, and the verdict is VULNERABLE with the reason affected-eos-no-fix. The follow-up call carries no mode and no targetVersion, so it too sends nothing to validate and nothing to traverse. This closes a gap in which a legacy server would otherwise read as unidentifiable.

Usage

# 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+, standard library only — no third-party packages.

Run the tool against the management servers (Security Management, Multi-Domain Management, Log, Multi-Domain Log, and SmartEvent), not the gateways. The check targets the CPM SOAP listener on TCP 19009, which the gateways do not run.

Options

FlagDescription
TARGETOne or more HOST[:PORT] targets; the port defaults to 19009
-f, --targets-file FILERead targets from a file (one per line; # comments)
-p, --port PORTDefault port when a target omits one (default: 19009)
--timeout SECSPer-probe timeout (default: 15)
--workers NConcurrent targets (default: 16); output stays in input order
-b, --briefSingle aligned line per target, for scanning many hosts
--jsonEmit structured JSON, including the probe markers per target
--no-colorDisable coloured output (also honours NO_COLOR and non-TTY)

Examples

Vulnerable server (default output; the [!] marker and VULNERABLE are shown in red on a 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

Patched server:

$ ./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)

A Check Point management server that answered but did not dispatch the login method, so patch state could not be read:

$ ./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

Multiple targets with --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 output with --json. The probe markers are included so the verdict can be checked against what the response actually contained:

$ ./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": ""
    }
  }
]

Is it Safe to Run?

The check is intended for use against production systems:

  • It does not authenticate. No session, credential, or client certificate is presented. It observes how the server handles one malformed parameter, which depends on the installed build.
  • It never sends a traversal sequence. The primary probe puts a single illegal character (!) in targetVersion; that one character is enough to trip the patched build's validation, and it cannot escape a directory the way a path separator would. The legacy follow-up probe carries no targetVersion at all.
  • It executes nothing. The primary probe omits the domainId element, so on an unpatched server the method raises a NullPointerException while building its parameters, before ReflectionUtils reaches Runtime.exec. Even without that, the probe value resolves to a directory that does not exist, so there is no script to run. The legacy probe sends only an application name and timeout, so it has nothing to build a path from.
  • It does not upload a file. The file-write half of the exploit chain uses a different service, which this tool never calls.
  • It opens one TCP connection per probe and closes it after reading the response.

Request and log footprint

#CallWhenPurpose
1UpgradeSvcRemote.loginAsApplicationReadOnlyPublicSession (current shape)alwaysThe patch-state probe
2UpgradeSvcRemote.loginAsApplicationReadOnlyPublicSession (legacy shape)only if call 1 is rejected at unmarshalling by a Check Point serverConfirms an end-of-support build
Download Tool