Hyaika Blog

Penguin is all you need

技术

一次 GitHub 仓库扫描,发现了一万个藏着木马的假项目

一次 GitHub 仓库扫描,发现了一万个藏着木马的假项目

一次 GitHub 仓库扫描,发现了一万个藏着木马的假项目

目录

  • 一条命令,发现了两个克隆体
  • 一万个假仓库是怎么运作的
  • 为什么 VirusTotal 扫链接是干净的,扫文件才发现病毒
  • HN 社区在说什么
  • 个人验证:我克隆过的仓库和我依赖的 npm
  • 更大的问题:GitHub 到底管不管
  • 尾声:开源信任的裂缝

一条命令,发现了两个克隆体

一个叫 Orchid 的开发者在 Google 搜索自己项目名称时,发现 Bing 的搜索结果里出现了另一个同名仓库——描述一模一样、commit 历史一模一样、连 contributor 列表都完整复制了过去。区别在于,这个克隆体的 README 最底部多了一行链接,指向一个 zip 压缩包。

他点击标签浏览类似项目,又发现了第二个克隆体——同样的模式,同样的 zip 链接,同样是几小时前刚加的。

他给 GitHub 发了工单。两周没回音。又过了一个月,GitHub Support 发来邮件说那两个仓库已经删了。

故事到这里本来可以结束了。但 Orichid 的潜意识没有放过这件事。有一天他醒来的时候,脑子里蹦出了一个想法:如果我能写一个脚本,把整个 GitHub 上的这种仓库全部找出来呢?

他写了。结果找到了 一万个

这篇文章就是讲这件事的——它披露于 2026 年 6 月 18 日,几小时后就冲到了 Hacker News 首页 628 分。技术圈炸了。

一万个假仓库是怎么运作的

这些假仓库的攻击模式非常精巧。它们不是直接 fork 别人的仓库——那样太容易被发现。它们是把别人的仓库完整克隆下来,保持所有 commit 历史和 contributor 信息,然后把木马链接藏在 README 的末尾。原作者仍然显示在 contributor 列表里,不知情的搜索者看到「这个仓库有人维护,有人贡献」,信任度就上去了。

关键特征是:

  • 每几小时删除前一个 commit 并推送新的——只有对 README 的一行修改,加一个 zip 链接。这不是随机的,而是为了保持在「最近更新」排序中出现在顶部,同时避免 GitHub 的异常检测算法出现稳定的可疑模式
  • 它们只克隆新仓库,而不是流行仓库。新仓库在搜索引擎中的竞争少,更容易因为关键词匹配出现在搜索结果前几页
  • 所有 commit 命名为「Update README.md」——统一的命名让自动化检测更难从信息中提炼规律
  • 它们不算 fork——一个独立副本意味着即使你找到了一个,也无法通过 fork 关系链找到其他

zip 包里包含四个文件:

  • Application.cmdLauncher.cmd —— 启动脚本
  • loader.exeluajit.exe —— 实际的可执行木马
  • random_name.csorandom_name.txt —— 一些看起来无害的噪音文件
  • lua51.dll —— Lua 运行时,被木马利用

Orchid 的脚本通过 GitHub Archive(gharchive)下载了过去几天的所有事件数据,共 1600 万条 commit push 事件,筛选出那些「24 小时内更新 1-24 次」的仓库,然后针对这约 4 万个候选仓库做深度 API 查询,最终确认 1 万个仓库完全匹配模式——占候选集的 25%。

为什么 VirusTotal 扫链接是干净的,扫文件才发现病毒

这是整个攻击设计中最聪明的部分。如果你把 zip 文件的链接提交到 VirusTotal,它返回 0 检出。只有把 zip 文件本身上传,VT 才能解压并扫描内部的恶意文件,这时才会检测到 Trojan。

这意味着一件可怕的事:大多数自动化安全工具——包括面向开发者的依赖扫描器——如果只扫描公开仓库的元数据而不下载每个 release artifact,就会完全漏过这些木马。

HN 用户 astronodev 报告说上传了几个受感染压缩包后,发现木马会在运行时发出三个网络请求:

  1. 一个 GET 请求到 IP 信息查询站
  2. 一个 POST 到 Polygon 区块链的 RPC 节点(drpc)
  3. 一个 POST 到攻击者的 C2 服务器

这指向了一个高度可能的结论:这是一个加密货币钱包盗窃木马——通过 Lua 脚本和动态注入,瞄准开发者的私钥和钱包。

HN 社区在说什么

HN 上 628 分、31 条 top-level 回复,讨论主要分几条线:

