作者:Joker & Ccj
近日,NPM 社区再次爆发大规模 NPM 包投毒事件。此次事件与 2025 年 9 月的 Shai-Hulud 攻击事件高度相关。攻击者通过恶意代码窃取开发者的密钥、API 密钥以及环境变量等敏感信息,并利用这些密钥创建公开仓库,上传窃取的数据。
慢雾(SlowMist) 自主研发的 Web3 威胁情报与动态安全监控工具 MistEye 第一时间响应,迅速推送相关威胁情报,为客户提供关键的安全保障。


同时,后台会在第一时间保存恶意样本,并计算其对应的 SHA-256 等特征值。

以 @asyncapi/php-template@0.1.1 包为例,在对比旧版本 @asyncapi/php-template@0.1.0 时可以发现,0.1.1 版本新增了两个 js 文件,分别为 setup_bun.js 和经过混淆的 bun_environment.js 文件。

在 package.json 中新增了 preinstall 脚本,使得在依赖安装之前会自动执行 setup_bun.js。

在 setup_bun.js 中,首先会检查系统是否已安装 Bun,如果未安装,则自动从官方下载并安装 Bun,并正确设置环境变量以便找到 Bun 可执行文件。
最后使用 bun 执行 bun_environment.js 文件,该文件是一个经过高度混淆的恶意脚本。

通过对恶意脚本的部分代码进行反混淆,可知 aL0() 是整个恶意脚本的主入口函数。此脚本主要进行敏感信息的窃取,先对运行环境进行检查是否存在 NPM 或 GitHub 等凭据。若检测到这些凭据,它会利用 NPM 凭据进行供应链传播,并将所有收集到的系统信息和敏感数据打包上传至攻击者控制的 GitHub 仓库。
凭据窃取
AWS:该恶意脚本实现 runSecrets() 和 listAndRetrieveAllSecrets() 方法。runSecrets() 方法会遍历所有能找到的云访问凭据以及所有可能的区域,最大化扫描范围;而 listAndRetrieveAllSecrets() 则在指定凭据与区域内进行“深度挖掘”,遍历出所有 Secret,并获取其最新明文内容。两者配合后,攻击者能够一次性导出受害者 AWS 账号中可访问的所有 SecretString 和 SecretBinary。

enumerateValidCredentials() 方法主要用于全面搜集所有可用的云服务密钥。它会从环境变量、配置文件、CLI 登录等各种来源逐一尝试,凡是能成功验证的凭据都会被记录下来,供后续窃取云端机密时使用。

GCP:该恶意脚本中的另一个 listAndRetrieveAllSecrets() 方法主要针对 GCP 模块。它会根据指定的 Project ID 列出该 GCP 项目下所有的 Secret,然后直接定位每个 Secret 的最新版本,并调用 accessSecretVersion 读取其明文内容,最终将所有获取到的机密(如 API Key、数据库密码等)逐一收集起来。

Azure:该恶意脚本中的另一个 listAndRetrieveAllSecrets() 方法专门针对 Azure 模块。它会通过 Azure Resource Manager 扫描整个订阅,找出所有 Key Vault;随后使用获得的凭据逐一连接每个 Vault;最后枚举其中的所有 Secrets,并调用 getSecret 获取每个机密的明文值。

此外,攻击者还利用合法的安全工具来实施攻击。在 extractAndInstall() 方法中,解压并提取出 TruffleHog 的二进制文件。TruffleHog 本是用于检测代码库中泄漏的机密信息的工具,却被攻击者用来对受害者的整个文件系统进行扫描。

该恶意脚本实现了一个 updatePackage() 函数,用于进行 NPM 供应链传播。首先,使用窃取的 NPM Token 下载受害者拥有发布权限的合法 NPM 包源代码,然后修改 package.json 文件,在 scripts 字段中插入恶意的 preinstall 脚本命令。同时将恶意脚本放入包中,自动将包的版本号加 1,以触发用户的自动更新,将带有恶意脚本的 NPM 包推送到 NPM 官方仓库中。

在窃取完信息后,攻击者利用窃取的 GitHub Token 在其账号下创建一个随机名称的仓库,并获取注册令牌,将受害者的电脑伪装成该仓库的自托管 GitHub Actions Runner。随后,攻击者在仓库中植入恶意工作流,使得任何被触发的 Actions 任务都会在受害者机器上执行,从而实现远程代码执行。

并将窃取的信息经过双重 base64 加密上传到创建的仓库里,这些仓库的描述均为“Sha1-Hulud: The Second Coming.”。

经过解密后可以看到用户泄漏的敏感数据。



本次 NPM 仓库投毒事件结合了蠕虫传播和自托管运行程序的长期持久性,并利用 TruffleHog 进行攻击。慢雾安全团队建议开发者在构建和发布新迭代时,应采用依赖包版本锁定策略。若依赖包存在必要的安全或功能更新,应通过内部严格的安全审计流程进行更新,并同步更新锁定版本,避免盲目更新引入新的风险。