At a glance: fixes and indicators
Written for organizations and the teams who defend them. IoC = evidence it already happened (an address, an account, a log line). IoA = the behavior of an attack in progress. Network IoCs are defanged: remove the square brackets before using them. Indicators age fast, so re-check the source before blocking.
| Item | Exploited? · Fix | Do now | Top IoCs | Top IoAs |
|---|---|---|---|---|
| 1. PHP2Shell CVE-2026-109618 / -109619 | Yes: attempts since 17 Oct (Amazon), active attempts (watchTowr); not in CISA's catalog as of 2026.10.21 · 8.5.12, 8.4.27, 8.3.36, 8.2.35 | Update every PHP runtime and restart workers; hunt web logs back to 17 Oct | 103.216[.]220[.]92, 134.209[.]159[.]64 (Amazon: shared infrastructure, investigate) |
"Allowed memory size … exhausted" "in Unknown on line 0"; PHP_SESSION_UPLOAD_PROGRESS in multipart uploads; PHP workers starting /bin/sh |
| 2. Palo Alto GlobalProtect CVE-2026-0257 | Yes, ransomware-linked (Unit 42); CISA catalog since 29 May · fixed builds per branch | Test management ports 4443 and 3879 from outside; check ESXi execInstalledOnly; confirm Veeam is fixed |
146.19[.]216[.]119, 179.43[.]172[.]213; host IDs WINDOWS-LAPTOP-001, DESKTOP-GP01 |
ESXi execInstalledOnly turned off; vCenter logins from the VPN pool |
| 3. OVHcloud CLI release binaries | Yes, release assets replaced 19 Oct · v0.16.0 | Find the CLI on workstations and build hosts; rotate secrets if an affected binary ran | Replaced binary SHA-256 3833daff…933cb; build revision 5ead8ef9b43d…; ~/init.json |
Release-binary build info showing vcs.modified=true / +dirty |
| 4. eMudhra intermediate CAs | Keys compromised; no misissued certificate seen in CT logs (Chrome) · Go 1.27.3 / 1.26.10, NSS 3.131.1, Firefox 158.0.1 | Rebuild Go programs; update CA bundles | None published | Ours: a TLS chain through EM … TLS CA - G3B/G3C on your network |
| 5. Google Cloud LLMjacking | Yes, multiple intrusions (Wiz) · not a software flaw | Audit billing-account members and the iam.allowedPolicyMemberDomains policy |
212.73[.]134[.]136; gboogl[.]com, groosl[.]com |
SetOrgPolicy removing the domain restriction; Gmail accounts given roles/billing.admin |
| 6. CISA catalog: Plex, Siemens, SiteGuard | Yes (CISA, added 20 Oct) · vendor fixes | Patch by 23 Oct (three CVEs) and 3 Nov (three CVEs) | None published in the catalog | Requests to /video/:/transcode/universal carrying a full URL |
Highest payoff today — analysis. Item 2. It is the only item where a defender who patched months ago can still be inside an active intrusion, and the two checks that answer the question — an outside connection attempt to two ports, and one ESXi setting per host — take minutes.
How to use this. A published-IoC hit means compromise: handle it under the item's defined response. An IoA hit alone is a lead to validate (PIVCCERL™'s Validation stage). An empty IoC row is not reassurance. The hunt packs say what to do on a hit and what a clean result means.
1. PHP2Shell: two critical PHP flaws were attacked before the fix, and the fixes are out
Bottom line. PHP released 8.5.12, 8.4.27, 8.3.36 and 8.2.35 on 21 October to fix CVE-2026-109618 and CVE-2026-109619, two flaws that "can allow unauthenticated remote code execution" (CVSS 4.0 9.2 each).
- PHP says every installation serving web requests is at risk, including PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed, with the risk highest for mod_php.
- Amazon saw a first exploitation attempt against its honeypots on 17 October, four days before disclosure, and more from several sources on 21 October; watchTowr reports "active exploitation attempts of both" flaws. Neither flaw was in CISA's catalog as of version 2026.10.21.
- Amazon says to start any investigation from 17 October, not the disclosure date.
- Do now: update every PHP runtime to the fixed release for its branch, or the vendor's backported package, and restart every worker; for PHP 8.1 and older, get a vendor backport or take the site off the internet; then hunt web logs back to 17 October.
- Skip if: you run no PHP anywhere, including inside products and platforms you host.
Indicators
| Type | Indicator | Where to look | Source |
|---|---|---|---|
| IoC | 103.216[.]220[.]92 (17 Oct); 31.223[.]184[.]166, 37.19[.]200[.]5, 134.209[.]159[.]64, 103.114[.]163[.]188, 95.217[.]98[.]37 (21 Oct) — sources of exploitation attempts against Amazon's honeypots. Amazon says these are shared anonymization infrastructure: investigate hits, do not just block |
Web server, proxy, WAF and firewall logs from 17 October | Amazon Threat Intelligence |
| IoC | No hashes, payloads or domains published | — | Amazon, watchTowr, PHP, Fastly (checked 22 Oct, ~13:35 UTC) |
| IoA | URL-encoded form POSTs above 1–2 MB, or bodies starting with = followed by a field name of repeated [ characters |
Web server, proxy or WAF logs | Fastly |
| IoA | POST multipart uploads containing PHP_SESSION_UPLOAD_PROGRESS; unexpectedly large PHPSESSID values in responses |
Web server, proxy or WAF logs | Amazon, Fastly (upload field); Imperva, Wiz (PHPSESSID) |
| IoA | "Allowed memory size … exhausted" with the location "in Unknown on line 0"; bursts of Apache AH00052 "exit signal Segmentation fault (11)" |
PHP and Apache error logs | Fastly |
| IoA | A mod_php, php-fpm, php-cgi, httpd or apache2 worker starting /bin/sh or a downloader |
EDR process events | Fastly; Huntress |
What
- What PHP says (21 October)
- Fixed in 8.5.12, 8.4.27, 8.3.36 and 8.2.35; the GitHub advisories list every earlier release on those branches as affected.
- CVE-2026-109618, "RCE via OOM corruption": an out-of-memory error can interrupt PHP while request data is half-initialized, and cleanup then treats it as valid.
- CVE-2026-109619, "RCE via stale global state": request-owned state can outlive its memory, and a later request on the same worker may use it.
- mod_php has "a demonstrated exploit where an unauthenticated request can trigger the attack before any application code runs."
- PHP 8.1 and older get no project release; PHP published minimal source backports for 7.4, 8.0 and 8.1, and distributions and LTS vendors received patches in advance.
- Interim measures "reduce exposure to specific attack paths but do not make an installation safe":
memory_limit=-1set administratively, a lowpost_max_size,session.upload_progress.enabled=0with every worker restarted, andfatal_error_backtraces=0on 8.5.
- What Amazon and watchTowr report (21 October)
- Amazon Threat Intelligence: first exploitation attempt against its MadPot honeypots on 17 October from
103.216[.]220[.]92; proof-of-concept exploits from about 02:00 UTC on 21 October, and attempts from more sources between 02:00 and 08:00 UTC that day; varied payloads suggest multiple actors. Amazon does not know whether the attempts would have succeeded and names no actor. - Amazon's advice: patch; if that must wait, consider blocking multipart file uploads after testing; hunt POST requests for
PHP_SESSION_UPLOAD_PROGRESS; investigate from 17 October. - watchTowr "is observing active exploitation attempts of both CVE-2026-109618 and CVE-2026-109619."
- Amazon Threat Intelligence: first exploitation attempt against its MadPot honeypots on 17 October from
- What WAF vendors say
- Akamai: App & API Protector customers "are protected because we have released security updates," including Adaptive Security Engine rule 3000991 v1, "PHP Remote Code Execution Attack Detected," and existing command-injection rules against weaponized payloads. Akamai's 21 October post does not say whether the rule is automatic or needs customer action, and it does not mention Kona.
- AWS WAF: AWS's bulletin 2026-143-AWS points to the Core rule set's SizeRestrictions_BODY rule (bodies over 8 KB) for CVE-2026-109618, and to PHP managed rule group version 2.3 or a custom Block rule for CVE-2026-109619.
- AWS also says WAF "is a defense-in-depth control in this situation, not a replacement for the PHP upgrade," and to test rules in Count mode before Block.
- Imunify360 (CloudLinux): WAF rulesets 8.83 to 8.85, delivered automatically to hosts with the WAF enabled, block the public exploit request and tool variants. As of its 22 October update, "no rule blocks the out-of-memory path of CVE-2026-109618 yet"; ImunifyAV is not covered.
- Azure WAF: Microsoft's 21 October posts give three custom rules for Front Door, Application Gateway and Application Gateway for Containers, plus a response-side managed rule (Front Door) or rewrite rule (Application Gateway). Microsoft says these "are not a replacement" for patching and to validate the rules before enforcing.
- Google Cloud Armor: Google says customers with active managed rules are protected automatically, and recommends at minimum enabling the File Upload and RFI categories, testing in preview mode, then enforcing deny(403). Google calls it a "defense-in-depth mitigation."
- Imperva: Cloud WAF customers "are protected against this vulnerability out of the box"; eWAF after a software update; WAF Gateway after a software update and an ADC security content update.
- F5: says WAF on Distributed Cloud, BIG-IP and NGINX "already provided coverage through existing signatures," and that it has released dedicated signatures for both CVEs (advisory K000163821). It tells customers to confirm blocking mode and that the dedicated signatures are active.
- Barracuda: we found no PHP2Shell advisory in its blog, documentation or a web search as of 11:24 ET on 22 October; ask Barracuda support whether a definition covers it.
- Fastly: a "Virtual Patch for CVE-2026-109618 & CVE-2026-109619" templated rule for Next-Gen WAF; opted-in customers receive updates automatically.
- Cloudflare: initial WAF rules "available to all customers, including free," per its CTO as carried by Tenable; Cloudflare calls them a stopgap.
- PHP and Wiz both say the update is the only complete fix.
- Where sources disagree
- Exploitation: Amazon and watchTowr report attempts, Patchstack reports attacks and Fastly cites evidence of pre-disclosure attacks, and Cloudflare (via Tenable) reported early attacks; Imperva saw none in its pre-disclosure monitoring and Huntress had seen none by the morning of 21 October. We plan on exploitation.
- Configuration changes: PHP lists interim settings that "reduce exposure to specific attack paths"; watchTowr says mitigations that change
.inifiles "should be understood to be ineffective." We plan on watchTowr's reading: settings are not a substitute for the update.
So what
- A WAF rule covers the patterns known today. Fastly expects "novel variants to emerge this week and next at minimum"; a rule written for today's exploit is not a patch.
- Exploitation started before anyone could patch. Amazon's first attempt is dated 17 October, four days before the fix was released; a server patched on 21 October still needs checking, not assuming.
- The vulnerable code runs before the application does. Application logs may show nothing, so evidence lives in web-server error logs, worker crashes and process trees.
- PHP 8.1 and older is the long tail. Those servers need a vendor backport, a source build with PHP's backport, or isolation.
Now what — P → I (analysis)
- Configuration.
- Update first, then reduce exposure where an update must wait.
- Install 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or the distribution's patched package; check with
php -vand restart every PHP worker and Apache. - Rebuild container images built
FROM php:rather than patching running containers. - Where updating must wait: block multipart file uploads at the proxy or WAF where the application allows it (Amazon), and set
session.upload_progress.enabled=0andmemory_limit=-1in php.ini or the FPM pool (notini_set()or.user.ini), then restart every worker. Treat these as time-buyers only. - Where a WAF fronts the site, confirm the vendor's PHP2Shell rule is deployed and set to block, not log (Akamai: rule 3000991).
- Blast radius.
- List what each PHP application's service account, database credentials and API keys can reach, so rotation is quick if a host is confirmed.
- Detection with a defined response.
- Run the hunt pack below over web-server and error logs back to 17 October.
- Defined response: a PHP or web-server worker starting a shell or downloader that the application does not normally run is a confirmed compromise. Isolate the host, preserve the web root and logs, rotate the application's secrets, and rebuild from a patched image.
- Communication.
- Ask hosting providers and vendors whose products embed PHP for their patch date in writing.
Hunt pack — run it, then act on what it says
No indicators of compromise have been published, so these hunts implement the behaviors Fastly and Huntress published (memory-exhaustion and segfault log lines, web-server or PHP processes starting shells and downloaders); the first Datadog query adds Amazon's six addresses and the upload-progress field for web, proxy or WAF logs plus a runtime inventory; the logic is our analysis. The php parent and the dash, python3 and ncat children are our additions. The bash script was executed against synthetic process tables (a PHP-FPM worker with a shell child, a clean table, an empty file and bad arguments). It exits 1 whenever any PHP runtime is present, so each listed runtime should be checked against the fixed versions. The Sigma, KQL and Datadog queries were reviewed, not executed. We are not offering a YARA or Suricata rule: no exploit strings have been published, and the request patterns depend on body size, which a signature handles poorly. The Sigma rule converts with pySigma to Splunk, Kusto and Lucene. Adjust field and table names to your logging.
#!/usr/bin/env bash
# Read-only. Lists PHP runtimes on this host and flags web-server or PHP processes
# with shell or downloader children (Huntress guidance). Optional arg: a saved
# 'ps -eo pid,ppid,comm' file to read instead of the live process table.
# Exit: 0 no PHP, no suspicious lineage | 1 PHP present or suspicious lineage | 2 usage | 3 nothing readable
[ $# -le 1 ] || { echo "usage: $0 [ps-snapshot]" >&2; exit 2; }
php_found=0
for b in $(compgen -c 2>/dev/null | grep -E '^php(-fpm|-cgi)?[0-9.]*$' | sort -u); do
p=$(command -v "$b") || continue; v=$("$p" -v 2>/dev/null | head -1)
echo "php runtime: $p ${v:-version unreadable}"; php_found=$((php_found+1)); done
if [ $# -eq 1 ]; then [ -r "$1" ] && [ -s "$1" ] || { echo "unreadable or empty: $1" >&2; exit 3; }; PS=$(cat "$1"); else PS=$(ps -eo pid=,ppid=,comm= 2>/dev/null); fi
[ -n "$PS" ] || { echo "process table unreadable" >&2; exit 3; }
sus=$(awk 'NR==FNR{name[$1]=$3; next} ($3 ~ /^(sh|bash|dash|cmd|powershell|python[0-9.]*|perl|curl|wget|nc|ncat|certutil)$/) && (name[$2] ~ /^(php-fpm[0-9.]*|php-cgi|php|httpd|apache2)$/) {print "suspicious: pid " $1 " " $3 " child of " name[$2] " (ppid " $2 ")"}' <(echo "$PS") <(echo "$PS"))
[ -n "$sus" ] && echo "$sus"; n=$(printf '%s' "$sus" | grep -c . )
echo "php_runtimes=$php_found suspicious_children=$n"
[ "$n" -gt 0 ] || [ "$php_found" -gt 0 ] && exit 1; exit 0
title: Shell or downloader spawned by PHP or web server process
id: 6b1f7c2e-4a8d-4b55-9f3e-2d7c1a9e5b40
status: experimental
description: Behavioral lead from Huntress and Fastly guidance for CVE-2026-109618 / CVE-2026-109619. Validate against known application behavior.
references:
- https://www.huntress.com/blog/php2shell-leaked-critical-php-vulnerabilities
- https://www.fastly.com/blog/fastlys-proactive-protection-critical-php-rce-cve-2026-109618
logsource:
category: process_creation
product: linux
detection:
parent:
ParentImage|endswith: ['/php-fpm', '/php-cgi', '/httpd', '/apache2', '/php']
child:
Image|endswith: ['/sh', '/bash', '/dash', '/python', '/python3', '/perl', '/curl', '/wget', '/nc']
condition: parent and child
level: high
DeviceProcessEvents
| where Timestamp > ago(7d)
| where InitiatingProcessFileName matches regex @"^(php-fpm[0-9.]*|php-cgi(\.exe)?|php(\.exe)?|httpd(\.exe)?|apache2)$"
| where FileName in~ ("sh","bash","dash","cmd.exe","powershell.exe","python","python3","perl","curl","wget","nc","certutil.exe")
or ProcessCommandLine has_any ("/dev/tcp/","fsockopen","mkfifo")
| project Timestamp, DeviceName, InitiatingProcessFileName, FileName, ProcessCommandLine
@network.client.ip:(103.216[.]220[.]92 OR 31.223[.]184[.]166 OR 37.19[.]200[.]5 OR 134.209[.]159[.]64 OR 103.114[.]163[.]188 OR 95.217[.]98[.]37) OR *:"PHP_SESSION_UPLOAD_PROGRESS"
(*:"Allowed memory size" *:"Unknown on line 0") OR (*:"AH00052" *:"Segmentation fault")
(*:"php-fpm" OR *:"php-cgi" OR *:"apache2" OR *:"httpd") (*:"/dev/tcp/" OR *:"fsockopen" OR *:"mkfifo")
| If you see | Do this |
|---|---|
| A PHP or web-server process starting a shell or downloader that the application does not normally run | Confirmed compromise under the defined response: isolate, preserve the web root and logs, rotate secrets, rebuild patched. |
| A shell child that matches a known job (an admin script, a cron wrapper) | Expected. Record it as an exception with an owner, so the next hit stands out. |
| PHP runtimes listed by the script | Check each against 8.5.12, 8.4.27, 8.3.36 or 8.2.35; anything older is unpatched. |
| The script exits 3, or the EDR in use does not record parent processes | This is not a clean result. Fix the telemetry before relying on it. |
Memory-exhaustion lines "in Unknown on line 0" or AH00052 segfault bursts with no shell child |
Attempts, or an exploit that failed. Confirm the update is in place and look for new files in the web root. |
| A request from one of Amazon's addresses | Shared anonymization infrastructure, so not proof on its own. Check what it requested and the server's error log at that minute; a matching memory or segfault line or a shell child makes it a confirmed compromise. |
| No hits | A good sign, not an exoneration. Amazon published six addresses from shared infrastructure, so attackers elsewhere are invisible to this search; application logs may show nothing because the flaws run before application code; a payload that runs inside PHP never starts a child process; and new variants are expected. Patch anyway. |
2. Palo Alto GlobalProtect: ransomware crews are using a May flaw to reach the hypervisor
Bottom line. Unit 42 updated its CVE-2026-0257 threat brief on 19 and 20 October: Qilin and Inc ransomware operators use the GlobalProtect authentication bypass to get a VPN session.
- In one case it investigated, they then moved to vCenter, disabled an ESXi safeguard and dumped domain credentials from a domain controller's virtual disk.
- CISA added the flaw to its catalog on 29 May and marks ransomware use as known; Palo Alto published its advisory on 13 May.
- Unit 42 also found management interfaces exposed on ports 4443 and 3879 through GlobalProtect profiles, a recurring misconfiguration Unit 42 saw in its incident-response engagements.
- Do now: test the management IP on ports 4443 and 3879 from outside your network; check every ESXi host's
execInstalledOnlysetting; confirm the GlobalProtect fix and the Veeam fix for CVE-2023-27532 are in place; hunt the indicators below. - Skip if: you run no PAN-OS GlobalProtect portal or gateway and no Prisma Access. Palo Alto says only portals and gateways with authentication override cookies enabled are affected; check before skipping the hunt.
execInstalledOnly enforcement, and a fixed, isolated Veeam server. Solid blue boxes are reported steps; dashed orange boxes are not yet reported. The diagram is our analysis.Indicators
| Type | Indicator | Where to look | Source |
|---|---|---|---|
| IoC | 23.128[.]228[.]6, 104.207[.]144[.]154, 146.19[.]216[.]119, 146.19[.]216[.]120, 146.19[.]216[.]125, 179.43[.]172[.]213, 185.195[.]232[.]139, 198.12[.]106[.]60, 202.144[.]192[.]47 — source addresses from activity before the 29 May proof-of-concept; Unit 42 says to look for successful logins from them |
GlobalProtect logs (successful gateway-connected events) | Unit 42 |
| IoC | Host IDs WINDOWS-LAPTOP-001, DESKTOP-GP01, GP-CLIENT; MAC addresses aa:bb:cc:dd:ee:ff, 00:11:22:33:44:55 — search gateway-connected events from any address |
GlobalProtect logs | Unit 42 |
| IoC | endpoint_os_version "Microsoft Windows 10 Pro 64-bit" with an empty source_user_info.domain — values hard-coded in the public proof-of-concept |
GlobalProtect logs (treat as a lead: real clients can share the OS string) | Unit 42 |
| IoA | execInstalledOnly disabled on an ESXi host; vCenter logins from the VPN address pool |
ESXi host settings and logs; vCenter events | Unit 42 (behavior); ours (where to look) |
| IoA | Offline access to a domain controller's VMDK (datastore browse, copy or snapshot of the DC disk) | vCenter tasks and events; datastore access logs | Unit 42 (behavior); ours (where to look) |
| IoA | A successful connection to the firewall's management IP on port 4443 or 3879 from outside | External test; firewall traffic logs | Unit 42 |
What
- What Unit 42 reports (updates of 19 October, 4:00 p.m. PT, and 20 October, 1:30 p.m. PT)
- Exploitation attempts continue by Spikey Scorpius (Qilin) and Tarnished Scorpius (Inc); public reporting also names Settra ransomware actors.
- After the VPN session: RMM tools for reconnaissance, RDP and SMB for lateral movement, and tool staging for credential harvesting, exfiltration and ransomware.
- In one case: VPN gateway to vCenter,
execInstalledOnlydisabled on ESXi hosts, and offline credential dumping directly against a domain controller's virtual disk (VMDK), in Unit 42's description. - Access has been chained with exploits against Veeam CVE-2023-27532.
- A recurring misconfiguration: GlobalProtect profiles mapped to HTTP/HTTPS services on management interfaces expose them on ports 4443 and 3879; remediate with Interface Management profiles.
- Sectors named by Unit 42: education, financial services, healthcare, high technology, hospitality, manufacturing, professional and legal services, government, transportation and logistics, utilities and energy, wholesale and retail.
- What Palo Alto says
- The flaw affects GlobalProtect portals and gateways on PAN-OS and Prisma Access; Cloud NGFW is not affected.
- Fixed builds include 12.1.7 / 12.1.4-h6; 11.2.12, 11.2.10-h7, 11.2.7-h14, 11.2.4-h17; 11.1.15, 11.1.13-h5, 11.1.10-h25, 11.1.7-h6, 11.1.6-h32, 11.1.4-h33; 10.2.18-h6, 10.2.16-h7, 10.2.13-h21, 10.2.10-h36, 10.2.7-h34; Prisma Access 10.2.10-h36 and 11.2.7-h13.
- The mitigation is a dedicated certificate for authentication override cookies, or turning the override options off.
- CISA catalog
- CVE-2026-0257 added 29 May 2026, ransomware use "Known". Veeam CVE-2023-27532 added 22 August 2023, ransomware use "Known".
- Where sources disagree
- Unit 42's executive summary still says no post-access behavior has been identified; its 19 October update describes lateral movement and the hypervisor pivot. We plan on the newer update.
So what
- A fix applied after a session was taken does not end the session's consequences. Attackers who reached vCenter or a DC disk before you patched hold credentials that outlive the patch.
- The VMDK step is invisible to in-guest EDR. A clean EDR console on the domain controller says nothing about whether its disk was read from the hypervisor. The wave is new, not the flaw.
- Management ports open through a GlobalProtect profile are easy to miss. An inventory that lists only the portal will not show them.
Now what — P → I (analysis)
- Configuration.
- Close the paths Unit 42 names.
- Test
https://<management IP>:4443and:3879from an outside network; if either answers, restrict it with an Interface Management profile per Palo Alto's documentation. - Upgrade to the fixed build for the branch in use, or give authentication override cookies their own certificate, or turn the override options off.
- On every ESXi host, run
esxcli system settings kernel list -o execinstalledonlyand confirm it is enforced. - Confirm the Veeam Backup & Replication server carries the fix for CVE-2023-27532 and cannot be reached from the VPN pool.
- Blast radius.
- Assume the VPN session reached what the VPN pool can reach.
- List what the GlobalProtect address pool can reach: vCenter, ESXi management, Veeam, domain controllers.
- If any indicator hits, plan a domain-wide credential reset including
krbtgt(twice), service accounts and vCenter local accounts.
- Detection with a defined response.
- Run the hunt pack below over GlobalProtect logs back to May.
- Defined response: a successful GlobalProtect login from a listed address or host ID, or
execInstalledOnlyfound disabled without a change record, is a confirmed compromise. Isolate the hypervisor management network, preserve vCenter and ESXi logs and the firewall configuration, reset domain credentials, and rebuild from known-good backups after checking them.
- Communication.
- Decide now who owns the call to the cyber insurer, if one is in place, and, where a reporting duty applies, to the regulator; the clock starts when compromise is confirmed, not when the investigation ends.
Hunt pack — run it, then act on what it says
These hunts implement Unit 42's published indicators (addresses, host IDs, MAC addresses and proof-of-concept log values) and the ESXi behavior it describes; the logic is our analysis. The bash script was executed against synthetic logs (a hit, a near-miss address, a host-ID hit, a compressed log, an empty file and no arguments). The Sigma rule (Unit 42's addresses and host values, against a generic firewall log source) and the KQL, SPL and Datadog queries were reviewed, not executed. We are not offering a Suricata rule: the activity is inside an encrypted VPN session. The Sigma rule converts with pySigma to Splunk, Kusto and Lucene. Adjust field and table names to your logging.
#!/usr/bin/env bash
# Read-only. Usage: panos.sh <globalprotect-log-export>... (text, csv or .gz)
# Exit: 0 scanned, none found | 1 found | 2 usage | 3 nothing readable
[ $# -ge 1 ] || { echo "usage: $0 <gp-log-export>..." >&2; exit 2; }
IOC='23.128[.]228[.]6 104.207[.]144[.]154 146.19[.]216[.]119 146.19[.]216[.]120 146.19[.]216[.]125 179.43[.]172[.]213 185.195[.]232[.]139 198.12[.]106[.]60 202.144[.]192[.]47'
pat=""; for i in $IOC; do r=$(printf '%s' "$i" | tr -d '[]' | sed 's/\./\\./g'); pat="$pat|(^|[^0-9.])$r([^0-9]|$)"; done
pat="${pat#|}|WINDOWS-LAPTOP-001|DESKTOP-GP01|GP-CLIENT|aa:bb:cc:dd:ee:ff|00:11:22:33:44:55"
scanned=0; hits=0
for f in "$@"; do
[ -r "$f" ] && [ -s "$f" ] || { echo "unreadable or empty: $f" >&2; continue; }
case "$f" in *.gz) c="zcat -f";; *) c="cat";; esac
scanned=$((scanned+1))
n=$($c "$f" | grep -Eic -- "$pat"); hits=$((hits+n))
[ "$n" -gt 0 ] && $c "$f" | grep -Ei -- "$pat" | cut -c1-300
done
echo "scanned=$scanned hits=$hits"
[ $scanned -eq 0 ] && exit 3; [ $hits -gt 0 ] && exit 1; exit 0
let iocs = dynamic(["23.128[.]228[.]6","104.207[.]144[.]154","146.19[.]216[.]119","146.19[.]216[.]120","146.19[.]216[.]125","179.43[.]172[.]213","185.195[.]232[.]139","198.12[.]106[.]60","202.144[.]192[.]47"]);
let ids = dynamic(["WINDOWS-LAPTOP-001","DESKTOP-GP01","GP-CLIENT","aa:bb:cc:dd:ee:ff","00:11:22:33:44:55"]);
CommonSecurityLog
| where TimeGenerated > ago(180d)
| where DeviceVendor == "Palo Alto Networks"
| where SourceIP in (iocs) or AdditionalExtensions has_any (ids) or Message has_any (ids)
| project TimeGenerated, DeviceName, SourceIP, SourceUserName, Activity, AdditionalExtensions
title: GlobalProtect activity from Unit 42 CVE-2026-0257 indicators
id: 3c9e2a71-5d84-4f0b-9a6e-81d2c4b7e015
status: experimental
description: Source addresses and hard-coded client values Unit 42 published for CVE-2026-0257 exploitation. A successful login match is a confirmed compromise.
references:
- https://unit42.paloaltonetworks.com/active-exploitation-of-pan-os-cve-2026-0257/
logsource:
category: firewall
detection:
ip:
src_ip:
- '23.128[.]228[.]6'
- '104.207[.]144[.]154'
- '146.19[.]216[.]119'
- '146.19[.]216[.]120'
- '146.19[.]216[.]125'
- '179.43[.]172[.]213'
- '185.195[.]232[.]139'
- '198.12[.]106[.]60'
- '202.144[.]192[.]47'
hostid:
- 'WINDOWS-LAPTOP-001'
- 'DESKTOP-GP01'
- 'GP-CLIENT'
- 'aa:bb:cc:dd:ee:ff'
- '00:11:22:33:44:55'
condition: ip or hostid
falsepositives:
- Real devices named GP-CLIENT; validate the user and device
level: high
index=* sourcetype=vmw-syslog ("execInstalledOnly" OR "execinstalledonly")
| table _time host _raw
@network.client.ip:(23.128[.]228[.]6 OR 104.207[.]144[.]154 OR 146.19[.]216[.]119 OR 146.19[.]216[.]120 OR 146.19[.]216[.]125 OR 179.43[.]172[.]213 OR 185.195[.]232[.]139 OR 198.12[.]106[.]60 OR 202.144[.]192[.]47) OR *:"WINDOWS-LAPTOP-001" OR *:"DESKTOP-GP01" OR *:"GP-CLIENT"
| If you see | Do this |
|---|---|
| A successful GlobalProtect login from a listed address, host ID or MAC | Confirmed compromise. Follow the defined response: isolate hypervisor management, preserve vCenter, ESXi and firewall evidence, reset domain credentials. |
| Attempts from listed addresses with no successful login | Attempts only. Confirm the fix or mitigation is in place and keep the hunt running weekly. |
| The proof-of-concept OS string on a session from a known employee device | Expected for some real clients. Validate the device and user before acting. |
execInstalledOnly disabled with no change record |
Treat as confirmed compromise of the hypervisor layer; start incident response. |
| The script exits 3, or logs do not reach back to May | This is not a clean result. Find older logs or record the gap. |
| No hits | A good sign, not an exoneration. Only Unit 42's published values were searched, the address list covers activity before 29 May, firewall log retention is often shorter than the exposure window, and the VMDK step leaves no trace inside the guest. Close the management ports anyway. |
3. OVHcloud CLI: a hijacked account swapped release binaries for a secret-stealer
Bottom line. On 19 October, release binaries of OVHcloud's command-line tool were replaced with a build that, per OVHcloud founder Octave Klaba (translated, as reported by SecurityWeek), was meant to "retrieve secrets from the disk", using a contributor's hijacked GitHub account.
- The files were downloadable from about 12:47 UTC until OVHcloud deleted them at 14:21 UTC.
- OVHcloud lists v0.11.0 through v0.15.0 as affected; v0.10.0 and v0.16.0 are clean.
- Installs through the official install script, Homebrew or a direct GitHub download on macOS, 64-bit Linux and Windows x86_64 are affected;
go install, building from source and the Docker image are not. - Do now: find the CLI on every workstation and build host; if an affected binary ran, rotate every secret that machine could read, from a different machine; install v0.16.0.
- Skip if: no one in your organization uses the OVHcloud CLI, or it was only installed with
go install, from source or as the Docker image.
Indicators
| Type | Indicator | Where to look | Source |
|---|---|---|---|
| IoC | SHA-256 3833daffcaaaab27e4e0e0833240ffcb1df8df648f4ec0bc4a75c176e28933cb — replaced v0.15.0 ovhcloud-cli_Linux_arm64.tar.gz (the original was 5c2beb56e6d83a4b426565a1557791ef759316abcc4effb38dd627c90aeb80e0) |
Download folders, package caches, CI artifact stores | Issue reporter on OVHcloud's GitHub; OpenSourceMalware |
| IoC | Build info in the replaced binary: vcs.revision=5ead8ef9b43d354dfb5caadff803b11afc8c5c58, vcs.modified=true, a +dirty pseudo-version |
go version -m <binary> |
Issue reporter; OpenSourceMalware |
| IoC | Uploader account HassenBF on the replaced release assets |
GitHub release metadata | Issue reporter; OpenSourceMalware |
| IoC | ~/init.json (a macOS throttle marker limiting the loader to about one run every two days), preinstall.js SHA-256 43df42fd79f6f81e530892b54634598770d6e496796a863c596e616bcb3fec70, stage-two SHA-256 0f79989912572a24ba13baabb32b3fd084496271c51448d47b66fe1aedbf293c, Solana dead-drop wallet BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC — from the related loader in the same account's repositories; OpenSourceMalware links it to the CLI case as its own inference |
Developer machines; npm projects; egress logs | OpenSourceMalware |
| IoA | Outbound Solana RPC traffic from a build host or developer workstation that has no reason to make it | DNS and proxy logs | OpenSourceMalware (recommends blocking it); ours (hunting for it) |
What
- What OVHcloud says (GitHub issue 300; statements reported by SecurityWeek)
- "All binaries involved have been deleted at 16:21 GMT+2" (14:21 UTC).
- v0.16.0 was released; "This release is immutable, so the assets attached to it can be trusted."
- Root cause per SecurityWeek: GitHub release immutability was not enabled, so a user with the right permissions could change existing releases without CI/CD checks; it is now enabled and CI/CD pipelines were not affected.
- Affected v0.11.0 through v0.15.0 per OVHcloud, as reported by SecurityWeek.
- What OpenSourceMalware reports (analysis of the account)
- Replaced assets: Darwin arm64 and x86_64, Linux arm64 and x86_64, Windows x86_64, and
checksums.txt; the i386, Windows arm64 and WASM assets were not replaced. - The account's earliest verified attacker use was 5 March 2026; the link to the GlassWorm campaign is its inference.
- Which files the stealer reads and where it sends them is not published; the replaced binary was deleted before analysis.
- Replaced assets: Darwin arm64 and x86_64, Linux arm64 and x86_64, Windows x86_64, and
- Where sources disagree
- The issue reporter lists v0.13.0 to v0.15.0; OVHcloud's count reaches back to v0.11.0. We plan on the wider range.
- SANS ISC's 20 October podcast said "Friday"; the issue and both write-ups say 19 October (a Monday). We plan on 19 October.
So what
- A replaced checksums file means the checksum check passed. Anyone who verified against the release's own
checksums.txtwas checking the malware against itself. - The target was the operator's machine, not the cloud. OVH API keys, other clouds' credentials, SSH keys and registry tokens on that disk are what is at risk. A secret read once is spent.
Now what — P → I (analysis)
- Configuration.
- Replace and pin.
- Run
ovhcloud versionandgo version -m $(command -v ovhcloud); any+dirtyorvcs.modified=truebuild is suspect. - Install v0.16.0 and verify its attestation with
gh attestation verify, as OpenSourceMalware recommends; pin the hash in CI.
- Blast radius.
- If an affected binary ran, rotate from a different, clean machine:
- OVH API application and consumer keys; other cloud credentials; SSH keys; package-registry and Kubernetes tokens on that machine.
- Detection with a defined response.
- Run the hunt pack below on every machine that has the CLI.
- Defined response: a hash or build-revision match is a confirmed compromise. Isolate the machine, rotate everything it could read from another machine, review the cloud accounts those secrets unlock for activity since 19 October, and rebuild the machine.
- Communication.
- Ask any provider or contractor who manages OVHcloud on your behalf which CLI version they ran on 19 October.
Hunt pack — run it, then act on what it says
These hunts implement the hashes, build revision and file marker published by the issue reporter and OpenSourceMalware; the logic is our analysis. The bash script was executed against synthetic files (a binary carrying the revision and modified flag, a clean build, an empty file and no arguments). The Sigma rule (the loader's published preinstall command and the build revision), SPL and Datadog queries were reviewed, not executed. We are not offering a Suricata or YARA rule: no network indicator or byte pattern for the stealer itself has been published, and a rule from a guess would be counted as a control it is not. The Sigma rule converts with pySigma to Splunk, Kusto and Lucene. Adjust field and table names to your logging.
#!/usr/bin/env bash
# Read-only. Usage: ovh.sh <path-to-ovhcloud-binary-or-archive>... Also checks ~/init.json.
# Exit: 0 scanned, none found | 1 found | 2 usage | 3 nothing readable
[ $# -ge 1 ] || { echo "usage: $0 <file>..." >&2; exit 2; }
BAD="3833daffcaaaab27e4e0e0833240ffcb1df8df648f4ec0bc4a75c176e28933cb 43df42fd79f6f81e530892b54634598770d6e496796a863c596e616bcb3fec70 0f79989912572a24ba13baabb32b3fd084496271c51448d47b66fe1aedbf293c"
scanned=0; hits=0
for f in "$@"; do
[ -r "$f" ] && [ -s "$f" ] || { echo "unreadable or empty: $f" >&2; continue; }
scanned=$((scanned+1)); h=$(sha256sum "$f" | cut -d' ' -f1)
for b in $BAD; do [ "$h" = "$b" ] && { echo "HIT hash $h $f"; hits=$((hits+1)); }; done
if grep -aq '5ead8ef9b43d354dfb5caadff803b11afc8c5c58' "$f"; then echo "HIT build revision 5ead8ef9b43d in $f"; hits=$((hits+1)); fi
if grep -aq 'ovhcloud-cli' "$f" && grep -aq 'vcs.modified=true' "$f"; then echo "LEAD vcs.modified=true in $f (a locally modified build; verify)"; hits=$((hits+1)); fi
done
[ -e "$HOME/init.json" ] && echo "LEAD $HOME/init.json exists (macOS throttle marker per OpenSourceMalware; check its contents and age)"
echo "scanned=$scanned hits=$hits"
[ $scanned -eq 0 ] && exit 3; [ $hits -gt 0 ] && exit 1; exit 0
title: OVHcloud CLI compromise - related loader or modified build revision
id: 8f41d6b2-0c37-4e9a-b5d1-6a2e9c7f3b48
status: experimental
description: The npm preinstall loader OpenSourceMalware tied to the hijacked account, and the build revision of the replaced OVHcloud CLI binary. A match is a lead to validate against the hashes in the item.
references:
- https://opensourcemalware.com/blog/glassworm-hacks-ovh-clouds-cli-tool
- https://github.com/ovh/ovhcloud-cli/issues/300
logsource:
category: process_creation
detection:
loader:
CommandLine|contains: 'node preinstall.js'
build:
CommandLine|contains: '5ead8ef9b43d354dfb5caadff803b11afc8c5c58'
condition: loader or build
falsepositives:
- Legitimate npm packages that ship a file named preinstall.js
level: medium
index=* (sha256="3833daffcaaaab27e4e0e0833240ffcb1df8df648f4ec0bc4a75c176e28933cb" OR sha256="43df42fd79f6f81e530892b54634598770d6e496796a863c596e616bcb3fec70" OR sha256="0f79989912572a24ba13baabb32b3fd084496271c51448d47b66fe1aedbf293c")
| table _time host sha256 file_path
@dns.question.name:*solana* [email protected]:*.yourdomain.example
| If you see | Do this |
|---|---|
A hash match or the 5ead8ef9b43d build revision |
Confirmed compromise under the defined response: isolate, rotate from another machine, review the cloud accounts, rebuild. |
vcs.modified=true on an OVHcloud CLI binary with no revision match |
A lead. Compare the binary's hash against v0.16.0 and treat it as compromised until proven otherwise. |
~/init.json on a Mac |
A lead only: other software can create a file with that name. Read it and check its age. |
| Solana lookups from a host with a wallet or crypto tooling | Expected. Exclude that host by name. |
| The script exits 3 | This is not a clean result. Point it at the actual binary path. |
| No hits | A good sign, not an exoneration. Hashes were published for one replaced file only, the stealer's behavior was never analysed, so what it leaves behind is unknown, and the binary may already have been updated over. If anyone installed v0.11.0 to v0.15.0 from a release on 19 October, rotate anyway. |
4. eMudhra: eight intermediate CA keys are compromised
Bottom line. The private keys of eight eMudhra intermediate certificate authorities were compromised; Mozilla received the report on 17 October and browsers blocked the certificates between 17 and 20 October.
- Chrome found no TLS certificate under the six TLS intermediates logged to Certificate Transparency before its block.
- Programs that do not check revocation are not covered by browser blocks: Go programs need a rebuild on Go 1.27.3 or 1.26.10, and bundled trust stores need updating.
- Do now: rebuild Go services on a fixed Go release; update NSS, certifi, webpki-roots and similar bundles; check internal trust stores for the eMudhra root.
- Skip if: you ship no Go binaries, bundle no CA list and rely only on up-to-date browsers and operating-system trust stores that receive revocation updates.
Indicators
| Type | Indicator | Where to look | Source |
|---|---|---|---|
| IoC | None published — no misissued certificate was found in Certificate Transparency before the block | — | The Hacker News, citing Chrome (checked 21 Oct) |
| IoA | A TLS chain through EM DV TLS CA - G3B/G3C, EM OV TLS CA - G3B/G3C, EM EV TLS CA - G3B/G3C, or code signed under EM OV CS CA - G3B/G3C |
TLS-inspection and proxy logs; code-signing verification logs | Ours, built on the certificate names reported by The Hacker News |
| IoA | The roots emSign ECC Root CA - G3 or emSign Root TLS CA - G3 in a bundled CA file |
Application CA bundles, container images | The Hacker News (names); ours (where to look) |
What
- What Mozilla says (20 October)
- The report arrived 17 October at 20:06 UTC; the OneCRL block reached standard Firefox installs at 22:59 UTC the same day.
- Firefox 158.0.1, ESR 115.43.1 and ESR 153.5.1 carry the block for installs that cannot receive OneCRL; NSS 3.131.1 removes the root that signed the affected intermediates.
- What The Hacker News reports (20 October)
- The eight: EM DV, OV and EV TLS CA - G3B and - G3C, and EM OV CS CA - G3B and - G3C (code signing); the six TLS intermediates chain to "emSign ECC Root CA - G3."
- Chrome blocked the six TLS intermediates by 17 October 19:45 UTC; Apple blocked on 19 October and Microsoft on 20 October.
- Go 1.27.3 and 1.26.10 (20 October) reject chains with the eight keys under CVE-2026-111943; Go 1.25 and older get no fix.
- certifi 2026.10.19 and webpki-roots 1.0.10 remove roots; Node.js and Composer fixes were pending.
- How the keys left eMudhra, and whether anyone besides the reporter holds them, is unknown.
So what
- Revocation only protects software that checks it. Go binaries and anything carrying its own CA bundle trust what was compiled in until rebuilt.
- Code-signing keys are part of this. Two of the eight sign code, so software signed under them deserves a second look.
Now what — P (analysis)
- Configuration.
- Update what browsers cannot.
- Rebuild and redeploy Go programs with Go 1.27.3 or 1.26.10; for Go 1.25 and older, move to a supported release.
- Update
certifito 2026.10.19 or later,webpki-rootsto 1.0.10 or later and NSS to 3.131.1 or later; rebuild container images that copy a CA bundle. - Where the platform supports it, add the eight intermediates to a block list.
- Blast radius.
- List services that trust a bundled CA file rather than the operating system's store.
- Detection with a defined response.
- Run the bundle check below.
- Defined response: a production TLS connection or a signed binary that chains through one of the eight intermediates after 17 October is a confirmed lead requiring incident response: capture the certificate, identify the endpoint, and treat traffic through it as intercepted.
- Communication.
- Removing the roots breaks legitimate certificates chaining to them; tell service owners before rolling the bundle out.
Hunt pack — run it, then act on what it says
No IoCs have been published, so these hunts look for the certificate names reported by The Hacker News in trust bundles and in TLS logs; the logic is our analysis. The bash script was executed against synthetic PEM bundles (a bundle holding a test certificate with the root's name, a clean certificate, a non-PEM file and an empty file). The Sigma rule (Zeek x509 log source), SPL and Datadog queries were reviewed, not executed. We are not offering a Suricata rule: we have not checked a published fingerprint list. The Sigma rule converts with pySigma to Splunk, Kusto and Lucene. Adjust field and table names to your logging.
#!/usr/bin/env bash
# Read-only. Usage: emudhra.sh <PEM-bundle>... (e.g. /etc/ssl/certs/ca-certificates.crt, certifi's cacert.pem)
# Exit: 0 scanned, none found | 1 found | 2 usage | 3 nothing readable
[ $# -ge 1 ] || { echo "usage: $0 <pem-bundle>..." >&2; exit 2; }
command -v openssl >/dev/null || { echo "openssl not found" >&2; exit 3; }
pat='emSign ECC Root CA - G3|emSign Root TLS CA - G3|EM (DV|OV|EV) TLS CA - G3[BC]|EM OV CS CA - G3[BC]'
scanned=0; hits=0
for f in "$@"; do
[ -r "$f" ] && [ -s "$f" ] || { echo "unreadable or empty: $f" >&2; continue; }
subj=$(openssl crl2pkcs7 -nocrl -certfile "$f" 2>/dev/null | openssl pkcs7 -print_certs -noout 2>/dev/null | grep -E '^subject=')
[ -n "$subj" ] || { echo "no certificates parsed: $f" >&2; continue; }
scanned=$((scanned+1)); m=$(printf '%s\n' "$subj" | grep -E -- "$pat")
[ -n "$m" ] && { printf '%s: %s\n' "$f" "$m"; hits=$((hits+$(printf '%s\n' "$m" | wc -l))); }
done
echo "scanned=$scanned hits=$hits"
[ $scanned -eq 0 ] && exit 3; [ $hits -gt 0 ] && exit 1; exit 0
title: Certificate chaining through a compromised eMudhra intermediate
id: d27b5e94-61a3-4c8f-9e02-4fb3a1c6d859
status: experimental
description: Certificates whose issuer is one of the eight eMudhra intermediates reported compromised in October 2026. Seen after 17 October, treat traffic through them as intercepted.
references:
- https://blog.mozilla.org/security/2026/10/20/protecting-firefox-users-following-the-compromise-of-emudhra-intermediate-certificates/
- https://thehackernews.com/2026/10/eight-emudhra-ca-keys-compromised.html
logsource:
product: zeek
service: x509
detection:
selection:
certificate.issuer|contains:
- 'EM DV TLS CA - G3B'
- 'EM DV TLS CA - G3C'
- 'EM OV TLS CA - G3B'
- 'EM OV TLS CA - G3C'
- 'EM EV TLS CA - G3B'
- 'EM EV TLS CA - G3C'
- 'EM OV CS CA - G3B'
- 'EM OV CS CA - G3C'
condition: selection
falsepositives:
- Legitimate eMudhra-issued sites contacted before the block
level: high
index=* sourcetype="bro:x509:json" ("certificate.issuer"="*EM DV TLS CA - G3*" OR "certificate.issuer"="*EM OV TLS CA - G3*" OR "certificate.issuer"="*EM EV TLS CA - G3*")
| stats count earliest(_time) latest(_time) by "certificate.subject" "certificate.issuer"
*:"EM DV TLS CA - G3B" OR *:"EM DV TLS CA - G3C" OR *:"EM OV TLS CA - G3B" OR *:"EM OV TLS CA - G3C" OR *:"EM EV TLS CA - G3B" OR *:"EM EV TLS CA - G3C" OR *:"EM OV CS CA - G3B" OR *:"EM OV CS CA - G3C"
| If you see | Do this |
|---|---|
| A connection or signed file chaining through one of the eight after 17 October | Defined response: capture the certificate, identify the endpoint or file, and treat the traffic as intercepted. |
| A legitimate eMudhra-issued site your business depends on | Expected. Ask the site owner when they will move to a new chain, and note the date. |
| The root in a bundle you ship | Update the bundle and rebuild. |
| The script exits 3 | This is not a clean result. Point it at a PEM file, not a directory or a Java keystore. |
| No hits | A good sign, not an exoneration. Only names were searched, many networks log no certificate chains at all, and a Go binary can still trust the old chain without any log line. Rebuild anyway. |
5. Google Cloud: search-ad phishing ends in someone else's AI bill
Bottom line. Wiz reported on 20 October multiple intrusions that start with Google Search ads for terms like "google cloud" and end with Gemini API charges of tens to hundreds of thousands of dollars within 24 to 48 hours.
- In between, they pass through a Google Sites redirect to a fake Google login that captures credentials and MFA codes.
- The attackers delete the organization policy that limits IAM members to company domains, add external Gmail accounts to billing with admin roles, link their own projects to the victim's billing account, and demote existing billing admins to viewers.
- Do now: check who holds
roles/billing.adminand whetheriam.allowedPolicyMemberDomainsis still set; set budget alerts on billing accounts. - Skip if: you have no Google Cloud organization or billing account.
Indicators
| Type | Indicator | Where to look | Source |
|---|---|---|---|
| IoC | 212.73[.]134[.]136 — attacker infrastructure, initial login from the phishing page |
Google Workspace login logs; GCP audit logs | Wiz |
| IoC | Phishing domains as Wiz wrote them: *.gboogl[.]com, *.groosl[.]com, *.gprokl[.]com, *.gxoosl[.]com, *.gsoolg[.]com, *gzoozl[.]com, *groonl[.]com, *gsool[.]space, *gbrokl[.]space, *gbrokl[.]xyz, *gsoosl[.]xyz, *gsool[.]xyz, *gpoosl[.]com, *groolg[.]com, *gcslom[.]com, *gcoalg[.]com |
DNS and proxy logs | Wiz |
| IoA | SetOrgPolicy removing iam.allowedPolicyMemberDomains |
Cloud Audit Logs (organization) | Wiz |
| IoA | EnableService, CreateServiceAccount, CreateServiceAccountKey, CreateKey in old, low-use projects; grants of roles/ml.admin, roles/mcp.toolUser, roles/recommender.billingAccountCudAdmin, roles/billing.admin |
Cloud Audit Logs | Wiz |
| IoA | External Gmail accounts added to a billing account; billing admins demoted to viewer; sudden Gemini spend | Billing IAM; billing reports | Wiz |
What
- What Wiz reports (20 October)
- The phishing kit logged in from the attacker's address within minutes, then re-authenticated from a second address; later activity came from addresses in the victim's headquarters country.
- In existing low-use projects the attackers enabled the Gemini API, created service accounts and API keys, and granted high-privilege roles.
- Attacker-controlled projects were linked to the victim's billing account, so their usage was charged to the victim.
- Wiz names no sector.
So what
- The bill is the loss, and it arrives fast. Charges reach six figures within two days, and the admins who would notice have been demoted.
- The domain restriction is the control the attacker removes first. If no one is alerted when it changes, the rest of the chain is quiet.
Now what — P → I (analysis)
- Configuration.
- Restore and watch the controls Wiz names.
- Confirm
constraints/iam.allowedPolicyMemberDomainsis set at the organization, and alert on anySetOrgPolicythat changes it. - Review members of every billing account for non-corporate accounts and for unexpected
roles/billing.admin. - Set budgets and alerts on each billing account; consider spend caps on Gemini API usage.
- Blast radius.
- List the projects a billing account pays for and any project linked recently.
- Detection with a defined response.
- Run the audit-log hunts below over at least 30 days.
- Defined response: a login from the listed address, or a removal of the domain restriction you did not approve, is a confirmed compromise. Revoke the user's sessions, reset credentials and MFA, remove external billing members and unknown keys and service accounts, unlink foreign projects, and open a billing dispute with Google.
- Communication.
- Tell finance now that a sudden cloud bill can be an incident, and who to call when one appears.
Hunt pack — run it, then act on what it says
These hunts implement the address, method names, roles and policy name Wiz published; the Gemini service name in the bash script (generativelanguage.googleapis.com) is our addition. The bash script was executed against synthetic audit-log JSON (a hit on the address and policy, a near-miss address, a compressed file and an empty file). The Sigma rule (Google Cloud audit log source), SPL and Datadog queries were reviewed, not executed. The Sigma rule converts with pySigma to Splunk, Kusto and Lucene. Adjust field and table names to your logging.
#!/usr/bin/env bash
# Read-only. Usage: gcp.sh <audit-log-export.json[.gz]>... (from 'gcloud logging read --format=json' or a sink)
# Exit: 0 scanned, none found | 1 found | 2 usage | 3 nothing readable
[ $# -ge 1 ] || { echo "usage: $0 <file>..." >&2; exit 2; }
ip=$(printf '%s' '212.73[.]134[.]136' | tr -d '[]' | sed 's/\./\\./g')
pat="(^|[^0-9.])$ip([^0-9]|\$)|allowedPolicyMemberDomains|roles/ml\.admin|roles/mcp\.toolUser|roles/recommender\.billingAccountCudAdmin|roles/billing\.admin|generativelanguage\.googleapis\.com"
scanned=0; hits=0
for f in "$@"; do
[ -r "$f" ] && [ -s "$f" ] || { echo "unreadable or empty: $f" >&2; continue; }
case "$f" in *.gz) c="zcat -f";; *) c="cat";; esac
scanned=$((scanned+1)); n=$($c "$f" | grep -Eoc -- "$pat"); hits=$((hits+n))
[ "$n" -gt 0 ] && $c "$f" | grep -Eo -- ".{0,120}($pat).{0,80}" | head -50
done
echo "scanned=$scanned hits=$hits"
[ $scanned -eq 0 ] && exit 3; [ $hits -gt 0 ] && exit 1; exit 0
title: GCP organization policy change or billing-admin grant matching Wiz LLMjacking reporting
id: 5a8c3f17-92e6-4d0b-8c71-e3b9d0a4f2c6
status: experimental
description: The method names, policy and roles Wiz published for a phishing-to-LLMjacking campaign. A removal of the domain restriction that no one approved is a confirmed compromise.
references:
- https://www.wiz.io/blog/from-phishing-to-llmjacking
logsource:
product: gcp
service: gcp.audit
detection:
policy:
gcp.audit.method_name: 'SetOrgPolicy'
domains:
- 'allowedPolicyMemberDomains'
roles:
- 'roles/billing.admin'
- 'roles/mcp.toolUser'
- 'roles/ml.admin'
- 'roles/recommender.billingAccountCudAdmin'
condition: (policy and domains) or roles
falsepositives:
- Approved administrator changes with a ticket
level: high
index=* sourcetype="google:gcp:pubsub:message" ("data.protoPayload.methodName"="SetOrgPolicy" OR "data.protoPayload.methodName"="CreateServiceAccountKey" OR "data.protoPayload.requestMetadata.callerIp"="212.73[.]134[.]136" OR "allowedPolicyMemberDomains" OR "roles/billing.admin")
| table _time "data.protoPayload.methodName" "data.protoPayload.authenticationInfo.principalEmail" "data.protoPayload.requestMetadata.callerIp"
@network.client.ip:212.73[.]134[.]136 OR (*:"SetOrgPolicy" *:"allowedPolicyMemberDomains") OR *:"roles/billing.admin" OR *:"roles/mcp.toolUser"
| If you see | Do this |
|---|---|
| Activity from the listed address, or the domain restriction removed without approval | Confirmed compromise under the defined response: revoke sessions, remove external members and keys, unlink foreign projects, dispute the charges. |
| New Gemini API enablement or service-account keys in old projects | A lead. Ask the project owner; treat as compromise if no one made the change. |
A known administrator granting roles/billing.admin through a change ticket |
Expected. Record it. |
| The script exits 3, or audit logs for the organization are not exported | This is not a clean result. Admin Activity logs are on by default; export them before relying on the hunt. |
| No hits | A good sign, not an exoneration. One address was published and the attackers moved to addresses in the victim's own country; phishing domains change; and a log search does not show charges already incurred. Check the billing report anyway. |
6. CISA's catalog adds six: Plex Media Server, Siemens Software Center and SiteGuard Server Edition
Bottom line. CISA added six exploited flaws to its catalog on 20 October: four in Plex Media Server, one in Siemens Software Center and one in SiteGuard Server Edition.
- Due dates: 23 October for Plex CVE-2026-96654 and CVE-2026-96656 and for SiteGuard CVE-2026-106931; 3 November for Plex CVE-2026-96652 and CVE-2026-96655 and for Siemens CVE-2026-110936.
- Do now: apply the vendors' fixes; treat any internet-exposed Plex server as possibly compromised and hunt it.
- Skip if: you run none of these three products.
Indicators
| Type | Indicator | Where to look | Source |
|---|---|---|---|
| IoC | None published in the catalog entries | — | CISA catalog data, version 2026.10.20 |
| IoA | Requests to /video/:/transcode/universal carrying a full URL — the SSRF path CISA names for CVE-2026-96655 |
Reverse-proxy or web logs in front of Plex | CISA (path); ours (the full-URL test) |
| IoA | A protocol parameter carrying a full URL, sent with any X-Plex-Token — the SSRF CISA describes for CVE-2026-96652 |
Reverse-proxy or web logs | CISA |
| IoA | A DLL placed in a directory Siemens Software Center searches, then loaded by it | EDR image-load events | CISA description of CVE-2026-110936; ours (where to look) |
What
- What CISA's catalog says (catalog 2026.10.20)
- Plex Media Server: CVE-2026-96652 (SSRF via the
protocolparameter), CVE-2026-96654 (encoded URI schemes, lets an attacker call other plugins' functions), CVE-2026-96655 (SSRF via/video/:/transcode/universal), CVE-2026-96656 (admin file write that may execute on load); CISA says the four can be chained. - Siemens Software Center CVE-2026-110936: uncontrolled search path element; an authenticated local attacker places a specially crafted DLL to run code with the application's privileges.
- SiteGuard Server Edition CVE-2026-106931 (EG Secure Solutions): OS command injection that may run commands with root or SYSTEM privileges.
- Ransomware use is listed as "Unknown" for all six.
- Plex Media Server: CVE-2026-96652 (SSRF via the
- What the CVE record says
- CVE-2026-96656 affects Plex Media Server before 1.43.3.10861.
- Not read directly
- Fixed versions for the other Plex CVEs, for Siemens Software Center and for SiteGuard: follow each vendor's advisory.
So what
- The catalog date is a deadline for some and a signal for everyone. Three of the six are due tomorrow, 23 October.
- Our view: a media server is still a way in. Plex on a shared office machine sits on the same network as everything else there.
Now what — P → I (analysis)
- Configuration.
- Patch by the due dates.
- Update Plex Media Server to 1.43.3.10861 or later and remove direct internet exposure where it is not needed.
- Apply Siemens's fix for Software Center and EG Secure Solutions's fix for SiteGuard Server Edition, per their advisories.
- Blast radius.
- For Plex, rotate the Plex account and any credentials stored on the same host if it was reachable from the internet before patching.
- Detection with a defined response.
- Run the hunt pack below on proxy logs in front of Plex.
- Defined response: a transcode or
protocolrequest carrying an outside URL, followed by new files or processes on the Plex host, is a confirmed compromise. Isolate the host, preserve the Plex data directory and logs, rotate tokens, and rebuild.
- Communication.
- Where the catalog's due dates bind you, record the patch date for each CVE.
Hunt pack — run it, then act on what it says
These hunts implement the request paths and parameters in CISA's catalog descriptions; the logic is our analysis. The bash script was executed against synthetic access logs (a hit with an encoded full URL, a clean log, a compressed log, an empty file and no arguments). The Sigma rule (the Plex path CISA names, against a generic web-server log source), KQL and Datadog queries were reviewed, not executed. We are not offering a Suricata rule, or any rule for SiteGuard: no request pattern or file name has been published for it. The Sigma rule converts with pySigma to Splunk, Kusto and Lucene. Adjust field and table names to your logging.
#!/usr/bin/env bash
# Read-only. Usage: plex.sh <web-or-proxy-access-log>... (text or .gz)
# Flags requests to the transcode path named in CISA's entry for CVE-2026-96655.
# Exit: 0 scanned, none found | 1 found | 2 usage | 3 nothing readable
[ $# -ge 1 ] || { echo "usage: $0 <log>..." >&2; exit 2; }
pat='/video/:/transcode/universal|/video/%3A/transcode/universal'
scanned=0; hits=0
for f in "$@"; do
[ -r "$f" ] && [ -s "$f" ] || { echo "unreadable or empty: $f" >&2; continue; }
case "$f" in *.gz) c="zcat -f";; *) c="cat";; esac
scanned=$((scanned+1)); n=$($c "$f" | grep -Eic -- "$pat"); hits=$((hits+n))
[ "$n" -gt 0 ] && $c "$f" | grep -Ei -- "$pat" | grep -Ei 'https?(%3A|:)' | cut -c1-300
done
echo "scanned=$scanned hits=$hits (lines printed above carry a full URL, the stronger lead)"
[ $scanned -eq 0 ] && exit 3; [ $hits -gt 0 ] && exit 1; exit 0
title: Plex Media Server transcode request carrying an outside URL (CVE-2026-96655 path)
id: 1e7d4b38-a5c9-4f62-b3e0-7c84d2f9a613
status: experimental
description: The SSRF path CISA names for CVE-2026-96655, with a full URL in the request. Followed by new files or processes on the Plex host, this is a confirmed compromise.
references:
- https://github.com/cisagov/kev-data
logsource:
category: webserver
detection:
path:
cs-uri-stem|contains:
- '/video/:/transcode/universal'
- '/video/%3A/transcode/universal'
url:
cs-uri-query|contains:
- 'http://'
- 'https://'
- 'http%3A'
- 'https%3A'
condition: path and url
falsepositives:
- Plex clients that pass full URLs for remote media; validate the source
level: medium
DeviceImageLoadEvents
| where Timestamp > ago(30d)
| where InitiatingProcessFolderPath has "Siemens" and InitiatingProcessFolderPath has "Software Center"
| where not(FolderPath startswith @"C:\Windows\") and not(FolderPath startswith @"C:\Program Files")
| project Timestamp, DeviceName, InitiatingProcessFileName, FileName, FolderPath, SHA256
*:"/video/:/transcode/universal" OR *:"/video/%3A/transcode/universal"
| If you see | Do this |
|---|---|
A transcode or protocol request carrying an outside URL, then new files or processes on the host |
Confirmed compromise under the defined response: isolate, preserve, rotate tokens, rebuild. |
| Transcode requests with no outside URL | Expected: that is normal playback. |
| A DLL loaded by Software Center from a user-writable folder | A lead. Validate who placed it; treat as compromise if no one did. |
| The script exits 3, or Plex is reached directly without a proxy that logs | This is not a clean result. Plex's own logs are the next place to look. |
| No hits | A good sign, not an exoneration. Only the published paths were searched, encoded variants beyond the two included are possible, and a server reached without a logging proxy leaves nothing here. Patch by the due date anyway. |
Making this the last time: controls that outlast these incidents
Bottom line. Three of today's items share one lesson: a trusted channel — a VPN gateway, a release download, a certificate chain — was the way in. The controls below hold even when the next flaw or key leak is unknown.
- Do now: pick the one row that matches your biggest gap and assign an owner this week.
- Skip if: every row is already in place and tested.
| Control | Why it matters here | Do this | Needs |
|---|---|---|---|
| Hypervisor management on its own network | Item 2's pivot went from the VPN to vCenter | Allow vCenter and ESXi management only from a privileged-access network, never from the VPN pool; enforce execInstalledOnly on every host |
Network change; vSphere admin |
| Pinned, attested release downloads | Item 3's checksums.txt was replaced along with the binary |
Pin hashes in CI and verify vendor attestations (gh attestation verify) instead of the release's own checksum file |
CI change |
| Trust stores you can update in a day | Item 4 left Go binaries and bundled CA files trusting a compromised chain | Inventory every bundled CA file and Go build; make rebuilding them a routine job | Build pipeline owner |
| Alerts on control removal | Item 5's first move was deleting a domain restriction | Alert on any change to organization policies and billing roles | Cloud audit-log alerting |
Sector signal — only what a source actually said
- Unit 42 lists education, financial services, healthcare, high technology, hospitality, manufacturing, professional and legal services, government, transportation and logistics, utilities and energy, and wholesale and retail among the sectors in its GlobalProtect investigations (item 2).
- No source attributed items 1 and 3 through 6 to a sector; that is an absence of sector-attributable reporting, not an absence of risk.
How this brief is put together
- Facts are reported as their named source published them: the GlobalProtect campaign from Unit 42's updated threat brief, Palo Alto's advisory and CISA's catalog data
- the PHP flaws from PHP's release announcements and GitHub advisories, with exploitation from Amazon Threat Intelligence and watchTowr and WAF coverage from Akamai, AWS, F5, Fastly, Google Cloud, Imperva, Imunify360, Microsoft, Patchstack, Tenable, Wiz and Huntress, each labeled as theirs
- the OVHcloud CLI compromise from OVHcloud's GitHub issue, SecurityWeek and OpenSourceMalware
- the eMudhra keys from Mozilla's post and The Hacker News
- the Google Cloud campaign from Wiz
- and the catalog additions from CISA's own published data.
- Where sources disagree — Unit 42's summary against its update, the reporter's version range against OVHcloud's — we say so in the item and say which reading we plan on.
- Where vendors disagree on whether the PHP flaws are exploited, we show both and plan on exploitation.
- IoCs appear only as a named source published them and are defanged; IoAs are cited or marked ours.
- The hunt packs are our analysis, and each says what was executed and what was only reviewed.
- PIVCCERL™ is Threat Vector Management's incident lifecycle — Preparation, Identification, Validation, Containment, Communication, Eradication, Recovery, Lessons Learned; an unaffected organization is in Preparation, and a second stage appears where a hunt is warranted.
- This brief publishes when something warrants it, not on a schedule.
ATT&CK (ours unless noted): T1190 Exploit Public-Facing Application (items 1, 2, 6); T1133 External Remote Services (item 2); T1003 OS Credential Dumping (item 2); T1195.002 Compromise Software Supply Chain (item 3); T1552.001 Credentials in Files (item 3); T1553 Subvert Trust Controls (item 4); T1566 Phishing and T1078.004 Cloud Accounts (item 5); T1574.001 DLL Search Order Hijacking (item 6).
Threat Vector Management helps organizations and the MDR and SOC teams that defend them turn briefs like this into action — running a look-back hunt across the logs you already keep, and deciding what a clean result does and does not let you close. Start a conversation →
More editions: Threat Brief archive.
Threat Vector Management is not affiliated with any company operating under the name “ThreatVector.”
Sources
- Palo Alto Networks Unit 42 — Threat Brief: Active Exploitation of PAN-OS CVE-2026-0257, updated 19 and 20 Oct 2026
- Palo Alto Networks — advisory CVE-2026-0257, published 13 May 2026
- CISA — Known Exploited Vulnerabilities catalog data, catalog versions 2026.10.20 and 2026.10.21
- PHP — Security advisory: Critical remote code execution vulnerabilities, update now, 21 Oct 2026
- PHP — GitHub advisory GHSA-w8hw-w9fx-j79w, RCE via OOM corruption (CVE-2026-109618), 21 Oct 2026
- PHP — GitHub advisory GHSA-6wmf-4rv5-p3rp, RCE via stale global state (CVE-2026-109619), 21 Oct 2026
- Fastly — Proactive protection for PHP2Shell, CVE-2026-109618 and CVE-2026-109619, 21 Oct 2026
- Amazon Threat Intelligence — Amazon Threat Intelligence identifies PHP2Shell exploitation prior to public disclosure in MadPot, 21 Oct 2026; watchTowr — PHP2Shell: PHP Remote Code Execution Exploited, 21 Oct 2026; Akamai — Critical Remote Code Execution Vulnerabilities in PHP Core, 21 Oct 2026; AWS — Security Bulletin 2026-143-AWS: PHP web runtimes, 21 Oct 2026; AWS — Using AWS WAF to apply mitigations for PHP2Shell RCE vulnerabilities, 21 Oct 2026; CloudLinux — PHP CVE-2026-109618 and CVE-2026-109619: Imunify360 WAF rulesets, 21 Oct 2026, updated 22 Oct; Microsoft — Addressing PHP2Shell: upgrade guidance and Azure WAF mitigations, 21 Oct 2026; Microsoft — Azure WAF custom rules for PHP2Shell mitigation, 21 Oct 2026; Google Cloud — Responding to core PHP vulnerabilities CVE-2026-109618 and CVE-2026-109619, 21 Oct 2026; F5 — AI found it. AI is stopping it, 22 Oct 2026; Imperva — PHP2Shell: When PHP Runs Out of Memory at the Wrong Moment, 21 Oct 2026; Patchstack — Major security alert: PHP vulnerable to critical RCE, attacks ongoing, 21 Oct 2026; Tenable — php2shell FAQ, 21 Oct 2026; Wiz — PHP2Shell: AI uncovers critical RCE vulnerabilities affecting 70% of the Internet, 21 Oct 2026; Huntress — Rapid Response: php2shell, Leaked Critical PHP Vulnerabilities (CVE-2026-109618 & CVE-2026-109619), 21 Oct 2026
- OVHcloud CLI — GitHub issue 300, opened 19 Oct 2026
- SecurityWeek — Hijacked Developer Account Used to Plant Stealer in OVHcloud CLI, 21 Oct 2026
- OpenSourceMalware — GlassWorm hacks OVHcloud's CLI tool, Oct 2026
- Mozilla Security Blog — Protecting Firefox users following the compromise of eMudhra intermediate certificates, 20 Oct 2026
- The Hacker News — Eight eMudhra CA Keys Compromised, 20 Oct 2026
- Wiz — From Phishing to LLMjacking, 20 Oct 2026
- CVE record CVE-2026-96656
- SANS Internet Storm Center — Stormcast, Tuesday, October 20th, 2026, 20 Oct 2026
Provenance: compiled 21–22 October 2026 by Threat Vector Management from a sweep of vendor, government and researcher sources, with research and fact-checking support from Claude (Anthropic). Every CVE identifier, version string, score, date and indicator was checked against its cited source on the day of publication; the hunt logic is our analysis of those records.