TeamPCP’s March 2026 Campaign Chained Trivy Compromise Into Multiple Supply-Chain Attacks

· Original article ↗

Summary

A retrospective traces TeamPCP’s March 2026 supply-chain campaign from retained Trivy credentials into Aqua, npm, LiteLLM, Checkmarx, OpenVSX and Telnyx, detailing credential theft, payloads and defenses.

Key points

  • The report traces the campaign to a February Trivy workflow compromise that exposed a personal access token; incomplete credential rotation allegedly allowed access to persist for 20 days.
  • On March 19, attackers poisoned Trivy releases and GitHub Actions tags, using compromised CI runners to collect secrets and credentials and exfiltrate them.
  • Harvested credentials enabled further compromises across Aqua Security, npm packages, LiteLLM, Checkmarx Actions and OpenVSX extensions, and Telnyx PyPI releases.
  • CanisterWorm spread through npm packages; the report also details malicious LiteLLM and Telnyx versions that stole credentials, with Telnyx payloads delivered in WAV files.
  • A geotargeted payload reportedly wiped systems in Iran, while non-Iranian systems could receive a persistent backdoor. The report says the campaign’s destructive component remains unexplained.
  • The article recommends pinning GitHub Actions to commit SHAs, limiting and rotating credentials, separating CI scanning and publishing permissions, and monitoring runner behavior and outbound traffic.

Article Details

Attack Vectors
  • A pull_request_target workflow executed code from a fork with access to repository secrets; a curl-to-bash payload extracted a Personal Access Token from process memory.
  • Credentials retained after an incomplete rotation were reused to push malicious Trivy tags and workflows and to compromise additional Aqua Security projects.
  • Compromised CI runners exposed npm and PyPI publishing tokens, enabling malicious package releases and propagation to downstream users.
  • Stolen service-account credentials with cross-organization administrative access were used to deface Aqua Security's internal GitHub repositories.
  • Malicious GitHub Actions and OpenVSX extensions harvested CI runner secrets and attempted to exfiltrate them to attacker infrastructure or repositories in victims' own GitHub accounts.
  • Malicious LiteLLM and Telnyx packages executed payloads on import; Telnyx payloads used WAV files to deliver second-stage payloads through audio steganography.
  • A geotargeted payload used Tehran timezone or Iranian locale indicators to select destructive behavior, including Kubernetes DaemonSet deployment and filesystem wiping.
Defensive Notes
  • Audit CI/CD workflows for pull_request_target configurations that run fork code with access to repository secrets.
  • Use short-lived OIDC credentials where possible and revoke credentials atomically across all systems after a compromise.
  • Pin GitHub Actions to full commit SHAs and verify signatures on security-critical workflow commits.
  • Use least-privilege, narrowly scoped service-account and package-publishing credentials; separate CI scanning credentials from deployment credentials.
  • Monitor CI runners for unexpected system calls, outbound connections to newly registered domains or IPs, and suspicious package publications.
  • Monitor for unexpected repository creation and .pth file creation, and inspect Python environments for the reported malicious package versions.
  • Rotate credentials accessible to environments where the affected packages or actions ran; users were advised to downgrade Telnyx to 4.87.0.

Indicators of compromise

TypeIndicatorContext
DOMAINcheckmarx[.]zoneC2 and second-stage payload domain used in the Checkmarx phase.
DOMAINmodels[.]litellm[.]cloudListed in the article as a C2 domain for exfiltration during the LiteLLM phase.
DOMAINplug-tab-protective-relay[.]trycloudflare[.]comCloudflare Tunnel subdomain used as an additional exfiltration C2 during the Trivy phase.
DOMAINrecv[.]hackmoltrepeat[.]comExfiltration destination for the Personal Access Token stolen during the Trivy pull request workflow attack.
DOMAINscan[.]aquasecurtiy[.]orgTyposquatted exfiltration domain used to receive stolen data from compromised CI runners.
DOMAINtdtqy-oyaaa-aaaae-af2dq-cai[.]raw[.]icp0[.]ioICP Canister dead-drop hostname used for CanisterWorm C2 and dynamic payload delivery.
IPV445[.]148[.]10[.]212IP address listed as C2 infrastructure for the Trivy campaign.
IPV483[.]142[.]209[.]203C2 and exfiltration endpoint used by the malicious Telnyx package to deliver WAV payloads and receive stolen data.

MITRE ATT&CK

T1005 · Data from Local SystemThe stealer collected SSH keys, cloud credentials, Kubernetes tokens, configuration files, and cryptocurrency wallets from CI runners and developer machines.T1021.004 · SSHLater versions of the Iran-targeted payload added SSH propagation.T1041 · Exfiltration Over C2 ChannelStolen data was encrypted and exfiltrated as tpcp.tar.gz to campaign C2 endpoints.T1057 · Process DiscoveryThe Trivy payload located Runner.Worker processes before scraping their memory for secrets.T1059.004 · Unix ShellThe February workflow attack used a curl-to-bash payload, and the Iran-targeted payload used shell commands to wipe files.T1059.006 · PythonPython backdoors and payloads were installed or executed, including sysmon.py and the CanisterWorm service script.T1059.007 · JavaScriptA Node.js postinstall loader in compromised npm packages decoded and launched a Python payload.T1105 · Ingress Tool TransferCompromised Checkmarx extensions fetched a second-stage payload, and Telnyx packages downloaded WAV files containing payloads.T1195.001 · Compromise Software Dependencies and Development ToolsAttackers compromised Trivy, GitHub Actions, OpenVSX extensions, and PyPI packages to deliver malicious code through software supply chains.T1485 · Data DestructionThe Iran-targeted payload forcibly wiped filesystems and rebooted affected hosts.T1543.002 · Systemd ServiceCanisterWorm installed a persistent systemd user service named pgmon.service.T1547.001 · Registry Run Keys / Startup FolderThe Windows Telnyx payload dropped msbuild.exe into the Startup folder for persistence across reboots.T1552.001 · Credentials In FilesMalware harvested credentials and secrets from CI environments, including environment variables, .env files, shell history, and Docker configuration.T1567.001 · Exfiltration to Code RepositoryWhen direct exfiltration failed, malware created repositories in victims' GitHub accounts and uploaded stolen data as release assets.T1610 · Deploy ContainerOn targeted Kubernetes clusters, the payload deployed a privileged DaemonSet across nodes, including the control plane.

People

Threat Actors

Malware

Vendors

Products

Tools

Countries

Industries

Related Articles