Cymulate named a Customers' Choice in 2025 Gartner® Peer Insights™
Learn More
New Gartner® Report: Strategic Roadmap for CTEM
Learn More
New Integration Partnership with WIZ!
Learn More
Threat Exposure Validation Impact Report 2025
Learn More

Shai-Hulud 2.0: NPM Supply Chain Attack Exposes the SDLC's Weakest Link 

By: Cymulate Research Lab

Last Updated: December 12, 2025

Executive summary 

The "Shai-Hulud" supply chain campaign has returned, striking harder and smarter than before. This latest wave of attacks has compromised hundreds of popular npm packages, including those from Zapier, ENS Domains and Postman, turning the software development lifecycle (SDLC) into a weapon against itself. 

This campaign burrows deep into development environments, leveraging compromised maintainer accounts to publish trojanized packages. However, unlike simple script-kiddie malware, Shai-Hulud 2.0 exhibits sophisticated behaviors: context-aware execution (CI vs. Developer machine), Docker breakouts and novel persistence mechanisms via GitHub Actions. 

All organizations utilizing the Node.js ecosystem (npm) and automated build systems (CI/CD pipelines) are potentially affected. This exposure is particularly critical for the technology, finance and software development sectors due to their heavy reliance on cloud platforms (AWS, GCP, Azure) and Source Code Management (SCM) credentials accessible during the build process. The attack targets the global npm registry, making it worldwide in scope. 

The potential impact is severe: full compromise of the CI/CD pipeline and underlying cloud identity. This grants attackers the ability to pivot from a low-privilege build container to an elevated cloud role (via IMDS theft), resulting in unauthorized data exfiltration, financial losses, service disruption and the potential for the malware to self-propagate further into the organization's codebase. 

At Cymulate, we have reverse-engineered these attack vectors and created safe, executable advanced simulations to help you test your defenses. We’ll take a deep technical dive into the specific execution flows of Shai-Hulud 2.0 and the more than 12 new attack scenarios now available in Cymulate Exposure Validation. 

Attack overview 

The attack logic is engineered for maximum speed and stealth. It executes immediately via the installation hook, launching an instantaneous, context-aware malicious operation designed for reconnaissance, credential harvesting, persistence, privilege escalation, secrets exfiltration and bypassing both endpoint and CI/CD security monitoring. 

Below you can find the Shai-Hulud 2.0 Attack Overview provided with links to the related Scenarios created for each Phase of the attack, so you can easily navigate to the parts that interest you the most in this blog. 

Phase 1: Initial compromise 

Weaponizing NPM lifecycle hooks scenarios  

The attack begins when a developer runs npm install on a compromised package. The malicious preinstall script in package.json automatically executes obfuscated JavaScript code (setup_bun.js and bun_environment.js) that performs immediate system reconnaissance and CI/CD environment fingerprinting. This is the initial foothold that triggers the entire attack chain, requiring no user interaction beyond the normal package installation. 

Phase 2: Execution and tactical evasion  

CI vs. Developer detection scenario 

The payload begins with a layer of extreme defense evasion. The bun_environment.js file is massive and utilizes polymorphic obfuscation (including huge hex-encoded arrays and pre-execution anti-analysis loops) to defeat signature-based security products and static analysis tools. 

The script then executes with contextual intelligence to optimize its flow for evasion: 

  • CI/CD environments: If the script detects indicators like GITHUB_ACTIONS or GITLAB_CI, it proceeds to the full harvest and exfiltration immediately, prioritizing speed in a time-sensitive environment. 
  • Developer machines: To maintain stealth, the malware avoids blocking the user's terminal. It employs process forking via Bun.spawn to create a completely detached background process. The original npm install command then exits instantly, giving the user the illusion of a clean, normal installation while the hidden payload executes the full credential theft silently in the background. 

Phase 3: The harvest – credential theft 

Once running in a safe context, the payload initiates a comprehensive lateral access sweep (collectAndExfiltrate), performing a targeted theft across the build pipeline and cloud estate: 

  • The initial and highest-value objective is to capture the victim's full GitHub Personal Access Token (PAT), which is sourced from environment variables (GITHUB_TOKEN) or configuration files (~/.netrc). 
  • Workflow injection and workflow exfiltration scenarios – When running inside GitHub Actions, the malware creates a workflow that uses the expression ${{ toJSON(secrets) }} to dump ALL repository secrets into a file. These secrets are then uploaded as artifacts or exfiltrated via base64-encoded log output, a technique that harvests secrets from workflow logs even if the original workflow is deleted. 
  • Cloud reconnaissance and credential theft scenario – Using any acquired credentials (including those from IMDS probes), the script launches concurrent, credentialed API calls to enumerate and retrieve secrets from high-value cloud vaults, including AWS Secrets ManagerGCP Secret Manager and Azure Key Vault
  • TruffleHog Secret Scanner scenario – Beyond simple environment dumps, the script performs host fingerprinting and notably executes TruffleHog to scan the local repository workspace or environment for any further committed or generated secrets. 

