ReversingLabs researchers discovered a self-replicating npm worm named Shai-hulud that compromises developer accounts to inject a malicious bundle.js into maintained packages, adding postinstall scripts that execute token-stealing and repo-exfiltration routines. The worm steals npm, GitHub, AWS and GCP tokens (using TruffleHog to find secrets), exfiltrates data to attacker-controlled GitHub repositories/branches, and attempts to make private repos public—impacting hundreds of packages including ngx-bootstrap, ng2-file-upload, and @ctrl/tinycolor. #Shai-hulud #ngx-bootstrap #TruffleHog
Keypoints
- ReversingLabs detected Shai-hulud on September 15; it is a self-replicating worm that injects malicious code into npm packages maintained by compromised developer accounts.
- The worm adds a postinstall script and a malicious bundle.js to package releases, which executes on install and harvests environment and cloud service tokens.
- Stolen secrets are double Base64-encoded and exfiltrated to newly created GitHub repositories named “Shai-Hulud Repository” or via malicious branches/workflows that POST data to an attacker-controlled webhook.
- The worm installs and uses TruffleHog to increase secret discovery (over 800 secret types) and attempts to create public “-migration” copies of private repositories to expose source code and embedded secrets.
- Hundreds of npm packages were compromised within ~24 hours, including high-impact packages (ngx-bootstrap, ng2-file-upload, @ctrl/tinycolor) totaling millions of weekly downloads.
- Initial compromise vector is unknown but resembles recent incidents (Nx compromise, Qix compromise) that used social engineering or abused vulnerable GitHub Actions for exfiltration.
- Recommended defenses include monitoring for anomalous package updates, enforcing 2FA and token hygiene, scanning for suspicious postinstall scripts, and implementing an emergency publication pause for registries.
MITRE Techniques
- [Tactic: Initial Access / Account Compromise — not a specific Txxxx cited] Account compromise – attackers seized npm developer accounts (possible phishing or abuse of CI/CD) to publish malicious package versions (“the exact nature of the initial compromise is not known…social engineering is a likely tool”).
- [T1608 ] Modify Software Supply Chain – The worm injects a malicious postinstall script and bundle.js into legitimate npm packages to propagate (“adds a postinstall script to the package.json file that adds the bundle.js file to the package archive”).
- [T1552 ] Unsecured Credentials – Token theft of environment and cloud service tokens (npm, GitHub, AWS, GCP) by searching environment variables and files (“the worm’s bundle script searches for environment tokens, focusing on npm, GitHub, AWS, GCP, etc.”).
- [T1083 ] File and Directory Discovery – Use of TruffleHog to search repositories and files for secrets (“the worm also installs TruffleHog…that can detect more than 800 different types of secrets”).
- [T1041 ] Exfiltration Over C2 Channel – Exfiltration to attacker-controlled GitHub repositories and to a webhook URL with double Base64-encoded data (“exfiltrated to newly created GitHub repositories…double Base64-encoded and uploaded to a file named data.json”; “exfiltrate the tokens…to the url hxxps://webhook.site/…”).
- [T1098 ] Develop Capabilities: Account Manipulation – Creation of new branches and workflows and creation of public copies of private repos (“creating a new branch named shai-hulud…upload .github/workflows/shai-hulud-workflow.yml” and “create a public copy of all private repositories…suffix -migration”).
- [T1609 ] Data from Information Repositories – Exposure and theft of private repository contents by migrating private repos to public copies (“the worm tries to create a public copy of all private repositories belonging to the compromised user”).
Indicators of Compromise
- [Package names & versions] Compromised npm packages – rxnt-authentication v0.0.3 (Patient Zero), ngx-bootstrap (infected versions), ng2-file-upload (infected versions), @ctrl/tinycolor (infected versions), and hundreds more.
- [File names / scripts] Malicious files and scripts – bundle.js (malicious payload executed via postinstall), package.json containing added postinstall scripts.
- [GitHub repositories / descriptions] Attacker-created repos and repo descriptions – repositories named “Shai-Hulud Repository” with description “Shai-Hulud Repository”, and public “-migration” repositories with description “Shai-Hulud Migration” (close to 700 results observed).
- [GitHub branches / workflow files] Malicious branches and workflow path – branch named shai-hulud and workflow .github/workflows/shai-hulud-workflow.yml that exfiltrates tokens to hxxps://webhook.site/bb8ca5f6-4175-45d2-b042-fc9ebb8170b7.
- [Exfiltration artifact] Data file in repo – data.json containing double Base64-encoded exfiltrated data (exfiltrated secrets stored in attacker-created GitHub repos).
- [Tools] Secret discovery tool – TruffleHog installed by the worm to enumerate secrets (used to find >800 secret types).
Read more: https://www.reversinglabs.com/blog/shai-hulud-worm-npm