StepSecurity Details Mini Shai-Hulud Attack on AntV npm Ecosystem

Summary
StepSecurity details a Mini Shai-Hulud campaign that it says poisoned npm packages across AntV and related projects, stealing CI/CD credentials. Its analysis traces package-install execution, credential theft and exfiltration, persistence, and runner defenses.
Key points
- StepSecurity reports malicious versions across the AntV ecosystem and related npm packages, published through the compromised atool account; its article lists affected package versions.
- The payload can read GitHub Actions Runner.Worker memory to extract masked secrets and searches more than 130 file-path patterns for cloud, developer, Kubernetes, and other credentials.
- Malicious package-install hooks or a poisoned optional dependency can launch the payload through Bun; it also installs persistence in Claude Code and VS Code configurations and can add a GitHub Actions workflow.
- StepSecurity's runtime analysis observed attempted exfiltration through a GitHub API dead drop and t[.]m-kosche[.]com, disguised as an OpenTelemetry endpoint.
- StepSecurity reports that more than 2,500 public repositories bearing the campaign marker had been created using stolen GitHub tokens.
- In StepSecurity's Harden-Runner test, default controls blocked the C2 connection and detected runner-memory reads, providing two independent points of interruption.
- The article advises checking dependency lockfiles and CI logs, removing persistence artifacts, and rotating credentials accessible to environments that installed affected versions.
Article Details
- Attack Vectors
- The attackers used the compromised npm account atool to publish malicious versions of packages, including packages in the @antv namespace.
- Malicious preinstall or postinstall hooks execute the payload during package installation. In another delivery pattern, an optional dependency points to a poisoned commit in antvis/G2 whose prepare hook runs the payload.
- The payload reads GitHub Actions runner memory and harvests credentials from environment variables and credential files.
- Stolen data is exfiltrated either to a dead-drop branch in antvis/G2 through the GitHub API or over HTTPS to t.m-kosche.com.
- The payload installs persistence hooks in Claude Code and VS Code configurations and injects a GitHub Actions workflow.
- The payload attempts privilege escalation by writing a passwordless sudoers rule on Linux CI runners.
- Defensive Notes
- If a compromised package version was installed, treat secrets accessible in that environment as compromised and rotate them, including GitHub, npm, cloud, SSH, and other credentials.
- Check lockfiles and dependency trees against the article's compromised package versions; pin affected packages to safe versions, remove node_modules, and reinstall.
- Check for injected files and configuration changes, including .claude/settings.json, .claude/setup.mjs, .vscode/tasks.json, .vscode/setup.mjs, and .github/workflows/codeql.yml.
- Review CI logs and process telemetry for @antv/setup, bun run index.js, and processes reading /proc/*/mem; review network logs for t.m-kosche.com and suspicious GitHub API activity.
- Audit repositories for unauthorized commits, branches, repositories, or workflow changes, and review and revoke unrecognized npm access tokens.
- Use network egress controls and package cooldown or compromised-package checks to reduce the risk of payload execution and exfiltration.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| DOMAIN | t[.]m-kosche[.]com | Attacker-controlled fallback C2 domain used to exfiltrate encrypted stolen data over HTTPS. |
| SHA1 | 7cb42f57561c321ecb09b4552802ae0ac55b3a7a | Poisoned antvis/G2 commit referenced by an optional dependency to trigger the malicious prepare hook. |
MITRE ATT&CK
T1003.007 · Proc FilesystemPython processes read Runner.Worker memory through /proc/[pid]/mem to extract CI/CD secrets.T1027 · Obfuscated Files or InformationThe JavaScript payload is obfuscated with a large string table and a custom PBKDF2-based per-string cipher.T1041 · Exfiltration Over C2 ChannelThe payload sends encrypted stolen data to the fallback C2 server over HTTPS.T1059.004 · Unix ShellShell commands are used in the attack chain, including downloading and installing Bun with curl piped to bash.T1059.007 · JavaScriptThe malicious JavaScript payload in index.js runs under the Bun runtime.T1071.001 · Web ProtocolsThe payload communicates with its fallback C2 over HTTPS and uses a path disguised as an OpenTelemetry collector endpoint.T1078.004 · Cloud AccountsThe attackers use stolen GitHub tokens to create public repositories under accounts they control.T1119 · Automated CollectionThe payload automates credential collection by scanning environment variables and more than 130 credential-file patterns.T1195.002 · Compromise Software Supply ChainThe attackers distributed the payload through compromised npm packages and a poisoned commit referenced as an optional dependency.T1528 · Steal Application Access TokenThe payload collects application tokens such as GITHUB_TOKEN and other CI/CD tokens.T1546 · Event Triggered ExecutionThe payload installs Claude Code SessionStart and VS Code folderOpen hooks that re-execute it on later sessions or project opens.T1548.003 · Sudo and Sudo CachingThe payload attempts privilege escalation by writing a passwordless sudoers rule for the runner account.T1552.001 · Credentials In FilesThe payload searches more than 130 file paths for credentials, including cloud, developer-tool, and Kubernetes credential files.T1552.004 · Private KeysThe payload harvests SSH private key files, including ~/.ssh/id_rsa, ~/.ssh/id_ed25519, and ~/.ssh/id_ecdsa.T1567.001 · Exfiltration to Code RepositoryThe payload exfiltrates encrypted data by committing it to a dead-drop branch in the antvis/G2 repository.
Malware
Vendors
Alibaba GroupA new wave of the Mini Shai-Hulud npm worm is actively compromising packages across Alibaba's AntV data visualization ecosystem. The compromised npm account atool, which publishes timeago.js (1.5 million weeklyGitHubEvery compromised package carries an obfuscated payload that reads GitHub Actions runner process memory to extract masked CI/CD secrets in plaintext, harvests credentials from over 130 file paths covering AWS, GCP,npmA new wave of the Mini Shai-Hulud npm worm is actively compromising packages across Alibaba's AntV data visualization ecosystem. The compromised npm account atool, which publishes timeago.js (1.5 million weeklyStepSecurityhttps://app.stepsecurity.io/github/actions-security-demo/compromised-packages/actions/runs/26079710896?jobId=76678285829
Products
AntVA new wave of the Mini Shai-Hulud npm worm is actively compromising packages across Alibaba's AntV data visualization ecosystem. The compromised npm account atool, which publishes timeago.js (1.5 million weeklyBun1. C2 domain blocked by Global Block List. When bun.exe attempted to connect to t.m-kosche.com, the attacker's command-and-control server, Harden-Runner's Global Block List immediately flagged the domain and blocked theClaude Codedisguised as an OpenTelemetry collector endpoint. The payload also drops persistent backdoors into Claude Code and VS Code configurations that survive across sessions.echarts-for-reactecharts-for-react 3.0.7, 3.1.7, 3.2.7GitHubEvery compromised package carries an obfuscated payload that reads GitHub Actions runner process memory to extract masked CI/CD secrets in plaintext, harvests credentials from over 130 file paths covering AWS, GCP,GitHub ActionsEvery compromised package carries an obfuscated payload that reads GitHub Actions runner process memory to extract masked CI/CD secrets in plaintext, harvests credentials from over 130 file paths covering AWS, GCP,npmA new wave of the Mini Shai-Hulud npm worm is actively compromising packages across Alibaba's AntV data visualization ecosystem. The compromised npm account atool, which publishes timeago.js (1.5 million weeklytimeago.jsacross Alibaba's AntV data visualization ecosystem. The compromised npm account atool, which publishes timeago.js (1.5 million weekly downloads) and maintains packages across the @antv namespace, was used to pushVS Codeas an OpenTelemetry collector endpoint. The payload also drops persistent backdoors into Claude Code and VS Code configurations that survive across sessions.