Phase 4: Persistence - maintaining access 

  • The "discussion" backdoor – The malware injects a malicious GitHub Actions workflow (.github/workflows/discussion.yaml) containing a command injection vulnerability that executes arbitrary code from repository discussion bodies. It also registers the compromised machine as a self-hosted GitHub Actions runner named "SHA1HULUD," giving the attacker persistent remote code execution capabilities on the victim's infrastructure. 
  • Docker breakout – On compromised CI runners with Docker access, the malware runs a privileged container that mounts the host filesystem (-v /:/host) and modifies /etc/sudoers.d/ to grant passwordless root access. This privilege escalation ensures the attacker maintains persistent root-level access to the runner's infrastructure, surviving container restarts and job completions. 
  • In-flight package subversion via race condition – This technique is a core element of the Shai-Hulud kill chain, representing an advanced post-exploitation persistence mechanism. The initial payload races the npm install process to patch vital dependency files within the node_modules directory, effectively poisoning the build environment. The resulting injected code uses character code obfuscation to conceal the C2 channel, ensuring that the malicious code executes whenever the compromised package is imported by any application, thereby trojanizing a trusted dependency for resilient, enduring access. 

Phase 5: Covert artifact exfiltration 

  • Covert artifact exfiltration and persistence via SCM – The harvested secrets are compiled into structured JSON artifacts, specifically separating them into files such as environment.json and cloud.json. The attacker then uses the stolen GitHub PAT (Personal Access Token) to create a new public repository under the victim’s account, named with a random UUID, and proceeds to exfiltrate the collected secrets to this public repository.

The entry point – hooks and race conditions 

NPM packages are allowed to define scripts in their package.json file that run at specific stages of the installation process. The malware exploits these scripts, chiefly preinstall and postinstall, to achieve instantaneous, covert execution under the privileges of the executing user or Continuous Integration/Continuous Deployment (CI/CD) runner. 

The attack begins the moment a developer or CI pipeline runs npm install. Shai-Hulud 2.0 doesn't wait for the code to be imported; it strikes during the installation lifecycle. 

Weaponizing NPM lifecycle hooks 

Shai-Hulud's success lies in its ability to hijack the native NPM installation process itself, utilizing powerful features known as lifecycle hooks to execute its malicious payload. In a critical maneuver for evasion, the Shai Hulud 2 malware utilizes the preinstall hook to execute its payload, such as bun_environment.js, before the package is even fully laid out on the disk. This ensures the malicious script runs at the earliest possible stage in the installation process. 

Lifecycle hook Execution timing Shai-Hulud usage Attack advantage 
postinstall Runs after the package, and its dependencies are fully installed. Used in the initial wave for immediate, direct exfiltration of basic environment variables and credentials. A simple, widely utilized vector for arbitrary code execution and quick data theft. 
preinstall Runs before the package files are fully laid out on the disk. Used in the advanced Shai-Hulud 2.0 wave to execute the payload (like bun_environment.js) at the earliest possible stage of installation. Ensures the malicious script runs even if the package installation technically fails, increasing the attack success rate and allowing it to launch before standard post-installation checks. 

The simulation  

To test your defenses against both the original and advanced Shai-Hulud hook execution methods, we created three new attack scenarios for Cymulate Exposure Validation: 

A. Preinstall hook execution simulation  

Attack Scenario: NPM Supply Chain – Preinstall Hook Execution faithfully mimics the critical maneuver of Shai-Hulud 2.0: 

The simulation creates a temporary package directory (malicious-pkg) containing the following key files: 

  • package.json (The Manifest): This file is the mechanism that ensures the malicious code runs. It contains the key script definition, as you can see from the attack scenario execution output: 

The "preinstall" script executes the command node setup_bun.js. This hook automatically runs when a user or CI pipeline executes npm install. 

setup_bun.js (Execution Stager): This entry-point script, executed by the preinstall hook, manages the attack's initial staging. Its primary action is to check if the Bun runtime environment is available and then bootstrap the core reconnaissance payload (bun_environment.js) by calling its main function, runRecon().  

