# ChainDrop npm Supply-Chain Compromise: Self-Propagating Mini Shai-Hulud Credential-Stealing Worm Affecting 444+ Packages

> ChainDrop is a large-scale npm supply-chain attack affecting 444+ packages (2,212 malicious versions) across 14+ unrelated publisher organizations, delivered via a Mini Shai-Hulud self-propagating credential-stealing worm. Malicious releases execute via the npm preinstall lifecycle hook, steal credentials (npm, GitHub, AWS, Azure, GCP, Kubernetes, HashiCorp Vault, AI agent configs, cryptocurrency wallets), exfiltrate via Ethereum blockchain-resolved C2 with AES-256-GCM + RSA-OAEP encryption, and republish modified packages to propagate, including via GitHub Actions OIDC abuse for trusted-publisher publication carrying valid SLSA provenance.

- **Published:** 2026-08-04T00:00:00Z
- **Last reviewed:** 2026-10-05T03:17:05.700Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-1875
- **ID:** TL-2026-1875
- **Severity:** CRITICAL
- **Category:** SUPPLY_CHAIN
- **Status:** ACTIVE
- **Actor:** TeamPCP
- **Detections:** 9 · **IOCs:** 45 (full data via the Threadlinqs MCP server — Purple tier)

## Description

On August 4, 2026 (UTC), the npm ecosystem experienced one of the most sophisticated supply-chain attacks ever recorded. Dubbed ChainDrop, the attack propagated via a Mini Shai-Hulud variant worm that poisoned 444 packages (2,212 versions) in under four hours, affecting packages with a combined 2+ billion monthly installs. The attack began with the compromise of the GitHub account of Jared Wray, maintainer of the Keyv package (153.7M weekly downloads), and rapidly spread across the jaredwray ecosystem to packages including flat-cache (149.9M), file-entry-cache (147.6M), cacheable-request, cache-manager, ecto, and then autonomously propagated to 433 additional packages across 14+ organizations including ServiceTitan, OneReach, Ornikar, Qlik, Picsart, and Deliveroo.

The initial compromise was achieved via stolen GitHub maintainer credentials, not an npm token — the attacker pushed unsigned commits directly to the main branch and triggered legitimate release workflows configured with OIDC trusted publishing. This meant that every malicious version from the jaredwray wave carried valid SLSA provenance attestation signed by GitHub Actions. The resulting provenance accurately recorded the poisoned commit hash; it could not prove the commit was authorized.

The worm delivery mechanism exploits npm's preinstall lifecycle hook. Each poisoned package includes a setup.mjs file (29,918 bytes, wave 1; 11,017 bytes, re-obfuscated wave 2) and a heavily obfuscated 727,680-byte Bun-bundled second-stage payload (Math_Symbol.js or math_init.js). When npm install runs, the preinstall hook executes setup.mjs via Node.js, which downloads the legitimate Bun v1.3.13 JavaScript runtime from the official oven-sh/bun GitHub release and uses it to detonate the second-stage worm. The worm downloads a platform-specific Bun binary (Linux x64 glibc/musl, Linux arm64, macOS x64/arm64, Windows x64/arm64) and cleans up the staging directory afterward. If Bun is already installed, the download is skipped. The second-wave dropper variant includes a hand-rolled minimal ZIP extractor with PowerShell Expand-Archive fallback on Windows.

The stage 2 payload (727,680 bytes) is a Bun-bundled CommonJS program with three obfuscation layers: a rotated 1,283-entry string table with custom charset decoder, anti-tamper Object hardening, and AES-256-GCM encrypted configuration blobs. Its startup sequence includes a Russian-locale kill switch (exits if LANG indicates a Russian locale — a classic CIS avoidance pattern), a detached self-respawn mechanism outside GitHub Actions, and anti-debug checks. It writes a camouflaged state file at $TMPDIR/tmp.dpkg_<pid>.lock disguised as a dpkg lock.

The credential harvesting subsystem targets approximately 140 filesystem paths across 19 categories. These include npm tokens (~/.npmrc, ~/.yarnrc), GitHub tokens (via gh auth token and filesystem scanning), AWS credentials (~/.aws/credentials, config, IMDSv2, ECS metadata), Azure tokens (az account get-access-token, ~/.azure/accessTokens.json), Google Cloud (~/.config/gcloud, gcloud config config-helper), Docker (~/.docker/config.json), Kubernetes (~/.kube/config, in-cluster API enumeration), SSH keys (~/.ssh/), HashiCorp Vault (token discovery, Kubernetes auth, AWS IAM auth, KV v1/v2 path walk across all mounts), Jenkins (master.key), Terraform state files, PostgreSQL and MySQL connection strings, and cryptocurrency wallet.dat files (Bitcoin, Dash, Dogecoin, Litecoin, Zcash, Electrum). The worm also performs AWS Secrets Manager ListSecrets/GetSecretValue and SSM GetParameters calls across 16 regions, and Kubernetes namespace-wide secret enumeration.

