# Mini Shai-Hulud Resurfaces — intercom-client@7.0.4 npm Worm Harvesting GitHub & Cloud Credentials (TeamPCP)

> On 2026-04-30 the Mini Shai-Hulud worm trojanized intercom-client@7.0.4 (~360k weekly downloads, 100+ dependents) on npm via a preinstall hook that downloads an unverified Bun runtime and executes an obfuscated ~11.7 MB router_runtime.js to harvest GitHub PATs, npm tokens, AWS/GCP IMDS credentials, Kubernetes/Vault secrets, and environment variables. The same campaign poisoned PyTorch Lightning 2.6.2/2.6.3 on PyPI plus four SAP-related npm packages (@cap-js/sqlite, @cap-js/postgres, @cap-js/db-service, mbt). Stolen secrets are exfiltrated to zero.masscan.cloud (fallback 94.154.172.43) and dead-dropped to attacker-controlled GitHub repos tagged with the description 'A Mini Shai-Hulud has Appeared' and the commit-search keyword 'beautifulcastle'; attribution to TeamPCP (LAPSUS$ overlap) rests on a shared RSA public key and a Russian language-region killswitch reused from prior Checkmarx/Bitwarden operations.

- **Published:** 2026-04-30T12:00:00Z
- **Last reviewed:** 2026-04-30T12:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-0446
- **ID:** TL-2026-0446
- **Severity:** CRITICAL
- **Category:** SUPPLY_CHAIN
- **Status:** MONITORING
- **Actor:** TeamPCP
- **Detections:** 9 · **IOCs:** 29 (full data via the Threadlinqs MCP server — Purple tier)

## Description

OVERVIEW

Mini Shai-Hulud is the third-generation reincarnation of the Shai-Hulud npm worm family (original September 2025; Shai-Hulud 2.0 November 2025). On 2026-04-30 multiple vendors (Socket, Wiz, OX Security, The Hacker News) reported a coordinated supply-chain campaign in which the worm was published into widely-used JavaScript and Python packages over a roughly 47-minute exposure window. The flagship infection vector was intercom-client@7.0.4, the official Intercom Node.js SDK with approximately 360,000 weekly npm downloads and more than 100 known dependent projects, but the same actor simultaneously trojanized PyTorch Lightning 2.6.2 and 2.6.3 on PyPI (~2.1M weekly downloads) and four SAP-related npm packages: @cap-js/sqlite@2.2.2, @cap-js/postgres@2.2.2, @cap-js/db-service@2.10.1, and mbt@1.2.48.

INITIAL ACCESS AND EXECUTION

Maintainer accounts were taken over (likely via phished or harvested 2FA-disabled credentials and reused npm/PyPI tokens). On the npm side, malicious versions were published with two payload files added to the package: setup.mjs and router_runtime.js. The package.json was edited so that setup.mjs is invoked from the preinstall lifecycle hook, guaranteeing execution the moment a victim runs npm install. setup.mjs (SHA-256 fe64699649591948d6f960705caac86fe99600bf76e3eae29b4517705a58f0e2) reaches out and downloads an unverified Bun runtime binary, drops router_runtime.js (SHA-256 5ae8b2343e97cc3b2c945ec34318b63f27fa2db1e3d8fbaa78c298aa63db52ed, ~11.7 MB heavily obfuscated JavaScript), and executes it under Bun. A Wiz-collected variant of setup.mjs (SHA-256 4066781fa830224c8bbcc3aa005a396657f9c8f9016f9a64ad44a9d7f5f45e34) carries the same logic with minor mutations.

The Python lightning compromise uses an analogous trick: a malicious setup script delivered through the wheel performs the same Bun + router_runtime.js handoff, allowing the JavaScript-based credential stealer to run identically across npm and PyPI ecosystems.

GUARDRAILS AND DEFENSE EVASION

router_runtime.js contains an execution guardrail that aborts on systems whose locale resolves to Russian language/region — the same killswitch observed in earlier TeamPCP-attributed compromises against Checkmarx and Bitwarden customers, and one of the strongest pieces of attribution evidence. Static obfuscation is multi-layered (string array shuffling, control-flow flattening) and the entire payload is embedded in a single ~11.7 MB file to overwhelm signature scanning and frustrate manual review.

CREDENTIAL HARVESTING

Once running, router_runtime.js performs a comprehensive sweep of the host:

- Filesystem scan for .npmrc, .yarnrc, ~/.config/gh, ~/.docker/config.json, ~/.aws/credentials, ~/.kube/config, ~/.vault-token, .env, .envrc, and Helm/Terraform state files;
- HTTP requests to AWS IMDSv1/v2 (169.254.169.254/latest/meta-data/iam/security-credentials/) and to metadata.google.internal to retrieve role STS tokens and GCE service-account tokens;
- Direct interrogation of git config and ~/.gitconfig to find personal access tokens (PATs) and GitHub App installation tokens;
- Enumeration of process environment variables, including CI/CD-injected secrets (GITHUB_TOKEN, NPM_TOKEN, NPM_AUTH_TOKEN, PYPI_TOKEN, AWS_*, GCP_*, KUBE*).

COMMAND AND CONTROL & EXFILTRATION

