
攻击者利用 Ethersphere 项目自身的发布自动化流程,为其 Swarm 去中心化存储网络的两款工具发布了恶意版本:bee-js 13.3.0 和 Swarm Desktop 0.56.2。
这两个版本都会下载并运行一段代码,其目的是窃取 Swarm Desktop 为其节点保存的钱包密钥,以及用于解锁该密钥的已存储密码。这段代码还会在 Windows、macOS 和 Linux 机器上安装后门。
bee-js 包是 Swarm Desktop 和 swarm-cli 命令行工具背后的 JavaScript 库。Swarm Desktop 在用户自己的计算机上运行一个 Swarm 节点,并将该节点的私钥保存在那里。
两个恶意版本均已被下架,项目维护者今天发布了干净的 Swarm Desktop 更新。但这两步既不能移除已经安装的后门,也无法保护已经外泄的密钥。截至本文撰写时,尚未有资金被盗的报告。
Swarm Desktop 0.56.2 于今日 00:36 UTC 左右出现在 GitHub 上,并在约 8.5 小时后被撤回。根据供应链安全公司 Socket 的事件分析,该应用内置的更新器可能会在约 10 分钟内将其推送给 Windows x64 计算机和 Apple Silicon Mac。Intel Mac 从未收到该版本的推送,Linux 安装也不会自动更新。
bee-js 版本 13.3.0 在 npm 上作为最新版本存在了约 75 分钟,从今日 00:09 到 01:25 UTC。其代码以 postinstall 脚本的形式运行,除非禁用了安装脚本,否则 npm 会在安装过程中自动执行它。项目无需导入该库,代码就会运行。
该项目自家的 swarm-cli 和 bee-dashboard 包,以及 Swarm Desktop 的源代码,所接受的版本范围都包含 13.3.0。在该时间窗口内进行全新安装,就可能拉取到恶意版本。
这些报告均未给出受感染机器的数量。该公司的粗略估计是,bee-js 13.3.0 的下载量约为 10 次,其中包括安全扫描器和镜像的下载。截至 08:27 UTC,Swarm Desktop 0.56.2 的下载次数达到 65 次,其中包括研究人员的下载。
Ethersphere 的维护者撤下了 0.56.2,并于今日用干净的版本 0.56.3 替换。在为新版本所做的变更中,其中一位维护者写道,0.56.2“是由攻击者使用窃取的 CI 凭据发布的,现已被撤回。”
根据该维护者的事件说明,0.56.3 版本与上一个版本 0.56.1 的代码相同,只是使用了新签发的 Developer ID 证书进行签名。该说明称,应用自动更新器会将 0.56.2 的安装迁移到该版本,但 Linux 软件包仍需手动替换。The Hacker News 对比两个版本的源代码后发现,除版本号和发布说明外没有任何改动。
当 The Hacker News 今日查看 npm 时,13.2.0 重新成为最新的 bee-js 版本,13.3.0 已无法从 registry 下载。
该怎么做
bee-js 13.3.0 的 GitHub 安全公告称:“任何安装或运行了该软件包的计算机都应被视为已完全失陷。”软件供应链安全公司 SafeDep 对任何安装过 Swarm Desktop 0.56.2 的计算机给出了同样的建议。
如果你在项目或 CI 任务中使用 bee-js:
- 在 lockfile、包缓存、内部 registry 和 CI 安装日志中搜索 @ethersphere/[email protected],包括由其他包引入的副本。
- 将版本固定为 13.2.0,并清除 13.3.0 的缓存副本,包括你用于安装的任何 npm 镜像。
- 如果 13.3.0 是在开启安装脚本的情况下安装的,即使安装日志没有显示任何错误,也应将该机器或 CI runner 视为已失陷。这段代码会隐藏自身的网络错误。
文章标题:黑客入侵 Ethersphere 的 bee-js 和 Swarm Desktop,投放窃取钱包的恶意软件
正文:
- 在一台干净的电脑上,更换安装用户或 CI 任务能够读取的所有密码、令牌和密钥。
如果你运行 Swarm Desktop:
- 在应用日志文件 bee-desktop.log 中查找 Bee Desktop version: 0.56.2 (production) 这一行。版本 0.56.2 会在每次启动时写入,就在恶意代码运行之前。
- 日志文件夹在 macOS 上是 ~/Library/Logs/Swarm Desktop/,在 Windows 上是 %LOCALAPPDATA%\Swarm Desktop\Log\,在 Linux 上是 ~/.local/state/Swarm Desktop/。
- 安装 0.56.3。在 Linux 上,需要手动替换该软件包。
- 如果 0.56.2 曾经运行过,请将该节点的密钥和密码视为已被窃取。在一台干净的电脑上,将节点的资金、支票簿和质押转移到一个新密钥。
在任何代码运行过的机器上:
- 删除 ~/.solidity/ 文件夹、Linux 上的 solidity-langsupport-runner.service 用户服务、macOS 上的 com.solidity.langsupport.runner LaunchAgent,以及 Windows 上的 ScreenConnect Client (5cbe79c9c25524df) 服务。
- 更新、重装或卸载应用或软件包并不会移除它们。
- 在可能的情况下,从可信镜像重建机器,而不是就地清理。
恶意软件如何运作
SafeDep 在其技术分析中发现,两个版本携带的是同一个加载器。它只有几行代码,会从 api.frameworkmetrics[.]xyz 下载更多代码,并以用户的权限运行。在 bee-js 中,加载器是 postinstall 脚本;在 Swarm Desktop 中,它在每次应用启动时运行。
下载的代码会在 Swarm Desktop 的数据文件夹中查找两个文件:config.yaml 和 data-dir/keys/swarm.key。如果两者都存在,它就会把它们发送到攻击者的服务器。
密钥文件是一个加密的 Ethereum keystore,但 Swarm Desktop 将密码以明文形式保存在 config.yaml 中。该公司表示,拿到这两个文件后,攻击者就能取走节点钱包中的 xDAI 和 xBZZ 代币、其支票簿资金以及其质押。
下载的代码还会安装一个后门。在 Linux 和 macOS 上,它是一个名为 evjawbreaker 的 Go 远程 shell,保存在隐藏的 ~/.solidity 文件夹中。它在 Linux 上作为用户服务、在 macOS 上作为 LaunchAgent 在后台运行。
该 shell 从一份 Ethereum 智能合约中读取其控制服务器的地址,因此攻击者可以随时更改该地址。他们在恶意 bee-js 代码被加入前 29 分钟更新了该地址。
在 Windows 上,下载的代码会安装一个正版的 ScreenConnect 远程访问客户端,由其制造商 ConnectWise 签名。该客户端作为系统服务运行,并连接到攻击者的中继。
如果用户是管理员,代码会通过一种已知的绕过用户账户控制提示的方式获取管理员权限。如果不是,则每当用户取消提示时,它都会再次显示该提示。获得这些权限后,它会添加一条 Microsoft Defender 排除项,并静默安装该客户端。
这些版本是如何发布的
两个版本都来自 bee-worker,这是 Ethersphere 用于自动化其发布的账户。两处更改均未签名,也未以拉取请求的形式提交。
对于 bee-js,攻击者为新版本发布了一个 GitHub release,这启动了该项目的 npm 发布工作流。据 Socket 称,该工作流无需审批,并在 73 秒内将软件包发布到了 npm。
由于是由项目真实的工作流构建的,该软件包带有有效的 provenance,即把 npm 软件包与其构建所用的仓库和工作流关联起来的记录。Provenance 显示的是软件包的构建位置,而不是是否有人审查过其中的代码。
对于 Swarm Desktop,攻击者手动启动了一个构建工作流,该工作流拥有项目的 Apple 和 Windows 签名证书,且无需审批。该安全公司发现,macOS 应用使用项目的 Developer ID 签名并经 Apple 公证,因此 macOS 只显示其正常的首次启动提示。
此后,维护者已让应用的签名任务等待项目 DevOps 团队的批准,并且只能从 main 分支运行。
截至本文撰写时,攻击者如何获得访问权限仍不清楚。维护者的事件说明将此事归咎于 CI 凭据和密钥被盗。
该公司的分析表明,使用了两个 GitHub 账户:bee-worker 和一名长期维护者的账户。没有任何报告解释这些凭据是如何被盗的。
与早期攻击的关联
这些载荷共用一个 Ethereum 合约、一个 ScreenConnect 中继,以及与 9 月在 Open VSX 市场出现的、面向 Solidity 开发者的伪造扩展相同的文件名。Pluto Security 的研究人员在其 10 月 1 日的 EtherDuck 分析中描述了这些扩展。
Pluto “高度确信”将它们与原始 SleepyDuck 扩展背后的组织联系起来,该扩展在 2025 年从另一个 Ethereum 合约读取其服务器地址。Socket 表示,bee-js 和 Swarm Desktop 版本背后也是同一个组织。
入侵指标
防御者可以在日志和机器中搜索以下内容。
- 域名:api.frameworkmetrics[.]xyz
- URL 路径:/v1/analytics(bee-js 加载器)
- URL 路径:/v1/electron(Swarm Desktop 加载器)
- URL 路径:/v1/assets/(后续载荷)
- URL 路径:/v1/swarm/report(被盗钱包文件)
- HTTP 头:X-Ethersphere: 1
- IP:端口:193[.]57[.]9[.]155:4912(evjawbreaker 控制服务器)
- IP:端口:185[.]232[.]84[.]169:8041(ScreenConnect 中继)
- Ethereum 合约:0xf8a900Db50b3331be6B768bA460BB59f3E40C344
- 路径:~/.solidity/
- systemd 单元:solidity-langsupport-runner.service
- LaunchAgent:com.solidity.langsupport.runner
- 服务:ScreenConnect Client (5cbe79c9c25524df)
- SHA-256:9b73e7cd4e1425e770392549d8df46c706139ef476f4f7b9ac405165dc8d9696(linux_amd64)
- SHA-256:b601776817363b96295119f7221338a122d5247a35a77a64b04f286e1bbcc565(linux_arm64)
- SHA-256:80d2672e2599732d3c0ae2a4cd0d1e3fe4d555a60273ce33feb99db3f34d250f(darwin_amd64)
- SHA-256:fae61f31f00988fdc5cc9e7272b51e08af2e245d81003237875415930fd27358(darwin_arm64)
- SHA-256:37d14bff30762ca701e9c1f8bc6c57c065bb20ae3a2208cb7411a6530610f08e(invoke.ps1)
- SHA-256:7527e86d70e7c9493db4356f1c3775380431b310000f2602c1e993cf435d01da(app.msi)