攻击者投毒了三个 Rust crate,以在构建期间窃取开发者凭证

这些恶意发布在涉及累计下载量约为 2.64 亿次的软件包中在线存在了 86 到 107 分钟。

By · Published

Primary source: BleepingComputer

Why it matters

Rust build scripts execute with developer privileges during compilation, giving a poisoned dependency access to the credentials, source code, and signing keys used to ship software.

Attackers poisoned three Rust crates to steal developer credentials during builds — The malicious releases remained online for 86 to 107 minutes across packages with roughly 264M lifetime downloads.

攻击者在 8 月 20 日利用 crates.io 上 David Roundy 的合法发布者账户,通过三个被广泛下载的 Rust 包投放恶意软件,将普通的软件构建过程变成对开发者工作站和 CI 系统的代码执行。

受影响的发布版本是 arrayref 0.3.10internment 0.8.7append-only-vec 0.1.9,据 Rust Security Response Team 报道。Rust 管理员在判断 Roundy 的计算机或凭据很可能被攻破后删除了这些发布并锁定了 Roundy 的账户。他们表示并不认为 Roundy 是蓄意为之。

Roundy 是一名物理学家和长期的开源开发者,最初开发了 Darcs version-control system。他的学术简历列有来自 University of California, Berkeley 的物理学博士学位,随后在 MIT 和 Cornell 任研究职务,并在 Oregon State University 任教。此次攻击利用了围绕他多年维护的软件所积累的信任,而不是引入一次性包并等待开发者发现它。

BleepingComputer 报道称 这三个被投毒的发布在 23 分钟内出现。每个发布都增加了对 proc-macro1 的依赖,这是攻击者控制的对合法项目 proc-macro2 的模仿,该项目与知名 Rust 维护者 David Tolnay 相关。Tolnay 被通过相似的包元数据和名为 dtolney 的账户冒充;报道没有表明他的真实账户被攻破。

One dependency line carried the attack

Roundy 的 crate 中的常规源代码基本保持不变。恶意的添加是一个指向 proc-macro1 1.0.107 的依赖声明,来自 StepSecuritySafeDepAikido 的分析显示了这一点。

即使受影响的库并未调用该依赖,Cargo 也会自动构建所声明的依赖。proc-macro1 内的 build.rs 文件随后从 Base64 片段重建服务器地址,禁用了证书校验,针对宿主操作系统和处理器架构选择有效负载,并在编译期间下载该负载。

该投放器支持 Linux x86-64、Windows x86-64、macOS x86-64 和 macOS ARM64。在 Unix 系统上它将可执行文件写入 /tmp/rust-setup 并以分离进程的方式启动。在 Windows 上它在临时目录创建一个 PowerShell 文件并通过 wscript.exe 下的隐藏 VBS 启动器运行。构建仍然可能成功完成,给开发者留下正常的编译输出,而有效负载在后台继续运行。

Wiz 研究人员 对第二阶段植入体进行分析,发现了凭证窃取、持久化和远程命令功能。Wiz 表示该恶意软件查询了 Chrome、Brave 和 Edge 的登录数据库,传输了主机信息和被窃凭证,并通过 Windows 注册表 Run 键、macOS LaunchAgent 或 Linux systemd 用户服务安装持久化。它还可以下载并执行附加的 shell 或 PowerShell 脚本。

The attacker manufactured an upgrade path

该行动在触及 Roundy 的包之前数小时就开始了。01:17 UTC,攻击者创建了相似的 dtolney GitHub 账户。几分钟后出现了匹配的 crates.io 身份。01:55,该账户发布了 proc-macro1 1.0.106,作为看似干净的 proc-macro2 副本,给该包提供了数小时的发布历史,然后在 07:11 发布的 1.0.107 版本中添加了恶意构建脚本。

四分钟后,Roundy 的账户发布了 arrayref 0.3.10。该账户随后快速地撤回了 0.3.5 到 0.3.9 版本。现有的 lockfile 可以继续使用已撤回的发布,但 Cargo 会警告开发者更新。遵循该警告的开发者可能会解析到新发布的 0.3.10 版本,而该版本即为被投毒的版本。

同一账户在 07:34 发布了 internment 0.8.7,在 07:37 发布了 append-only-vec 0.1.9。07:54 出现了公开的 RustSec 报告。注册表管理员在 86 分钟后删除了 arrayref 0.3.10,在 90 分钟后删除了 internment 0.8.7,在 107 分钟后删除了 append-only-vec 0.1.9。他们还删除了攻击者控制的包 proc-macro1proc-macro-enaovinearonearonenaotinymember

StepSecurity 估计这三个合法包的累计下载量约为 2.64 亿次。arrayref 占其中约 2.45 亿次,并在前 90 天内有 5370 万次下载。这些注册表总数统计的是下载次数,而不是唯一开发者、安装量或确认的感染数。更窄的暴露人群是那些在该恶意版本可用期间解析并构建了其中一个恶意版本的机器。

依赖覆盖范围仍然很大。StepSecurity 识别出 406 个直接依赖 arrayref 的 crate 版本,包括进入 blake3 哈希库的路径、Rust GUI 项目如 eguieframeiced,以及以太坊和 Solana 软件中使用的组件。预先存在且固定到干净发布的 lockfile 通常会避免被投毒的更新。在暴露窗口中新建或刷新的 lockfile 风险更高。

Developer machines became the target

Wiz 表示,指挥控制基础设施与以往归因于朝鲜(DPRK)行为者的供应链行动中看到的基础设施和技术存在重叠,包括此前报道的 Mastra 和 axios 事件。重叠包括托管地址段、信标路径、证书以及在另一次活动中报告的一个地址。这些证据在技术上将行动联系起来;但它们并不能独立确定谁控制了 Roundy 的账户。

该攻击集中针对编译软件的机器,因为这些系统通常保存源代码、浏览器会话、云凭据、CI 令牌、签名密钥和包发布访问权限。植入体并不需要最终应用程序运行。Cargo 在准备依赖项时就会执行它,而在受影响库的功能发挥作用之前就已运行。

Rust Security Response Team 建议开发者检查 Cargo 缓存和 lockfile 中是否存在被删除的版本和攻击者控制的包名。Wiz 和 StepSecurity 还建议检查是否有与 23.254.165.112 的 9089 和 443 端口的连接,以及是否存在包括 /tmp/rust-setuprust-setup.ps1rust-setup-launch.vbs 在内的文件。

任何在相关时间窗口内构建过受影响依赖的工作站或 CI 运行器都应视为已被攻破。补救措施包括旋转从该机器可访问的所有凭据、撤销浏览器会话和 CI 令牌、替换签名与发布密钥,并从已知干净的源重建受影响的环境和产物。

Reader comments

Conversation for this story loads after sign-in.