>>>>>>Once executed, this novel worm — dubbed Shai-Hulud — steals credentials, exfiltrates them, and attempts to find additional NPM packages in which to copy itself. The malicious code also attempts to leak data on GitHub by making private repositories public.<<<<<<
You should investigate the initial Entry and Execution to search through the logs with these IoCs / IoAs to find the right artifacts for Threat Hunting.
C2 / exfil endpoint used by the malware. Use webhook.site (dot replaced) when searching. Unit 42
Filename / Workflow
shai-hulud-workflow.yml
Malicious YAML workflow filename called out. Unit 42
GitHub repo name
Shai-Hulud
Malware creates public repo named Shai-Hulud to publish exfiltrated secrets. Unit 42
Tool abuse indicator
trufflehog
Legit tool abused by actors for secrets discovery — hunt for usage. Unit 42
Tool: trufflehog execution
Defender XDR Hunting
Other SOC Customer Case where Defender already flagged the malicious npm packages
2.1) Executions from Threat Actor - Steps
worm executes during the post-install phase of the compromised NPM packages, running a huge bundle.js script
code targets Linux and macOS machines, performing multiple operations in parallel to spread itself in the NPM package registry and steal sensitive information like credentials
Shai-Hulud conducts local system discovery
searching for sensitive details on the machine, including GitHub and NPM credentials, as well as credentials for AWS and GCP
spread itself and compromise other ecosystems
worm uses the GitHub user and their credentials ( ghp_* and gho_* tokens), iterating over the repositories belonging to the user
gain persistence and steal their associated secrets via a malicious GitHub action that is invoked on a “push” action
receive the credentials, the site https://webhook[.]site is used
trufflehog binary is downloaded and used to search for other sensitive credentials in the filesystem
Shai-Hulud also contains code that looks for AWS and GCP credentials, searching both locally in the file system and any Instance Metadata Service (IMDS) endpoints
malicious JavaScript checks again if the GitHub user is authenticated. If so, it creates a new GitHub repository named “Shai-Hulud”, where the previously found credentials are uploaded in a base64 encoded JSON file
2.2) Indicators of Compromise - Executions
3.) Initial Access
worm executes during the post-install phase of the compromised NPM packages, running a huge bundle.js script
4.) Finding through Threat Hunting
We hunted through the Datalake logs in the whole infrastructure and yes you guess it right we found a malicious execution not related to legit admin tasks which was also confirmed by the system owner (macOS user), so we saved the "life" of this company.
5.) Mitigation
Strengthen Supply Chain Controls
Pin dependencies to verified versions and use ‘npm ci’ instead of ‘npm install’ to enforce lockfile consistency. While this strengthens supplychain integrity, it adds complexity for developers (slower iteration, lockfile conflicts, harder testing of new versions). Whether to enforce strict reproducibility should be decided based on each team’s risk appetite and operational needs.
Conduct security awareness training for developers to identify phishing and credential harvesting attempts. Include this case-study to demonstrate the risk.
Integrate automated dependency scanning tools (e.g., Snyk, Semgrep, Mend.io, Socket.dev) into CI/CD pipelines to flag malicious or anomalous packages early.
Mirror critical open-source packages in private registries and vet updates before internal distribution.
Rebuild and Redeploy
Recompile and redeploy all applications that previously included compromised dependencies to remove malicious code from runtime environments.
For web applications, publish clean client-side builds immediately to eliminate malware exposure for new sessions.
Remove and Replace Malicious Packages
Uninstall compromised versions immediately and upgrade to patched releases (e.g., [email protected] or later).
If a patch is not out yet, roll back to the last known good version before the incident (e.g., downgrade [email protected] to 6.0.0) and lock your dependency there.
Perform a clean reinstall:
Delete the node_modules directory.
Clear the npm cache.
Regenerate lockfiles to ensure all code is sourced from trusted versions.
HOST and user
reset all passwords
clear NPM Cache
remove NPM node_modules
generate new package-lock.json
rotate All Tokens
restage the host
Secure Secrets and Tokens
Assume that secrets may have been exfiltrated from ‘build’ or ‘runtime’ environments where compromised packages were present.
Rotate all private keys, API tokens, and credentials used in affected CI/CD pipelines and applications.
Audit Dependencies
Inventory all applications, services, and build pipelines for use of affected package versions.
Use lockfiles (package-lock.json, yarn.lock) or a Software Composition Analysis (SCA) tool to pinpoint instances of vulnerable packages.
Use a read-only dependency scanner to identify compromised package versions listed in this advisory. For example, the Open Tools Vulnerable Packages Scanner supports npm, yarn, pnpm, and bun lockfiles, generates a JSON report, and can be integrated into CI pipelines to fail builds when a match is detected.
Begin with a scan only or dry run mode. Once confirmed, replace affected packages, regenerate lockfiles, and redeploy updated applications.
6.) Detection and Hunting
6.1) Sigma Rules
6.2) Linux Commandline Hunting
6.3) Hunting Queries Microsoft Defender XDR
6.4) Hunting Queries Palo Cortex XDR
6.5) Hunting Queries Tanium EDR
7.) Conclusion and Learning for a Hunter Blue
The NPM incident reveals Supply chain attacks are increasing in frequency. It is more important than ever to monitor third-party packages for malicious activity. Since malicious code can be hidden in many different ways, using runtime threat detection is critical to catching these attack
its definitely necessary to check during Hunting or Initial Triage how Malware was staged
-> showcasing how fruitful Compromise Assessment Hunting and Time Line Analysis can be and should be used in such cases -> it is essential.
#IOCs
ProcessCommandLine
sh -c "node bundle.js"
InitiatingProcessCommandLine
node /Users/<USERNAME>/.nvm/versions/node/v20.14.0/bin/npm install
Trufflehog Tool execution modification (rights) - Tool to search for Api keys, credentials, tokens,
chmod +x /Users/<USERNAME>/Workspaces/ivf/platform/frontend/apps/client-ivf/node_modules/@nativescript-community/ui-pulltorefresh/trufflehog
Trufflehog extraction
ProcessCommandLine
tar -xzf /Users/<USERNAME>/Workspaces/ivf/platform/frontend/apps/client-ivf/node_modules/@nativescript-community/ui-pulltorefresh/trufflehog_3.90.6_darwin_arm64.tar.gz -C /Users/<USERNAME>/Workspaces/ivf/platform/frontend/apps/client-ivf/node_modules/@nativescript-community/ui-pulltorefresh trufflehog
Other Cases
Filepath
/home/devops-agent-1/.npm/_cacache/content-v2/sha512/34/b8/00d4fe26f80010b9a7ad0ca97cf7d8709cf41df1c1745e37c85ffcdd3206bf92079a9d1167d0c3f6fc76ccc4f60d7897242a207fd4ce032e96f55d259cbc
npm (and the underlying cacache) stores downloaded package content in a content-addressable cache under ~/.npm/_cacache/content-v2/sha512/<first2>/<next2>/<fullhash>.
The path encodes a sha512-derived key (the 34/b8/... prefix is just sharding of the hash).
The file itself typically contains the compressed package tarball (or a data blob) as fetched from the registry (registry.npmjs.org, github, or mirrors).
###HUNT06 - Description: Detect malicious bundle.js file, trufflehog
Get Trace Executed Processes[unlimited,1758288047852|1758291646852,0,0,99,0,"","",".*(trufflehog).*","","",""] from all machines
Get Trace Executed Processes[unlimited,1758288047852|1758291646852,0,0,99,0,"","",".*(bundle.js).*","","",""] from all machines
Get Trace Executed Processes[unlimited,1758288047852|1758291646852,0,0,99,0,"","",".*(bundle\.js|trufflehog|tinycolor|node\_modules|chmod|sh -c).*","","",""] from all machines
###HUNT03 - MAL-Domain01-Hunting - Webhook Site
#######// Description: This query will check for Domain, DNS, Queryevents, Network Events, URL Infos in Mails and URL Click Events requesting suspicious Domains.
Get Trace DNS Queries[unlimited,1758287446087|1758291045087,1,0,100,0,"","",".*(webhook.site).*","",""] from all machines