Threat reportSupply ChainTL-2026-0530
TeamPCP @antv Supply Chain Wave — Mini Shai-Hulud Multi-Ecosystem npm/GitHub Actions/VSCode Compromise
Coordinated multi-ecosystem supply chain compromise (May 19, 2026) attributed by Wiz Research to TeamPCP — backdoors 200+ @antv npm packages, the actions-cool/maintain-one-comment and actions-cool/issues-helper GitHub Actions, and nrwl.angular-console v18.95.0 VSCode extension. Multi-stage infection retrieves payloads from orphaned GitHub commits, uses bun to install secondary payloads, harvests GitHub tokens/SSH keys/cloud credentials/browser secrets, and exfiltrates via attacker-created public GitHub repositories (description marker 'niagA oG eW ereH :duluH-iahS').
Key facts for TeamPCP antv supply chain attack
| Identifiers | TL-2026-0530 |
|---|---|
| Also known as | Mini Shai-Hulud, TeamPCP @antv Wave, Shai-Hulud: Here We Go Again, antv supply chain attack |
| Severity | CRITICAL |
| Exploitation status | Exploited in the wild |
| Affected products | AntV (Ant Group) @antv npm namespace; actions-cool actions-cool/maintain-one-comment (GitHub Action); actions-cool actions-cool/issues-helper (GitHub Action); Nrwl nrwl.angular-console (VSCode extension) |
| Weaknesses (CWE) | CWE-506, CWE-829, CWE-494, CWE-522, CWE-912 |
| Attribution | TeamPCP (medium confidence) |
| Malware | Shai-Hulud |
| Tools | bun |
| MITRE ATT&CK techniques | T1005 Data from Local System, T1008 Fallback Channels, T1027 Obfuscated Files or Information, T1036 Masquerading, T1041 Exfiltration Over C2 Channel, T1053.003 Cron, T1059 Command and Scripting Interpreter, T1059.004 Unix Shell, T1059.006 Python, T1071.001 Web Protocols, T1082 System Information Discovery, T1083 File and Directory Discovery and 22 more in the attack flow |
| Motivation | FINANCIAL |
| Target sectors | technology, software-development, open-source, financial-services, ai-ml, data-analytics, fintech, consulting |
| Target regions | Global, North America, Europe, Asia-Pacific, China |
| Detection rules | 9 (1 shown free) |
| Sources | 8 cited sources |
Detection coverage for TeamPCP antv supply chain attack
As of 2026-05-19, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-0530 across Splunk SPL, Microsoft KQL and Sigma, covering 27 indicator(s) of compromise. The whole corpus is readable without an account. Every threat comes with one complete detection in Splunk SPL, Microsoft KQL and Sigma, free for everyone; a free account adds daily TL Creds to unlock the rest. Paid plans add a larger daily allowance, correlation and the MCP server. Threadlinqs MCP server · View plans.
Free detection: TeamPCP @antv npm Postinstall Spawning bun Loader to raw.githubusercontent.com — Exploitation Phase
Detects the Mini Shai-Hulud bootstrap stage: an npm/node/pnpm/yarn lifecycle script (postinstall of a compromised @antv package, an actions-cool GitHub Action runner step, or the nrwl.angular-console VSCode extension) spawning the 'bun' runtime as a child, which then reaches raw.githubusercontent.com to fetch a secondary payload hosted in an orphaned GitHub commit. Catches the exact TeamPCP infection chain on developer workstations and CI runners. Bun-as-loader is anomalous for projects that do not otherwise declare bun as a runtime — this pairing of package-manager parent + bun child + raw.githubusercontent.com fetch is the highest-fidelity exploitation signal in the campaign.
- Languages: Splunk SPL, Microsoft KQL, Sigma
- ATT&CK: T1195.002, T1059.001, T1059.004, T1105, T1036
- Data sources: sysmon, edr, microsoft_defender_for_endpoint, process_creation
- Severity: critical
- Confidence: high
Splunk SPL
index=edr sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" (EventCode=1 OR EventCode=3)
| eval parent_lower=lower(ParentImage), proc_lower=lower(Image), cmd_lower=lower(CommandLine)
| where (match(parent_lower, "(\\\\|/)(npm|node|pnpm|yarn)(\\.exe)?$") OR like(parent_lower,"%code.exe%") OR like(parent_lower,"%code-helper%"))
AND (match(proc_lower, "(\\\\|/)bun(\\.exe)?$") OR (match(proc_lower,"(\\\\|/)(curl|wget|node|powershell)(\\.exe)?$") AND like(cmd_lower,"%raw.githubusercontent.com%")))
| eval suspect_payload=if(like(cmd_lower,"%raw.githubusercontent.com%") OR like(cmd_lower,"%api.github.com%") OR like(cmd_lower,"%bun install%"),1,0)
| where suspect_payload=1 OR like(cmd_lower,"%@antv%") OR like(cmd_lower,"%actions-cool%") OR like(cmd_lower,"%nrwl.angular-console%")
| stats min(_time) as first_seen max(_time) as last_seen values(CommandLine) as cmd values(ParentImage) as parents by host, User, Image
| eval threat="TL-2026-0530 TeamPCP Mini Shai-Hulud bootstrap (npm/yarn/pnpm/node -> bun -> raw.githubusercontent.com)"
| table _time host User Image parents cmd threatMicrosoft KQL
DeviceProcessEvents
| where Timestamp > ago(24h)
| extend parent = tolower(InitiatingProcessFileName), proc = tolower(FileName), cmd = tolower(ProcessCommandLine), pcmd = tolower(InitiatingProcessCommandLine)
| where parent in~ ("npm","npm.exe","node","node.exe","pnpm","pnpm.exe","yarn","yarn.exe","code.exe","code-helper")
or pcmd has_any ("postinstall","@antv","actions-cool/maintain-one-comment","actions-cool/issues-helper","nrwl.angular-console")
| where proc in~ ("bun","bun.exe") or (proc in~ ("curl","curl.exe","wget","wget.exe","powershell.exe","node","node.exe") and cmd has "raw.githubusercontent.com")
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine
| extend Threat = "TL-2026-0530 TeamPCP Mini Shai-Hulud — npm postinstall -> bun -> raw.githubusercontent.com payload fetch"Sigma
title: TeamPCP Mini Shai-Hulud — npm Postinstall Spawning bun Reaching raw.githubusercontent.com
id: 4f1a30ce-1e10-4c8e-9c2b-0530aabb0001
status: experimental
description: Detects the TeamPCP @antv Mini Shai-Hulud bootstrap chain where an npm/node/pnpm/yarn (or VSCode-hosted nrwl.angular-console) process spawns the bun runtime, which then fetches a payload from raw.githubusercontent.com (orphaned-commit pattern).
references:
- https://www.wiz.io/blog/mini-shai-hulud-teampcp-hits-antv-supply-chain
- https://attack.mitre.org/techniques/T1195/002/
- https://attack.mitre.org/techniques/T1105/
author: AII-Detector — ThreadLinqs Intelligence
date: 2026-05-19
tags:
- attack.initial_access
- attack.execution
- attack.command_and_control
- attack.t1195.002
- attack.t1059.001
- attack.t1059.004
- attack.t1105
- attack.t1036
- threatlinqs.teampcp
- threatlinqs.shai_hulud
logsource:
category: process_creation
detection:
selection_parent:
ParentImage|endswith:
- '/npm'
- '/node'
- '/pnpm'
- '/yarn'
- '\\npm.exe'
- '\\node.exe'
- '\\pnpm.exe'
- '\\yarn.exe'
- '\\Code.exe'
- '/code-helper'
selection_bun:
Image|endswith:
- '/bun'
- '\\bun.exe'
selection_payload:
CommandLine|contains:
- 'raw.githubusercontent.com'
- 'api.github.com/repos'
- 'bun install'
selection_marker:
CommandLine|contains:
- '@antv/'
- 'actions-cool/maintain-one-comment'
- 'actions-cool/issues-helper'
- 'nrwl.angular-console'
condition: selection_parent and (selection_bun or selection_payload or selection_marker)
falsepositives:
- Legitimate projects that intentionally use the bun runtime alongside npm/yarn (rare in mixed environments — exclude on known-bun repos)
- Internal mirrors that intentionally proxy raw.githubusercontent.com for build assets
level: highKnown false positives:
- Projects that legitimately use the bun runtime as part of their toolchain alongside npm/yarn/pnpm
- CI build images that pre-warm caches from raw.githubusercontent.com for legitimate assets
- Internal developer tooling that wraps bun under a wrapper invoked from node
Tuning notes: Allowlist hosts where bun is a declared dependency (e.g., repos with bun.lockb in version control). Add allowlist for known internal mirrors of raw.githubusercontent.com. Tighten by requiring concurrent file write under node_modules/@antv/ within +/- 5s of the parent process spawn. If false-positive volume is high on dev workstations, scope the rule to CI runner hostnames first, then graduate to endpoints.
- VSCode nrwl.angular-console / npm Lifecycle Spawning bun Reaching api.github.com — Exploitation Phase (KQL) · unlock with TL Creds
- Developer Credential Enumeration by npm Postinstall / bun / python3 — Post-Exploitation (KQL) · unlock with TL Creds
- Anomalous Public GitHub Repository Creation with Shai-Hulud Marker — C2 / Exfil (KQL) · unlock with TL Creds
- Compromised @antv / actions-cool / nrwl Package Installation — Exploitation Phase (Sigma) · unlock with TL Creds
- cat.py / launchd / systemd-user Process Tree — Post-Exploitation Persistence Active (Sigma) · unlock with TL Creds
- TeamPCP Fallback C2 Egress to [indicator] / [indicator] — C2 Channel (Sigma) · unlock with TL Creds
- Shai-Hulud cat.py Backdoor Drop + Kitty-Masquerade Persistence — Post-Exploitation · unlock with TL Creds
- TeamPCP GitHub-as-C2 — firedalazer Search + [indicator] Fallback + Public-Repo Exfil · unlock with TL Creds
Indicators of compromise for TeamPCP antv supply chain attack
As of 2026-05-19, Threadlinqs Intelligence tracks 27 indicators of compromise for TL-2026-0530.
Sample indicators (3 of 27)
- IP address:
185.95.159[.]32 - Domain:
m-kosche[.]com - File hash:
fb5c97557230a27460fdab01fafcfabeaa49590bafd5b6ef30501aa9e0a51142
Defanged, TLP:CLEAR. Full set of 27 indicators: unlock with TL Creds.
How TeamPCP antv supply chain attack works
Persistence via Python backdoor at ~/.local/share/kitty/cat.py polling api.github.com for commits containing the C2 trigger string 'firedalazer'; backup C2 at m-kosche.com (185.95.159.32). Reuses Shai-Hulud family TTPs.
The TeamPCP @antv Supply Chain Wave (aka "Mini Shai-Hulud") is a coordinated, multi-ecosystem software supply chain compromise that reemerged on May 19, 2026, simultaneously affecting npm packages in the @antv visualization namespace, two widely-used actions-cool GitHub Actions (actions-cool/maintain-one-comment, actions-cool/issues-helper), and the nrwl.angular-console v18.95.0 VSCode extension. Wiz Research attributes the campaign with moderate confidence to the threat actor TeamPCP based on infrastructure overlaps, malware functionality, operational patterns, and tradecraft consistent with prior Shai-Hulud-family activity.
The infection begins when a developer or CI runner installs a compromised @antv npm package (200+ packages were published with malicious versions, e.g., @antv/g2 5.5.8/5.6.8, @antv/g6 5.2.1/5.3.1, @antv/util 3.4.11/3.5.11), executes a compromised GitHub Action workflow step, or activates the trojanized nrwl.angular-console v18.95.0 extension. Postinstall (or Action) code reaches out to GitHub-hosted infrastructure to retrieve additional payloads. Many of those payloads were stashed in orphaned GitHub commits, a deliberate evasion technique that decouples the malicious blob from any branch ref while keeping it reachable by commit SHA — the commit survives even if the repository is later cleaned.
Once the bootstrap stage runs, the malware uses `bun` (a fast JavaScript runtime/installer) to fetch and execute secondary payloads responsible for credential theft and persistence. The credential-stealing stage harvests a broad set of developer secrets: GitHub personal access tokens (from gh CLI, npm `.npmrc`, environment variables), SSH private keys (`~/.ssh/`), cloud provider credentials (AWS `~/.aws/credentials`, GCP application-default credentials, Azure CLI tokens), and browser-stored secrets (Chromium login data, cookies). Exfiltration is achieved by creating attacker-controlled **public** GitHub repositories from the victim's account and uploading the stolen data — repositories are tagged with the distinctive description string `niagA oG eW ereH :duluH-iahS` (the phrase "Shai-Hulud: Here We Go Again" reversed).
Persistence is established by dropping a Python backdoor at `~/.local/share/kitty/cat.py` (the "kitty" path masquerades as the Kitty terminal emulator's data directory). On macOS, persistence is anchored with a LaunchAgent plist at `~/Library/LaunchAgents/com.user.kitty-monitor.plist`; on Linux, with a systemd user unit at `~/.config/systemd/user/kitty-monitor.service`. The backdoor periodically polls the GitHub API endpoint `api.github.com/search/commits?q=firedalazer` looking for commits containing the C2 trigger string `firedalazer`. When a valid signed instruction is identified, the backdoor fetches and executes remote Python code, granting the operator ongoing arbitrary code execution. A fallback C2 channel is provided by the domain `m-kosche.com` (185.95.159.32). At time of disclosure Wiz had not observed the C2 channel active, suggesting the operators were in the staging phase.
The backdoor binary (cat.py / packaged blob) carries the following hashes: MD5 b06b126b9e26af03a7ef2f8b8e90d446 / SHA-1 783b4019fc5b942a29846132d28441c8fc31bed8 / SHA-256 fb5c97557230a27460fdab01fafcfabeaa49590bafd5b6ef30501aa9e0a51142.
Impact is severe because the affected components target high-trust environments: developer workstations (where local SSH keys and cloud credentials live), GitHub Actions runners (where repository write tokens and cloud OIDC trust live), and the @antv ecosystem (high-traffic data visualization libraries with deep transitive dependency reach — @antv/g2 and @antv/g6 alone are dependencies of thousands of downstream projects, including AI/ML dashboards using @antv/mcp-server-chart). Any organization that built, tested, or deployed an affected package version on May 19, 2026 must assume token, key, and credential compromise.
This wave is a continuation of the broader Shai-Hulud worm family of self-propagating npm supply chain attacks (originally documented in 2025 with the s1ngularity-repository pattern). TeamPCP's tradecraft reuses orphaned-commit payload hosting, GitHub-as-C2, and credential-harvest-then-republish propagation seen in earlier waves, but with a tighter focus on a single high-value npm namespace plus CI Actions and IDE extensions for broader developer reach. Recommended response is immediate: pin/remove affected versions, rotate ALL developer and CI secrets, audit repositories for unauthorized public repos with the marker description, hunt for the cat.py persistence file and the LaunchAgent/systemd units, and block egress to api.github.com search endpoints querying for `firedalazer` and to m-kosche.com / 185.95.159.32.
MITRE ATT&CK techniques by tactic:
Collection
Command and Control
T1008 Fallback Channels; T1071.001 Web Protocols; T1102 Web Service; T1102.002 Bidirectional Communication; T1105 Ingress Tool Transfer
Defense Evasion
T1027 Obfuscated Files or Information; T1036 Masquerading; T1564 Hide Artifacts
Exfiltration
T1041 Exfiltration Over C2 Channel; T1567 Exfiltration Over Web Service
Persistence
T1053.003 Cron; T1543.001 Launch Agent; T1543.002 Systemd Service
Execution
T1059 Command and Scripting Interpreter; T1059.004 Unix Shell; T1059.006 Python; T1204 User Execution
Discovery
T1082 System Information Discovery; T1083 File and Directory Discovery; T1526 Cloud Service Discovery
Initial Access
T1195 Supply Chain Compromise; T1195.002 Compromise Software Supply Chain; T1199 Trusted Relationship
Impact
Credential Access
T1528 Steal Application Access Token; T1539 Steal Web Session Cookie; T1552.001 Credentials In Files; T1552.004 Private Keys; T1555.003 Credentials from Web Browsers
Resource Development
T1583 Acquire Infrastructure; T1586 Compromise Accounts; T1587 Develop Capabilities; T1608 Stage Capabilities
Remediation for TeamPCP antv supply chain attack
Patches
- Affected @antv packages: downgrade to last clean version per Wiz appendix (each compromised package has a clean prior version; e.g., @antv/g2 < 5.5.8).
- actions-cool/maintain-one-comment and actions-cool/issues-helper: pin to commit SHA prior to 2026-05-19 publication.
- nrwl.angular-console: upgrade to post-incident clean release (>= 18.96.0) or downgrade to 18.94.x.
Immediate actions
- Audit package-lock.json / yarn.lock / pnpm-lock.yaml for any @antv package with a publish date of 2026-05-19; remove and pin to a known-good prior version.
- Remove or pin actions-cool/maintain-one-comment and actions-cool/issues-helper to a commit SHA published before 2026-05-19 (not a floating tag).
- Uninstall nrwl.angular-console v18.95.0 from every developer workstation; replace with 18.94.x or 18.96.x (post-incident clean release).
- Rotate ALL GitHub personal access tokens (gh CLI, npm publish tokens, CI tokens) for any developer or runner that executed affected packages or workflows on/after 2026-05-19.
- Rotate SSH private keys in ~/.ssh/ for any developer who ran an affected package.
- Rotate cloud credentials: AWS access keys (~/.aws/credentials), GCP application-default credentials, Azure CLI tokens.
- Audit the victim GitHub account(s) for newly created PUBLIC repositories with the description string 'niagA oG eW ereH :duluH-iahS' and delete them after preserving forensic copies.
- Hunt for and remove ~/.local/share/kitty/cat.py on all developer workstations and CI runners.
- Disable / unload persistence units: ~/Library/LaunchAgents/com.user.kitty-monitor.plist (macOS) and ~/.config/systemd/user/kitty-monitor.service (Linux).
Workarounds
- Set 'ignore-scripts=true' in .npmrc for all dev and CI environments until ecosystem is confirmed clean.
- Block egress from CI runners to api.github.com search endpoints (api.github.com/search/commits) at the network layer.
- Block egress to m-kosche.com and 185.95.159.32 at perimeter and host firewall.
- Add detection rule for repository creation events with description containing 'niagA oG eW ereH :duluH-iahS' or 'Shai-Hulud'.
Longer-term hardening
- Implement dependency allowlisting (npm install --ignore-scripts as default; explicit allowlist for packages that require lifecycle scripts).
- Enforce SBOM generation in CI (Syft / Anchore) and diff SBOMs across builds to detect new dependencies pulled in by typosquats or version bumps.
- Adopt npm package provenance / Sigstore attestations and reject packages without valid provenance for security-sensitive namespaces.
- Pin GitHub Actions to immutable commit SHAs, not tags or branches; use Dependabot to track Action SHA updates.
- Deploy EDR with behavioral detection on developer workstations — flag postinstall script spawning bun/curl/wget reaching api.github.com or unknown hosts.
- Network egress allowlisting on CI runners — block all outbound except registry, source repo, and explicitly allowed artifact destinations.
- Adopt short-lived, OIDC-federated cloud credentials in CI in place of long-lived access keys.
- Continuous monitoring of org-wide GitHub events for repository creation, especially with anomalous descriptions or by service accounts.
Affected and fixed versions
- AntV (Ant Group) — @antv npm namespace
Vulnerable versions: 200+ packages published 2026-05-19 — see Wiz appendix; e.g., @antv/g2 5.5.8/5.6.8, @antv/g6 5.2.1/5.3.1, @antv/util 3.4.11/3.5.11, @antv/g 6.4.1/6.5.1, @antv/component 2.2.11/2.3.11
Fixed in: Last prior published version of each package (downgrade required); ecosystem republish in progress - actions-cool — actions-cool/maintain-one-comment (GitHub Action)
Vulnerable versions: All tags during compromise window 2026-05-19
Fixed in: Commit SHA prior to 2026-05-19 - actions-cool — actions-cool/issues-helper (GitHub Action)
Vulnerable versions: All tags during compromise window 2026-05-19
Fixed in: Commit SHA prior to 2026-05-19 - Nrwl — nrwl.angular-console (VSCode extension)
Vulnerable versions: 18.95.0
Fixed in: 18.94.x or post-incident >= 18.96.0
Timeline of TeamPCP antv supply chain attack
- Original Shai-Hulud npm supply chain worm publicly disclosed by Wiz, Socket, and StepSecurity — established TTP family (orphaned-commit payload hosting, GitHub-as-C2, self-propagating credential harvest).
- Attacker stages payloads in orphaned GitHub commits and prepares backup C2 infrastructure at locked-ioc-24 (locked-ioc-23) ahead of mass publish.
- Wiz notes that as of disclosure the C2 polling for 'firedalazer' commits had not been observed to return active commands — operators appeared to still be in staging.
- AntV maintainers, npm, GitHub Marketplace, and VSCode Marketplace begin coordinated package removal and tag-overwrite reversal. Nrwl/Nx issues impact report for angular-console 18.95.0.
- Full IOC set published: cat.py backdoor hashes (SHA-256 locked-ioc-5), C2 trigger string 'firedalazer', GitHub API polling endpoint, fallback C2 locked-ioc-24 / locked-ioc-23, persistence paths.
- Wiz Research publishes 'The Worm That Keeps on Digging: locked-ioc-26 Hits @antv in Latest Wave' attributing the campaign with moderate confidence to locked-ioc-26 based on infrastructure overlaps, malware functionality, and operational patterns.
- Wiz Research observes related malicious activity in real time across developer and CI/CD environments — postinstall scripts spawning locked-ioc-27, fetching secondary payloads, and creating public exfil repos with description 'niagA oG eW ereH :duluH-iahS'.
- Coordinated mass-publish: 200+ malicious @antv npm package versions, locked-ioc-14 and locked-ioc-20 GitHub Action tag overwrites, and nrwl.angular-console v18.95.0 VSCode extension all push compromised builds within hours.
- As of 2026-05-29, this specific @antv wave is largely contained — GitHub/npm pulled ~640 malicious packages and npm invalidated 61,274 2FA-bypass tokens — but locked-ioc-26's self-propagating Mini Shai-Hulud worm remains active in the wild with recurring waves and survives package removal. Treat as MONITORING: vector neutralized, actor/tooling persists and could resurge.
Sources cited for TeamPCP antv supply chain attack
- Nx (nrwl) Impact Report — angular-console 18.95.0 Compromise GitHub · Advisory · 2026-05-19
- The Worm That Keeps on Digging: TeamPCP Hits @antv in Latest Wave Wiz · Vendor report · 2026-05-19
- MITRE ATT&CK T1195.002 — Supply Chain Compromise: Compromise Software Supply Chain MITRE · Research · 2025-04-15
- Wiz prior coverage — Shai-Hulud worm campaign (2025) Wiz · Vendor report · 2025-09-16
- Original GitHub Issue Thread — @antv compromise GitHub · Code repository · 2026-05-19
- StepSecurity — actions-cool GitHub Actions Compromise Analysis stepsecurity.io · Blog · 2026-05-19
- StepSecurity — VSCode Marketplace Extension Compromise Analysis stepsecurity.io · Blog · 2026-05-19
- Socket — Mini Shai-Hulud Overall Compromise Tracker socket.dev · Blog · 2026-05-19
More from TeamPCP
- Developer credential exposure on dev machines: StepSecurity Dev Machine Guard credential-source inventory (context: TeamPCP stealer, Bitwarden CLI npm hijack, Shai-Hulud)
- Open Source Supply Chain Attack Surge: 56 Confirmed Attacks in 12 Months Across npm, PyPI, RubyGems, Composer, Rust Crates and GitHub Actions (Shai-Hulud, TeamPCP, Axios, Miasma, ChainDrop)
- Mini Shai-Hulud: Compromised @antv npm Packages Steal Developer and CI/CD Credentials (TeamPCP)
- Re-Enabled actions-cool GitHub Actions (issues-helper, maintain-one-comment) Resume Executing Mini Shai-Hulud CI/CD Credential-Theft Payload
- Google Cloud Threat Intelligence: Supply Chain Compromise Campaigns and Mitigation Guidance (2025-2026)
- ChainDrop/Mini Shai-Hulud npm Worm Compromises keyv, cacheable, and 400+ Downstream Packages via Ethereum-Resolved C2
Previous and next in supply chain
Further reading
Drafted by the Threadlinqs research pipeline from 8 sources; published ; last updated —.