安全研究

GitHub 热门 Solana 工具暗藏盗币陷阱:供应链攻击分析

#供应链攻击#恶意软件#样本分析#Web3 Security
近黑深绿蓝背景上,刷高 Star/Fork 的 GitHub 仓库,package-lock.json 中被劫持的 npm 依赖 URL 重定向至恶意包,铜橙色外传箭头流向 C2 服务器——象征 GitHub 上 Solana 交易机器人供应链攻击

事件背景

2025 年 7 月 2 日,一名受害者联系到慢雾安全团队,寻求协助分析其钱包资产被盗的原因。事件起因于他前一天使用了一个托管在 GitHub 上的开源项目 —— zldp2002/solana-pumpfun-bot,随后加密资产被盗。

我们随即着手调查此次事件。

样本鉴定

首先访问该项目的 GitHub 仓库,可以看到它的 Star 和 Fork 数量相对较高,但其各个目录下的代码提交时间均集中在三周前,呈现出明显的异常,缺乏正常项目应有的持续更新轨迹。

GitHub 仓库截图

这是一个基于 Node.js 的项目。我们首先对其依赖包进行了分析,发现其引用了一个名为 crypto-layout-utils 的第三方包。

package.json 中的可疑依赖

进一步核查发现,该依赖包已被 NPM 官方下架,而且 package.json 中指定的版本并未出现在 NPM 官方的历史记录中。我们初步判断该包为可疑组件,并已无法通过 NPM 官方源进行下载。

那么,受害者又是如何获取到这个恶意依赖的呢?

NPM 未找到对应版本

依赖劫持

继续深入项目,我们在 package-lock.json 文件中找到了关键线索:攻击者将 crypto-layout-utils 的下载链接替换成了 GitHub Releases 地址。

package-lock.json 中被替换的下载链接

替换后的地址为:

https://github.com/sjaduwhv/testing-dev-log/releases/download/1.3.1/crypto-layout-utils-1.3.1.tgz

我们下载了这个可疑的依赖包,发现这是一个使用 jsjiami.com.v7 进行高度混淆后的代码,这增加了分析的难度。

高度混淆的恶意代码

窃密行为

解混淆后我们确认了这是一个恶意的 NPM 包。攻击者在 crypto-layout-utils-1.3.1 中实现了扫描受害者电脑文件的逻辑 —— 如果发现钱包或私钥相关的内容或文件,就上传到攻击者控制的服务器 githubshadow.xyz

解混淆后的代码片段

恶意 NPM 包扫描敏感文件和目录:

扫描敏感文件的逻辑

恶意 NPM 包上传包含私钥的内容或文件:

上传私钥的逻辑

攻击者画像

我们继续探索攻击手法。项目作者 zldp2002 疑似控制了一批 GitHub 账号,用于 Fork 恶意项目并进行恶意程序分发,同时刷高项目的 Fork 和 Star 数量,引诱更多用户关注,以便扩大恶意程序的分发范围。

恶意仓库的 Fork 网络

我们还识别出多个 Fork 项目也存在类似恶意行为,其中部分版本使用了另一款恶意包 bs58-encrypt-utils-1.0.3

恶意包版本时间线

该恶意包自 2025 年 6 月 12 日创建,猜测攻击者这时候就已经开始分发恶意 NPM 和恶意 Node.js 项目。在 NPM 下架 bs58-encrypt-utils 后,攻击者改用了替换 NPM 包下载链接的方式进行分发 —— 从直接发布恶意包,演进为劫持 package-lock.jsonresolved 字段。

此外,我们使用链上反洗钱与追踪工具 MistTrack 分析发现,其中一个攻击者地址盗币后,将资金转移至了交易平台 FixedFloat。

MistTrack 追踪结果

攻防视角

