By falco365 · Published April 30, 2026

Team PCP: tracking a six-week supply-chain campaign through Trivy, Checkmarx, Bitwarden, and beyond

A self-spreading credential-theft campaign that has chained through six security-tooling vendors since March 2026. Patterns, IOCs, and detection guidance.

Team PCP: tracking a six-week supply-chain campaign through Trivy, Checkmarx, Bitwarden, and beyond
Analysis

Since March 20, 2026, a credential-theft operation tracked under the campaign name Team PCP has chained through six security-tooling vendors and at least nine published packages across npm, PyPI, Docker Hub, OpenVSX, and the GitHub Actions marketplace. Each compromise feeds the next: stolen CI/CD credentials are used to publish trojanized versions of downstream packages, whose installations in turn yield more credentials. The campaign's distinguishing feature is its meta-targeting — the victims are mostly the security industry's own supply-chain scanning tools (Trivy, Checkmarx KICS, Aqua Security's GitHub org, Bitwarden's release pipeline). The operator infrastructure has self-named a worm component "CanisterWorm" and uses Cloudflare Tunnel and Internet Computer Protocol canisters as fallback C2 channels. This piece consolidates the public reporting from Wiz, Socket, StepSecurity, Aikido, Sysdig, JFrog, and Open Source Malware into one campaign timeline and one detection playbook.

What we know

The campaign's confirmed timeline, in chronological order:

  • March 20, 2026aquasecurity/trivy-action, aquasecurity/setup-trivy, and a malicious Trivy v0.69.4 release. Many existing tags force-updated to malicious commits. Per StepSecurity, credential-stealing logic injected into action.yaml at commit 8afa9b9; clean tag is v0.2.6 aligned with 3fb12ec. Exfiltration to scan.aquasecurtiy[.]org (typosquat of aquasecurity.org).
  • March 23, 2026 — Aqua Security's internal GitHub org defaced. CanisterWorm propagates via stolen tokens. C2 domain rotation begins. Open Source Malware and Aikido publish IOC sets.
  • March 23, 2026 (12:58–16:50 UTC) — Checkmarx kics-github-action compromised via imposter commits and tag hijacking. New C2: checkmarx[.]zone. Kubernetes-oriented persistence added. Wiz attributes to Team PCP based on overlapping TTPs and infrastructure.
  • March 23, 2026ast-github-action tag 2.3.28 observed malicious (Sysdig). OpenVSX ast-results 2.53.0 and cx-dev-assist 1.7.0 published via the ast-phoenix account on Open VSX. VS Code Marketplace versions described as unaffected.
  • March 24, 2026litellm on PyPI (versions 1.82.7 and 1.82.8). The vector cited is the compromised Trivy GitHub Action stealing PyPI publishing credentials from litellm's CI/CD pipeline. Malicious litellm_init.pth file means execution at Python interpreter startup, no explicit import required.
  • April 22, 2026xinference on PyPI (versions 2.6.0, 2.6.1, 2.6.2). JFrog identifies the marker string # hacked by teampcp in decoded payload. Exfiltration to whereisitat[.]lucyatemysuperbox[.]space.
  • April 22, 2026 — Checkmarx KICS Docker images at checkmarx/kics trojanized; tags v2.1.20, v2.1.20-debian, debian, alpine, latest overwritten; fake v2.1.21 tag published. Checkmarx VS Code and OpenVSX extensions cx-dev-assist 1.17.0/1.19.0 and ast-results 2.63.0/2.66.0 published with hidden MCP-addon feature that downloads mcpAddon.js from a backdated orphaned commit (68ed490b) inside the legitimate Checkmarx/ast-vscode-extension repository.
  • April 22, 2026 (5:57 PM – 7:30 PM ET)@bitwarden/cli@2026.4.0 published to npm with bundled bw1.js second-stage payload. Bitwarden confirms abuse of a GitHub Action in its CI/CD pipeline; package pulled within roughly 90 minutes of detection. Bitwarden's public statement reports no end-user vault data accessed.