The script finalizes the execution by writing the full JSON results of the reconnaissance scan to a file named cicd_recon_result.json within the package directory.

  • bun_environment.js (The Payload Module): This file contains the obfuscated JavaScript logic that performs the actual data collection, mimicking the real shai-hulud v2 malware analysis. 

The preinstall hook action (reconnaissance and harvesting) 

When the user runs npm install, the preinstall hook executes the JavaScript payload in multiple phases: 

Phase 1: NPM preinstall hook execution and fingerprinting 

The malicious script first performs basic system fingerprinting, capturing details that help an attacker determine the execution environment. 

  • System information: It collects the system's platform, architecture, hostname and OS user. 
  • Obfuscation: The code is intentionally obfuscated (using array lookups like _0x4a8f and function aliases) to evade simple signature-based detection. 

Phase 2: CI/CD credential harvesting 

The script specifically looks for environment variables that indicate it is running inside a CI/CD pipeline, which are rich targets for credentials. 

  • CI/CD detection: It checks for variables from major CI/CD providers, including GITHUB_ACTIONS, BUILDKITE, CODEBUILD_BUILD_NUMBER and CIRCLE_SHA1, among others. 
  • Token discovery: The script scans environment variables for known token names such as GITHUB_TOKEN, GH_TOKEN, NPM_TOKEN and NODE_AUTH_TOKEN. All discovered token values are masked in the simulation output to prevent accidental exposure. 

Phase 3: Privilege check and simulated exfiltration 

Following the initial reconnaissance, the simulation proceeds to test for privilege escalation vectors and conclude with a safe, simulated exfiltration attempt: 

GitHub actions privilege check: The script attempts to identify potential privilege escalation vectors. 

  • It checks specifically if the package is executed within a GitHub Actions Linux runner. 
  • The scenario simulates a sudoers access check using sudo -n true in a READ-ONLY manner. 
  • It also simulates defense evasion technique by flushing the iptables firewall rules (which clears all existing firewall rules), not before taking a backup and immediately restoring the rules after the check to make sure no real harm is done. 
  • The goal is to report on potential privilege escalation opportunities that an attacker could exploit and simulate defense evasion techniques. 

Exfiltration simulation: The final step mimics the actual data theft without compromising security. 

  • A local HTTP server is used to simulate the Command and Control (C2) endpoint for exfiltration. You can also configure the scenario to send the exfiltration data to your own server of choice by providing the server address in the attack scenario input arguments. 
  • This demonstrates a POST-based data theft technique. 
  • Crucially, no actual data is sent to external servers unless you change the configurations yourself
  • The scenario ensures that no system configurations are modified during this process. 

B. ShadowPost exfiltration simulation (postinstall vector) 

Cymulate Exposure Validation attack scenarios 

  1. NPM Supply Chain - ShadowPost Postinstall Exfiltration (Linux & Mac)  
  2. NPM Supply Chain - ShadowPost Postinstall Exfiltration (Windows) 

Our ShadowPost simulation targets the mechanism of this immediate, direct compromise by testing your runtime and network defenses across all major platforms: 

We deploy two distinct attack scenarios: one for Linux/macOS utilizing native Shell commands and another for Windows using PowerShell

These simulations create a temporary package that consists of two key files: 

  • package.json (The Manifest): This file defines the package metadata and crucially, the script that runs after installation. 

The key malicious element is the "postinstall" entry, which is configured to execute the separate shell script using bash. This ensures that running the npm install command triggers the arbitrary code execution. 

  • postinstall.sh (The Malicious Payload): This is the shell script that performs the actual data exfiltration. The postinstall.sh is designed to use curl to send data to a safe, remote listener.  
  • When npm install is run, the postinstall script runs automatically. The script gathers system information (reconnaissance) and then uses curl to perform an HTTP POST request to a configured webhook URL with the exfiltration data. 

This process effectively simulates a supply-chain attack where a seemingly harmless package silently runs a malicious script during installation to send information to an attacker-controlled endpoint. 

In-flight package subversion via race condition 

Attack scenario: NPM supply chain - race condition package patching 

Sophisticated adversaries are continually developing tactics to evade detection, moving beyond well-known mechanisms like postinstall hooks. One of the most devious techniques observed is the exploitation of a Race Condition within the package manager's I/O operations, allowing for the subversion of code in-flight. 

The attack  