从攻击者视角看,这是一次精心设计的「技术伪装」:

  • 信任劫持:利用 GitHub 的社交信任机制,通过批量 Fork 和刷数据营造项目的「合法性」幻觉
  • 供应链投毒:不直接投毒 npm registry(会被扫描下架),而是劫持 package-lock.json 的下载链接指向私有 Release —— 代码审查时很难注意到 resolved 字段的微小改动
  • 代码混淆:使用商业化混淆器 jsjiami.com.v7 对抗静态分析,增加安全研究人员的时间成本(但终究没有用)
  • 资产清洗:通过 FixedFloat 等无需 KYC 的即时兑换平台转移资金

从防御视角看,这类攻击有几个关键检测点:

  • package-lock.jsonresolved 字段指向非 NPM registry 的 URL 是一个强信号
  • 项目维护者是否持有一批可疑 GitHub 账号(可通过 commit 时间、命名模式、头像一致性分析)
  • 依赖包的注册时间和下载量不匹配 —— 恶意包往往下载量极低但存在于多个项目中

我的判断

这是一次典型的一致性缝隙攻击。攻击者利用的是开发者对 GitHub 社交指标(Star/Fork)的信任与项目实际安全性之间的缝隙,以及开发者对 package-lock.json 自动化生成内容的信任与 resolved 字段可被任意覆盖之间的缝隙。

具体而言,两个关键缝隙:

  1. 「Star 多 → 安全」的认知缝隙。Star 和 Fork 可以通过脚本批量操作,但多数开发者在看到高 Star 项目时会下意识降低审查强度
  2. 「lock 文件 → 自动生成 → 可信」的信任缝隙package-lock.jsonnpm install 自动生成,看起来像机器产物,导致很多人不会仔细审查其中的 resolved 字段

最后,给出几点务实的建议:

对开发者

  • 运行任何涉及钱包或私钥的开源项目前,至少看一眼 package-lock.json 中是否有非 NPM registry 的 resolved 字段
  • 在独立、无敏感数据的沙箱环境中调试陌生项目
  • Star 数不是安全指标

对用户

  • 如果你怀疑资产已泄露,不要犹豫 —— 立即创建新钱包并转移剩余资产
  • 钱包私钥和 mnemonic 永远不要出现在任何可被 Node.js 脚本读取的目录中

恶意依赖包相关信息

恶意 GitHub 仓库列表(29 个)

  • 2723799947qq2022/solana-pumpfun-bot
  • 2kwkkk/solana-pumpfun-bot
  • 790659193qqch/solana-pumpfun-bot
  • 7arlystar/solana-pumpfun-bot
  • 918715c83/solana-pumpfun-bot
  • AmirhBeigi7zch6f/solana-pumpfun-bot
  • asmaamohamed0264/solana-pumpfun-bot
  • bog-us/solana-pumpfun-bot
  • edparker89/solana-pumpfun-bot
  • ii4272/solana-pumpfun-bot
  • ijtye/solana-pumpfun-bot
  • iwanjunaids/solana-pumpfun-bot
  • janmalece/solana-pumpfun-bot
  • kay2x4/solana-pumpfun-bot
  • lan666as2dfur/solana-pumpfun-bot
  • loveccat/solana-pumpfun-bot
  • lukgria/solana-pumpfun-bot
  • mdemetrial26rvk9w/solana-pumpfun-bot
  • oumengwas/solana-pumpfun-bot
  • pangxingwaxg/solana-pumpfun-bot
  • Rain-Rave5/solana-pumpfun-bot
  • wc64561673347375/solana-pumpfun-bot
  • wj6942/solana-pumpfun-bot
  • xnaotutu77765/solana-pumpfun-bot
  • yvagSirKt/solana-pumpfun-bot
  • VictorVelea/solana-copy-bot
  • Morning-Star213/Solana-pumpfun-bot
  • warp-zara/solana-trading-bot
  • harshith-eth/quant-bot

恶意 NPM 包

  • crypto-layout-utils
  • bs58-encrypt-utils

恶意包下载链接

https://github.com/sjaduwhv/testing-dev-log/releases/download/1.3.1/crypto-layout-utils-1.3.1.tgz

数据外传服务器

githubshadow[.]xyz