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

推荐订阅源

Microsoft Security Blog
Microsoft Security Blog
WordPress大学
WordPress大学
Stack Overflow Blog
Stack Overflow Blog
D
DataBreaches.Net
罗磊的独立博客
博客园 - 司徒正美
Last Week in AI
Last Week in AI
The Cloudflare Blog
大猫的无限游戏
大猫的无限游戏
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog RSS Feed
The GitHub Blog
The GitHub Blog
宝玉的分享
宝玉的分享
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
小众软件
小众软件
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Hugging Face - Blog
Hugging Face - Blog
B
Blog
博客园 - 【当耐特】
V
V2EX
Apple Machine Learning Research
Apple Machine Learning Research
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
酷 壳 – CoolShell
酷 壳 – CoolShell

Security Research | Blog

SloppyRAT: A New Tool For Ransomware Attacks | ThreatLabz Microsoft Exchange Vulnerability: What Admins Should Do C2Looper Backdoor Uses GitHub for C2 | ThreatLabz Midnight Blizzard launches CaptiveCrunch | ThreatLabz Abyssos Modular RAT Analysis | ThreatLabz Frontier AI and Enterprise Readiness | Zscaler Ransomware Victims Research | ThreatLabz Targeted Attack on Middle East Govts (Part 2) | ThreatLabz Technical Analysis of GoGRPC | ThreatLabz Targeted Attack on Middle East Govts (Part 1) | ThreatLabz ClaudeFix: Shared Claude Chats Meet ClickFix | Zscaler Why Do F1 Teams Need Cybersecurity, and What Is AI’s Role? Indirect Prompt Injection Targets AI Agents | ThreatLabz Splunk Enterprise RCE (CVE-2026-20253) | ThreatLabz Edgecution: Malicious Edge Extension Backdoor | ThreatLabz SmartApeSG Supply Chain Attack Targets Okendo | ThreatLabz AI Generated ClickFix Attack Delivers SmartRAT | ThreatLabz What the ThreatLabz 2026 Phishing and Initial Access Report Means for the Public Sector | Zscaler Shai-Hulud: Miasma, Hades, & AI Scanner Evasion | ThreatLabz Zscaler ThreatLabz 2026 Phishing and Initial Access Report Technical Analysis of MLTBackdoor | ThreatLabz When the Scanner Starts Thinking: Learnings from Mythos & GPT 5.5 Cyber in Security Testing | Zscaler OpenClaw Skill Distributes Remcos & GhostLoader | ThreatLabz Tropic Trooper: AdaptixC2 + Custom Beacon | ThreatLabz Do not delete blog (testing) | Zscaler Payouts King Takes Aim at the Ransomware Throne | ThreatLabz The Alibaba Incident and Why Zero Trust Matters More Than Ever In-Memory Loader Drops ScreenConnect | ThreatLabz Supply Chain Attacks Surge in March 2026 | ThreatLabz Claude Code Leak: Critical AI Security Threat 2026
ChainDrop NPM Worm Analysis | ThreatLabz
Manisha Ramcharan Prajapati · 2026-08-12 · via Security Research | Blog

Technical Analysis

The exact account takeover mechanism the attacker leveraged is unknown at this time. Once inside, the attacker pushed two malicious files, setup.mjs and Math_Symbol.js, directly to the main branches of the affected repositories, and modified package.json to add a preinstall hook. The figure below shows the package.json modification that triggers setup.mjs.

Shows the package.json modification that triggers setup.mjs in the ChainDrop attack flow.

Figure 1: Shows the package.json modification that triggers setup.mjs in the ChainDrop attack flow.

Because the attacker operated as the legitimate maintainer, the project's existing GitHub Actions release workflow kicked in automatically, built the poisoned package, and published it to npm with valid OIDC trusted-publisher provenance and a valid SLSA Build Level 3 attestation.

Stage 1: Dropper execution (setup.mjs)

The setup.mjs file runs automatically when any developer or CI system executes npm install. The file does the following:

  • Detects the operating system (OS) platform (such as Linux, macOS, or Windows).
  • Checks for a Russian-language system locale; if found, it exits without executing. This is a common evasion technique used to avoid targeting certain regions.
  • Downloads the Bun JavaScript runtime v1.3.13 directly from its official GitHub release page.
  • Launches the second-stage payload via Bun.