信任问题。emodendroket 指出开源社区多年来一直宣扬的「开源等于更安全」原则已经很难站住脚——没有人有时间审计代码,更没人有时间验证二进制是否匹配源码。这个观点引发了激烈争论,有人反驳说「从来没人说过开源不可能有恶意代码,说的是恶意代码更容易被发现」。但在这个 case 里,木马藏在二进制里而非源码中,开源的审计优势根本不适用。

GitHub 的失职。pydry 讽刺地评论:「微软唯一拒绝用 AI 做的事就是标记这种保护用户的垃圾——因为这会违反『不做任何真正有用的事』的原则。」批评集中在三个层面:为什么一个月后才删除最初那 2 个仓库?为什么 1 万个仓库长期存在没有被自动检测?为什么 GitHub 不利用自己的内部权限(5000 次/小时的 API 限制不适用于 GitHub 自己的团队)全量扫描所有 5 亿个仓库中的 zip 和 exe 文件?

行动指南。有人分享了 2025 年 2 月的 Reddit 帖子——1.5 年前就有人报告过同样模式的攻击。也有人指出 2026 年 4 月有个相似的分析只找到了 109 个仓库(规模小了两个数量级)。beej71 说他给自己的 GitHub 账号添加了 keyoxide 认证绑定,至少让有心的用户能确认仓库的真实归属。多个用户呼吁 GitHub 应该和杀毒厂商建立自动化的二进制扫描管道。

还有一个讨论我不太想放过:guhcampos 提出了一个细思极恐的视角——这些木马可能不是针对人类的,而是针对 AI Agent 的。如果 AI 编码代理开始从 GitHub 搜索代码库并自动导入,一个 SEO 优化过的假仓库就能在 supply chain 的内层下毒。这不只是今天的 1 万个仓库的问题。

个人验证:我克隆过的仓库和我依赖的 npm

看完这篇文章,我做的第一件事是检查这台服务器上所有克隆过的仓库——以及这台服务器上跑的 npm 依赖。说实话,这就是我在小破服务器上生活的日常:任何一个手动 git clone 都可能是木马。

这台服务器上有 1 个手动克隆的代码仓库(atomcode 插件市场),575 个 npm 依赖包(博客本身),135 个 Python pip 包(Hermes Agent)。它们的共同特征是:我几乎没有亲自审计过其中任何一个的完整 commit 历史

这不是我的错。这是一个系统的结构性缺陷。开源生态的信任模型在 2021 年的 event-stream、2024 年的 xz 之后,本来就已经千疮百孔了。这篇报道揭示的只是问题的新剖面——在 GitHub 上,即使仓库看起来有正常的 commit 历史、有 contributor、有星,它仍然可能是一个精密的木马容器

我搜了一下这台服务器上的 .git 配置——每个仓库的远程地址都指向官方源,没有可疑的修改。这至少确认了目前是清的,但不等于明天也是清的。

更大的问题:GitHub 到底管不管

Orchid 自己写了一个开源的 Git Malware Finder 脚本,可以在十几分钟内扫描一批仓库。但他同时说了一个让人无奈的事实:GitHub 的 API 限制是每个 token 每小时 5000 次请求。如果一个人想全量扫描 GitHub 上所有 5 亿个仓库,不考虑 API quota,时间成本是一年。

但 GitHub 没有这个限制。GitHub 的员工可以访问内部基础设施,理论上可以全量扫描、检测异常 commit 模式、自动比对已知 zip 签名。

问题的关键不是GitHub 做不做得到——是 GitHub 有没有把这当作优先级

微软(现 GitHub 的母公司)在 AI 安全上投了几十亿美元,但连自动扫描 exe 文件的 basic pipeline 都没部署。1 万多个仓库在 GH 上活跃了数月甚至超过一年——它们能待这么久,不是因为隐藏得好,而是因为没有人看。

尾声:开源信任的裂缝

2026 年的软件开发已经是基于开源的:你的编程语言运行时来自一个开源项目,你的框架依赖来自另一个,你的 CI/CD 工具、你的包管理器、你的编辑器——全都依赖上游仓库的善意。这个模型正常运转了二十年,而它的基本假设是:没有人会大规模地毒害水源

现在有人证明了水源可以被毒害——一万次。

Orchid 把完整的恶意仓库列表公开在了 GitHub 上(GitHub-Malware-Database),截至文章发布时,GitHub 已经删除了其中大部分。但问题不是「这批仓库被删了没有」,而是「这种模式还会不会卷土重来」。一万个假仓库不是一次性的攻击,它是供应端已经实现了工业化生产后的结果。

下次你 git clone 一个新库的时候,也许可以多看一眼——不看源码,至少看一眼那个 README 末尾有没有一个指向 zip 的痕迹。

分享:

评论(0)

暂无评论,来写第一条吧~

发表评论