
简而言之
据研究人员2026年11月12日发布的报告,wfx-loot攻击利用约4,800个被攻陷的GitHub账号,探测了超过61,000个代码仓库并植入CI密钥窃取程序;Aikido称该程序至少在其中1,806个仓库中运行过 [1]。它滥用的是被盗的令牌,而不是GitHub的漏洞 [2],并且会在大约一分钟内撤销自己的改动 [1]。
要点
- Aikido Security称,这场攻击大约始于2026年11月10日UTC时间12:45 [1]。
- 4,837个被攻陷的账号在61,764个仓库中发起了标题为“docs: dependency audit notes”的探测性拉取请求 [1]。
- 窃取程序至少在1,806个仓库中运行过,Aikido称这一数字可能低估了实际影响 [1]。
- 它会获取GitHub Actions密钥、云凭证和AI服务密钥,然后撤销自己的提交并删除工作流运行记录 [1][2]。
- 在可疑提交之后紧接着缺失一个工作流运行编号,是窃取程序已运行的最可靠迹象 [2]。
- 如果它已运行,请轮换该工作流可触及的所有密钥并清除云端后门,因为只轮换密钥是不够的 [2]。
本页内容 12 个部分
GitHub上的wfx-loot攻击是什么?
wfx-loot是一场攻击活动:攻击者利用被盗的GitHub凭证,把恶意工作流推送到这些账号有写入权限的仓库中,窃取GitHub Actions密钥和云凭证 [1]。最先报告此事的Aikido Security,以攻击者自己对恶意软件的称呼(“wfx”)和对被盗密钥的称呼(“loot”)为其命名 [1]。SafeDep也把首次报告的功劳归于Aikido [5]。
StepSecurity把同一个窃取程序称为“wfx”,并强调了关键的一点:攻击者并没有利用GitHub Actions中的漏洞 [2]。相反,它使用真实开发者账号和机器人账号的有效令牌,像开发者一样发起拉取请求、推送提交 [2][4]。
Aikido认为,其主要目标是CI密钥,而不是通过软件包传播,不过该载荷确实通过自动发布触发器进入了至少一个Packagist包和一个Go包 [1]。BleepingComputer依据Aikido的分析报道,一些被攻陷的账号属于大型机构 [3]。
wfx-loot攻击的规模有多大?
Aikido统计到4,837个被攻陷的账号在61,764个仓库中发起了探测性拉取请求,窃取程序至少在1,806个仓库中运行过 [1]。各研究人员给出的数字略有差异,因为他们各自在攻击仍在进行时、于不同时间搜索了GitHub。
- Aikido:4,837个账号,61,764个仓库;10,431个拉取请求被提交到该账号并不拥有的仓库中;92%仍处于打开状态;至少50名被攻陷的用户向npm、Go、Packagist、PyPI或crates发布软件包 [1]。
- Aikido(汇总数字):至少1,835个仓库运行了该载荷并被窃取凭证;BleepingComputer采用这一数字 [1][3]。
- StepSecurity:截至11月12日UTC时间07:40,探测性拉取请求超过63,000个,约90%仍处于打开状态 [2]。
- SafeDep:11月10日至12日,有8,093个仓库收到了恶意提交;正如SecurityWeek所指出的,这一数字并不一定意味着窃取程序被执行过 [5][4]。
Aikido警告说,其执行次数可能低估了实际影响,因为受影响仓库中的运行日志已被删除 [1]。
wfx-loot窃取程序是如何工作的?
对于被盗令牌能够写入的每个仓库,攻击者会先探测,再推送载荷,并在大约一分钟内清理痕迹 [1]。
- 探测:从名为wfx-docs的分支发起一个标题为“docs: dependency audit notes”的拉取请求,添加一个很小的说明文件。StepSecurity表示:“这个拉取请求本身什么也不做”;它只是证明令牌具有写入权限 [2][4]。
- 载荷:一个约1,500行的shell脚本以三种方式之一送达:注入到现有的工作流中(“ci: refresh build cache”);作为脚本加npm postinstall钩子(“chore: add ci helper”);或作为一次性chore/分支上的新工作流(“chore: add dependency audit workflow”)[1]。
- 清理:攻击者撤销改动,并删除工作流运行记录及其日志 [1]。缺失的运行编号往往是唯一的痕迹 [1]。
该脚本会收集GitHub Actions的密钥和令牌、完整的运行器环境、AWS、Azure、Google Cloud、Docker、Kubernetes、npm、PyPI、SSH等的凭证文件、shell历史记录,以及AI服务提供商和开发者工具的密钥 [1][3]。它甚至会读取运行器上正在运行的进程的内存 [1][4]。Aikido发现,它分析的样本只通过HTTP POST把窃取的数据发送到攻击者控制的服务器 [1]。StepSecurity后来发现了变化:从11月12日UTC时间约05:30起,新的样本只通过Telegram发送数据,因此仅仅封锁已公布的服务器地址已不足以阻止它们 [2]。
为什么只轮换密钥还不够?
因为窃取程序会试图植入能在凭证轮换后继续存活的后门 [1][2]。Aikido描述了三种持久化手段 [1]:
- 伪造的状态检查:Aikido称,它会使用仓库必需检查的名称发布虚假的“成功”检查,从而可能越过分支保护的合并关卡 [1]。StepSecurity发现,在它检查的全部101个样本中,该功能都处于关闭状态 [2]。
- 改写AWS信任策略:它可以把某个角色的信任策略设置为允许任何AWS账户 [1]。
- 注入Azure联合身份:它可以向Azure AD应用添加名为wfx-ci-…的联合凭证,使被攻陷仓库中的工作流无需存储的密钥即可完成认证 [1]。
它还可以生成GitHub OIDC令牌,并用其换取AWS、Google Cloud和Azure会话,串联进入其他IAM角色,并创建长期有效的AWS访问密钥 [1][3]。这就是StepSecurity说要“清除持久化后门,因为轮换做不到这一点”的原因 [2]。
如何检查我的GitHub仓库是否中招?
搜索自11月10日以来的探测性拉取请求和攻击者的提交信息,然后查找工作流运行编号中的缺口 [2][1]。
- 在拉取请求中搜索“docs: dependency audit notes”,以及名为wfx-docs或chore/后接八个字符的分支 [1][2]。
- 搜索自11月10日以来的提交,查找“ci: refresh build cache”、“ci: restore”、“ci: cleanup”、“chore: add ci helper”和“chore: add dependency audit workflow” [2]。
- 对每一个命中项,打开Actions标签页,查看该提交之后紧接着是否缺失一个运行编号;StepSecurity称这是窃取程序已运行的最可靠迹象 [2]。
- 记下是哪个账号推送了这些提交:该账号的令牌已被盗 [2]。如果存在探测性拉取请求,即使没有运行载荷,该账号也已被攻陷 [1]。
不要依赖缺失的产物。Aikido称,没有wfx-loot产物、wfx-缓存条目或特殊的步骤摘要,并不意味着数据没有被窃取,因为这些渠道在本次攻击中已被关闭 [1]。Aikido还认为,该载荷除公开仓库外,也可能部署在私有仓库中 [1]。
如果窃取程序已经运行,我该怎么办?
假定受影响工作流可用的每一个密钥和云角色都已被攻陷,轮换它们,然后排查持久化后门 [1][2]。
- 轮换:该作业可触及的每一个仓库、环境和组织密钥,而不只是工作流中点名的那些;npm、PyPI等发布令牌;以及作为密钥存储的云密钥 [2]。
- 检查软件包:查找在恶意提交之后发布的软件包版本 [2]。
- AWS:查找允许任意AWS主体的信任策略、自11月10日以来创建的IAM访问密钥,以及以wfx-开头的CloudTrail会话 [2]。
- Azure:删除应用注册上名为wfx-ci-*的联合身份凭证 [2]。
- Google Cloud、Vault、Kubernetes:检查使用GitHub Actions登录令牌所做的令牌生成和登录 [2]。
- GitHub:删除遗留的分支,关闭探测性拉取请求,检查是否有内容凭借伪造的检查被合并,并撤销该账号的令牌、OAuth授权和SSH密钥 [2]。
- 令牌,依据GitHub文档:在“Settings”“Developer settings”下查看你的个人访问令牌,删除任何你不认识或不需要的;GitHub建议使用细粒度令牌、仅授予必要的最小权限并设置过期日期,因为经典令牌可以访问你能访问的每一个仓库 [6]。
npm钩子也会在开发者的机器上运行:在那段短暂的时间内运行过npm install的人,也在本地运行了窃取程序,同样应该轮换自己的凭证 [2]。SecurityWeek总结了几家安全公司的建议:撤销被攻陷的令牌,轮换已暴露的密钥,并检查是否有未经授权的云端改动 [4]。对于机器人账号,StepSecurity还建议审查它们是否真的需要绕过分支保护的权限 [2]。强有力的登录保护能让盗号类攻击更难得逞;请参阅双重身份验证详解:哪种2FA方式最安全?。
哪些软件包受到了影响?
Aikido列出了一个通过自动发布获得该载荷的Packagist包和一个Go模块 [1]。
- Packagist:digitalelvis/neuronai-studio 3.14.3版本;Aikido称,凡是安装或打开过它的机器,都应视为已被攻陷 [1]。
- Go:github.com/onuragtas/docker-env v1.0.278和v1.0.280;载荷只存在于GitHub Actions工作流文件中,Go源代码和二进制文件没有变化,且Go构建从不运行工作流文件,但Aikido仍建议移除这些版本 [1]。
各方数字不一:SafeDep称,Packagist和Go模块代理上有三个软件包带有该载荷,而SecurityWeek提到了两个Go模块的若干版本 [5][4]。SafeDep补充说,对于用composer require或go get安装这些软件包的普通使用者,该载荷并未运行 [5]。在依赖任何一份清单之前,请先核对各研究人员当前的最新清单。
wfx-loot的幕后是谁?他们是如何拿到令牌的?
此处提到的报告都没有指明攻击者是谁,StepSecurity称,它尚未查明令牌是如何被获取的 [2][4]。
StepSecurity发现,有19个账号通过颁发给Fly.io GitHub App的令牌发起了173个探测性拉取请求;它表示无法确定这些令牌是如何获取的,也没有证据表明Fly.io的基础设施遭到入侵 [2][4]。
Aikido发现,这与10月GhostAction浪潮中受影响的账号有重叠,并在100多个仓库的GhostAction工作流文件中看到了注入的wfx-loot,但它判断这是两场不同的攻击活动,很可能由不同的行为者实施,因为被盗的凭证往往会落到多个团伙手中 [1]。它还注意到,一些较新的恶意软件版本中有印度尼西亚语的注释 [1]。妥善保管令牌在这里很重要;密码管理器详解:工作原理以及是否安全介绍了基础知识。
| 指标 | 数字 | 来源 |
|---|---|---|
| 被攻陷的账号 | 4,837 | Aikido |
| 被探测的仓库 | 61,764 | Aikido |
| 窃取程序运行过的仓库 | 至少1,806-1,835 | Aikido |
| 含恶意提交的仓库 | 8,093 | SafeDep |
| 探测性拉取请求 | 超过63,000(11月12日,UTC 07:40) | StepSecurity |
常见错误
常见问题
GitHub上的wfx-loot攻击是什么?
一场利用被盗GitHub令牌,在仓库中植入CI密钥窃取程序的攻击活动 [1]。
wfx-loot攻击的规模有多大?
4,837个账号探测了61,764个仓库;窃取程序至少在其中1,806个仓库运行过 [1]。
wfx-loot窃取程序是如何工作的?
先发起探测PR,然后通过工作流或npm钩子送达约1,500行的脚本,再撤销改动并删除日志 [1]。
如何检查我的GitHub仓库是否中招?
搜索探测PR和提交信息,然后查找缺失的运行编号 [2]。
如果窃取程序已经运行,我该怎么办?
轮换所有可触及的密钥,检查软件包并清除云端持久化后门 [2]。
哪些软件包受到了影响?
Aikido列出了Packagist的digitalelvis/neuronai-studio 3.14.3以及Go的docker-env v1.0.278和v1.0.280;SafeDep列出的更多 [1][5]。
wfx-loot的幕后是谁?他们是如何拿到令牌的?
报告中没有指明;StepSecurity把一些探测追溯到了Fly.io GitHub App的令牌,但尚未查明这些令牌是如何被获取的 [2]。
术语表
来源
- wfx-loot campaign pushes CI secret stealer to tens of thousands of repositories Aikido Security · 2026-11-12
- WFX Phantom: The GitHub Actions Secret Stealer That Deletes Its Tracks StepSecurity · 2026-11-12
- Hackers compromise 4,800 GitHub accounts to steal cloud credentials BleepingComputer · 2026-11-12
- Attacker Targets 60,000 GitHub Repositories in Credential Theft Campaign SecurityWeek · 2026-11-12
- wfx: GitHub Actions Credential Stealer Hits 8,000 Repos SafeDep · 2026-11-12
- Managing your personal access tokens GitHub Docs
评论
热门评论