A distinctive new capability in this generation targets AI developer tools — credential stores for Claude Code (.claude/credentials.json, .claude.json), OpenAI (.openai/auth.json), Codex (.codex/auth.json), Cursor (.cursor/credentials.json), Anthropic (.anthropic/auth.json), Gemini (.gemini/.env), OpenClaw, OpenCode, Hermes, and Kiro. The worm also performs GitHub Actions Runner.Worker memory scraping via sudo python3 — dumping readable pages of /proc/<Runner.Worker PID>/mem and grepping for "isSecret":true JSON fragments to extract every secret injected into CI/CD workflows.

The worm scans discovered credentials via 19 secret format regexes covering GitHub PATs (ghp_, gho_, ghs_, JWT formats), npm tokens (npm_), AWS key/secret/session formats, GCP service account JSON, Azure keys, database connection strings, Stripe, Slack, Twilio, SSH private keys, Docker auth configs, kubeconfigs, and generic password/token key-value pairs. Each credential is validated against the service API in real-time.

C2 infrastructure employs a defensive-resilient multi-layer architecture. The primary C2 resolution uses an Ethereum smart contract at 0xE1f2395ee43e45A1556EC6438a88c31B83493103 (function selector 0x53ed5143) via eth_call, querying 75 public RPC endpoints in order to retrieve the current C2 domain list — with no hardcoded domain, the attacker rotates C2 infrastructure on-chain. Two fallback mechanisms exist: GitHub commit search with markers "thebeautifulmarchoftime" and "IfYouBlockThisAPIKeyItWillCrashTheLiveProductionServersOfAllThirdPartyClients", and creation of a public GitHub repo with description "Shai-Hulud: Here We Go Again". The observed exfiltration endpoint is npm-cache.com:443/router (healthchecked by requiring HTTP 400 or 404 to fingerprint the server).

Data exfiltration follows a multi-layer analyst-proof envelope: gzip(JSON loot) → AES-256-GCM (random per-run 32-byte key, 12-byte IV) → RSA-OAEP-SHA256 wrapping of the AES key → base64. Only the attacker's private key can decrypt. The worm also exfiltrates via GitHub staging repos (creating repos via the victim's token and committing results-<timestamp>-<counter>.json files) and via a "Run Copilot" GitHub Actions workflow that writes ${{ toJSON(secrets) }} to format-results.txt and uploads it as an artifact named format-results.

Persistence mechanisms extend beyond npm install to the developer environment. The malicious commit planted .claude/settings.json with a Claude Code SessionStart hook and .vscode/tasks.json with a folderOpen shell task, each cross-referencing each other's dropper files (.claude/setup.mjs and .vscode/setup.mjs). Opening the repository in VS Code or starting a Claude Code session triggers execution — no npm install required. A token monitor component (gh-token-monitor.sh) is installed as a systemd user service (Linux) or LaunchAgent (macOS) that polls api.github.com/user every 60 seconds for 24 hours and executes an attacker-supplied handler when the stolen token is revoked — punishing credential rotation.

The worm's self-publishing engine is fully self-contained. It discovers maintainer packages via npm API (-/v1/search?text=maintainer:<user>&size=250, -/org/<org>/package), creates automation tokens with 2FA bypass, downloads current tarballs, injects the payload, recomputes integrity values, and publishes with self-generated Sigstore/SLSA provenance bundles (Fulcio + Rekor). One stolen token can produce malicious patch releases across every package available to that publisher.

