Shai-Hulud npm Stealer Uses Ethereum Contract to Resolve Its C2

Summary
Netskope analyzed 28 malicious npm package versions across four namespaces. Their stealer collected developer and CI/CD credentials, then sent encrypted data to a C2 domain resolved at runtime through an Ethereum contract.
Key points
- The 28 malicious package versions were published on August 4, 2026, across @or-sdk, @onereach, @servicetitan, and @umacloud namespaces.
- During installation, packages downloaded a signed Bun runtime, executed an obfuscated JavaScript stealer, and deleted the runtime afterward.
- The payload targeted SSH keys, AWS credentials, Docker authentication, Jenkins secrets, GitHub CLI tokens, and other secrets; it also enumerated AWS services across 17 regions.
- The stealer resolved its exfiltration host at runtime using an Ethereum smart-contract call, trying three public RPC providers; the reported endpoint was npm-cache[.]com/router.
- The recovered payload matched a sample used in a same-day keyv package family compromise, linking the activity to a shared campaign toolset.
- Researchers could not determine whether the packages were published using stolen organization tokens, maintainer-machine propagation, or stolen GitHub Actions OIDC credentials.
Article Details
- Attack Vectors
- Malicious npm package versions published under four unrelated enterprise namespaces execute an obfuscated JavaScript stealer through an install hook.
- The install hook downloads a signed Bun runtime from GitHub, runs the payload under it, and deletes the runtime afterward.
- The payload collects SSH private keys, AWS credentials, Docker registry authentication, Jenkins secrets, and /etc/shadow; it also enumerates AWS Secrets Manager and Systems Manager Parameter Store and queries EC2 instance metadata.
- The payload resolves its exfiltration host at runtime through an Ethereum smart-contract call and POSTs an encrypted bundle to the resolved endpoint.
- Defensive Notes
- Detection should focus on behavior: the tarballs contain no malicious binary, and the downloaded Bun executable is legitimately signed.
- Monitor npm package installation for unexpected Bun downloads and execution, credential and secret-store access, EC2 metadata queries, Ethereum RPC calls, and outbound POSTs to npm-cache.com/router.
- The article says the listed public Ethereum RPC providers are legitimate services abused for C2 resolution; use them for detection and alerting rather than blind blocking.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| DOMAIN | npm-cache[.]com | Runtime-resolved exfiltration endpoint; the payload POSTs an encrypted bundle to /router. |
| IPV4 | 104[.]21[.]35[.]216 | Reported resolution of the exfiltration domain npm-cache.com. |
| IPV4 | 172[.]67[.]179[.]231 | Reported resolution of the exfiltration domain npm-cache.com. |
| SHA256 | 9fc2570b7cef51c1b8df116d144d11ff4096357be7d2c4c6367cfc2509cf1bcc | SHA256 of the stealer payload, reported identical to the keyv-family sample. |
MITRE ATT&CK
T1027 · Obfuscated Files or InformationThe stealer's JavaScript is described as obfuscated.T1041 · Exfiltration Over C2 ChannelThe payload POSTs an encrypted bundle of collected data to its runtime-resolved exfiltration endpoint.T1059.007 · JavaScriptThe install hook executes an obfuscated JavaScript stealer under the downloaded Bun runtime.
Threat Actors
Products
BunAt install time, the packages fetch a signed Bun runtime release from GitHub, execute an obfuscated JavaScript stealer under it, and delete the runtime.npmNetskope Threat Labs identified and analyzed 28 malicious npm package versions published across four unrelated enterprise namespaces (@servicetitan, @or-sdk, @onereach, and @umacloud) on 2026-08-04.