The core of this attack relies on a precise timing vulnerability: 

  1. The setup: The malicious actor initiates a standard npm installation for a legitimate, widely used dependency (e.g., is-buffer). This installation begins fetching and writing the package files to the node_modules directory. 
  2. The race: Simultaneously, a high-speed background process "races" the installer. Its goal is to locate and patch the package's core file (node_modules/is-buffer/index.js) directly on the disk during the brief window after the file is written but before the installation process officially completes. 
  3. The compromise: If the race is won, the file is successfully patched with a malicious payload. Any application subsequently loading the package will execute the injected code, effectively subverting a core dependency dynamically. This method bypasses many standard integrity checks, as the original package published to the registry remains untampered. 

The simulation  

Our simulation rigorously validates this dynamic attack chain: 

  • Race Condition & Injection: We replicate the in-flight file patching process, injecting a stealthy, Node.js-payload into the targeted dependency. 

  • Execution and evasion: The scenario then simulates a host application loading the package (require("is-buffer")), which triggers the malicious code. The injected payload uses the native http module for C2 communication and employs Character Code Array Obfuscation for its C2 URL, a technique designed to hide the exfiltration endpoint from static security scanners. 

  • Targeted exfiltration: Once we require the patched module, the module will exfiltrate test data to the webhook server configured in the attack scenario, to mimic the real exfiltration done in the shai-hulud attack. 

Phase 2: Context-aware reconnaissance 

Shai-Hulud 2.0 doesn't just breach your defenses—it learns them. The malware's primary phase is deep reconnaissance, where it intelligently differentiates between a high-value CI/CD runner and a stealth-required developer's workstation. 

CI vs. Developer detection - Adaptive credential harvesting and secret scanning 

Attack scenario: NPM supply chain - CI detection, credential harvesting and secret scanning 

The most advanced supply chain malware, exemplified by the latest Shai-Hulud variants, is highly intelligent and environment-aware. It does not execute a one-size-fits-all payload; instead, it performs deep reconnaissance to maximize impact while minimizing its chances of detection. 

The attack   

This threat model targets the distinct operational difference between an automated CI/CD pipeline and a developer's local machine: 

Environment Malware tactic Security implication 
CI/CD pipeline Synchronous rxecution: The malware first detects CI environment variables (e.g., GITHUB_ACTIONS, BUILDKITE, CIRCLE_SHA1). It then executes its theft payload synchronously, keeping the runner process alive just long enough to ensure comprehensive secret harvesting before the build fails or times out. Maximum credential theft: CI runners often hold the most powerful secrets (Cloud keys, deployment tokens). 
Developer workstation Asynchronous stealth: On a developer's machine, the payload runs asynchronously in a background process. This prevents the infection from blocking the build or alerting the developer to unusual delays, providing effective, long-term persistence and credential scraping. Long-term persistence: Avoids detection and allows theft of local developer secrets (SSH keys, config files, personal tokens). 

The simulation  

Our comprehensive simulation, "NPM Supply Chain - CI Detection, Credential Harvesting & Secret Scanning," replicates this adaptive intelligence across the entire attack surface: 

  1. Environmental fingerprinting: The module precisely determines the execution environment to validate the synchronous/asynchronous behavioral shift. 

2. Targeted harvesting: This simulates a credential scraper, systematically seeking out high-value authentication files from default locations, including: 

  • Cloud provider credential files (~/.aws/credentials, Azure/GCP tokens). 
  • Key access tokens (~/.ssh/id_rsa, ~/.npmrc, .gitconfig). 
  • Docker configurations (~/.docker/config.json). 

3. TruffleHog-style secret scanning: Going a step further, the module simulates scanning the source code on the disk in search of hardcoded secrets, such as API keys, JWTs and private keys, a behavior common to major supply chain worms. 

The successful access reported by this simulation confirms that your access control policies and the underlying permissions granted to your build process can be fully leveraged for credential theft. This is a critical test of your security posture across both CI and local developer endpoints. 

Cloud reconnaissance and credential theft 

Attack scenario: NPM supply chain - cloud API reconnaissance and credential theft 

A successful compromise of a developer machine or a CI/CD container is merely a beachhead. The highest value target for a supply chain attacker is the ability to pivot from a compromised host into the Cloud Identity itself. This is achieved by targeting the Instance Metadata Service (IMDS). 

The attack   

When an application is run within a cloud environment (AWS EC2, GCP Compute Engine, Azure VM, or Kubernetes Pod), the host is typically assigned an identity (an IAM Role). This identity allows the host to retrieve temporary, high-privilege credentials, such as Access Keys or OAuth Tokens, by simply making an HTTP request to a local, non-routable IP address known as the Instance Metadata Service (IMDS)

  • Malware logic: The malicious package first detects that it is running on a cloud instance (e.g., by checking for specific cloud provider files or environment variables). It then immediately and silently attempts to query the IMDS endpoint (most famously 169.254.169.254 for AWS) to steal the temporary credentials assigned to the machine's role. 
  • The goal: The attack intends to move from a confined container or VM compromise to full control over the cloud resource's identity, allowing them to escalate privileges and access sensitive resources like databases or secret vaults. 

