Trivy Supply Chain Attack Explained: 75 Versions Poisoned
Imagine you hire a security guard to check everyone entering your building. You trust the guard completely — they've been working for you for years. One day, someone replaces your guard with an impersonator wearing the same uniform. The impersonator does the job perfectly, checking IDs just like the real guard would. But while they're checking, they're also photographing every key, password, and access card they see — and sending those photos to their employer.
That is exactly what happened on March 19, 2026, to one of the most trusted tools in software development.
- Target: Trivy — a widely used open-source security scanner made by Aqua Security
- Attack date: March 19, 2026 — active exploitation window approximately 19:00 UTC onwards
- Attacker: TeamPCP (also tracked as DeadCatx3, ShellForce, CipherForce) — cloud-native cybercrime group
- Method: Stolen credentials used to replace 75 out of 76 versions of Trivy with malware-infected copies
- What was stolen: AWS/Azure/GCP cloud keys, SSH keys, GitHub tokens, database passwords, Kubernetes credentials, crypto wallets
- Who is affected: Any developer or organisation that ran Trivy between March 19–21, 2026
- How to check if you were hit: Look for a repository named
tpcp-docsin your GitHub account - Safe versions: Trivy v0.69.3, trivy-action v0.35.0, setup-trivy v0.2.6
- C2 domain to block: scan.aquasecurtiy[.]org (note the typo — missing an 'i') / IP: 45.148.10.212
- This was the second attack on Trivy in March 2026 — the first occurred on March 1
What Is Trivy — And Why It Was the Perfect Target
Trivy is a free, open-source tool that developers use to scan their code and software for known security problems before releasing it to customers. Think of it as a quality control inspector that runs automatically every time a developer submits new code.
Because Trivy's job is to inspect everything, it gets given complete access to a company's software production line — the automated system that takes developers' code and turns it into finished products. This system, called a CI/CD pipeline, is where all the sensitive credentials live: the passwords for cloud accounts, the keys for databases, the tokens that give access to deployment servers.
Trivy is trusted by thousands of organisations globally — including banks, technology companies, and government agencies. That trust made it the perfect target. Compromising Trivy didn't mean attacking one company. It meant attacking every company that used Trivy, all at once, through a tool they believed was protecting them.
Root Cause — The Key That Was Never Changed
This attack didn't start on March 19. It started weeks earlier.
On March 1, 2026, an autonomous AI-powered attack bot called hackerbot-claw broke into Trivy's GitHub repository — the online location where Trivy's code is stored and distributed — and stole a master key. The bot exploited a misconfiguration in how Trivy handled public contributions, a flaw that gave external requests access to internal secrets. This is part of a documented 2026 trend of AI-driven automated repository takeovers — bots that scan thousands of open-source projects simultaneously, identify misconfigurations, and exploit them faster than any human team could detect. In software terms, this key is called a Personal Access Token — a credential that gives whoever holds it the ability to publish new versions of software, modify existing versions, and manage the entire distribution system.
Aqua Security detected the March 1 breach and began cleaning up. They changed some passwords and rotated some credentials. But they missed one. The master key was still valid.
Three weeks later, TeamPCP used that same key to walk back in — this time with a very different plan. Not destruction. Not noise. Silence, and theft.
Aqua Security confirmed it themselves: "Our containment of the first incident was incomplete. We rotated secrets and tokens, but the process wasn't atomic and attackers may have been privy to refreshed tokens." One missed credential. Three weeks of open access. That's the gap that caused this attack.
How The Attack Actually Worked — Step By Step
Step 1 — Poisoning the version history
GitHub allows software to be labeled with version numbers — like v0.28.0 or v0.33.0 — so that when a developer's system asks for "Trivy version 0.28.0", it gets exactly that specific version. These labels are called tags.
Using the stolen master key, TeamPCP silently went back through Trivy's entire version history and replaced 75 out of 76 tags to point to their malicious version instead of the real one. They did this without creating any new releases or making any public announcements — so nothing looked unusual from the outside.
The result: any developer asking for any of those 75 versions was now receiving malware. Even developers who thought they were using an old, safe, tested version of Trivy were getting the poisoned copy. The version number said one thing. The software delivered was something completely different.
The forensic tell — how researchers caught it
The poisoned versions were designed to blend into Trivy's five-year history. The attackers backdated their malicious commits to look like they were from 2021 and 2022 — old, trusted, long-established versions of the software. But they made one mistake that made the forgery obvious to anyone who looked closely.
In software, every commit has a parent — the previous version it was built on top of. The parent must always be older than the child. But the backdated "2021" commits had parent commits dated March 2026. A 2021 version cannot have a 2026 parent. The timeline was physically impossible. It was like finding a letter dated 1995 that references events from 2026.
The second tell: in real Trivy commits, changes typically touch multiple files simultaneously. In every poisoned version, only one file was modified — entrypoint.sh. The attackers kept their footprint minimal to reduce the chance of detection, but that minimalism itself became the pattern that flagged them.
Step 2 — The impersonator at work
When the poisoned Trivy ran on a developer's system, it did two things simultaneously. It ran the real Trivy scan — producing normal, expected results so the developer saw nothing wrong. And in parallel, it ran a hidden credential theft program called the TeamPCP Cloud Stealer.
The stealer worked in three stages. First, it searched the system's memory and file storage across more than 50 specific locations, looking for anything valuable: AWS, Azure, and Google Cloud credentials, SSH keys used for server access, GitHub tokens, database connection strings, Kubernetes cluster access tokens, Docker configuration files, and cryptocurrency wallet keys.
Second, it encrypted everything it found using AES-256 and RSA-4096 — the same encryption standards used by banks — so that even if the data was intercepted in transit, it would be unreadable.
Third, it sent the encrypted package to TeamPCP's server at a domain designed to look legitimate: scan.aquasecurtiy[.]org — note the deliberate typo, missing an 'i' from 'security'. A quick glance and it looks like an Aqua Security domain.
Step 3 — The backup plan
If the main theft server was unreachable, the malware had a fallback. It used the developer's own GitHub credentials — already stolen from the system — to create a public repository named tpcp-docs in the victim's own GitHub account, then uploaded the stolen data there as a file attachment.
The attacker's stolen data was stored in the victim's own account, hidden in plain sight, waiting to be retrieved.
Step 4 — Persistence on developer machines
The malware was intelligent enough to know where it was running. Automated CI/CD servers are temporary — they spin up, run a job, and are deleted. Installing a persistent back door on them is pointless. But a developer's personal laptop is permanent.
The stealer specifically checked whether it was on a developer's local machine rather than a temporary server. If it detected a local environment — which many developers use when testing pipelines locally before pushing to the official system — it installed a hidden program called sysmon.py that registered itself as a background service starting automatically at boot. TeamPCP could then return to that machine at any time, even weeks after the original breach was discovered and cleaned up. Every developer who ran Trivy locally during the attack window should check their machine for this implant.
MITRE ATT&CK Mapping
| Tactic | Technique ID | Technique Name | How It Applies |
|---|---|---|---|
| Initial Access | T1195.002 | Supply Chain Compromise: Software Supply Chain | Stolen credential used to replace legitimate Trivy versions with malware-infected copies |
| Credential Access | T1552.001 | Credentials in Files | Stealer swept 50+ filesystem paths for SSH keys, cloud credentials, tokens, wallet keys |
| Credential Access | T1082 | System Information Discovery | Environment variables scraped from CI/CD runner memory for cloud provider credentials |
| Exfiltration | T1567.001 | Exfiltration to Code Repository | Backup exfil used victim's own GitHub token to create tpcp-docs repo and upload stolen data |
| Persistence | T1053.006 | Scheduled Task: Systemd Timer | sysmon.py installed as a systemd service on developer machines for persistent re-access |
| Defense Evasion | T1036 | Masquerading | Malware ran real Trivy scan in parallel — workflow output appeared completely normal |
Indicators of Compromise (IOCs)
# Trivy TeamPCP Supply Chain Attack — Detection Indicators
# Immediate checks — do these now
Check: Any repository named 'tpcp-docs' in your GitHub account
→ If present: you were breached. Treat all credentials as stolen.
Check: GitHub Actions workflow runs between March 19–21, 2026
→ Any run using aquasecurity/trivy-action or aquasecurity/setup-trivy
by version tag (not commit SHA) = treat as compromised
# Network indicators — block at firewall
Domain: scan.aquasecurtiy[.]org
(typosquat — 'aquasecurity' becomes 'aquasecurtiy' — the 'i' is missing before the 't')
Legitimate domain is aquasecurity.github.io — these are completely different
IP: 45.148.10.212
Any outbound HTTPS traffic to this domain or IP from CI/CD runners
# File system indicators on developer machines
File: sysmon.py anywhere in home directory or /tmp
Systemd service: any newly created service running sysmon.py
Process: python3 executing sysmon.py polling an external server
# Stolen artifact targets — what the stealer specifically hunted
AWS/Azure/GCP credentials and access keys
GitHub personal access tokens and OAuth tokens
SSH private keys (.ssh/id_rsa, id_ed25519, etc.)
Kubernetes cluster config files (~/.kube/config)
Docker daemon authentication files
Database connection strings and passwords
Solana validator key pairs (hallmark of TeamPCP financial motivation)
Crypto wallet private keys and seed phrases
Any .env files containing API keys or secrets
# Malicious versions — do not use
Trivy binary: v0.69.4 (malicious) — use v0.69.3 instead
trivy-action: any tag except v0.35.0 was poisoned during attack window
setup-trivy: any tag except v0.2.6 was poisoned during attack window
# Commit to check in trivy-action repository
Malicious commit SHA: 8afa9b9 (contains credential stealer in action.yaml)
Spoofed author metadata — do not trust commit author names or dates
What To Do Right Now
If you ran Trivy between March 19–21, 2026: Assume every credential your CI/CD pipeline had access to was stolen. Rotate all of them immediately — AWS keys, GitHub tokens, database passwords, Azure service principals, SSH keys, Kubernetes tokens. Do not wait to confirm. Rotate first, investigate second.
Check your GitHub account: Log into GitHub and look at your repositories. If you see one named tpcp-docs that you didn't create, your data was exfiltrated through your own account. Delete it and escalate to incident response immediately.
Update to safe versions: Trivy v0.69.3, trivy-action v0.35.0, setup-trivy v0.2.6. If you have sysmon.py on any developer machine, delete it and check for associated systemd services.
The permanent fix — stop using version tags: This attack worked because version tags like @v0.28.0 can be silently redirected to point at different code. The solution is to reference software by its unique code fingerprint instead — a long string called a commit SHA that cannot be faked or redirected. A tag is a name that can be moved. A SHA is a fingerprint that is fixed forever.
This attack follows the same pattern as the broader supply chain threats we've been tracking. Attackers compromising the tools that build and protect software — then riding those tools into every organisation that trusts them:
→ The Stryker Cyberattack: How Iran-Linked Hackers Turned a Medical Giant's Own Tools Against It
→ The Ghost Attack: How Hackers Are Stealing Indian Fintech Sessions After MFA Already Passed
The ZyberWalls Perspective
We always say update your software. This time, the update was the attack.
That sentence captures why supply chain attacks are so difficult to defend against. Every security instinct — trust the official source, use the named version, keep tools up to date — was used against the victim. The developers who got hit didn't make a mistake. They followed best practices. The best practices just assumed that the official source could be trusted.
The real lesson is about how trust is extended in software. A version tag like v0.28.0 feels like a fixed, specific thing — like a serial number. But it isn't. It's a label that can be moved. The actual fingerprint of a piece of software is its commit SHA. That cannot be faked. That cannot be moved. If your automated pipelines reference software by name, an attacker who controls the naming system controls what you receive.
Aqua Security's incomplete containment of the March 1 breach is the other lesson. One credential was not rotated. That one credential gave attackers three weeks of silent access. Incident response is not finished when the obvious damage is cleaned up. It is finished when every credential that could have been seen, copied, or remembered by the attacker has been replaced.
Stay Alert. Stay Human. Stay Safe.— ZyberWalls Research Team
