Multiple popular npm scopes (including @zapier, @asyncapi, @postman, @posthog and @ensdomains) were compromised via account takeover and developer compromise to inject a stealthy two-stage loader (setup_bun.js → bun_environment.js) that installs or locates the Bun runtime and runs an obfuscated 10MB payload in the background while suppressing all output. The malicious code harvests CI and cloud credentials (GITHUB_TOKEN, NPM_TOKEN, AWS keys), performs aggressive multi-region cloud secret enumeration, propagates by using stolen NPM tokens to republish packages, and includes destructive file-shredding if no valid tokens are found. #Sha1-Hulud #Bun
Keypoints
- Attacker gained access via maintainer account takeover/developer compromise and injected a preinstall script (setup_bun.js) plus a bundled obfuscated payload (bun_environment.js) into many npm packages.
- The compromise uses a stealthy two-stage loader that downloads/locates the Bun runtime, caches it, spawns a detached Bun process with POSTINSTALL_BG=1, suppresses stdout/stderr, and allows installation to complete normally while the payload runs in background.
- The malware performs C2 discovery and self-healing by searching GitHub for the beacon phrase “Sha1-Hulud: The Second Coming.” to find stored GitHub access tokens which it decodes and reuses for exfiltration and re-seeding victims.
- It aggressively fingerprints environments and CI/CD metadata, captures environment variables (including GITHUB_TOKEN, NPM_TOKEN, AWS keys), runs TruffleHog to scan the filesystem for secrets, and enumerates AWS/GCP/Azure secrets across all regions.
- On Linux GitHub Actions runners it attempts privilege escalation via sudoers injection (including abusing privileged Docker) and then manipulates DNS/firewall (systemd-resolved, iptables) to control networking and block security telemetry.
- Data exfiltration is performed by creating GitHub repositories in victims’ accounts, uploading multiple JSON files encoded in triple-base64, and propagation is automated by validating NPM tokens and republishing patched versions of maintainer packages.
MITRE Techniques
- [T1195 ] Supply Chain Compromise – Compromised maintainer/developer accounts and injected malicious code into legitimate packages (‘Multiple npm packages … have been compromised via account takeover/developer compromise.’)
- [T1574 ] Hijack Execution Flow – Added and relied on npm preinstall script to execute attacker code during package install (‘Added a preinstall script setup_bun.js in the package.json file’)
- [T1059 ] Command and Scripting Interpreter – Executes JavaScript loader and bundled payload to perform runtime actions (‘When npm runs the preinstall script, it executes setup_bun.js’)
- [T1105 ] Ingress Tool Transfer – Downloads Bun runtime and TruffleHog binary for execution and secret discovery (‘Downloads or locates the Bun runtime for that platform’; ‘Downloads TruffleHog binary from github.com/trufflesecurity/trufflehog/releases’)
- [T1078 ] Valid Accounts – Uses recovered GitHub access tokens and NPM tokens for authenticated operations and exfiltration (‘Reads a stored file containing a GitHub access token’ ; uses token for exfiltration)
- [T1537 ] Transfer Data to Cloud Account / Exfiltration Over Web Service – Creates repositories and uploads encoded stolen data to GitHub to exfiltrate secrets (‘Creates a GitHub repository in the victim’s account … description: “Sha1-Hulud: The Second Coming.”‘; ‘All exfiltrated data is encoded through three layers of base64’)
- [T1543 ] Create or Modify System Process – Spawns a detached background Bun process to run the payload with suppressed output (‘Spawns a detached Bun process running bun_environment.js with POSTINSTALL_BG=1 flag’)
- [T1485 ] Data Destruction – Executes file deletion and shredding when no valid tokens are found to destroy user data (‘del /F /Q /S “%USERPROFILE%*” … cipher /W:%USERPROFILE%’ ; ‘shred -uvz -n 1 … find “$HOME” -depth -type d -empty -delete’)
- [T1490 ] Inhibit System Recovery / Modify System Network Configuration – After privilege escalation, stops systemd-resolved, replaces DNS config and flushes iptables to control network and block security updates/telemetry (‘Stops systemd-resolved … Restarts the resolver … sudo iptables -F OUTPUT; sudo iptables -F DOCKER-USER’)
Indicators of Compromise
- [File names ] malicious package modifications – setup_bun.js, bun_environment.js (injected into package tarballs and referenced by package.json preinstall scripts)
- [Beacon phrase / GitHub repo description ] C2/search signature – ‘Sha1-Hulud: The Second Coming.’ (used as a repository description and GitHub search beacon to find stored tokens)
- [Compromised package names ] infected npm packages (examples) – @zapier/ai-actions (v0.1.18–0.1.20), @asyncapi/cli (v4.1.2, v4.1.3), @postman/node-keytar (v7.9.4–7.9.6), @ensdomains/ensjs (v4.0.3), and many others (dozens/hundreds listed)
- [Environment variables / credentials ] captured secrets from CI and hosts – GITHUB_TOKEN, NPM_TOKEN, AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY (harvested from process.env and CI metadata)
- [Download sources / cached binaries ] tool distribution and cache paths – github.com/trufflesecurity/trufflehog/releases (TruffleHog); Bun binary cached in ~/.cache or platform-equivalent locations
Read more: https://socket.dev/blog/shai-hulud-strikes-again-v2