15 min to read
Check Point Gateways Under Attack: Hunting PHP2Shell and CVE-2026-123039
From Mobile Access portal to root to a wiped ESXi host, and how to check yours
Three weeks ago we wrote about PHP2Shell, the pair of critical bugs in PHP itself that attackers were exploiting before the patch landed (our earlier post). This week we learned where one of the most dangerous campaigns using it went: straight at Check Point firewalls.
Check Point Research (CPR) says attackers used PHP2Shell against Mobile Access portals on Check Point gateways, then escalated to root with a previously unknown Gaia flaw, CVE-2026-123039, planted custom backdoors, pivoted to VMware ESXi and, in some cases, ran a wiper (Check Point Research). Check Point says it saw the root escalation used “against a couple of dozen customers” (sk1000362), and CISA added CVE-2026-123039 to its Known Exploited Vulnerabilities (KEV) catalog on 13 November (Cyber Security News).
Check Point gateways are everywhere in Pakistani banks, telcos and government networks, and they are the device you trust to stop exactly this kind of thing. This guide is for the people who run them: how to tell if you’re exposed, how to close it today, and how to hunt for signs someone got there first.
TL;DR / Key takeaways
- The chain: PHP2Shell (CVE-2026-109618 / CVE-2026-109619) on the Mobile Access portal gives code execution as the portal service account; CVE-2026-123039 (CVSS 7.8) in Gaia’s DynamicCLI turns that into root.
- Affected: R82.20, R82.10, R82, R81.20, plus end-of-support R81.10 and R81. Fixed Jumbo Hotfix Takes: R82.20 Take 14, R82.10 Take 52, R82 Take 132, R81.20 Take 174. Spark and Smart-1 Cloud are not affected.
- Can’t patch tonight? Check Point’s temporary mitigation is to disable
dynamic_server(it breaks some Dynamic CLI commands).- Hunt now, even if you patch: exploitation started 30 October. Check
/var/log/dynamicCli.log, look forzz*.tplwebshells,/tmp/CPconfigdaemon,/lib/libcpfwcommon.so, a listener on TCP 11072, and SSH from the gateway to ESXi asvpxuser.- If you find indicators, treat the gateway as fully compromised and assume the attacker had root on your perimeter.
What happened (quick timeline)
| Date | Event |
|---|---|
| 21 Oct 2026 | PHP ships fixes for PHP2Shell (our coverage) |
| 30 Oct 2026 | First wave: Israeli organisations hit via Mobile Access gateways, with destructive activity against some. CPR notes this was about a week after a fix was available |
| 2 Nov 2026 | Second, broader wave across multiple countries and sectors; no destructive activity observed |
| 8 Nov 2026 | Check Point creates sk1000362 for CVE-2026-123039 |
| 12 Nov 2026 | CPR publishes its analysis and IOCs; sk1000362 updated |
| 13 Nov 2026 | CISA adds CVE-2026-123039 to KEV |
Sources: Check Point Research, sk1000362, Security Affairs, Cyber Security News.
Attribution is still murky. The backdoors are modified variants of PhiliKit, which ESET has linked to the China-nexus cluster UNC5221. The wiper’s note, though, is a Hebrew, politically themed file called DREAM_ANNEXATION.txt. CPR says the evidence “does not allow us to assess with high confidence the true nature of this operation” and lists a full campaign, an access broker handing off, or a false flag as plausible readings (Check Point Research). For defenders, the who matters less than the how, and the how is well documented.
How the chain works (conceptually)
Step 1: PHP2Shell on the portal. The Mobile Access portal is a PHP web application running on the gateway. CPR found PHP session files under /opt/CPcvpn-R81.20/tmp/ containing the marker upload_progress_pwn, and “hundreds of segmentation faults” in the portal’s Apache/PHP workers in the same window. That is what memory-corruption exploitation of PHP looks like from the outside: lots of crashes, then one that works.
Step 2: CVE-2026-123039, from service account to root. Gaia’s dynamic_server daemon, the root-owned process behind DynamicCLI, listens on a local Unix socket, /tmp/dynamic_socket. That socket was created world-writable (0777) and the daemon did not authenticate callers, so any local process could send it a command and have it run “as root” (sk1000362). On its own this bug needs local code execution; chained after PHP2Shell, it completes a remote-to-root path.
Step 3: Persistence. CPR documents three layers:
- PHP webshells dropped into the portal’s templates directory as
zz<random>.tpl, using a hardcoded keyzz2026, supporting OS commands, PHP execution and file upload. An upload staged at/tmp/.up.tplwas copied in aschallenge_render.tpl. - TSGA, a backdoor started from
/tmp/CPconfigdaemon(logging to/tmp/.bd.log), which relaunches as root under the nameslot_CPconfigdaemonfrom a boot persistence directory. CPR lists encrypted remote access, configuration theft, backup and snapshot persistence, process injection and binary firewall-log tampering among its capabilities. - TSProxy, written to
/lib/libcpfwcommon.soand loaded into selected appliance processes to provide encrypted SOCKS-style proxying. TSGA/TSProxy use TCP port 11072 and a Unix socket at/tmp/.p_sock.
Step 4: Lateral movement and impact. The attackers ran the gogo scanner from the gateway, then used SSH to reach a VMware ESXi host as the vpxuser account (the account vCenter uses to manage hosts), staged the destroy_v6 wiper and dropped DREAM_ANNEXATION.txt notes.
Note the log-tampering capability. If TSGA ran on your gateway, the gateway’s own logs may not be trustworthy, which is why the hunt below leans on evidence from other systems too.
Am I affected?
You need to act if all of the following are true:
- You run a Check Point Security Gateway, Management/Log Server, Multi-Domain server or Maestro Orchestrator on R82.20, R82.10, R82, R81.20, R81.10 or R81 (that’s the CVE-2026-123039 part). Spark firewalls and Smart-1 Cloud are not affected (sk1000362).
- You are below the fixed Jumbo Hotfix Take for your version.
Your exposure to the full chain is highest if the gateway has the Mobile Access blade exposed to the internet, since that is where CPR saw initial access. CPR does not spell out whether every Mobile Access configuration is reachable, so if the portal is enabled and internet-facing, assume yes.
To check your version and Take in Expert mode:
~|#| Gaia version and installed Jumbo Hotfix Take
cpinfo ~|-|y all 2>/dev/null | grep ~|-|iE "HOTFIX_.*JUMBO|^This is Check Point"
clish ~|-|c "show version all"
R81.10 and R81 are end of support and sk1000362 lists no fix for them. If you are still on either, mitigation is your only option and an upgrade to a supported release should be treated as urgent.
Step 1: Close the hole
Patch. Install the Jumbo Hotfix Accumulator at or above:
| Version | Fixed from |
|---|---|
| R82.20 | Take 14 |
| R82.10 | Take 52 |
| R82 | Take 132 |
| R81.20 | Take 174 |
| R81.10, R81 (EOS) | No fix listed: mitigate and upgrade |
The fix blocks and logs unauthenticated DynamicCLI calls. Patch every cluster member and your management servers, not just the internet-facing gateway.
If you can’t patch immediately, Check Point’s temporary mitigation is to stop the daemon (Expert mode):
~|#| Disable dynamic_server (Check Point sk1000362 temporary mitigation)
dbset process:dynamic_server
dbset :save
~|#| Confirm it is no longer running
ps auxw | grep ~|-|v grep | grep 'dynamic_server'
~|#| To re~|-|enable later
dbset process:dynamic_server t
dbset :save
This breaks the Dynamic CLI commands listed in sk144112, so warn whoever administers the box.
Patch PHP2Shell too. sk1000362 covers only the root escalation. The initial access was PHP2Shell on the portal, and we could not find a separate Check Point SK for that at the time of writing. Check the Check Point Support Center for guidance on the portal’s PHP component and, until you have it, consider whether the Mobile Access portal needs to be internet-facing at all.
Verify after patching:
~|#| Socket should now be 0660, owned root:config, not 0777
ls ~|-|l /tmp/dynamic_socket
~|#| expected: srw~|-|rw~|-|~|-|~|-|~|-| root config
~|#| Blocked escalation attempts are logged after the fix
grep "Rejected connection from unauthorized uid" /var/log/dynamicCli.log
A rejected connection from a non-zero UID such as 99 (nobody) means something tried to use the socket after you patched. Correlate the timestamp with portal and authentication logs: that is an active intrusion attempt, not noise.
Step 2: Hunt on the gateway
Run these on every gateway and cluster member, in Expert mode. They are read-only. If you plan a full investigation, take a snapshot or forensic copy before changing anything.
2a. DynamicCLI log (from sk1000362)
Legitimate DynamicCLI commands arrive wrapped in a Clish profile line. Check Point gives three checks:
~|#| 1. Commands missing the legitimate Clish wrapper
grep "Received ~|=|" /var/log/dynamicCli.log \
| grep ~|-|vF "CPprofile.sh >> /dev/null; export SP_DISTRIBUTE~|=|0; set ~|-|o noglob;"
~|#| 2. Use of the system() sink
grep ~|-|F "Received ~|=| ~|#|return_value~|#|" /var/log/dynamicCli.log
~|#| 3. Exploit~|-|style commands
grep ~|-|EI "Received ~|=|.*( id;| whoami| /etc/shadow| ncat| nc ~|-|| /dev/tcp| curl | wget | base64| useradd| authorized_keys)" /var/log/dynamicCli.log
Also check rotated copies (ls /var/log/dynamicCli*). Check Point notes these hits are not conclusive on their own, and an empty result does not prove a clean box if logs were tampered with.
2b. Portal exploitation traces and webshells
~|#| PHP2Shell marker in portal session files (CPR saw it under the R81.20 path;
~|#| adjust the directory name for your version)
ls ~|-|d /opt/CPcvpn~|-|*/tmp 2>/dev/null
grep ~|-|rl "upload_progress_pwn" /opt/CPcvpn~|-|*/tmp/ 2>/dev/null
~|#| Webshells and staged uploads named in CPR's report
find / ~|-|xdev \( ~|-|name 'zz*.tpl' ~|-|o ~|-|name 'challenge_render.tpl' ~|-|o ~|-|name '.up.tpl' \) 2>/dev/null
~|#| Bursts of PHP/Apache worker crashes
dmesg ~|-|T | grep ~|-|i segfault | tail ~|-|50
2c. Backdoor and proxy artifacts
~|#| TSGA dropper, hidden log and proxy socket
ls ~|-|la /tmp/CPconfigdaemon /tmp/.bd.log /tmp/.p_sock 2>/dev/null
~|#| Relaunched backdoor process name
ps auxw | grep ~|-|v grep | grep ~|-|i 'CPconfigdaemon'
find / ~|-|xdev ~|-|name '*CPconfigdaemon*' 2>/dev/null
~|#| TSProxy library and which processes have it loaded
ls ~|-|la /lib/libcpfwcommon.so 2>/dev/null
grep ~|-|l 'libcpfwcommon' /proc/[0~|-|9]*/maps 2>/dev/null
~|#| Listener or connections on TSGA/TSProxy port 11072
netstat ~|-|anp 2>/dev/null | grep ':11072'
libcpfwcommon.so is a name designed to blend in. Compare against a known-clean gateway on the same version and Take, and against Check Point’s guidance, before drawing conclusions. Any file in /lib you can’t account for deserves a hash check.
2d. Hash sweep against CPR’s IOCs
CPR published SHA-256 hashes for the webshell, both backdoor stages, the gogo scanner, the wiper, the note and the PhiliKit components. Put them in a file and sweep the likely locations:
cat > /var/tmp/cpr_iocs.txt ~|<|~|<|'EOF'
edb3e92eb7bda7413a09edcc4b1ba3cbed4bcdf42808a8abce63b6e4c3fda2b3
4171b521fa6441382aa2fa014a08e18ff9a6e0ab6096c9144072bf46b37a2ec8
d7549671c7189979f0624ec52dad9ea6a707d23146e3585ab8f8c4720eca0c63
3b51080a909023f7d484e2443740b572307ce0054eb9e32d98f0a06bfcd2db90
c7d9477309fac6c638a1128442056a242de086996add8cb49cd6496c36003237
0522937c0c0337be54fe25493539e5f5f8ceb9742c980aaff1cfc9515f3a96f7
ee16e1695711b9d60c62925fcfb2fe1a29c18ae26565bc05410a14e16d2a39d7
fb1a6235eb6bce8c9ec8cd8bb85f17c9c2bde8ecb45b7a243a30ceadf26654da
EOF
find /tmp /var/tmp /lib /opt ~|-|xdev ~|-|type f ~|-|size ~|-|50M 2>/dev/null \
| xargs ~|-|r sha256sum 2>/dev/null \
| grep ~|-|Ff /var/tmp/cpr_iocs.txt
Hash matching only catches exact copies; a rebuilt sample will slip past. Treat it as one signal among several. Remove the IOC file when you’re done.
Step 3: Hunt from the outside (SIEM)
Because TSGA can tamper with firewall logs, also look at what other systems saw. These are starting points; adjust table and field names to your parsers.
Microsoft Sentinel (KQL): traffic to CPR’s published IPs and port 11072, from Check Point logs forwarded via CEF:
let iocIPs ~|=| dynamic(["130.94.19.204", "130.94.19.168"]);
CommonSecurityLog
| where TimeGenerated > ago(30d)
| where DeviceVendor has "Check Point"
| where SourceIP in (iocIPs) or DestinationIP in (iocIPs)
or DestinationPort ~|=|~|=| 11072
| summarize events ~|=| count(), first ~|=| min(TimeGenerated), last ~|=| max(TimeGenerated)
by SourceIP, DestinationIP, DestinationPort, Activity
| order by first asc
Splunk (SPL): SSH from your gateways’ internal interfaces into ESXi hosts. A firewall has no business opening SSH sessions to your hypervisors (replace the example IPs with your gateways’ interface addresses):
index~|=|* sourcetype~|=|*esxi* ("Accepted password" OR "Accepted keyboard~|-|interactive" OR "Accepted publickey")
| rex "for (?~|<|user>\S+) from (?~|<|src_ip>\d{1,3}(?:\.\d{1,3}){3})"
| search src_ip IN ("10.0.0.1","10.0.0.2")
| stats count min(_time) as first max(_time) as last by host user src_ip
| convert ctime(first) ctime(last)
Pay particular attention to vpxuser logins that don’t originate from your vCenter server. Other signals worth a query:
- Inbound connections to the Mobile Access portal from
130.94.19.204/130.94.19.168, especially between 00:00 and 09:00 UTC, the window in which CPR saw scanning concentrate. - Any east-west scanning that originates from a gateway IP (CPR saw
gogorun from the gateway). DREAM_ANNEXATION.txtor unexplained mass file deletion on ESXi datastores.- Gaps in the gateway’s log stream around 30 October onward. Silence from a firewall is a finding.
Step 4: If you find something
- Don’t just patch and move on. A gateway with any of these artifacts should be treated as rooted. Isolate management access, preserve evidence (disk and memory if you can), and engage Check Point TAC.
- Rebuild from known-good media rather than cleaning in place; TSGA had snapshot and backup persistence, so validate any snapshot or backup before restoring from it.
- Rotate everything the gateway held or saw: admin accounts, VPN/portal credentials, certificates and keys, RADIUS/LDAP bind accounts, and SIC trust with management.
- Check ESXi and vCenter: review
vpxuseractivity, consider resetting it from vCenter, and restrict SSH on hosts to management jump hosts only. - Scope beyond the box: anything that traversed the gateway’s VPN or proxy could have been observed or relayed.
Prioritised checklist
Immediately (today)
- Inventory every Check Point gateway, cluster member, management and Maestro system with its version and Take.
- Install the fixed Jumbo Hotfix Take, or apply the
dynamic_servermitigation where you can’t. - Run the sk1000362 DynamicCLI log checks and the artifact checks above on every member.
- Block
130.94.19.204and130.94.19.168and search for historic contact.
This week
- Restrict the Mobile Access portal: disable it if unused, or limit source IPs.
- Sweep for CPR’s hashes and review ESXi SSH logs for logins from gateway IPs.
- Verify
/tmp/dynamic_socketis0660and monitorRejected connection from unauthorized uidevents. - Plan migration off R81.10/R81, which have no fix.
Longer term
- Forward gateway logs off-box in near real time, so a compromised device can’t quietly rewrite history.
- Segment hypervisor management: ESXi SSH off by default, reachable only from a jump host.
- Put edge appliances on a KEV-driven patch SLA (72 hours for exploited flaws) and include them in threat hunts and penetration tests.
OffensioX perspective
This campaign is a clean example of a pattern we keep seeing in 2026: the attack surface on a “security appliance” is mostly ordinary software. Here it was a PHP runtime behind a VPN portal and a local IPC socket with the wrong permissions. Neither is exotic, and the second only became critical once the first gave attackers a foothold. Teams that patched PHP on their web servers in October often didn’t realise their firewall also ran PHP.
The other lesson is visibility. Firewalls are usually the source of logs, rarely the subject of investigation, and few organisations have EDR-level telemetry on them. An attacker with root on the gateway, a log-tampering backdoor and a proxy into your network is in the best seat in the house. Make sure your appliances are patched on a KEV timeline, their logs leave the box, and someone actually tests them. OffensioX’s penetration testing and security assessments cover perimeter devices and VPN portals; if you’d like an independent look at yours, we’re happy to help.
References
- Check Point Research: PHP2Shell Exploitation on Check Point Gateway
- Check Point sk1000362: CVE-2026-123039, Local privilege escalation to root in the DynamicCLI process
- BleepingComputer: Check Point warns of zero-day flaw exploited for root access
- Security Affairs: Unpatched Check Point gateways are being wiped exploiting PHP2Shell
- Cyber Security News: CISA Warns of Check Point 0-Day Vulnerability Exploited to Gain Root Access
- GBHackers: CISA Warns of Actively Exploited Check Point Zero-Day Vulnerability
- SecurityOnline: CVE-2026-123039, Check Point Gateway Exploited Privilege Escalation
- CISA Known Exploited Vulnerabilities Catalog
- OffensioX: PHP2Shell, The PHP Flaws Under Attack and What to Do Now