The simulation  

The "NPM Supply Chain - Cloud API Reconnaissance & Credential Theft" Scenario is a comprehensive test of your cloud security boundaries. It operates in multiple phases, mirroring the full kill-chain of a cloud-aware supply chain worm. 

Attack Phase Technical Objective Target Infrastructure 
1. Instance Metadata Probing Directly query the well-known local endpoints to retrieve temporary access tokens. AWS IMDS (169.254.169.254), GCP Metadata Server (metadata.google.internal), Azure IMDS
2. Local Token Database Parsing Harvest potentially long-lived tokens stored locally by cloud SDKs. GCP's access_tokens.db (SQLite), Azure MSAL token cache. 
3. Cloud API Reconnaissance Use retrieved or parsed credentials to perform read-only reconnaissance against the cloud API. AWS: STS GetCallerIdentity, list S3 buckets, list Secrets Manager names. 
4. Kubernetes Service Account Check for the existence of Kubernetes Service Account tokens under the /var/run/secrets/ path. GCP/AWS/Azure Kubernetes Pods. 

Output of the scenario execution:

Instance metadata probing

Cloud API reconnaissance 

This scenario is a decisive test of your security posture regarding Identity and Access Management (IAM) and Network Segmentation. A successful execution confirms that your compute environment's IAM role is overly permissive, or that you are not effectively enforcing protective measures like AWS IMDSv2 enforcement or proper network egress filtering, allowing a compromised dependency to immediately compromise your cloud resources. 

Weaponized secret scanning 

Attack Scenario: NPM supply chain - TruffleHog secret scanner 

Instead of writing custom, error-prone scanning logic, the attackers download and execute powerful, off-the-shelf software to maximize their success, thereby blurring the line between legitimate security activity and malicious reconnaissance. 

The attack 

Attackers have been observed downloading and executing highly optimized, dual-use open-source security tools like TruffleHog, which is legitimately designed to find secrets in code and repositories. 

  1. Unauthorized acquisition: The compromised package initiates an unexpected and stealthy outbound connection to download the specialized, professional-grade scanner (TruffleHog binary) directly onto the victim’s host. 
  2. Aggressive filesystem scanning: It then executes this high-efficacy binary against the host's local filesystem, targeting the user's home directory, configuration files, and source code repositories. 
  3. Evasion and ffficacy: By using an externally deployed, well-maintained scanning tool, the malware gains a superior ability to find a vast array of high-entropy secrets (AWS keys, GitHub Tokens, private keys). This tactic also helps evade security controls that rely on detecting custom malware signatures. 

The simulation  

Our module is specifically designed to validate your security infrastructure's ability to detect this malicious sequence of actions 

  • The scenario replicates the attack by downloading the TruffleHog binary and running it on the target system, as well as against a dedicated set of generated "fake" secrets, to validate that the scenario execution is correct. 
  • This test validates a complex chain of malicious behavior: 
  • Unexpected network activity: Does your network monitoring or EDR detect the unauthorized binary download initiated by a npm or node process? 
  • Unauthorized tool execution: Does your EDR/Process Monitoring flag the execution of this known security tool within the unexpected context of a package installation, especially when the command is targeted at sensitive areas of the filesystem? 
  • Exfiltration of results: Does your network security flag the resulting exfiltration attempt, a base64-encoded, structured JSON payload of the "found" secrets, which is the final step in the attacker's kill chain? 

Output of the scenario execution: 

Downloading TruffleHog from S3 bucket 

TruffleHog scan execution 

Exfiltration results

A successful detection of this simulation is crucial, confirming that your security controls can discern malicious intent when an unauthorized, external utility is downloaded and executed for reconnaissance and theft. 

Phase 3: Escalation and persistence 

Once inside, the goal is to stay there or break out. 

Docker breakout 

Attack scenario: NPM supply chain - Docker privilege escalation 

In modern development, where CI/CD processes often rely on ephemeral, containerized runners, the ultimate prize for an attacker is container escape, breaking out of the isolated container to compromise the underlying host node. 

The attack 

