Tensorlake npm 包遭 Mini Shai-Hulud 蠕虫投毒
Tensorlake is compromised using mini Shai Hulud
安全公司 SafeDep 在 Tensorlake 的 npm 包中发现凭据窃取蠕虫 Mini Shai-Hulud,该版本在安装时即运行,npm 曾将其作为月下载量约 106,000 的包的最新版本分发。
原文完整还原了攻击者绕过 npm token、借 GitHub 网页提交与发布流程投毒的时间线,可看到供应链攻击的新路径。
我们在[email protected]中发现了一个窃取凭据的蠕虫。它在安装时运行,而 npm 将其作为latest提供给一个每月下载量约 106,000 次的软件包。
npm 记录的发布时间为 01:12:07 UTC。SafeDep 的自动化分析在 01:20 UTC(印度标准时间 6:50 AM)将其标记出来,八分钟之后。

该载荷是 Mini Shai-Hulud 的新构建版本,即 2026 年的 Shai-Hulud 蠕虫家族浪潮。它与 keyv 和 cacheable 入侵事件中的是同一个蠕虫。
- 窃取云、GitHub、npm、SSH、浏览器和钱包凭据。
- 传播通过 npm 软件包和 GitHub 仓库。
- 运行远程代码来自其命令与控制(C2)服务器。
- 当有人撤销被盗的 GitHub 令牌时,删除某些机器上的主目录。
npm 移除了该版本。维护者在
拉取请求 #1016 中还原了源代码,并发布了0.5.145。
此构建版本中的新内容
- 一个硬编码的 C2 域名,
iseekaigogo[.]com。 - 一个用于 C2 域名查询的新以太坊合约。
- 一个浏览器密码窃取器。
- 一个远程代码通道,使用
eval运行 C2 响应。 - 一个已知的删除处理器,
rm -rf ~/。keyv 分析无法为其命名。
载荷如何到达 npm
攻击者不需要 npm 令牌。他们使用仓库管理员账户通过 GitHub 网页界面将载荷提交到main。然后他们运行了项目自己的发布工作流。
| 时间,2026-10-07 UTC | 提交 | 变更 |
|---|---|---|
| 01:20:15 | e90c47bb | 添加typescript/lib/setup.mjs和typescript/lib/Math_Symbol.js |
| 01:24:19 | c79bc475 | 添加preinstall脚本 |
| 01:43:23 | ad5cf5a7 | 修复package.json语法 |
| 02:13 至 03:44 | 066b9d75、936302da、2ca2a7f1、41b38f09 | 加载器的四个修订版本和一次载荷重建 |
| 03:57:54 | e65ed94a | 将版本设置为0.5.144 |
GitHub 会为网页界面提交签名,因此所有八次提交都显示为已验证。第一次preinstall编辑破坏了 JSON:
typescript/package.json @ c79bc475
DIFF 5 行
修复在 19 分钟后到来。这表明有人在浏览器中编辑了文件(推断)。
10 月 8 日 00:08 UTC,该账户手动启动了
publish_npm.yaml。
构建日志显示 tarball 中的载荷文件:
发布到 npm 作业,运行 37706134202
TEXT 6 行
- 该发布使用了 npm 可信发布。
- 同系列的
tensorlake-native-*@0.5.144软件包带有本次运行的有效 SLSA 来源证明。 该来源证明对于被投毒源代码的构建是有效的。 preinstall钩子在此作业中运行,并在 0.1 秒内结束。加载器会跳过 CI,因此 载荷可能没有在运行器上执行(推断)。
加载器
发布的lib/setup.mjs使用 RC4 字符串混淆。蠕虫携带一份明文副本,并将其植入其他
软件包和仓库中:
lib/Math_Symbol.js 中嵌入的加载器,已解密
JS 15 行
- 它从官方 GitHub 发布页面下载 Bun 1.3.13。
- 它使用 Bun 运行
Math_Symbol.js。 - 它在 CI 运行器上退出。
发布的setup.mjs解码为相同的字符串。
载荷
lib/Math_Symbol.js为 856,501 字节。其第一行标明了构建版本:
lib/Math_Symbol.js,第一行
JS 2 行
三层隐藏了代码:
- 一个混淆器字符串数组隐藏了标识符。
- 一个自定义密码隐藏了配置字符串。它使用盐
svksjrhjkcejg,与 keyv 相同。 - AES-256-GCM 隐藏了十一个嵌入文件,包括脚本、钩子和两个 RSA 公钥。
所有层都可以在不运行样本的情况下解码。提交历史中一个更早的 849,332 字节构建具有相同的配置。
命令与控制
以下片段已去混淆,并保留原始标识符。
lib/Math_Symbol.js,C2 配置(已去混淆)
JS 2 行
该蠕虫将数据发送到 hxxps://iseekaigogo[.]com:443/router。如果失败,它会尝试:
- 以太坊。它通过 35 个公共 RPC 端点读取合约
0xb614155Fd88114d40549b259457Bcf921Df091B9。10 月 8 日,该合约返回了iseekaigogo.com。 - 已签名的 GitHub 提交。它搜索
thebeautifulmarchoftime,并且只信任使用内嵌 RSA 密钥签名的提交。 - 死信箱仓库。它将加密数据提交到新的公共仓库,描述为
Shai-Hulud: Here We Go Again。
每个 C2 响应都可以携带代码。蠕虫会运行它:
lib/Math_Symbol.js,applyRemoteCode(已去混淆)
JS 7 行
在数据外泄后,蠕虫每 45 到 90 秒 ping 一次 C2,并运行它收到的任何代码。
它收集什么
| 收集器 | 目标 |
|---|---|
| 文件系统 | SSH 密钥、云 CLI 文件、.npmrc、.env、Docker 和 Kubernetes 文件、~/.claude.json、~/.kiro/settings/mcp.json、shell 历史记录 |
| 钱包 | wallet.dat 文件、Exodus、Electrum、Ledger Live,以及 MetaMask 和 Phantom 等浏览器钱包扩展 |
| 浏览器密码 | 来自 hxxps://iseekaigogo[.]com/hbd/<platform> 的二进制文件 |
| AWS | STS、SSM Parameter Store 和 Secrets Manager |
| GitHub Actions | 从 Runner.Worker 进程内存中读取的机密 |
| Kubernetes、Vault | 服务账户令牌和 Vault 令牌 |
浏览器二进制文件以 dump -b all -c password -f json 运行。这些参数与 HackBrowserData 匹配(推断,未恢复该二进制文件)。该蠕虫在俄语区域设置下退出。
删除监视器
该监视器仅针对账户没有组织的被盗令牌启用:
lib/Math_Symbol.js,组织检查(已去混淆)
JS 3 行
lib/Math_Symbol.js,删除处理程序(已去混淆)
JS 3 行
gh-token-monitor每 60 秒检查一次令牌,持续 24 小时。- 如果 GitHub 返回 40x,例如在撤销后,它会删除主目录。
- 它作为 systemd 用户服务、macOS LaunchAgent 或 Windows 计划任务运行。
在撤销 GitHub 令牌之前,先移除 gh-token-monitor。
传播
- npm 令牌。它将有效载荷和
preinstall添加到该令牌可以发布的每个包中,提升补丁版本并发布。 - npm 可信发布。在 CI 中,它添加一个 git 依赖项,并使用 Fulcio 和 Rekor 对包进行签名。
- GitHub 令牌。它以作者
claude的身份提交 Claude Code 和 VS Code 钩子。它还植入一个Run Copilot工作流,该工作流会转储所有仓库机密,然后删除运行记录和分支。
这些钩子文件和工作流与 keyv 帖子 匹配。另请参阅 运行代码的配置文件。
代码中的两个错误可能会限制传播:
- npm 路径需要磁盘上的
./dist/Math_Symbol.js,没有它就会停止。 - 植入的加载器查找
ai_init.js,但蠕虫写入的是math_init.js。
入侵指标
| 类型 | 值 |
|---|---|
| 包 | [email protected],已从 npm 移除 |
| Tarball SHA-1 | 843a898ab72793568d77c53ff9282e6ce7c66aea |
lib/setup.mjs,32,645 字节 | 25a0735d0db7dc40e5d45ce42d9c106067e6a66e184d967cfecfab17c3bcb5ef |
lib/Math_Symbol.js,856,501 字节 | b50a00900399ba99fb6ce1fc151519cb99d44320ef2a631f2237e1aea0ad6fec |
| 较早的有效载荷构建,849,332 字节 | 03aa53f01b5b0fc4899c44041da90d7c5aa29fd90e4d99a5b70270f672ee43e1 |
| 构建标签 | WORMTAG='tensrlake' |
| C2 域名 | iseekaigogo[.]com,路径 /router 和 /hbd/ |
| 以太坊合约 | 0xb614155Fd88114d40549b259457Bcf921Df091B9,选择器 0x53ed5143 |
| 回退搜索字符串 | thebeautifulmarchoftime |
| 源提交 | tensorlakeai/tensorlake 中的 e90c47bb 到 6386121c |
| 持久化 | gh-token-monitor.service、com.user.gh-token-monitor、计划任务 gh-token-monitor |
| 持久化文件 | ~/.local/bin/gh-token-monitor.sh、~/.config/gh-token-monitor/、%LOCALAPPDATA%\gh-token-monitor\monitor.ps1 |
| 锁文件 | 临时目录中的 tmp.ts018051808.lock |
| 死信箱描述 | Shai-Hulud: Here We Go Again |
| 植入分支 | dependabot/github_actions/format/setup-formatter |
参考
来源:Hacker News · safedep.io