Attribution: The payload is consistent with the Mini Shai-Hulud worm, an open-source credential-stealing worm published by the threat actor TeamPCP (also tracked as UNC6780, DeadCatx3, PCPcat, ShellForce, CipherForce) in May 2026. The ChainDrop variant carries forward distinctive markers from Shai-Hulud 2.0 (November 2025 campaign): Bun-based preinstall delivery via setup.mjs, Runner.Worker memory scraping with isSecret:true grepping, npm self-republishing with stolen tokens, and GitHub-based exfiltration. New capabilities include EtherHiding on-chain C2, RSA+AES analyst-proof exfiltration envelopes, AI agent credential theft, Russian locale kill switch, and self-minted Sigstore/SLSA provenance. Wiz attributed at high confidence via a shared RSA-4096 public key with prior TeamPCP operations (Bitwarden CLI, Checkmarx KICS). However, other researchers note that hard attribution links remain unconfirmed. Google's Threat Intelligence Group tracks the group as UNC6780, assessing a single operator with some periods of operation from South Africa. The group is financially motivated, targeting developer ecosystems across npm, PyPI, RubyGems, and Packagist. Prior TeamPCP campaigns include supply chain compromises of Aqua Security Trivy, Bitwarden CLI, Checkmarx Jenkins AST Plugin, GitHub, LiteLLM, and Telnyx.

## MITRE ATT&CK

- T1078 Valid Accounts
- T1195 Supply Chain Compromise
- T1204 User Execution
- T1059 Command and Scripting Interpreter
- T1543 Create or Modify System Process
- T1098 Account Manipulation
- T1548 Abuse Elevation Control Mechanism
- T1027 Obfuscated Files or Information
- T1036 Masquerading
- T1608 Stage Capabilities
- T1552 Unsecured Credentials
- T1555 Credentials from Password Stores
- T1003 OS Credential Dumping
- T1082 System Information Discovery
- T1614 System Location Discovery
- T1046 Network Service Discovery
- T1087 Account Discovery
- T1069 Permission Groups Discovery
- T1005 Data from Local System
- T1213 Data from Information Repositories
- T1119 Automated Collection
- T1573 Encrypted Channel
- T1071 Application Layer Protocol
- T1008 Fallback Channels
- T1205 Traffic Signaling
- T1546 Event Triggered Execution
- T1055 Process Injection
- T1564 Hide Artifacts
- T1528 Steal Application Access Token
- T1083 File and Directory Discovery
- T1526 Cloud Service Discovery
- T1102 Web Service
- T1105 Ingress Tool Transfer
- T1048 Exfiltration Over Alternative Protocol
- T1567 Exfiltration Over Web Service
- T1070 Indicator Removal
- T1497 Virtualization/Sandbox Evasion
- T1074 Data Staged
- T1041 Exfiltration Over C2 Channel
- T1020 Automated Exfiltration

## Sources

- [ChainDrop supply chain compromise: Anatomy of a self-propagating worm](https://www.microsoft.com/en-us/security/blog/2026/08/04/chaindrop-supply-chain-compromise-anatomy-self-propagating-worm/)
- [ChainDrop npm Worm: Bun-loaded CI/CD credential harvester with OIDC abuse and EtherHiding C2](https://www.stepsecurity.io/blog/chaindrop-npm-worm)
- [Massive ChainDrop npm supply-chain attack infects hundreds of packages](https://www.bleepingcomputer.com/news/security/massive-chaindrop-npm-supply-chain-attack-infects-hundreds-of-packages/)
- [Massive supply-chain attack compromises 440 packages under four hours](https://cyberscoop.com/supply-chain-attack-malware-mini-shai-hulud-teampcp/)
- [ChainDrop credential-stealing worm infects over 400 npm packages](https://www.csoonline.com/article/4205276/chaindrop-credential-stealing-worm-infects-over-400-npm-packages.html)
- [A worm tore through npm by making the malware look perfectly legitimate](https://thenextweb.com/news/chaindrop-npm-worm-shai-hulud-provenance-ai-tools)
- [Shai-Hulud 2.0: Ongoing Supply Chain Attack Targeting npm](https://www.wiz.io/blog/shai-hulud-2-0-ongoing-supply-chain-attack)
- [SigmaHQ: Detection Rule for Malicious npm Package Installation (Shai-Hulud)](https://github.com/SigmaHQ/sigma/blob/master/rules-emerging-threats/2025/Malware/Shai-Hulud/proc_creation_win_mal_shai_hulud_malicious_npm_package_installation.yml)
- [ProjectDiscovery Nuclei Template: Shai-Hulud Supply Chain Malware](https://github.com/projectdiscovery/nuclei-templates/blob/main/file/malware/shai-hulud-supply-chain.yaml)
- [npm-supply-chain-detector: ChainDrop IOC tracker](https://github.com/otaviomarcal/npm-supply-chain-detector)
- [ChainDrop: Wiz Cloud Detection and Response](https://www.wiz.io/blog/chaindrop-npm-supply-chain-worm-august-2026)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-1875
