npm蠕虫利用死手开关:先隔离,别急着撤销token!

深入分析keyv/cacheable npm蠕虫:攻击者通过窃取npm token自动传播,利用Claude/VSCode配置实现打开仓库即感染,并植入撤销token即触发的死手开关。本文给出完整攻击链、IOC及正确应急响应顺序:先隔离、保留证据、根除,最后再轮换凭据。

⛓️ Critical 供应链攻击

攻击者劫持keyv/cacheable npm包维护者账号,植入恶意preinstall钩子窃取云凭证和令牌,并利用npm token自我传播,形成覆盖440+包的蠕虫。该恶意软件还通过Claude/VSCode配置在仓库打开时执行,并设置了撤销token即触发的死手开关,迫使应急响应必须改变处置顺序。

来源:SANS ISC | 2026-08-05 | 原文链接

🔍 关键发现

  • 蠕虫式传播:攻击者利用窃取的npm token自动向其他可发布包注入恶意钩子并重算哈希,数小时内从10个包扩散到440+包、2000+版本。
  • 无需npm install即可感染:仓库被克隆后,.claude/settings.json中的SessionStart和.vscode/tasks.json中的folderOpen任务会在打开目录时执行加载器,安全人员调查时也会中招。
  • 死手开关抵消常规响应:恶意载荷植入~/.config/gh-token-monitor/,通过systemd/LaunchAgent持久化,每60秒轮询token是否有效;一旦撤销token(HTTP 4xx),立即eval远程handler并自清除。
  • 常规安全检查全部失效:恶意版本带有有效SLSA证明,库本体未被更改,diff仅显示package.json和新增文件;受害者多通过eslint→file-entry-cache→flat-cache→keyv传递链引入。

⚔️ 攻击链分析

1. 攻击者接管keyv/cacheable维护者账号,发布带preinstall钩子的恶意版本。 2. setup.mjs下载Bun运行时,执行混淆的第二阶段Math_Symbol.js,窃取AWS元数据、云密钥、Vault/K8s令牌、npm token等。 3. 利用窃取的npm token自动注入钩子并重算哈希,发布到其他受害包,形成蠕虫扩散。 4. 同时在仓库中植入Claude/VSCode自动执行配置,并安装带死手开关的持久化监视器,等待token被撤销。

🚩 失陷指标 (IOC)

  • setup.mjs (preinstall hook)
  • Math_Symbol.js (~728 KB 混淆负载)
  • ~/.config/gh-token-monitor/{handler,token,started_at}
  • systemd user service 'GitHub Token Validity Monitor' / macOS LaunchAgent
  • .claude/settings.json 中的 SessionStart 条目及 .vscode/tasks.json 中的 folderOpen 任务

🛡️ 缓解建议

  • ✅ 立即将受影响主机从网络隔离,但不要关机——保持内存证据,且无网络连接可防止死手开关被触发。
  • ✅ 在轮换任何令牌前,先标记并保存~/.config/gh-token-monitor/内容、payload、plist/unit文件,记录哈希和started_at时间窗口。
  • ✅ 根除阶段:杀死watcher进程、卸载LaunchAgent/禁用systemd用户服务、关闭loginctl linger、删除.claude/.vscode钩子和包缓存。
  • ✅ 最后才轮换凭据:先npm token,再GitHub PAT、云密钥、Vault、K8s、CI secrets;必须撤销而非仅仅轮换。
  • ✅ 审计可疑活动:查找名为“Shai-Hulud: Here We Go Again”的仓库、异常npm publish、云日志中的凭证使用;确认执行过的主机应重建而非清洗。

涉及漏洞:[]


⚠️ 本文仅供安全研究与学习,IOC 信息请勿用于非法目的。

🤖 常见问题解答(FAQ)

❓ 撤销token一定会触发死手开关吗?

如果主机可访问网络且watcher进程存活,撤销token后60秒内GitHub API返回4xx,watcher就会eval远程handler并自清除。必须先在网络层面隔离主机,再执行撤销。

❓ 如何快速确认主机是否受影响?

检查package-lock.json/yarn.lock中keyv/cacheable恶意版本号,搜索~/.config/gh-token-monitor/目录、'GitHub Token Validity Monitor'服务、以及.claude/settings.json和.vscode/tasks.json中的可疑钩子。

❓ 为什么网络隔离是安全操作?

死手开关逻辑依赖HTTP响应:无网络则无4xx,瞬间不触发;同时隔离也切断了数据外渗通道。相比直接关机或撤销token,隔离最稳妥且保留证据。

[!] CONTACT_CHANNELS

如需商务合作、技术咨询或漏洞反馈,请通过以下离岸节点联系作者。

> PING_AUTHOR (@A1RedTeam)