Shai hulud - npm 软件包 - 供应链攻击

Shai-Hulud:npm 软件包蠕虫详解

TL博士

14 年 2025 月 XNUMX 日,研究人员发现 沙伊胡鲁德,隐藏在里面的自我复制蠕虫 npm 包,将常规依赖项更新转变为全面更新 供应链攻击. 首次发现于 @ctrl/tinycolor 由 Daniel dos Santos Pereira 开发的软件包 Shai-Hulud 收集机密信息,通过 GitHub 代码库和工作流窃取机密,并使用窃取的凭证在注册表中重新发布自身。几天之内,受感染软件包的数量从几十个激增到数百个,证实了 沙伊胡鲁德 不仅仅是另一个木马,而是一种旨在自动在 npm 生态系统中传播的蠕虫。

影响: 任何安装公共 npm 包的开发人员或 CI 运行者都面临风险。

立即采取的行动: 阻止已知版本、切换到仅锁定文件安装、轮换 npm 和 GitHub 令牌、审核工作流程以及监控妥协指标 (IoC)。

发生什么事?

Shai-Hulud 供应链攻击 npm 软件包 是近年来最具破坏性的事件之一。与孤立的木马不同,这种蠕虫病毒会混合 凭证盗窃、自动泄露和自我复制。因此,感染时间从几周缩短到几个小时。

对于 DevOps 团队来说,教训是明确的:如果每次安装都可以执行代码,那么每次依赖更新都是一个潜在的突破点。

可能的初始向量和目标凭证

早期分析 表明此次袭击可能始于 凭证被盗例如,钓鱼活动欺骗了 npm login 或者 MFA 提示可能已经捕获了开发者令牌。一旦攻击者获得第一个立足点,蠕虫就会通过嵌入到 npm 包中并窃取更多机密信息来进行传播:

  • npm 配置文件 喜欢 .npmrc,通常包含发布令牌。
  • 环境变量 并使用 GitHub PAT 进行配置 CI/CD 机密。
  • 云元数据端点 (AWS、GCP、Azure)产生用于横向移动的短期凭证。

因此,凭证盗窃成了攻击的跳板。有了有效的 npm 令牌和 GitHub 密钥,Shai-Hulud 无需额外人力即可在多个软件包和存储库之间进行自我复制。

Shai-Hulud供应链袭击事件对高管的影响

Shai-Hulud 至今仍活跃。该蠕虫加快了影响时间。以前木马病毒需要数周才能完成的任务,现在只需数小时即可完成。因此, 传播速度更快,而且更难控制。 它通过以下方式推进:

  • 窃取 npm 发布令牌和 GitHub 机密。
  • 将自身重新发布到其他 npm 包中。
  • 添加恶意 GitHub Actions 工作流以实现持久性。

谁受到影响:

任何安装公共 npm 软件包的团队都会面临风险。此外,拥有缓存 npm 或 GitHub 令牌的开发者面临高风险。使用广泛机密的 CI 运行人员也容易受到攻击。

经营风险

业务影响迅速增长。被盗令牌可能导致账户接管、软件包劫持,甚至云滥用。此外,GitHub 工作流程中的持久性使其更难清理。因此,各队必须将 Shai-Hulud 视为一个正在发生的事件,而不是一个已经结束的事件。

Shai-Hulud供应链攻击在npm包中的工作原理

攻击者的目标和动机

该活动针对三件事进行了优化:

  • 第一个目标是 大规模窃取凭证 来自开发人员笔记本电脑和 CI 运行人员。这包括 npm 发布令牌、GitHub 令牌和云凭证。事实上,多项分析证实了系统性的秘密收集行为,例如运行 TruffleHog 和查询云元数据端点。
  • 第二个目标是 自动传播 通过滥用受感染维护者的发布权。结果,一个立足点迅速扩展为多个立足点,因为无需额外的人力即可出现其他软件包的新受感染版本。
  • 第三个目标是 坚持并可靠地撤离 通过 GitHub 基础设施。攻击者创建了一个名为“Shai-Hulud”的公共仓库,其中包含双重 base64 数据.json,此外,他们还植入了一个序列化的工作流程 ${{ toJSON(秘密) }} 并将其发布到静态 webhook。

