TeamPCP executed a cascading 2026 open-source supply chain campaign that compromised trusted security tools and package ecosystems (Trivy, Checkmarx, LiteLLM, Telnyx, 66+ npm packages, PyPI, OpenVSX), resulting in roughly 500,000 stolen credentials and over 300 GB of exfiltrated data including a breach of the European Commission’s AWS environment. The group introduced novel techniques—including ICP-based C2 and a self-propagating npm worm (CanisterWorm)—and weaponized CI/CD scanners and runner environments to harvest secrets and propagate across GitHub Actions, Docker Hub, npm, PyPI, and OpenVSX. #TeamPCP #Trivy
Keypoints
- TeamPCP converted trusted CI/CD tooling (notably Aqua Security’s Trivy) into a malware distribution channel by injecting malicious build logic and poisoned releases that propagated through GitHub Releases, Docker Hub, AWS ECR, and GitHub Container Registry.
- The campaign harvested secrets from GitHub Actions runners by scraping process memory and filesystem paths, bundling data into an encrypted tpcp.tar.gz for exfiltration, enabling widespread credential reuse across vendor ecosystems.
- CanisterWorm and stolen publish tokens enabled rapid propagation across npm and PyPI, with automated package updates (28 npm packages in under 60 seconds) and compromised PyPI releases (litellm, Telnyx SDK) using WAV steganography for payload delivery.
- TeamPCP introduced ICP blockchain canisters as fallback C2 and used Cloudflare Tunnel typosquatted domains for primary exfiltration, with fallback tactics that uploaded encrypted archives to victim-owned GitHub repos to evade detection.
- Persistence and lateral movement included malicious systemd services, privileged Kubernetes DaemonSets (host-provisioner-std/iran), SSH key harvesting, and targeted destructive wipers on Iranian hosts.
- The operation functioned as an access-generation engine, partnering with other ransomware groups (Vect, CipherForce) to monetize breaches and demonstrating that supply chain compromise can seed multi-group ransomware campaigns.
MITRE Techniques
- [T1195.001 ] Supply Chain Compromise: Software Dependencies – Poisoned Trivy GitHub Actions, npm packages, PyPI (litellm), and OpenVSX extensions (‘Poisoned Trivy GitHub Actions, npm packages, PyPI (litellm), and OpenVSX extensions.’)
- [T1059.004 ] Command and Scripting: Bash/Python – kamikaze.sh served as the bash loader while kube.py and prop.py acted as Python controllers for deployment, propagation, and control (‘kamikaze.sh acts as the bash loader, while kube.py and prop.py serve as Python controllers.’)
- [T1543.002 ] Create/Modify System Process: systemd – Persistent systemd services (pgmon.service, pgmonitor.service, internal-monitor.service) were installed with Restart=always to maintain presence (‘pgmon.service and pgmonitor.service are used with Restart=always on compromised hosts.’)
- [T1610 ] Deploy Container – Privileged Kubernetes DaemonSets (host-provisioner-std, host-provisioner-iran) were deployed in kube-system with hostPath mounts for persistence and broader host access (‘Privileged Kubernetes DaemonSets are deployed in kube-system, including host-provisioner-std and host-provisioner-iran.’)
- [T1027 ] Obfuscated Files / Steganography – Version 3.3 embedded Python payloads as base64 data inside valid WAV audio files to bypass file-type and static analysis checks (‘Version 3.3 embeds Python payloads inside WAV audio files using base64 encoding.’)
- [T1036 ] Masquerading – Imposter commits spoofed trusted contributor identities and PostgreSQL-themed service names were used to blend malicious artifacts into normal system contexts (‘Imposter commits spoof GPG-associated identities, while PostgreSQL-themed service names help blend in.’)
- [T1552 ] Unsecured Credentials in Process Memory – The malicious Actions payload scraped /proc/[pid]/mem and searched runner memory and filesystem paths for secrets and tokens (‘/proc/[pid]/mem scraping targets Runner.Worker, alongside a sweep of 50+ filesystem paths.’)
- [T1560 ] Archive Collected Data – Collected secrets were packaged into tpcp.tar.gz using AES-256-CBC with RSA-4096 key exchange before exfiltration (‘AES-256-CBC and RSA-4096 hybrid encryption is used to package stolen data into tpcp.tar.gz.’)
- [T1567.001 ] Exfiltration to Code Repository – Fallback exfiltration uploaded encrypted archives as release assets to victim-owned GitHub repos (tpcp-docs) using the victim’s GITHUB_TOKEN (‘A fallback mechanism creates a tpcp-docs repository in the victim GitHub org and uploads stolen data as a release asset.’)
- [T1021.004 ] Remote Services: SSH – prop.py harvested ~/.ssh/id_* keys and auth.log entries to enable SSH-based lateral movement across local networks (‘prop.py harvests ~/.ssh/id_* keys and auth.log entries to support SSH-based spread.’)
- [T1485 ] Data Destruction – An Iran-targeted wiper executed destructive rm -rf / operations on Kubernetes and non-Kubernetes Iranian hosts (‘An Iran-targeted wiper executes rm -rf / on Kubernetes nodes and non-Kubernetes Iranian hosts.’)
Indicators of Compromise
- [Domain ] Primary and secondary C2 and delivery domains – scan.aquasecurtiy[.]org (typosquat C2), checkmarx[.]zone (Checkmarx phase C2), and multiple trycloudflare subdomains.
- [IP ] Command-and-control server – 45.148.10.212 (resolves for scan.aquasecurtiy[.]org).
- [ICP Canister ] Internet Computer Protocol fallback C2 – tdtqy-oyaaa-aaaae-af2dq-cai[.]raw[.]icp0[.]io (ICP canister used as alternate C2).
- [Cloudflare Tunnel ] Active Cloudflare Tunnel C2 endpoints – create-sensitivity-grad-sequence[.]trycloudflare[.]com, championships-peoples-point-cassette[.]trycloudflare[.]com (current and prior tunnel hosts).
- [GitHub Commit ] Imposter commits used to spoof contributors – 70379aad1a8b40919ce8b382d3cd7d0315cde1d0, 1885610c6a34811c8296416ae69f568002ef11ec (imposter commits in actions/checkout and aquasecurity/trivy).
- [File Paths ] Runtime and persistence artifacts – /tmp/pglog, /tmp/.pg_state (runtime artifacts), /var/lib/pgmon/pgmon.py (persistent stager path).
- [Systemd ] Persistence service names – pgmon.service, pgmonitor.service, internal-monitor.service (systemd services observed across payloads).
- [Kubernetes ] Malicious DaemonSet names – host-provisioner-std, host-provisioner-iran (privileged DaemonSets deployed in kube-system).
- [GitHub Repo ] Fallback exfiltration repositories and defacement markers – tpcp-docs (any org), repos prefixed tpcp-docs-* (used to upload stolen archives).
- [npm ] Infected package scopes and rapid-publish indicators – @EmilGroup (28 packages), @opengov (16 packages) tied to CanisterWorm propagation (and additional infected scopes such as @teale.io, @airtm).
- [PyPI ] Compromised package releases – litellm==1.82.7, litellm==1.82.8 (malicious PyPI releases and later quarantined versions).
- [VSIX / OpenVSX ] Malicious extension versions – ast-results v2.53.0, cx-dev-assist v1.7.0 (malicious OpenVSX extensions published via compromised accounts).
Read more: https://socradar.io/blog/dark-web-profile-teampcp/