The attack leverages a critical misconfiguration common in CI/CD pipelines where containers are run with excessive privileges or are executed directly on the host's Docker daemon. 

  1. Environment check: The malicious NPM package first determines if it is running inside a Docker container (a common practice for CI/CD runners). 
  2. Breakout command: The malware executes a command that instructs the host's Docker daemon to run a new, highly privileged container (e.g., docker run --rm --privileged). 
  3. Host subversion: Crucially, the command uses a volume mount (-v /:/host) to map the entire root filesystem of the host machine into the new container. With full privileges, the attacker can then modify critical system files on the host, such as copying a malicious script or sudoers file, thus granting themselves persistent, passwordless root access on the host node. 

This is the most critical escalation step, moving the attacker from a single application compromise to full control over the underlying infrastructure. 

The simulation 

Our "Docker Privilege Escalation" simulation safely validates the vulnerability of your container environment: 

Feature Standard CI container Malicious breakout attempt 
Required flag Default (No --privileged) Requires --privileged 
Filesystem access Isolated to Container Full Host Mount (-v /:/host) 
Target file Container-local files Host's /etc/sudoers.d/runner 
Security test Detect docker in docker or cgroupescapes Monitor for privileged containers and host volume mounts 

This scenario runs the actual logic, running a privileged container that attempts the host filesystem write, but targets a simulated host directory (not your actual /etc/sudoers), ensuring safety.  

Execution output 

A successful simulation result demonstrates that your container's security profile and access control policies are permissive enough to allow the execution of commands that an attacker could use to attempt a full container breakout and host privilege escalation. 

The "discussion" backdoor 

Attack scenario: NPM Supply Chain - Backdoor Workflow Injection (discussion.yaml)

After achieving a compromise, an attacker’s priority shifts to persistence and establishing a resilient Command and Control (C2) channel. Modern adversaries are now weaponizing the very infrastructure intended for automation, GitHub Actions, and self-hosted runners. 

The attack 

Turning a discussion into a C2 channel 

This sophisticated technique transforms the infected CI/CD environment into a persistent attack platform controlled entirely through public repository interactions, often bypassing network perimeter defenses. 

  1. Persistence via runner registration: The malware registers the compromised machine (e.g., a CI runner or developer workstation) as a new self-hosted runner, giving it a memorable, malicious name like SHA1HULUD. This step ensures that the attacker has a permanent execution environment. 
  2. Workflow injection: The malware commits a malicious workflow file (e.g., .github/workflows/discussion.yaml) to the target repository. This workflow is configured to trigger a public event, specifically the creation of a new GitHub Discussion
  3. C2 console: The core vulnerability is the workflow payload: it is programmed to extract and execute the text contained within the Discussion body. This effectively turns the benign GitHub Issues or Discussions tab into a covert Command and Control console, allowing the attacker to issue commands to the self-hosted runner simply by typing a comment on GitHub. 

The simulation 

Our "Workflow Injection" scenario simulates this entire persistence and C2 chain: 

Attack component Simulation objective Technical mechanism (The "how") 
Runner persistence Test detection of unauthorized self-hosted runner creation and usage. Simulates persistence by injecting a malicious GitHub Actions workflow(.github/workflows/discussion.yaml) into the repository. This file is configured to run on an unauthorized self-hosted runner named 'SHA1HULUD' and is set to be triggered by a repository discussion. This backdoor establishes a persistent remote code execution vector by using a command injection pattern (defanged in the simulation) via the discussion body.  
Workflow injection Verify SCM security for unauthorized workflow commits. Generates the malicious .github/workflows/discussion.yaml file containing the attack payload. 
C2 trigger logic Validate if GitHub event-driven execution is possible. The injected workflow is configured to use a similar trigger as the real malware, designed to extract and execute the body of a GitHub Discussion/Issue as code on the runner. 
Data exfiltration Test detection of C2 beaconing and data theft payload. Creates a JSON payload of FAKE secrets (GitHub Token, AWS Keys, etc.) and performs an HTTP POST using curl -d to the C2 server. 
Evasion technique Test detection of stealthy, log-based data exfiltration. The payload is Double Base64 Encoded and printed to the standard output (stdout) to mimic a technique for exfiltrating secrets via CI/CD job logs. 
Execution mode Validate attack success against a live SCM environment. Supports LOCAL MODE (simulated push/exfiltration) and REAL GITHUB MODE (pushes a defanged workflow to a test repository to trigger a live Actions run). 

Scenario execution output 

This scenario proves whether your security platform can detect the subtle network and SCM activity that establishes persistence, and most critically, if a malicious user can turn your public discussion forum into a platform for executing arbitrary code on your internal network infrastructure. 

Phase 4: The heist – Stealing CI/CD secrets 