Harvested data is encrypted with an embedded RSA public key (the same key reused across previous TeamPCP campaigns) and exfiltrated over HTTPS to zero.masscan.cloud:443/v1/telemetry. If DNS resolution for zero.masscan.cloud fails, the worm falls back to a hardcoded IP at 94.154.172.43. In parallel, valid GitHub PATs are reused immediately to fork the contents of the victim's accessible repositories into attacker-controlled GitHub accounts. The new repositories are created with the description string 'A Mini Shai-Hulud has Appeared' and named using LAPSUS$/Dune-themed patterns: ghola-melange-*, mentat-melange-*, powindah-sietch-*. A separate dead-drop channel relies on GitHub's commit-search API — the worm pushes commits whose message embeds the keyword 'beautifulcastle' so the operator can locate freshly compromised repos via a single search query.

WORM PROPAGATION AND REPOSITORY POISONING

For every writable GitHub repo that a stolen PAT can reach, router_runtime.js plants .claude/setup.mjs, .claude/execution.js, .vscode/setup.mjs, and .vscode/tasks.json — a hardcoded impersonation of Anthropic's Claude Code agent and Visual Studio Code task automation that is intended to fire whenever a developer opens the repo in their IDE. The worm pushes its payload to up to 50 branches per repo to maximize survival under naive cleanup attempts. It also republishes any npm package the compromised PAT can publish to (with an incremented patch version), explaining the worm-class self-propagation behavior that gave the Shai-Hulud family its name.

ATTRIBUTION

Multiple vendors converge on TeamPCP, a threat group with documented overlap with LAPSUS$. Key evidence: (1) the embedded RSA exfil public key is byte-identical to keys recovered from prior Checkmarx and Bitwarden customer-targeting incidents; (2) the Russian-locale killswitch is implemented in the same way and at the same point in execution as in earlier TeamPCP samples; (3) reuse of the masscan.cloud namespace and the same GitHub-repo-as-dead-drop technique. The compromised maintainer GitHub account 'nhur' is being treated as a victim, not as the operator.

IMPACT

This is a CRITICAL software supply-chain incident affecting JavaScript, Python, and SAP/ERP build pipelines simultaneously. Any organization that ran npm install or pip install for the affected packages between roughly 14:00 and 14:47 UTC on 2026-04-30 should assume credential compromise of every secret reachable from that build host (cloud roles, container registry tokens, GitHub PATs, npm/PyPI publish tokens, Kubernetes service-account tokens, Vault tokens). Because stolen GitHub PATs are reused to plant payloads in *other* repositories, the blast radius extends well beyond the original install host: any private repo whose PAT touched a poisoned build is a candidate for further investigation.

## MITRE ATT&CK

- T1583 Acquire Infrastructure
- T1586 Compromise Accounts
- T1195 Supply Chain Compromise
- T1195.002 Compromise Software Supply Chain
- T1199 Trusted Relationship
- T1059.007 Command and Scripting Interpreter: JavaScript
- T1059.006 Command and Scripting Interpreter: Python
- T1129 Shared Modules
- T1204.002 User Execution: Malicious File
- T1546 Event Triggered Execution
- T1098.001 Account Manipulation: Additional Cloud Credentials
- T1027 Obfuscated Files or Information
- T1480 Execution Guardrails
- T1036.005 Match Legitimate Resource Name or Location
- T1552.001 Unsecured Credentials: Credentials In Files
- T1552.005 Unsecured Credentials: Cloud Instance Metadata API
- T1528 Steal Application Access Token
- T1555 Credentials from Password Stores
- T1083 File and Directory Discovery
- T1082 System Information Discovery
- T1005 Data from Local System
- T1550.001 Use Alternate Authentication Material: Application Access Token
- T1071.001 Application Layer Protocol: Web Protocols
- T1102.001 Web Service: Dead Drop Resolver
- T1105 Ingress Tool Transfer
- T1041 Exfiltration Over C2 Channel
- T1567.001 Exfiltration Over Web Service: Exfiltration to Code Repository
- T1531 Account Access Removal

## Sources

- [Intercom's npm Package Compromised in Ongoing Mini Shai-Hulud Supply Chain Attack](https://socket.dev/blog/intercom-s-npm-package-compromised-in-supply-chain-attack)
- [Supply Chain Campaign Targets SAP npm Packages with Credential-Stealing Malware](https://www.wiz.io/blog/mini-shai-hulud-supply-chain-sap-npm)
- [PyTorch Lightning and Intercom-client Hit in Supply Chain Attacks to Steal Credentials](https://thehackernews.com/2026/04/pytorch-lightning-compromised-in-pypi.html)
- [8.3M Downloads Compromised: Lightning & Intercom-Client Infected in Latest Shai-Hulud Attack](https://www.ox.security/blog/lightning-python-package-shai-hulud-supply-chain-attack/)
- [MITRE ATT&CK T1195.002 Compromise Software Supply Chain: Software Dependencies and Development Tools](https://attack.mitre.org/techniques/T1195/002/)
- [MITRE ATT&CK T1552.005 Unsecured Credentials: Cloud Instance Metadata API](https://attack.mitre.org/techniques/T1552/005/)
- [MITRE ATT&CK T1567.001 Exfiltration Over Web Service: Exfiltration to Code Repository](https://attack.mitre.org/techniques/T1567/001/)

## 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-0446
