Binding.gyp "Phantom Gyp" Supply Chain Attack (Miasma Worm) Enables CI/CD Worm Propagation Across 57 npm Packages — Threadlinqs Intelligence
As of 2026-07-11, Binding.gyp "Phantom Gyp" Supply Chain Attack (Miasma Worm) Enables CI/CD Worm Propagation Across 57 npm Packages is a high-severity supply chain threat attributed to TeamPCP, tracked by Threadlinqs Intelligence with 9 detection rules (Splunk SPL, Microsoft KQL, Sigma) and 27 indicators of compromise.
Threat ID: TL-2026-1234 · Severity: HIGH · Status: ACTIVE · Category: SUPPLY_CHAIN
Attribution: TeamPCP · FINANCIAL
The TeamPCP-linked Miasma worm published trojanized versions of 57 npm packages (286+ malicious versions) using a novel "Phantom Gyp" technique that abuses binding.gyp's node-gyp command-substitution
On 2026-06-03, security researchers at StepSecurity identified a follow-on variant of the Miasma npm supply-chain worm, dubbed "Phantom Gyp," that abandoned the preinstall/postinstall lifecycle-script vector used by earlier Shai-Hulud-lineage worms in favor of a previously overlooked execution primitive: the binding.gyp native-addon build configuration file consumed by node-gyp. A minimal 157-byte binding.gyp embedded in trojanized package versions declares a `sources` array entry using GYP's `<!(...)` command-substitution syntax — `"sources": ["<!(node index.js > /dev/null 2>&1 && echo stub.c)"]` — which node-gyp evaluates as a shell command during the automatic `node-gyp rebuild` step npm performs whenever a package ships a binding.gyp, regardless of whether the package declares an explicit install script. Because binding.gyp is build metadata rather than a package.json script entry, script-scanning security tooling and SCA products largely failed to flag it, creating a detection blind spot the attackers exploited deliberately.
The payload chain is heavily obfuscated: a legitimate-looking package ships an oversized (4-5 MB) `index.js` at its package root — never imported by the actual application code, which remains untouched in `dist/` — that is first unwrapped through a ROT-N Caesar cipher (rotation values observed at 9, 14, 15, 18, 19, and 20 across samples) applied to a ~1.3 million character array, then decrypted with AES-128-GCM using hardcoded keys/IVs, then used to download and execute a standalone Bun JavaScript runtime binary (v1.3.13, sourced directly from the legitimate `github.com/oven-sh/bun` GitHub Releases CDN) in under one second. Running the ~650-750 KB final-stage stealer under Bun rather than Node.js specifically defeats process-monitoring EDR/XDR rules scoped to `node` child processes spawned during `npm install`.
Once running, the stealer systematically harvests CI/CD and cloud credentials: AWS access keys/secret keys/session tokens and IMDSv2 metadata, GCP service-account keys and `GOOGLE_APPLICATION_CREDENTIALS`, Azure managed-identity and IMDS tokens, HashiCorp Vault tokens (Kubernetes-auth and AWS-auth paths, plus local token files), Kubernetes service-account tokens, and local secrets stores (1Password, pass, gopass). Inside GitHub Actions runners specifically, the malware escalates via `sudo python3` and reads `/proc/[pid]/mem` of the `Runner.Worker` process, grepping for the JSON pattern GitHub uses to store unmasked secret values (`"[^"]+":{"value":"[^"]*","isSecret":true}`), completely bypassing GitHub's log-masking protections for secrets referenced in the workflow.
For persistence and lateral compromise of the developer's own tooling, the malware commits backdoor files into accessible repositories using stolen GitHub tokens, with commit messages such as "This is required for proper IDE integration and dependency setup": `.claude/setup.mjs` (abusing Claude Code's SessionStart hook), `.cursor/rules/setup.mdc`, `.gemini/settings.json`, `.vscode/tasks.json` (using a `runOn: folderOpen` auto-execution trigger), and `.github/setup.js` for GitHub Actions workflow injection. This specifically targets developers using AI-assisted IDEs, since the backdoors execute automatically the next time a victim opens the poisoned repository.
Stolen data is exfiltrated over GitHub.com itself rather than attacker-registered domains, using GitHub's API as covert C2/dead-drop infrastructure: the malware creates private repositories under the attacker-controlled account `github.com/liuende501` (observed with 236 programmatically created repos, using Dune-themed — atreides, fedaykin, sardaukar — and mythology-themed — nemean-hydra-N, cerberus, chimera — naming conventions), encrypts harvested credentials with an embedded attacker RSA public key, and uploads them via the GitHub Contents API to paths of the form `repos/liuende501/{repo}/contents/results/results-{timestamp}.json`, spoofing a `python-requests/2.31.0` U
Weaknesses (CWE)
CWE-506, CWE-829, CWE-78, CWE-494
Target sectors: technology, softwaredevelopment, cloudservices, devops, aitooling
Target regions: Global
Detections & IOCs
As of 2026-07-27, this threat has 9 detection rule(s) across Splunk SPL, Microsoft KQL and Sigma, and 27 indicator(s) of compromise. Detection query text and full IOC values are available to authenticated users and programmatically via the Threadlinqs MCP server (Purple tier). View plans.
SUPPLY_CHAIN, HIGH, threat intelligence, cybersecurity, CVE-2026-45321, CVE-2026-48027, T1586, T1585, T1195.001, T1195.002, T1199, T1059.007, T1059.004, T1204.003, T1610, T1546