供应链攻击已经绕过了安装脚本:恶意代码住进了运行时方法
2026 年 9 月,一个名为 indexed-btree 的 npm 包被从注册库移除,在此之前它的周下载量接近 200 万次。它冒充合法的 sorted-btree 库,但恶意代码不在 preinstall 或 postinstall 脚本里,而是直接嵌入在一个核心运行时方法 BTree.prototype.set 中。当这个方法接收到特定的键值时,代码会以独立的 Node.js 进程启动一个经过混淆的第一阶段加载器。
这个设计选择不是随意的。npm 在 2026 年 6 月对生命周期脚本引入了更严格的控制措施,安全团队开始建议用 --ignore-scripts 禁用安装钩子。攻击者放弃了安装脚本,把触发点搬到了正常的业务调用路径上。你可以在 CI 里禁用所有安装脚本、审查每一个依赖的 package.json,但你的业务代码仍然会调用 BTree.prototype.set,而恶意载荷就在那里等着。
加载器启动后做的第一件事是指纹识别:收集操作系统架构、主机名、CPU、内存和运行时间,通过硬编码的 Slack 频道和 Telegram 聊天外传。然后它从 Sepolia 以太坊测试网的一个智能合约里获取命令与控制地址。合约暴露了 getter 和 setter 函数,恶意软件通过轮询这些函数获取信息,而不是直接请求一个域名。这种技术对域名和 IP 封锁的抵御能力更强,因为智能合约只是一个指针,旧地址被封锁之后可以随时指向新地址。在攻击链的更深处,恶意软件生成加密密钥,与从区块链获取的公钥建立共享密钥,从智能合约的两个加密数据块中解锁第二阶段的载荷,载荷执行完之后会删除恶意文件并从原型函数中移除触发代码。
Checkmarx 还发现了另外九个关联包:ordered-kv-index、btree-leaderboard、priority-slot-queue、btree-range-store、btree-core、btree-time-index、btree-lru-cache、neighbor-key-map 和 sliding-score-window。其中多个包的下载量达到数十万次,btree-core 超过 190 万次。攻击者维护了一个包含大量提交记录的 GitHub 代码库,刻意把恶意代码排除在公开仓库之外,GitHub 账户还使用了一张 AI 生成的头像,让整个包生态系统看起来合法可信。
这个攻击链对防御的启示不是“不要用 npm”,而是安装脚本防护只是供应链防御的一层,而且攻击者已经绕过了它。运行时方法注入意味着依赖审查不能只停留在安装阶段,还需要在运行时层面做行为监控:一个 B-tree 实现为什么要启动子进程、为什么要访问网络、为什么要读主机指纹?这些行为在正常的 B-tree 库里没有理由出现。Node.js 的权限模型、网络出口白名单、运行时进程监控,这些控制的优先级正在上升。
锁文件固定版本、--ignore-scripts、依赖审计仍然是必要的底线,但它们不足以覆盖“合法包在运行时做非法事”的场景。供应链安全的下一步不是更严格地审查安装脚本,是假设安装脚本可能干净、而运行时行为可能恶意,把监控和权限边界下沉到进程和网络层。
- 点赞
- 收藏
- 关注作者
评论(0)