Shai-Hulud strikes again: CHAINDROP worm hits 400+ npm packages

Shai-Hulud strikes again: CHAINDROP worm hits 400+ npm packages
Elastic Security Labs identified a Shai-Hulud campaign that compromised the keyv maintainer and spread a self-propagating CHAINDROP worm through trojanized npm packages, affecting hundreds of packages and exposing a massive developer ecosystem. The operation steals credentials, uses smart-contract-based C2 resolution and GitHub-backed fallback exfiltration, and targets AI, cloud, GitHub, SSH, Kubernetes, and npm secrets. #ShaiHulud #CHAINDROP #keyv #Claude #OpenAI #Anthropic #npm-cache.com #awqhnjewqjkl.icu

Keypoints

  • The campaign targeted the maintainer of keyv, a widely used key-value storage library, and trojanized the monorepo.
  • A self-propagating worm named CHAINDROP used stolen npm credentials to backdoor every package the maintainer could publish.
  • More than 400 unique npm packages were compromised, with keyv and related packages reaching hundreds of millions of downloads.
  • Execution began through a package.json preinstall hook, requiring no further victim interaction after installation.
  • The malware was cross-platform and used dropper files such as setup.mjs along with payloads named Math_Symbol.js and math_init.js.
  • Credential theft focused on AI tooling, cloud providers, GitHub, SSH keys, Kubernetes tokens, HashiCorp Vault, and npm tokens.
  • C2 and exfiltration were designed for resilience, using an Ethereum smart contract, fallback domains, GitHub commit-history validation, and even public GitHub repositories.

MITRE Techniques

  • [T1195.001] Supply Chain Compromise – The attackers trojanized the keyv monorepo and republished infected packages to downstream users (‘trojanized the monorepo’ / ‘downloads the latest published tarball… injects the malicious components’).
  • [T1546.004] Event Triggered Execution: Unix Shell Auto-Start? – The malware uses package.json preinstall hooks to run code before installation (‘will run arbitrary commands before a package is installed’).
  • [T1105] Ingress Tool Transfer – setup.mjs downloads bun directly from the official release page when it is missing (‘download bun v1.3.13 directly from the official release page’).
  • [T1059.006] Command and Scripting Interpreter: JavaScript – The payload and droppers are JavaScript-based and executed with node/bun (‘node .claude/setup.mjs’ / ‘bun executing the obfuscated JavaScript payload’).
  • [T1027] Obfuscated Files or Information – The payload is heavily obfuscated with control-flow flattening and Base91 (‘heavily obfuscated at 711 kilobytes’).
  • [T1555] Credentials from Password Stores – The collector scans many credential stores on the developer machine (‘credential harvester, scanning over 300 unique patterns’).
  • [T1528] Steal Application Access Token – The malware targets tokens from GitHub, npm, and other services (‘GitHub (PATs, JWT, session tokens)… npm tokens’).
  • [T1095] Non-Application Layer Protocol – The payload uses RPC providers as fallbacks to query Ethereum infrastructure (‘uses multiple RPC providers as fallbacks’).
  • [T1568.002] Dynamic Resolution: Domain Generation Algorithms? – The C2 endpoint is resolved at runtime via an Ethereum smart contract (‘queries an Ethereum smart contract… to retrieve the current exfiltration endpoint at runtime’).
  • [T1102.001] Web Service: Dead Drop Resolver – The malware uses GitHub commit history as a fallback to discover the C2 domain (‘searches GitHub commit history for a cryptographically signed marker’).
  • [T1041] Exfiltration Over C2 Channel – Stolen credentials are encrypted and exfiltrated to attacker infrastructure (‘Only the attacker… can decrypt the data’).
  • [T1578] Modify Cloud Compute Infrastructure – The worm injects malicious hooks into repositories and repackages them for publication (‘injecting .claude/settings.json and .vscode/tasks.json’).

Indicators of Compromise

  • [File names ] Droppers/payloads used by the worm – setup.mjs, Math_Symbol.js, and math_init.js
  • [SHA-256 hashes ] Payload and dropper hashes referenced in the research – 9fc2570b7cef51c1b8df116d144d11ff4096357be7d2c4c6367cfc2509cf1bcc, fd3ca4007b225fdf8de7af4345a19179d5efa8c4bb9205f88cda806e5684b1eb, and 54dc7ea54a1317cca0e890a2770630cf7fa6c97813e0cb9d2caa93012b350668
  • [Domains ] Dead-drop/C2 domains observed during detonation – awqhnjewqjkl[.]icu, npm-cache[.]com
  • [Ethereum contract address ] Runtime C2 resolver used by CHAINDROP – 0xE1f2395ee43e45A1556EC6438a88c31B83493103
  • [GitHub marker / string ] Fallback validation marker and intimidation string – thebeautifulmarchoftime, IfYouBlockThisAPIKeyItWillCrashTheLiveProductionServersOfAllThirdPartyClients


Read more: https://www.elastic.co/security-labs/shai-hulud-chaindrop-npm-supply-chain