The Trivy vulnerability scanner suffered a supply-chain attack when threat actors known as TeamPCP compromised it and distributed credential-stealing malware through official releases and GitHub Actions.
Notably, Trivy functions as a widely used security scanner that helps teams identify vulnerabilities, misconfigurations, and exposed secrets across containers, Kubernetes environments, code repositories, and cloud infrastructure. Because developers and security teams rely on it heavily, attackers view it as a high-value target for stealing authentication secrets.
Initially, security researcher Paul McCarty disclosed the breach and warned that Trivy version 0.69.4 contained a backdoor, with malicious container images and GitHub releases published to users.
GitHub Actions and Build Pipeline Compromised
Subsequently, further analysis by Socket and later by Wiz revealed that the attack impacted multiple GitHub Actions, compromising nearly all version tags of the trivy-action repository.
Moreover, researchers discovered that threat actors compromised Trivy’s GitHub build process, replaced the entrypoint.sh in GitHub Actions with a malicious version, and published trojanized binaries in the Trivy v0.69.4 release. Both components acted as infostealers across the main scanner and related GitHub Actions, including trivy-action and setup-trivy.
At the same time, attackers abused a compromised credential with write access to the repository, which allowed them to publish malicious releases. These credentials originated from an earlier March breach, during which attackers exfiltrated credentials from Trivy’s environment and defenders failed to fully contain the incident.
In addition, the threat actor force-pushed 75 out of 76 tags in the aquasecurity/trivy-action repository, redirecting them to malicious commits.
As a result, any external workflows using the affected tags automatically executed the malicious code before running legitimate Trivy scans, which made detection significantly more difficult.
Extensive Credential Harvesting Activity
According to Socket, the infostealer collected reconnaissance data and scanned systems for files and locations that commonly store credentials and authentication secrets, including:
- Reconnaissance data: hostname, whoami, uname, network configuration, and environment variables
- SSH: private and public keys and related configuration files
- Cloud and infrastructure configs: Git, AWS, GCP, Azure, Kubernetes, and Docker credentials
- Environment files: .env and related variants
- Database credentials: configuration files for PostgreSQL, MySQL/MariaDB, MongoDB, and Redis
- Credential files: including package manager and Vault-related authentication tokens
- CI/CD configurations: Terraform, Jenkins, GitLab CI, and similar files
- TLS private keys
- VPN configurations
- Webhooks: Slack and Discord tokens
- Shell history files
- System files: /etc/passwd, /etc/shadow, and authentication logs
- Cryptocurrency wallets
Infostealer harvesting credentials, SSH keys, and environment files
Source: BleepingComputer
Furthermore, the malicious script scanned memory regions used by the GitHub Actions Runner.Worker process for the JSON string ” " <name> ":{ "value": "<secret>", "isSecret":true}" to locate additional authentication secrets.
Data Exfiltration and Persistence Mechanisms
On developer machines, the trojanized Trivy binary executed similar data collection, gathering environment variables, scanning local files for credentials, and enumerating network interfaces.
Afterward, the malware encrypted the collected data, stored it in an archive named tpcp.tar.gz, and exfiltrated it to a Typosquatted Command-and-control server at scan.aquasecurtiy[.]org.
If exfiltration failed, the malware created a public repository named tpcp-docs within the victim’s GitHub account and Uploaded the stolen data there.
To maintain persistence, the malware dropped a Python payload at ~/.config/systemd/user/sysmon.py and registered it as a systemd service. This payload then checked a remote server for additional payloads, giving the threat actor persistent access.
Investigators linked the attack to the threat actor TeamPCP, as one Infostealer payload Included a “TeamPCP Cloud stealer” comment in the Python script.
“The malware self-identifies as TeamPCP Cloud stealer in a Python comment on the final line of the embedded filesystem credential harvester. TeamPCP, also tracked as DeadCatx3, PCPcat, and ShellForce, is a documented cloud-native threat actor known for exploiting misconfigured Docker APIs, Kubernetes clusters, Ray dashboards, and Redis servers,” explains Socket.
Comment showing the script was named TeamPCP Cloud Stealer
Source: BleepingComputer
Aqua Security Response and Timeline
Aqua Security confirmed the incident and stated that a threat actor used Compromised Credentials from the earlier breach that defenders did not fully contain.
“This was a follow up from the recent incident (2026-03-01) which exfiltrated credentials. Our containment of the first incident was incomplete,” explained Aqua Security.
“We rotated secrets and tokens, but the process wasn’t atomic and attackers may have been privy to refreshed tokens.”
The Malicious Trivy release (v0.69.4) remained live for approximately three hours, while Compromised GitHub Actions tags stayed active for up to 12 hours.
Additionally, Attackers Tampered with the Project’s Repository and deleted Aqua Security’s initial disclosure of the earlier March incident.
Therefore, organizations that used affected versions during the incident should treat their environments as fully Compromised.
This includes Rotating all secrets, such as cloud Credentials, SSH keys, API tokens, and database Passwords, and thoroughly Analyzing systems for further compromise.
Meanwhile, researchers at Aikido linked the same threat actor to a Follow-up campaign Involving a Self-propagating worm named “CanisterWorm,” which targets npm packages.
The worm Compromises packages, installs a Persistent Backdoor via a systemd user service, and then uses stolen npm tokens to publish Malicious updates to other packages.
“Self-propagating worm. deploy.js takes npm tokens, resolves usernames, enumerates all publishable packages, bumps patch versions, and publishes the payload across the entire scope. 28 packages in under 60 seconds,” highlights Aikido.
Advanced Command-and-Control Techniques
Notably, the malware uses a Decentralized Command-and-control (C2) mechanism based on Internet Computer (ICP) Canisters, which act as a Dead-drop Resolver that provides URLs for additional Payloads.
Because of this design, the operation becomes more Resistant to Takedown, as only the Canister’s Controller can remove it, and stopping it would require a Governance proposal and network vote.
Finally, the worm includes Functionality to harvest npm Authentication tokens from Configuration files and environment variables, Enabling it to spread across developer environments and CI/CD pipelines.
At the time of analysis, some secondary payload infrastructure remained Inactive or contained Harmless content; however, researchers warn that this situation could change at any time.
Source: BleepingComputer, Lawrence Abrams
Read more at Impreza News
























