2026 年 8 月的供应链安全领域,被一起代号 ChainDrop 的事件重新定义了「竞速蔓延」的上限。StepSecurity、Zscaler ThreatLabz 与 Elastic Security Labs 先后跟进分析,拼出了一幅令人不安的画面:一个复活的 Shai-Hulud 蠕虫,通过劫持维护者的 GitHub 账号,把恶意代码塞进 jaredwray/keyv、jaredwray/cacheable、jaredwray/ecto 等仓库,让这些项目自带的 GitHub Actions 发布流程成了「自杀式发射台」,最终在 npm 生态里铺开 444 个包、2212 个恶意版本,并以约每秒一个包的速度自动传播。
一、攻击第一步:让项目的「自己人」发布流程替攻击者干活
ChainDrop 的精髓在于「不炸门,借钥匙」。攻击者没有直接往 npm 上传大量伪造包引起怀疑,而是先拿到维护者的 GitHub 账号访问权限,再顺势触发项目自身的发布流程。keyv、cacheable、ecto 这类库,都是被海量项目间接依赖的基础设施型组件——keyv@6.0.0 周下载量达 1.53 亿,flat-cache@6.1.24 1.49 亿,file-entry-cache@11.1.6 1.47 亿。攻击者往这样的库里埋毒,等于在无数条供应链的必经之路上设了卡,而利用 CI/CD 自发布,又让这些恶意版本看起来像是「项目官方发布」——使用者和安全扫描工具都很难第一时间察觉异样。
二、Stage 1 到 Stage 2:从 preinstall 钩子到凭证收割
载荷被设计成了清晰的接力式分两段。
Stage 1(setup.mjs)挂在 npm 的 preinstall 钩子上,安装依赖时自动执行,不需要开发者主动 import。它在动手前先做一次「国籍筛查」:检测系统平台和语言环境,若发现俄语本地化就直接退出——这是典型的定向攻击者自保设计,意在避开冲突地域的误伤与追查。通过筛查后,它下载 Bun JavaScript 运行时 v1.3.13,继而启动第二阶段的 Math_Symbol.js。
Stage 2(Math_Symbol.js)是一个约 710KB 的混淆载荷,真正承担凭证收割。它从被感染的机器上收集 npm 令牌、GitHub Personal Access Token、AWS/GCP/Azure 云凭据、Kubernetes kubeconfig、HashiCorp Vault 令牌、SSH 密钥,以及 Slack、Stripe 等各类服务令牌,连 AI 工具的配置也不放过。最狠的兜底逻辑写在这里:如果凭证窃取失败,它会直接执行 rm -rf ~/,把受害者的整个主目录清空。
三、传播机制:用偷来的 npm 令牌做「自动复制机」
ChainDrop 最值得称道(也最危险)的部分是它的传播循环。Stage 2 收割到完好无损的 npm 令牌后,脚本会挨个枚举攻击者能发布的所有包,为它们部署注入感染版本——速度大约每秒一个包。这种「借被动持团队的合法发布凭证自动蔓延」的机制,让感染的扩散不再依赖人为操作,而是变成一台不需要睡觉的印刷机,只要令牌有效,传播就不会停。
C2 基础设施则锚定在以太坊智能合约上(EtherHiding 技术)。攻击者把 C2 域名写进智能合约,然后通过区块链交易来旋转域名——这意味着防御者想靠拦截固定域名、封锁 DNS 来斩断指挥链路会屡屡落空,因为合法的 C2 地址可以随时被链上交易「换页」。基于 DNS 的封锁体系,对这种架构基本失效。
四、持久化:删掉包也没用,项目一打开就复活
即便管理员检测到恶意版本并移除,ChainDrop 还埋了第二层雷。它把钩子写进了 .claude/settings.json(通过 SessionStart 钩子在 Claude 会话启动时执行)和 .vscode/tasks.json(通过 runOn: folderOpen 在打开项目文件夹时触发)。也就是说,攻击者的恶意代码会跟着开发者常用的 AI 编程助手与编辑器一起「常驻」,每次打开项目都可能重新加载感染链路。对于把 AI 助手和 IDE 当日常工具的开发团队而言,这层持久化让「发现即清除」变成了「清除后仍会复发」的拉锯战。
五、防御姿态:这不再只是「升级依赖」的问题
ChainDrop 带来的教训超出了普通供应链事件:
锁定与校验优先:严格使用锁定文件(lockfile),用 npm ci 而非 npm install,减少每次拉取到恶意新版本的概率;
私有化拉取:对中大型团队,用私有 registry 代理对外部包做缓存与白名单,避免每个开发机直连公开源;
CI 隔离:限制 CI 系统对互联网包管理器的访问,对发布行为启用异常检测,发布管道必须视为高价值资产单独防守;
审计工具与 AI 配置:周期性检查 .claude/settings.json、.vscode/tasks.json 这类「配置即挂钩」的文件,是否有非预期的命令注入;
轮换凭证:若确认受影响,应轮换的不只是 npm 令牌,还包括可能被一并收割的云凭据、SSH 密钥与 CI 密钥。
Shai-Hulud 的复活以 ChainDrop 之名再次上演,把「供应链攻击」从一次性的投毒事件,升级成了「病毒式、自传播、抗封锁、带持久化」的复合威胁。它提醒每一个把第三方代码当基础设施的团队:信任需要建立在对发布链路的持续审视之上,而不是默认「能下载的就是安全的」。
参考:StepSecurity(ChainDrop npm worm)、Zscaler ThreatLabz(Tracking Shai-Hulud)、Elastic Security Labs 分析。