The campaign is reflexive: the tools that scan supply chains for compromise are themselves the supply-chain compromises. Trivy → Aqua's GitHub org → Checkmarx's KICS → Bitwarden's release pipeline. Each victim was a vendor whose product is supposed to detect this kind of attack.
Targeting
  • Security tooling vendors — disproportionate selection. Trivy (Aqua Security), Checkmarx KICS, Bitwarden's release infrastructure. The pattern compromises the vendor whose CI/CD pipeline has the credentials to publish artifacts that downstream defenders will install and trust.
  • CI/CD pipelines using affected GitHub Actions — pinning by version tag rather than by SHA exposed many victims, since tag force-updates pointed existing references at malicious commits.
  • Developer workstations — broad credential collection on non-CI hosts, with systemd-user persistence on Linux (per Wiz, polling https://checkmarx[.]zone/raw).
  • Kubernetes environments — provisioner-style persistence using pod names host-provisioner-std and host-provisioner-iran, container names provisioner and kamikaze.
TTPs and infrastructure
  • Initial access — credential theft from compromised CI/CD runners running affected GitHub Actions, then re-use of those credentials to publish trojanized versions of downstream packages. Self-spreading through the chain.
  • Execution — multiple delivery mechanisms across the campaign: GitHub Actions action.yaml injection, malicious setup.sh in imposter commits, preinstall hooks in npm packages, __init__.py and .pth files on PyPI, hidden "MCP addon" features in VS Code and OpenVSX extensions that fetch second stages via Bun runtime.
  • Persistence — systemd user units polling C2 (checkmarx[.]zone/raw); Kubernetes provisioner pods.
  • Defense evasion — backdated orphaned commits referenced by hardcoded URL but not visible in active branch history; __decodeScrambled obfuscation with seed 0x3039; Bun runtime as second stage to bypass Node-focused static analysis (shared TTP with the Mini Shai-Hulud cluster — see the Bun-runtime supply-chain analysis).
  • Command and control — tiered. Primary C2 at custom domains: scan.aquasecurtiy[.]org (Trivy phase), checkmarx[.]zone (KICS / extensions phase), audit.checkmarx[.]cx/v1/telemetry (Checkmarx Docker / Bitwarden phase). Fallback to Cloudflare Tunnel domains (*.trycloudflare[.]com) and an Internet Computer canister (tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0[.]io). When direct C2 is disrupted, the worm creates public repositories (tpcp-docs, docs-tpcp) on victims' GitHub accounts using GITHUB_TOKEN and uploads stolen material as release assets.
  • Lateral movement — CanisterWorm: stolen credentials from one victim used to publish trojanized versions of downstream packages, whose installations on new victims yield more credentials.
Indicators of compromise

Consolidated from Wiz, Socket, StepSecurity, Aikido, Sysdig, JFrog, and Datadog Security Research:

Network — C2 infrastructure:

  • scan.aquasecurtiy[.]org — Trivy phase typosquat (note transposed i and t)
  • aquasecurtiy[.]org — base typosquat
  • checkmarx[.]zone — KICS / extensions phase
  • audit.checkmarx[.]cx/v1/telemetry — Checkmarx Docker / Bitwarden phase
  • whereisitat[.]lucyatemysuperbox[.]space — Xinference phase
  • tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0[.]io — ICP canister fallback
  • championships-peoples-point-cassette.trycloudflare[.]com — Cloudflare tunnel
  • investigation-launches-hearings-copying.trycloudflare[.]com — Cloudflare tunnel
  • souls-entire-defined-routes.trycloudflare[.]com — Cloudflare tunnel
  • 83.142.209.11 — direct IP (KICS phase)

Filesystem and behavioral artifacts:

  • /tmp/pglog — CanisterWorm payload drop path
  • Pod names containing host-provisioner-std or host-provisioner-iran
  • Container names kamikaze or provisioner
  • Public GitHub repositories named tpcp-docs or docs-tpcp on victim accounts, with stolen material as release assets
  • Marker string # hacked by teampcp in decoded payloads

VirusTotal hash (Trivy phase): 18a24f83e807479438dcab7a1804c51a00dafc1d526698a66e0640d1e5dd671a

Xinference SHA-256s (JFrog):

  • xinference/__init__.pye1e007ce4eab7774785617179d1c01a9381ae83abfd431aae8dba6f82d3ac127
  • Decoded stage 1 — 077d49fa708f498969d7cdffe701eb64675baaa4968ded9bd97a4936dd56c21c
  • Decoded stage 2 — fe17e2ea4012d07d90ecb7793c1b0593a6138d25a9393192263e751660ec3cd0

GitHub identities used to publish malicious tags:

  • cx-plugins-releases (account ID 225848595) — KICS phase
  • ast-phoenix — OpenVSX extensions
Detection and mitigation

For environments that may have run any affected version, treat compromise as the working hypothesis until proven otherwise. The campaign harvests broadly and exfiltrates immediately.

  • Pin GitHub Actions by SHA, not by version tag. The Trivy and KICS compromises both relied on tag force-update — workflows that pinned to @v3 or similar received the malicious commit when the tag moved. SHA pinning is the structural fix that survives tag-hijack.
  • Audit GitHub audit logs for unusual create/delete branch sequences from service accounts (TeamPCP rapidly created and deleted branches to test stolen tokens), unfamiliar repository creation, and any commits to tpcp-docs or docs-tpcp repositories.
  • Block egress to the listed C2 domains at the network perimeter and on agent hosts. The Cloudflare Tunnel and ICP-canister fallbacks are harder to block without breaking legitimate traffic, but the primary domains and the typosquat are clean blocks.
  • Hunt for the systemd user-unit persistence on Linux developer hosts and CI workers that touched any affected version: any user-unit polling checkmarx[.]zone/raw is the persistence mechanism.
  • Rotate everything reachable from any host that ran an affected version: GitHub PATs, npm publish tokens, AWS / Azure / GCP credentials, Kubernetes service account tokens, SSH keys, signing material, secrets in non-sensitive environment variables. The malware enumerates broadly; assume everything is exfiltrated.
  • Ban Bun fetches from CI runners that don't legitimately use Bun. Outbound to github.com/oven-sh/bun/releases from a runner mid-install is a strong adversary signal across the Bun-runtime variant of the payload.
  • Treat security tooling like any other supply chain. The same review hygiene that protects against generic npm/PyPI compromise — lockfile pinning, --ignore-scripts by default, signed releases, provenance attestation — applies to the security industry's own tools.
Attribution discipline

"Team PCP" is a tracking name applied independently by Wiz, Sysdig, Aikido, Open Source Malware, and Datadog Security Research based on overlapping TTPs and infrastructure across the campaign chain. The marker string # hacked by teampcp appears in payloads, and the campaign's worm component self-labels as CanisterWorm. Third-party reporting has associated related activity with the aliases DeadCatx3, PCPcat, ShellForce, and CanisterWorm; these are self-applied labels in payload material and onion-site claims, not independent confirmation of actor identity. The Mini Shai-Hulud npm cluster of April 29-30 (Lightning PyPI + SAP CAP npm packages) shows tooling overlap; whether it's the same operator is consistent with available reporting but not confirmed.

We use the campaign codename Team PCP throughout this writeup. We do not claim hard attribution to a specific country, group, or named individual. Defenders can act on the IOCs and TTPs without needing attribution to be settled.

What this signals for 2026

Three durable observations from the chain so far:

  • Self-spreading credential theft scales. The CanisterWorm pattern — stolen credentials used to publish trojanized downstream packages — converts each successful compromise into multiple new victims without operator effort. As long as security tooling pipelines hold publishing credentials with broad scope, this pattern continues.
  • Security tooling is high-value target. Six weeks of repeated targeting against Trivy, Checkmarx, and Bitwarden is not coincidence. The vendors whose products defenders trust to detect supply-chain compromise are the highest-leverage victims. Treat your scanner-vendor's release pipeline with the same rigor you'd apply to any production supply chain.
  • Tag pinning is over. GitHub Action consumers who pin by version tag get whatever the maintainer (or the maintainer's compromised account) currently points the tag at. Two separate vendors got force-updated within five weeks. SHA pinning is the structural answer; allowlisted action versions in policy-as-code is the second-best.

The closest peer pattern in the recent CVE record is CVE-2026-12091 — npm maintainer-account takeover with postinstall credential theft. Same shape, different vector. The time-to-criminalization framework applied to that CVE shows what to expect from this class of bug: the implant work is already done, so commoditization happens on the order of days rather than months. Patch and rotate accordingly.

Final observation on the threat-intelligence shape. Despite Team PCP's loud operational footprint — six weeks of researcher coverage, public IOCs in widely-shared formats, named C2 domains — the campaign has no measurable presence in commodity criminal markets. There's no broker pricing for the worm, no exploit-kit packaging of the GitHub Actions injection technique, no forum trade volume. That isn't a sensor failure. It's the campaign's actual shape: Team PCP is the operator, not a vendor selling capability. The credentials they exfiltrate may eventually appear in stealer-log markets, but the attack itself doesn't commoditize. Same telemetry-surface lesson as the AI-IDE marketplace surface: monitor the legitimate channel where the attack actually lives — package registries, GitHub Actions tag history, OAuth grants — not .onion forums where it doesn't.