An attacker broke into the update system of the cPGuard security tool on November 2 and used it to send a malicious script to customers' Linux servers.

The script installed a backdoor and collected password hashes and other sensitive files from servers that ran it, cPGuard maker OPSSHIELD said in an advisory. In a later disclosure, OPSSHIELD said about 2,950 customer servers ran the script, which sent the files it collected back to the attacker.

OPSSHIELD first named cPGuard 5.88.25 as the fix. Its later disclosure says version 5.88.26 removes the backdoor, and a follow-up update removes a scheduled task the script also left. Admins should install the latest version and then check that those files are gone.

Credentials the script copied may still work after the update, so any server that may have run the script also needs new passwords and keys.

At 02:06 UTC, the attacker, who has not been identified, used compromised credentials to get into cPGuard's update system. The script went out in cPGuard versions 5.88.12 through 5.88.19.

The attack was detected within 12 hours of those versions going out, according to OPSSHIELD. The company has cleared its infrastructure credentials and stopped the script from reaching more servers. It has since traced the attack to a break-in at its billing and licensing server.

Servers installed the script between 02:08 and 03:20 UTC on November 2, according to OPSSHIELD's later disclosure. A server where cPGuard was not online in that window did not receive it.

OPSSHIELD's disclosure page also offers a lookup that checks server IP addresses or hostnames against its incident records. A missing record does not prove a server was unaffected.

Admins can check whether a server installed an affected version by searching its update log:

grep 'Successfully updated' /opt/cpguard/logs/install_log

An entry for any version from 5.88.12 through 5.88.19 means the server installed an affected update. The entry alone does not show that the script ran or that data left the server. The server should still be treated as potentially compromised, even after updating.

A server with no matching entries, or with a missing or incomplete log, may still have run the script. Admins who are unsure can contact OPSSHIELD Support.

The script read these files, OPSSHIELD's later disclosure says: /etc/shadow and /etc/passwd, root's SSH private keys and other files in /root/.ssh, the MySQL root password in /root/.my.cnf where present, and root's shell history. On a small number of servers, it also read cloud storage keys in /root/.s3cfg.

The /etc/shadow file stores one-way password hashes. Weak, common or previously leaked passwords can be recovered from those hashes by testing guesses offline, and even strong ones still need resetting. Secrets that may sit in the database configuration or shell history have no such hashing to protect them.

OPSSHIELD first said the script uploaded what it collected to a licensing server run by OPSSHIELD itself, using a compromised account, so the attacker could pick it up later. OPSSHIELD has since secured that account. Its later disclosure says the files went to a server the attacker controlled.

OPSSHIELD's first estimate, late on November 2 UTC, was that the attacker took 32 files from the licensing server, each tied to one customer server.

The attacker also made copies of three of OPSSHIELD's cloud servers and took billing records for about 7,900 customer accounts, the later disclosure says.

What cPGuard Admins Should Do Now

OPSSHIELD asks admins to update every cPGuard server now and then check for files the script left:

  1. Run cpgcli update --start on each server.
  2. Run cpgcli --version and confirm the server is on the latest version. If the update fails, contact OPSSHIELD Support.
  3. Check that /etc/cron.d/i93677, /var/tmp/.i93677/ and /var/tmp/.cpg91511_sh are gone, and delete any that remain.

Admins should also take these steps for any server where the script ran or may have run:

  1. From a trusted recovery environment, reset the passwords for root and every other local Linux account that uses a password.
  2. From a trusted device, change any of those passwords that are also used on other systems.
  3. Change the MySQL root password and any database passwords stored in /root/.my.cnf, and rotate S3 access keys, DigitalOcean tokens, keys in /root/.s3cfg and any secrets recorded in root's shell history.
  4. Replace the SSH private keys stored under /root/.ssh, remove the matching old public keys from every system that trusts them, and review authorized_keys for entries you do not recognize.
  5. Treat other servers this one can reach with SSH keys as exposed until their keys are replaced.

All OPSSHIELD customers should also reset their billing portal password at manage.opsshield.com and turn on two-factor login.

OPSSHIELD is not recommending a full reset or operating system rebuild as a routine step, and says that view could change as the investigation continues. Admins who find other signs of compromise, or cannot confirm a server is clean, should ask OPSSHIELD Support for a case-by-case review, which may lead to a rebuild. If OPSSHIELD tells an owner that the attacker logged in to their server by hand, the later disclosure says that server should be rebuilt from a clean backup taken before November 1.

Separately, OPSSHIELD said it was releasing another update, as a precaution, that removes its support-access keys from cPGuard servers where they were added earlier.

Support access is a cPGuard feature customers use to let OPSSHIELD staff into a server for troubleshooting. Granting it adds an SSH public key belonging to OPSSHIELD to the authorized_keys file for root, according to the company's documentation.

OPSSHIELD has not said whether the private key that matches its support-access key was exposed in the attack.

Files and Indicators to Check

OPSSHIELD published these indicators. Updates remove the backdoor shell, the collection directory and the scheduled task, so their absence after updating proves nothing about whether the script ran.

  • File: cpguard-v58812-i91511.sh and variants ending in b, c and d (the malicious script)
  • SHA-256: 2c2acd988da531d133d0e17f245c49bf15781278f837543d18c95e8410eabd38 (cpguard-v58812-i91511.sh)
  • SHA-256: ffd7a47f65fa1244429baa936ae94be54676b53d2f88bc39564f24e22011de8a (cpguard-v58812-i91511b.sh)
  • SHA-256: d73919af84bf46de941db85e27fd1abc65701ef9ce6cf33bb27c5397f4a41c26 (cpguard-v58812-i91511c.sh)
  • SHA-256: 6add0201e9a3d02de772d561d05e0da86eb1c538686753b7adcc3aedf7366f77 (cpguard-v58812-i91511d.sh)
  • File: /var/tmp/.cpg91511_sh (backdoor, a hidden setuid-root shell)
  • File: /etc/cron.d/i93677 (scheduled task left by the script)
  • Directory: /var/tmp/.i93677/ (files for the scheduled task)
  • Directory: /var/tmp/.cpg91511 (where the script gathered files)
  • File: /var/tmp/.cpg91511/loot.tgz (archive the script prepared)
  • IP: 94.183.188[.]91 (main address the attacker operated from, according to OPSSHIELD)

Update: Attacker Got In Through a Fake Customer Account

OPSSHIELD's later disclosure, posted on November 3, says the attacker registered a customer account under a false identity on November 1 and ordered a free cPGuard trial. The attacker then sent crafted requests to callback pages on the company's billing portal and, at 22:58 UTC, gained the ability to run commands on its billing and licensing server.

The attacker took the key used to publish updates and uploaded the malicious script to cPGuard's update system between 02:04 and 02:09 UTC on November 2. OPSSHIELD's logs do not record the exact request that gave the attacker access, and the company has patched two possible entry points.

Those billing records include names, company names, postal addresses, email addresses and passwords stored as bcrypt hashes. OPSSHIELD has reset every billing portal session and rotated its billing and reseller API keys.

The company has also revoked the stolen update key and its cloud access keys, and is rebuilding its billing, licensing and internal servers from clean images. It is reissuing all cPGuard license keys because the attacker holds copies of them.

(The story was updated after publication on November 4, 2026, to include OPSSHIELD's later disclosure.)

(Corrected on November 4, 2026: An earlier version said cPGuard 5.88.25 and later versions remove the backdoor and the files the script left. The script also left a scheduled task, which OPSSHIELD says a separate follow-up update removes.)

Found this article interesting? Follow us on Google News, Twitter and LinkedIn to read more exclusive content we post.