The attacker uses Bun deliberately. By running the payload outside of the standard node process, the attacker bypasses security tools and endpoint detection and response (EDRs) that specifically monitor Node.js child-process behavior. The following figure shows the portion of setup.mjs that specifies the next-stage filename and references bun.exe.

Shows setup.mjs trying to load Math_Symbol.js using bun.exe.

Figure 2: Shows setup.mjs trying to load Math_Symbol.js using bun.exe.

Stage 2: Credential theft and worm propagation (Math_Symbol.js)

The Math_Symbol.js file is a heavily obfuscated file executed by Bun, as shown in the figure below.

Obfuscated Math_Symbol.js file.

Figure 3: Obfuscated Math_Symbol.js file.

The Math_Symbol.js file performs the following:

Credential harvesting

The payload performs a broad sweep of the infected environment, targeting:

  • npm tokens from ~/.npmrc, environment variables (NPM_TOKEN), and CI runner contexts.
  • GitHub credentials such as PATs, GITHUB_TOKEN, and OIDC tokens from runner memory.
  • AWS credentials from ~/.aws/credentials, IMDS/ECS metadata endpoints, and environment variables.
  • Google Cloud and Azure credentials from service account files and environment-based authentication.
  • Kubernetes credentials from ~/.kube/config and service account tokens.
  • HashiCorp Vault tokens including VAULT_TOKEN and related environment variables.
  • SSH keys from ~/.ssh/.
  • Slack and Stripe tokens and other API keys from environment variables or configuration files.
  • AI tooling credentials and configuration for Claude Code and GitHub Copilot.

Worm propagation

If the payload finds a valid npm token with publishing rights, it will:

  1. Query the npm registry to enumerate all packages that are owned or writable by that token.

  2. For each package, the payload fetches the current tarball.

  3. Injects setup.mjs and Math_Symbol.js into the package and adds the preinstall hook to package.json.

  4. Bumps up the patch version (e.g., '1.2.3' → '1.2.4').

  5. Publishes the new poisoned version to the npm registry using the stolen token.

This is what caused the spread from the initial compromised packages to completely unrelated organizations. Developers at those organizations had installed a poisoned version in their CI runners, where the malware stole their publishing tokens and then used them to republish additional compromised packages under their own accounts.

Data exfiltration

Stolen credentials are serialized to JSON, compressed, and encrypted using AES-256-GCM with a randomly generated key. That key is then wrapped with an RSA-4096 public key embedded in the payload. The encrypted data is exfiltrated via two channels:

  • Primary - GitHub dead-drop repositories: The worm uses the victim's own GitHub token to create a new public repository under their identity. These repositories are identifiable by the description string: "Shai-Hulud: Here We Go Again" (some variants used the reversed string: "niagA oG eW ereH :duluH-iahS").
  • Fallback - EtherHiding (Ethereum C2): If GitHub exfiltration fails, the malware calls an Ethereum smart contract (StringListStore, address 0xE1f2395ee43e45A1556EC6438a88c31B83493103) via eth_call to retrieve active C2 domains. The confirmed fallback domain was npm-cache[.]com

Persistence, AI agents, and IDE hooks

In a notable evolution from earlier Shai-Hulud waves, ChainDrop plants execution hooks that target modern AI-assisted developer tooling:

  • .claude/settings.json: Hooks Claude Code to execute node .vscode/setup.mjs at the start of a session.
  • .vscode/tasks.json: Hooks VS Code to execute the payload when a project folder is opened.
  • .github/copilot-instructions.md: In some variants, this is used to provide instructions within the GitHub Copilot chat context.

These hooks allow the malware to re-execute when a developer opens a project folder in an IDE or starts an AI agent session with no npm install required. This persistence can also survive package cleanup.

Token revocation trap

The worm installs a background process (identified as gh-token-monitor in some variants) that polls the GitHub API every 60 seconds using the stolen token. If the token returns a 4xx error, indicating the victim has revoked it, the worm triggers a secondary destructive payload. Depending on the variant, this can include remote code execution or deletion of the user's home directory.