可能的回报包括长期访问注册表和源代码、快速横向移动到云账户,以及进一步利用供应链的选项。公开报告显示,私人代码库被公开, “-迁移” 后缀,可增加数据曝光度和动量

Shai-Hulud 有效载荷内部: 包.js 在 npm 包中

夏胡鲁德号飞船 大型、Webpack 打包并高度压缩 JavaScript 文件 (包.js(约 3–3.7 MB) 从执行 安装后 钩入 的package.json。 最后, 每次安装都会自动触发有效负载。这种设计隐藏了标识符,压缩了控制流,并将所有逻辑推送到安装过程中执行的单个组件中。分析师一致确认存在 Webpack 打包、文件大小异常以及安装时执行的问题。

您将在样本中看到混淆和反分析特征:

  • 最小化模块图 带有数字模块 ID、稀疏注释和扁平控制流。此外, 这种结构使得人工审查极其困难。
  • 字符串隐藏 通过 base64 层和构造助手。例如, 重复的 base64 编码和解码通常出现在泄露例程周围。
  • 动态调度 通过 评估风格的模式和生成的函数体,从而使代码能够在运行时改变行为。
  • 操作系统过滤 更喜欢在 CI 运行器和开发人员笔记本电脑上执行 Linux 和 macOS。

从功能角度来看,该捆绑包是模块化的。 文档描述了操作系统发现、文件系统和 Git Secret 扫描、云 SDK 访问、GitHub API 操作以及用于编辑维护者拥有的其他软件包的传播引擎等模块。事实上,StepSecurity 和 ReversingLabs 都重点介绍了一个使用恶意钩子自动更新软件包的功能。

Shai-Hulud 中的安装时执行:npm 包如何触发蠕虫

攻击开始于 postinstall 运行节点 包.js. 此时,脚本初始化并解压内存中的工作状态,为蠕虫的全面运行做好准备。

发现和收获

  • Payload 会转储 process.env 文件,并扫描本地文件中的高熵机密和令牌前缀。此外,它还通过运行 TruffleHog 来扩展覆盖范围。
  • 它查询云元数据端点以收集短期凭证。 例如, 呼吁 169.254.169.254 在 AWS 上或 metadata.google.internal GCP 上经常出现在受感染的主机中。
  • 所以, 找到的任何凭证都可以立即用于发布新的 npm 包或推送 GitHub 工作流程。

渗出

  • 该蠕虫创建了一个名为 沙伊胡鲁德 并写入双 base64 编码 data.json 包含平台详细信息、环境转储和机密信息。由此可见,如果防御者知道在哪里查看,这种干扰行为很容易被发现。
  • 它还植入了一个 GitHub Actions 工作流,通常在名为 夏胡鲁德,序列化 ${{ toJSON(secrets) }} 并将数据发布到静态 webhook。此外,此工作流程将持续存在,直到有人主动将其删除。

传播

  • 使用任何发现的 npm 令牌,payload 会枚举受感染维护者拥有的所有软件包。然后,它会获取每个 tarball,注入 bundle.js 和 postinstall 条目,并重新发布软件包。
  • 因此,在几个小时内就会出现数十个受感染的软件包,从而增加整个生态系统的爆炸半径。

坚持和暴露

  • 该蠕虫使恶意工作流程保持活跃,并在某些情况下将私人存储库翻转为公开存储库 “-迁移” 后缀。总之,这确保了攻击者的立足点并最大限度地泄露数据。

按键检测说明
这种不寻常的用法 ${{ toJSON(secrets) }} 在 Actions 工作流中很少见。 因此, 团队应该将其视为狩猎期间的高信号指标。

您应该寻找的净化工作流模式

这种不寻常的用法 JSON(秘密) 行动是此次事件中一个高信号指标。

高级传播伪代码(安全、描述性)

async function propagate(token, owner) {
  const pkgs = await npmApi.listPackages(owner, token);
  for (const p of pkgs) {
    const tgz = await npmApi.fetchTarball(p, token);
    const modified = injectBundleAndPostinstall(tgz); // adds bundle.js + "postinstall"
    await npmApi.publish(modified, token);            // publishes new malicious version
  }
}

分析人士大规模地观察到了这种循环,这解释了受感染包裹数量从数十个迅速增加到数百个的原因。

为什么说这是软件包生态系统中的蠕虫

蠕虫是一种无需手动操作即可自行传播的恶意软件。在操作系统中,蠕虫通常利用网络漏洞从一台机器传播到另一台机器。相比之下,Shai-Hulud 在 npm 注册表内运行。其高效路径是通过 凭证重用.

该蠕虫利用窃取的 npm 发布令牌。一旦获得有效凭证,它就会在同一维护者拥有的其他软件包下重新发布受感染的版本。随后,这些软件包会被毫无戒心的开发人员或 CI 运行人员安装,如此循环往复。

因此,包括 黑暗阅读,将 Shai-Hulud 归类为 自我复制的蠕虫 而不是简单的木马病毒或域名抢注事件。两者之间的区别很重要:木马病毒通常只会感染一台主机,而蠕虫病毒会自动在整个生态系统中扩大其影响。

“工作原理”速查表

总结一下 Shai-Hulud 的生命周期,这里有一个cis其主要步骤的细分:

  • 带有 安装后 已安装,并且 bundle.js 执行。
  • 有效载荷转储环境变量,扫描文件和 git 历史记录,运行 松露猪并查询云元数据服务。因此,任何发现的秘密都会立即变得有用。
  • 泄露有两种方式:首先,通过创建名为 沙伊胡鲁德 使用双重 base64 编码 data.json; 其次,通过植入 GitHub Actions 工作流程,发布 ${{ toJSON(secrets) }} 到 webhook。
  • 该蠕虫会利用任何窃取的 npm 令牌,使用相同的恶意钩子重新发布受感染维护者拥有的所有其他软件包。通过这种方式,感染迅速增加。
  • 最后,攻击者掌握了更多的秘密,更多的数据包可以传播,并且 坚持 在 GitHub 帐户和存储库内。

如何切实避免此类攻击

Shai-Hulud 敲响了警钟。窃取代币并重新发布的蠕虫病毒并非未来的风险,它存在于 npm 包生态系统 今天。为了防止这种 供应链攻击团队需要可编程、自动化且直接在 CI/CD pipelines. 这些防御措施与你之前已经实施的相同 西吉尼.

将不良文物拒之门外

您应该在 npm 包和 tarball 到达开发人员或 CI 作业之前对其进行扫描。超大 bundle.js 文件,可疑的安装后文件 hooks和混淆标记都是早期的危险信号。此外,在 pipelines 可防止自动消耗未经审查的新鲜版本。

硬化 CI/CD 默认情况下,

Guardrails in CI/CD 至关重要。它们会拒绝引入新脚本或二进制文件的合并或安装。同时,它们会阻止序列化机密或尝试外部发布的工作流程。团队还应要求仅使用锁文件安装(npm ci) 在所有 pipeline因此依赖集仍然可重现且安全。

减少代币爆炸半径

机密信息绝不能成为单点故障。持续扫描代码、配置和 pipeline 输出 暴露的凭证令牌应限定在狭窄的范围内,并赋予较短的生命周期,并在检测到暴露时自动轮换。通常情况下,在执行可疑安装后操作的主机上使用的任何令牌都应视为已泄露。

尽早发现蠕虫行为

非常规信号检测 至关重要。例如,npm 发布事件的突然激增、无缘无故出现的新工作流程,或者充斥着奇怪编码文件的新公共代码库,都可能预示着蠕虫活动。因此,团队应迅速发出警报,并隔离任何出现这些警告信号的维护人员或运行人员。

快速修复,无需中断构建

速度和安全必须并存。自动化 pull requests 可以用经过审查的版本替换受损的 npm 软件包。此外, 可达性 以及 开发性 分析确保升级保持最小化和稳定。最后,一旦确认暴露,就从干净的镜像重建受影响的CI运行器,防止攻击进一步蔓延。

妥协指标 (IoC)

在分析 Shai-Hulud 时,球队应该注意 静态 IoC 在文件和 行为 IoC in pipelines. 这些信号共同帮助及早发现感染并在蠕虫进一步扩散之前做出反应。

静态 IoC

观察到以下 SHA-256 摘要匹配 bundle.js 样本:

  • 46faab8ab153fae6e80e7cca38eab363075bb524edd79e42269217a083628f09
  • 81d2a004a1bca6ef87a1caf7d0e0b355ad1764238e40ff6d1b1cb77ad4f595c3
  • dc67467a39b70d1cd4c1f7f7a459b35058163592f4a9e8fb4dffcbba98ef210c

此外,请注意以下重复出现的模式:

  • A bundle.js 在包根目录下。
  • "postinstall": "node bundle.js"package.json.
  • 存储库命名 沙伊胡鲁德.
  • GitHub 工作流程包含 ${{ toJSON(secrets) }}.

行为 IoC

除了文件签名之外,蠕虫活动还会通过行为暴露自身。例如:

  • 一位维护者突然爆发大量 npm 发布事件。
  • 将数据推送到外部端点的新工作流程。
  • 由 CI 运行器触发的出站 POST 请求。
  • 最近创建了带有编码 blob 的公共存储库。

快速狩猎

# Find postinstall in package.json
grep -R --line-number '"postinstall"' --include="package.json" /path/to/archives

# Detect tarballs with bundle.js
find /path/to/tarballs -name "*.tgz" -print0 \
 | xargs -0 -n1 -I{} sh -c 'tar -tf "{}" | grep bundle.js && echo "== {}"'

# Search workflows for toJSON(secrets)
grep -R --line-number "toJSON(secrets)" --include="*.yml" .github || true

结论:来自沙伊·胡鲁德的教训

Shai-Hulud供应链攻击 npm 软件包中的漏洞表明了当今软件供应链的脆弱性。该蠕虫病毒不仅添加了恶意代码,还窃取了令牌,发送了数据,然后自动重新发布。因此,攻击在数小时内就蔓延开来,而不是数周。

对于开发人员和 DevOps 团队来说,教训是明确的:

  • 每次安装都会运行代码。 即使是一个常见的 npm 包也可能隐藏安装后蠕虫。
  • 每个代币都具有很高的价值。 一旦被盗,它就会被用来进一步传播恶意软件。
  • 所有的 pipeline 需要检查。 没有 guardrails 在依赖关系、工作流和秘密方面,一次妥协就能迅速影响生产。

因此,要阻止像 Shai-Hulud 这样的攻击,需要自动化且易于执行的控制措施。团队应该在安装前扫描 npm 软件包,使用 lockfile 构建,检测异常发布活动,并保持令牌的短期有效期。这些步骤不再是可选的,而是现代系统韧性的基础。 pipelines.

在 Xygeni,我们将 Shai-Hulud 供应链攻击视为对整个开源生态系统的警示。可持续的前进之路是将供应链安全直接纳入开发流程,在代码、npm 包和 pipeline连接。

以下是 Shai-Hulud 中已报告受损的 npm 软件包和版本的完整列表。请使用它来检查您的锁文件、注册表和 CI。 pipelines 代表曝光。

受损软件包列表

📦 受损 npm 软件包预览

软件包名称 版本 发布日期
json-规则引擎简化0.2.12025-09-14T17:58:51.203Z
飞行员0.8.82025-09-14T18:35:07.600Z
mcp-知识图谱1.2.12025-09-14T18:35:09.494Z
空军首领0.3.12025-09-14T18:35:09.521Z
跳跃门0.0.22025-09-14T18:35:09.651Z
TVI-CLI0.1.52025-09-14T18:35:10.996Z
@thangved/回调窗口1.1.42025-09-14T20:31:38.479Z
@tnf-dev/api1.0.82025-09-14T20:31:39.547Z
@tnf-dev/js1.0.82025-09-14T20:31:41.251Z
@tnf-dev/mui1.0.82025-09-14T20:31:41.259Z
@tnf-dev/核心1.0.82025-09-14T20:31:42.728Z
@teselagen/react-table6.10.202025-09-14T20:37:08.597Z
@hestjs/演示0.1.22025-09-14T20:45:52.348Z
@nexe/eslint-配置0.1.12025-09-14T20:45:53.625Z
@hestjs/eslint-配置0.1.22025-09-14T20:45:55.044Z
@nexe/配置管理器0.1.12025-09-14T20:45:55.066Z
@nexe/记录器0.1.32025-09-14T20:45:55.170Z
@hestjs/记录器0.1.62025-09-14T20:45:55.197Z
@hestjs/验证0.1.62025-09-14T20:45:55.595Z
@hestjs/核心0.2.12025-09-14T20:45:55.888Z
➡️ 查看受损软件包的完整列表
软件包名称 版本 发布日期
json-规则引擎简化0.2.12025-09-14T17:58:51.203Z
飞行员0.8.82025-09-14T18:35:07.600Z
mcp-知识图谱1.2.12025-09-14T18:35:09.494Z
空军首领0.3.12025-09-14T18:35:09.521Z
跳跃门0.0.22025-09-14T18:35:09.651Z
TVI-CLI0.1.52025-09-14T18:35:10.996Z
@thangved/回调窗口1.1.42025-09-14T20:31:38.479Z
@tnf-dev/api1.0.82025-09-14T20:31:39.547Z
@tnf-dev/js1.0.82025-09-14T20:31:41.251Z
@tnf-dev/mui1.0.82025-09-14T20:31:41.259Z
@tnf-dev/核心1.0.82025-09-14T20:31:42.728Z
@teselagen/react-table6.10.202025-09-14T20:37:08.597Z
@hestjs/演示0.1.22025-09-14T20:45:52.348Z
@nexe/eslint-配置0.1.12025-09-14T20:45:53.625Z
@hestjs/eslint-配置0.1.22025-09-14T20:45:55.044Z
@nexe/配置管理器0.1.12025-09-14T20:45:55.066Z
@nexe/记录器0.1.32025-09-14T20:45:55.170Z
@hestjs/记录器0.1.62025-09-14T20:45:55.197Z
@hestjs/验证0.1.62025-09-14T20:45:55.595Z
@hestjs/核心0.2.12025-09-14T20:45:55.888Z
@hestjs/cqrs0.1.62025-09-14T20:45:55.966Z
@hestjs/标量0.1.72025-09-14T20:45:56.386Z
ng2 文件上传7.0.32025-09-15T02:44:29.555Z
电容器通知处理程序0.0.22025-09-15T04:54:48.431Z
电容器插件-vonage1.0.22025-09-15T04:54:48.501Z
电容器插件健康应用0.0.22025-09-15T04:54:48.704Z
电容器android权限0.0.42025-09-15T04:54:48.753Z
voip呼叫套件1.0.22025-09-15T04:54:49.223Z
电容器插件-ihealth1.1.82025-09-15T04:55:08.113Z
@art-ws/common2.0.222025-09-15T05:21:15.411Z
@art-ws/config-eslint2.0.42025-09-15T05:21:17.199Z
ngx-ws1.1.52025-09-15T05:21:17.514Z
@art-ws/slf2.0.152025-09-15T05:21:17.524Z
@art-ws/http 服务器2.0.212025-09-15T05:21:17.745Z
pm2-gelf-json1.0.42025-09-15T05:21:18.413Z
@art-ws/di2.0.282025-09-15T05:21:18.488Z
@art-ws/di-节点2.0.132025-09-15T05:21:18.849Z
@art-ws/config-ts2.0.72025-09-15T05:21:19.408Z
@art-ws/db-context2.0.212025-09-15T05:21:19.814Z
@art-ws/openapi0.1.92025-09-15T05:21:19.969Z
@art-ws/web-app1.0.32025-09-15T05:21:20.383Z
@art-ws/ssl-信息1.0.92025-09-15T05:21:20.927Z
sca-tools-软件-成分分析工具
确定软件风险的优先级、进行补救并加以保护
7-day免费试用
无需信用卡

保护您的软件开发和交付

使用 Xygeni 产品套件