Mini Shai-Hulud npm Worm Spreads to 444 Packages, Stealing Developer Credentials

· Original article ↗

Summary

A Mini Shai-Hulud npm worm has spread to at least 444 packages, stealing developer and CI credentials, exfiltrating data, and using compromised accounts to poison packages and repositories.

Key points

  • The worm starts through an npm preinstall script that launches an obfuscated JavaScript payload using Bun.
  • It searches developer machines and CI runners for credentials, configuration files, and secrets across services including GitHub, npm, AWS, Kubernetes, and Vault.
  • Stolen data is sent to attacker-controlled infrastructure or stored in public GitHub repositories created as dead drops.
  • The worm uses stolen credentials and GitHub Actions OIDC access to publish poisoned npm packages and inject malicious workflows or repository files.
  • Its command server can return JavaScript that the payload evaluates on the infected system, enabling remote code execution.
  • The article advises isolating affected hosts, preserving logs, rebuilding CI runners, revoking sessions, rotating exposed credentials, and checking GitHub and npm activity.

Article Details

Attack Vectors
  • A malicious npm package runs a preinstall script that launches setup.mjs and the JavaScript payload using Bun.
  • Stolen credentials are used to publish poisoned npm package releases, inject GitHub Actions workflows, and commit malicious files across repository branches.
  • The payload collects developer and CI credentials, exfiltrates them to a resolved C2 destination or public GitHub repositories, and evaluates JavaScript returned by the C2 server.
  • The worm can install GitHub-token-monitor persistence and target developer environments through malicious .vscode tasks and .claude configuration.
Defensive Notes
  • Isolate affected workstations and CI runners, preserve relevant logs, and rebuild disposable runners from trusted images.
  • Revoke active sessions and rotate credentials available to the affected process from a known-clean system.
  • Review GitHub for unexpected public repositories containing results/, suspicious repository descriptions, unexpected branch commits, workflow changes, OIDC requests, and repository-creation or contents/results/ API activity.
  • Review npm packages controlled by affected maintainers for unexpected patch releases, a new @opensearch/setup optional dependency, unfamiliar publishing activity, OIDC exchanges, and provenance or trusted-publishing changes.
  • Detection should focus on the /router path, npm/Bun process ancestry, credential-access behavior, unusual GitHub repository creation, and subsequent package publication rather than relying only on domain blocklists.

Indicators of compromise

TypeIndicatorContext
DOMAINnpm-cache[.]comAttacker-controlled domain resolved by the malware for data exfiltration.
IPV4169[.]254[.]169[.]254Cloud metadata endpoint queried by the malware to obtain workload credentials.
IPV4169[.]254[.]170[.]2Cloud workload-credential endpoint queried by the malware.
SHA2569fc2570b7cef51c1b8df116d144d11ff4096357be7d2c4c6367cfc2509cf1bccSHA-256 hash of the malicious math_init.js and Math_Symbol.js payloads.
SHA256fd3ca4007b225fdf8de7af4345a19179d5efa8c4bb9205f88cda806e5684b1ebSHA-256 hash of the malicious setup.mjs dropper.
URLhxxps[:]//npm-cache[.]com/routerMalicious exfiltration endpoint used by the malware.

MITRE ATT&CK

People

Malware

Vendors

Products

Related Articles