The ultimate goal is often the secrets stored in your GitHub repository variables. 

Workflow injection and exfiltration 

Attack scenarios:  

  1. NPM supply chain - Workflow injection 
  2. NPM supply chain - Workflow secrets exfiltration 

This devastating tactic represents the attacker's highest-value payoff and their critical step toward anti-forensics. By gaining repository write access, the adversary bypasses the typical execution limitations of a compromised package and leverages GitHub's own API to steal every available secret. 

The attack 

toJSON(secrets) and obfuscation 

The attack capitalizes on two key vulnerabilities: the power of the GitHub Actions workflow engine and the weakness of secrets redaction when faced with encoded data. 

1. Bulk Secret Dump: The attacker pushes a malicious, temporary workflow file containing the line: 

env: 
  DATA: ${{ toJSON(secrets) }} 
 

The built-in ${{ toJSON(secrets) }} function forces GitHub to serialize the entire secrets context, including repository, environment, and organization secrets, into a single, massive JSON string, exposing the full payload in one action. 

2. Anti-Forensics and exfiltration: The attacker then takes the captured data ($DATA), double Base64 encodes it, and either posts it to an external server or prints it to the workflow logs. Double encoding is a core anti-forensics technique used by real-world supply chain malware (like Shai-Hulud) to bypass GitHub's automated log-redaction mechanism, which relies on recognizing the plaintext secret value. 

3. Covering tracks: To ensure the compromise remains undetected, the malware immediately executes commands to delete the malicious workflow file, the branch it was committed on and the workflow run artifacts (which contain the logs with the double-encoded secrets). 

The simulation: Full-chain secrets theft 

The "Workflow Secrets Exfiltration" module is a full-fidelity test of your ability to detect this high-impact, low-trace attack. 

Attack component Simulation objective Technical mechanism (The "How") 
Mass secret harvesting Test the detection of bulk access to all available secrets. The malicious workflow uses the GitHub Actions expression ${{ toJSON(secrets) }} to dump the entire secrets context object, capturing all repository, organization, and environment secrets in a single JSON string. 
Data encoding for evasion Test defenses against log-based secret exfiltration and redaction bypass. The captured secrets JSON is subjected to Double Base64 Encoding before being printed to the log, which is a known technique to bypass GitHub's built-in log masking filters. 
Exfiltration Validate monitoring for anomalous outbound network connections from the runner. The encoded secrets payload is sent via an HTTP POST using curl to a target C2 server (or a local mock server if none is configured), mimicking the attacker's data theft pattern. 
Anti-forensics cleanup Test monitoring for rapid artifact deletion after an attack. The REAL GITHUB MODE proactively deletes the malicious workflow file, the attack branch, the test secret, and proactively deletes the workflow run artifacts to erase the evidence from GitHub's records. 

The attack scenario NPM supply chain - Workflow secrets exfiltration acts like the real malware and uses the same IOCs during execution: 
 
1. Creates a branch with the same name as the real malware, “add-linter-workflow-{Date.now()}”. 

2. Uploads all the secrets that were gathered to an artifact named actionsSecrets.json. 

A successful run of this simulation demonstrates that your Source Code Management (SCM) monitoring, your security rules for workflow creation, and your log inspection tools are unable to stop the most efficient method of mass credential theft and subsequent trace-erasing. 

Covert artifact exfiltration and persistence via SCM 

Attack scenario: NPM supply chain - Exfiltration repo creation 

The final, most critical stage of the Shai-Hulud 2.0 campaign is the weaponized use of the stolen GitHub credentials to execute covert exfiltration and establish repository persistence. This highly advanced technique turns the victim's Source Code Management (SCM) environment into the Command and Control (C2) channel itself. 

The attack 

After harvesting credentials, the malware uses the victim's GitHub Personal Access Token (PAT) to fully orchestrate the exfiltration: 

  • Repository creation: The payload creates a new, public repository under the victim's account with a random name (a UUID equivalent). This acts as the dedicated drop zone, blending the stolen data into legitimate user activity. 
  • Covert upload: The harvested secrets (cloud credentials, environment variables, system info) are encoded and committed to this new repository. The use of the GitHub contents API for this process ensures the data theft appears only as "file add" commits, effectively bypassing network egress filtering and traditional DLP solutions. 
  • Persistence injection: Crucially, the attack includes a persistence mechanism by committing a malicious workflow file (e.g., .github/workflows/discussion.yml). This is designed to ensure future access and continued repository modification, even if the initial exploit is patched. 

The simulation 

