OpsShield cPGuard update channel hijacked; malicious 5.88.12–5.88.19 updates ran as root on customer servers
A fake cPGuard update reached customer servers for about 70 minutes, ran a root script, planted a hidden root shell and temp files, and sent data out. Today, find every cPGuard host and every hosting provider that runs cPGuard. Image any host that ran 5.88.12–5.88.19 before moving it to 5.88.25 or later.
Triage: Vendor-stated root execution of attacker code on customer servers through a trusted update channel [S1].
Three reputable secondary outlets report the incident and quote OpsShield's statements. No OpsShield advisory is in the source set.
What happened
- Attackers used compromised credentials to reach OpsShield's update CDN and its billing/licensing server [S1][S2][S3].
- They uploaded a fake cPGuard update signed with a stolen access key. Versions 5.88.12–5.88.19 were served for about 70 minutes [S1][S2][S3].
- The update ran as root on servers that polled OpsShield's update infrastructure during the window. It deployed a hidden root shell and files in the temp folder [S1].
- The script collected data and uploaded it to OpsShield's licensing server under a compromised account [S1].
- OpsShield estimates about 2,950 servers ran the script and about 7,900 client account records were copied [S1][S2][S3].
- OpsShield says versions 5.88.25 and later remove the artifacts [S1][S2][S3].
Timeline
| 2026-11-04 | Public reporting of the cPGuard update-channel compromise. Malicious versions 5.88.12–5.88.19 identified; fix in 5.88.25+. S1 |
Detect
cPGuard hosts that received 5.88.12–5.88.19 · Linux package/update logs or software inventory
index=* "cpguard" ("5.88.12" OR "5.88.13" OR "5.88.14" OR "5.88.15" OR "5.88.16" OR "5.88.17" OR "5.88.18" OR "5.88.19") | stats earliest(_time) as first_seen latest(_time) as last_seen values(source) as sources by hostFROM logs-* | WHERE message LIKE "*cpguard*" AND (message LIKE "*5.88.12*" OR message LIKE "*5.88.13*" OR message LIKE "*5.88.14*" OR message LIKE "*5.88.15*" OR message LIKE "*5.88.16*" OR message LIKE "*5.88.17*" OR message LIKE "*5.88.18*" OR message LIKE "*5.88.19*") | STATS first_seen = MIN(@timestamp), last_seen = MAX(@timestamp), sources = VALUES(log.file.path) BY host.name
A hit means: The host recorded a malicious cPGuard version. Treat it as root-compromised until its artifacts are reviewed [S1].
Shell spawned by the cPGuard update process · Linux auditd or EDR process events
index=* (parent_process_name="*cpguard*" OR parent_process="*cpguard*") (process_name="sh" OR process_name="bash" OR process_name="dash") | stats count values(process) as cmdlines values(user) as users by host parent_process_name
FROM logs-* | WHERE (process.parent.name LIKE "*cpguard*" OR process.parent.command_line LIKE "*cpguard*") AND process.name IN ("sh", "bash", "dash") | STATS count = COUNT(*), cmdlines = VALUES(process.command_line), users = VALUES(user.name) BY host.name, process.parent.nameA hit means: The cPGuard updater launched a shell. Because the malicious update ran as root, review the command lines for script execution or data collection [S1].
Temp-folder and hidden files written by cPGuard · Linux file integrity or EDR file events
index=* (process_name="*cpguard*" OR parent_process_name="*cpguard*") (file_path="/tmp/*" OR file_path="/var/tmp/*" OR file_name=".*") | stats count values(file_path) as paths values(file_name) as files by host
FROM logs-* | WHERE (process.name LIKE "*cpguard*" OR process.parent.name LIKE "*cpguard*") AND (file.path LIKE "/tmp/*" OR file.path LIKE "/var/tmp/*" OR file.name LIKE ".*") | STATS count = COUNT(*), paths = VALUES(file.path), files = VALUES(file.name) BY host.name
A hit means: A possible match for the hidden root shell and temp-folder files OpsShield described [S1]. Preserve the files before upgrading.
SSH authorized_keys changes on cPGuard hosts · Linux file integrity, auditd or EDR file events
index=* file_name="authorized_keys*" (action="created" OR action="modified" OR action="write") | stats count values(file_path) as paths values(process_name) as writers values(user) as users by host
FROM logs-* | WHERE file.name LIKE "authorized_keys*" AND event.action IN ("created", "modified", "write") | STATS count = COUNT(*), paths = VALUES(file.path), writers = VALUES(process.name), users = VALUES(user.name) BY host.nameA hit means: An SSH key changed and may be attacker persistence. Unexpected SSH keys appear in the story summary but not in the quoted vendor text [S1]. Validate against change records.
Verify
- Check whether the host's cPGuard update history shows 5.88.12–5.88.19, and whether the host was online during the roughly 70-minute window [S1].
- Confirm a hidden root shell or unexplained temp-folder files dated to the update [S1].
- Benign look-alike: normal cPGuard updates also run as root and spawn shells. Separate them by version and time window.
- Benign look-alike: legitimate cPGuard traffic to OpsShield's licensing server. The exfil used that same destination, so destination alone does not prove anything [S1].
- Benign look-alike: SSH key changes from admin onboarding or automation. Check them against change tickets.
Scope
Affected
- cPGuard versions 5.88.12–5.88.19 (OpsShield)
Only if
- Server polled OpsShield update infrastructure during the compromise window (about 70 minutes)
Not affected if
- cPGuard was not online during the compromise window, per OpsShield
Fixed in: 5.88.25
Enumerate
- All servers with cPGuard installed, with version history and update timestamps.
- Third-party hosting and web providers that run cPGuard on servers holding your data or sites.
- Credentials, SSH keys, API tokens and client data present on affected servers.
- Client or licensing account records you hold with OpsShield, which may be among the roughly 7,900 copied records [S1].
Contain
- Isolate or restrict outbound traffic from hosts that ran 5.88.12–5.88.19.
- Take disk and memory images before upgrading. OpsShield says 5.88.25+ removes the artifacts [S1], so upgrading first destroys evidence and cannot be undone.
- Pause cPGuard auto-update on unverified hosts until you confirm the update source is trustworthy.
- Rotate root passwords, SSH keys and service credentials on affected hosts. Data already uploaded cannot be recalled.
- Ask hosting providers that run cPGuard whether their servers were in the window, and what data was exposed.
Eradicate
- Remove the hidden root shell and temp-folder files, or upgrade to 5.88.25+ after imaging [S1].
- Remove unauthorized SSH keys.
- Because the code ran as root, consider rebuilding affected hosts. The sources do not list the script's full set of actions.
Recover
- Before restoring service, confirm cPGuard is at 5.88.25 or later and the artifacts are gone [S1].
- Confirm credentials and keys were rotated after the host was cleaned.
- Monitor for new shells from the cPGuard process, new SSH keys, and unusual outbound uploads.
Re-enter the loop when
- OpsShield publishes IoCs, file hashes or exact paths for the root shell and temp files.
- OpsShield revises the window, the affected versions or the count of affected servers.
- Evidence emerges that the script did more than plant a shell and upload data.
- A hosting provider confirms your servers or data were in scope.
Debrief
- Record which hosts ran malicious versions, when, and what data they held.
- Record whether evidence was preserved before the upgrade.
- Gap: no OpsShield primary advisory is in the source set.
- Gap: no hashes, file paths or exfil indicators were published.
- Gap: the exact UTC compromise window is not given.
- Gap: the full behaviour of the script is unknown.
Detection coverage — checked automatically
| Category | Source | Status |
|---|---|---|
| Vendor | Impacted vendor / CERT advisory | nothing found — no vendor or CERT page among the thread sources; secondary reporting only |
| Government | CISA KEV | not checkable — no CVE: the catalog is keyed by CVE |
| EDR / endpoint VM | CrowdStrike blog | nothing found — no post names it among the feed's 10 newest items |
| EDR / endpoint VM | Microsoft Security blog | nothing found — no post names it among the feed's 10 newest items |
| EDR / endpoint VM | SentinelOne blog | nothing found — no post names it among the feed's 10 newest items |
| EDR / endpoint VM | SentinelOne Labs | nothing found — no post names it among the feed's 10 newest items |
| WAF / edge | Akamai blog | nothing found — no post names it among the feed's 1183 newest items |
| WAF / edge | Cloudflare WAF managed-ruleset changelog | nothing found — no post names it among the feed's 139 newest items |
| Cloud / container | Wiz blog | nothing found — no post names it among the feed's 717 newest items |
| IDS / research | Cisco Talos blog | nothing found — no post names it among the feed's 15 newest items |
| Detection content | Elastic detection rules | nothing found — no rule file names OpsShield |
| Detection content | Elastic Security Labs | nothing found — no post names it among the feed's 102 newest items |
| Detection content | SigmaHQ rules | nothing found — no rule file names OpsShield |
| Detection content | Splunk ESCU | nothing found — no rule file names OpsShield |
| MSSP / IR firms | Arctic Wolf blog | nothing found — no post names it among the feed's 10 newest items |
| MSSP / IR firms | Huntress blog | nothing found — no post names it among the feed's 754 newest items |
| MSSP / IR firms | Rapid7 blog | nothing found — no post names it among the feed's 20 newest items |
| MSSP / IR firms | Sophos threat research | nothing found — no post names it among the feed's 15 newest items |
| Research | Unit 42 | nothing found — no post names it among the feed's 15 newest items |
Checked automatically 2026-11-10 11:17Z from public sources: 0 published, 18 nothing found, 1 not machine-checkable, 0 failed. "Nothing found" means the public source answered and had nothing, as of that moment; a feed covers only its newest posts. Re-checked daily.
What a person would still look up (4)
| Linux EDR | Can it show child processes of the cPGuard updater, and does it keep that history past the window? |
| File integrity monitoring | Does it watch temp folders, hidden files and authorized_keys on hosting servers? |
| Asset/software inventory | Does it record cPGuard versions and update times? |
| Third-party risk | Which hosting providers run cPGuard, and what is their notification path? |
Exposure queries — generated automatically
shodan · alias · card
http.title:"cPGuard"
open · Banner spelling suggested by the model from the card text (product name of OpsShield's server security agent, shown as the console title); counted against Shodan before it was shown.
1services internet-wide on Shodan · 2026-11-10▬ 1 on 2026-11-04 (+0 +0%) · 1 on 2026-11-09 (+0 +0%)
Internet-wide count, trend
| Query | First | Latest | Change |
|---|---|---|---|
http.title:"cPGuard" | 1 2026-11-04 | 1 2026-11-10 | +0 (+0%) over 7 days |
Shodan's count of matching services on the whole internet, one point a day; the scope (your ranges) is never part of it. A count moves with Shodan's crawl as much as with patching, so read the direction, not the digit.
No CVE in this campaign: nothing an internet scanner keys on. Scope by product in your own tool.
Banner spellings: a model read 2 from the NVD names and this card's text (former and marketing names, console titles); 1 matched something on Shodan and is shown above, the rest was dropped.
Scope every query in your own tool, never in a shared document: Shodan `net:<your_ranges>`, `org:"<your_org>"` or `hostname:<your_domain>` (or a Shodan Monitor network alert, which applies the scope for you); Censys `host.ip: <your_ranges>` or `host.dns.names: <your_domain>`. Then compare the banner version with the affected range. Generated automatically 2026-11-10 11:17Z from the CVE ids and NVD's CPE configurations, each Shodan query counted against Shodan itself; re-built daily with the coverage check.
Open questions
- What is the exact date and UTC time of the roughly 70-minute window?
- Are there file hashes, paths or names for the hidden root shell and temp files?
- The story summary mentions unexpected SSH keys, but the quoted vendor text does not. Which source states this?
- What data did the script collect from customer servers, beyond the client account records?
- Has OpsShield published a primary advisory or customer notification?
- Does 5.88.25 fully remediate the host, or does it only remove the named artifacts?
Sources
- [S1] https://www.securityweek.com/malicious-cpguard-updates-served-in-opsshield-supply-chain-attack/ · SecurityWeek
- [S2] https://thehackernews.com/2026/11/cpguard-update-channel-hijacked-to.html · The Hacker News
- [S3] https://www.bleepingcomputer.com/news/security/hackers-hijack-cpguard-autoupdate-to-deploy-backdoor-steal-data/ · BleepingComputer
Public OSINT only. AI-generated by the pipeline; structure follows the DAIR model from Dynamic Incident Response (Joshua Wright). Published automatically; a dismissed draft unpublishes it.