Our "NPM Supply Chain - Exfiltration Repo Creation" scenario tests the entire exfiltration and persistence chain by mimicking the attacker's final steps, validating your defenses against this advanced technique. 

Exfiltration repo (the drop zone) 

This scenario creates a primary, randomly named repository described as "Shai-Hulud: The Second Coming." It is populated with fake exfiltrated data to test security scanners and monitoring:

  • Secret artifacts: It commits file iocs like cloud.json and environment.json containing fake cloud and database credentials. These contents are triple Base64 encoded to simulate the obfuscation used by the attacker and stress log analysis tools. 

  • Persistence Payload: A malicious but DEFANGED GitHub Actions workflow (discussion.yml) is committed. It uses an impossible cron schedule (Feb 30th) and invalid runners to ensure it never executes, while still demonstrating the file injection pattern that creates a persistent backdoor. 

Lure repo (social engineering) 

To simulate the full attack ecosystem, the scenario also creates a secondary "Lure Repository." This repository contains social engineering components, such as a defanged Discord invite link, creating a repository to advertise:  # Free AI at api[.]airforce hxxps://discord[.]gg/AJDsM7jtbq in its description and README.md, testing your ability to detect the broader social layer of the supply chain attack. 

The simulation confirms if your SCM security controls, secret scanners and network monitoring can detect the unauthorized creation of new repositories, the commitment of heavily encoded secret artifacts and the injection of a persistent GitHub Actions workflow using a stolen user token. 

How to use these simulations 

These scenarios are available now on the Cymulate platform. We even created a template called “Shai-Hulud 2.0 - NPM Supply Chain Compromise” that will execute the full npm supply chain killchain in just a few clicks. 

Configure the environment 

1. Choose your desired execution environment and Agent(s) you want the Scenarios to execute on. For Local Mode, simply run the Scenarios without configuring them and it will simulate the scenarios locally without interacting with your GitHub account. 

2. For Real GitHub Mode - Provide GitHub token and target repository. The agent will actively push the safe simulation files to your repo and trigger the necessary GitHub actions to test your security posture. 

Real GitHub Mode available on the following scenarios:  

  • NPM Supply Chain - Workflow Injection 
  • NPM Supply Chain - Workflow Secrets Exfiltration 
  • NPM Supply Chain - Backdoor Workflow Injection (discussion.yaml) 
  • NPM Supply Chain - Exfiltration Repo Creation 

3. Customizing the simulation: 

All Scenarios offer a range of Input Arguments, such as the number of files to scan, the target webhook URL, or the option to enable/disable defanging, which allows you to precisely tune the attack for your environment. Please consult the 'Configuration' section when launching an assessment in the UI for the full list of parameters to ensure the Scenario executes the way you want. 

4. Analyze results: Check if your EDR blocked the preinstall hook, if your cloud security posture detected the IMDS probe, or if your SIEM flagged the suspicious GitHub Action creation. 

Detection engineering with Cymulate 

At Cymulate, we go beyond simply identifying gaps; we empower security teams to close them efficiently with actionable, high-fidelity detection content. Our detection engineering offering provides a comprehensive suite of mitigation artifacts tailored to each Scenario, including EDR rules, Sigma detections and clear, human-readable text mitigations. 

These artifacts are designed to help organizations rapidly strengthen detection coverage, reduce dwell time and ensure that response capabilities keep pace with emerging threats. 

Detection Engineering
Further reading
Detection Engineering

Build, test and optimize threat detection with attack simulations and custom rules that automate detection engineering.

Read More

Final summary 

The true lesson of Shai-Hulud 2.0 is that the conventional security boundary has fundamentally collapsed. This attack wasn't just on code; it was a sophisticated offensive against the very identity, tools, and automation of the modern Software Development Life Cycle (SDLC). The modern perimeter is no longer the firewall; it is the developer's identity and the associated cloud and SCM permissions. 

To counter adversaries who employ Shai-Hulud 2.0's unique and highly effective tactics, such as establishing remote code execution via GitHub Discussion backdoors and turning the SCM into their C2 by covertly exfiltrating harvested secrets to newly created public repositories, organizations must adopt a fundamental principle of zero trust across the entire build ecosystem. 

Full coverage, therefore, demands continuous validation of your defenses. You must not only monitor the integrity of your codebase but also actively test the behavior of your build pipelines, the true permissions of your cloud identity and the security rules governing your SCM environment. It is only through automated, high-fidelity security validation that organizations can actively defeat the next generation of supply chain threats and prevent and ensure adversaries cannot achieve persistent, credentialed access to their cloud and production pipelines. 

References 

Book a Demo