Gheist 活动利用被盗 GitHub token 植入泄密工作流
Gheist campaign plants secret-dumping workflows using stolen GitHub tokens
Wiz Research 发现 Gheist 活动利用被盗 GitHub token 向可访问仓库植入 sync-check 工作流,目标是导出仓库和环境密钥。
报告给出了针对 Gheist 的 GitHub Actions 安全排查清单,涵盖异常分支、审计日志、云端角色承揽和自托管 runner 失陷判断。
自 2026 年 9 月 15 日起,Wiz Research 一直在追踪 Gheist:一场利用失陷 GitHub 令牌实施大规模滥用的新攻击活动。该攻击会向每个令牌有权访问的每个仓库提交一个名为 sync-check 的工作流。该工作流试图将仓库的机密信息打印到其自身的工作流日志中。随后,该工具通过 GitHub API 下载日志,并在几秒后删除这次运行。该工具发出的 API 请求带有用户代理 gheist,此次攻击活动也因此得名。
我们已从 850 多个失陷账户中找回 13,500 多个被植入的分支,涉及从个人项目到企业组织私有仓库的各类场景。
GitHub 最近推出的一项控制措施已阻止在公共仓库中的利用,但我们已观察到在私有仓库和 GitHub Enterprise 环境中成功利用及后续活动。
截至 10 月 24 日:
攻击仍在持续并不断演化
约有 ⅔ 的涉事账户已无法在 GitHub 上使用。这很可能表明正在进行处置活动,因为我们已向 GitHub 报告了这些活动。
攻击的工作方式
对于每个仓库,该工具会创建一个名为 ci-sync- 加六个随机字符的分支,然后提交 .github/workflows/sync-check.yml,提交消息为 ci: sync config。该提交未签名,作者身份设为令牌所有者。推送事件会触发工作流:
有三个细节使攻击得以奏效:
GitHub 只有在机密值原样逐字出现在日志中时,才会对其进行遮盖。采用 base32 编码的机密值不匹配这一条件,因此会被完整打印出来。
虽然
permissions: {}限制了作业的GITHUB_TOKEN(攻击者并不需要它),但并未限制 secrets 上下文。当仓库设有部署环境时,该工具会使用
environment: ${{ matrix.environment }}将这些环境列入作业矩阵,因此限定于环境的机密信息(通常是生产凭据)也会被打印出来。
由于这些机密信息是通过 GitHub 自身的 API 传出的,因此不存在可供拦截的攻击者域名或出站连接。
在企业组织中,我们看到该工具在几分钟内轮番使用多个用户和自动化账户的令牌,先克隆私有仓库,再植入工作流;数小时后,来自同一组织的云凭据被用于枚举 AWS Secrets Manager。
攻击载荷的演变
我们并行观察到这种攻击的两个变体。可以通过分支名称区分它们。
工具 A 使用十六进制后缀和未经修改的载荷。
工具 B 使用 base36 后缀,在 9 月 28 日首次运行后的数小时内加入了 timeout-minutes: 6 和环境矩阵,并针对每个仓库修改所选载荷。
10 月 19 日,工具 B 在各次转储之间加入了 echo X | base32 -w 120,用于将 LAFA==== 作为分隔符打印出来,很可能是供操作人员的日志解析器使用。数小时后,它推送了第二个作业 sync-host,并附带 runs-on: self-hosted,似乎只针对注册了自托管 runner 的仓库。它会写入三个辅助文件(.gdmp_pat、.gdmp_patg、.gdmp_sweep),并在 ===== gdmp-pivot: <stage> ===== header 下记录每个阶段:
主机详情和 crontab。
对主目录、工作区和系统路径进行递归搜索,查找 31 种令牌格式(包括 Anthropic、Hugging Face、Groq 和 NVIDIA 等 AI 提供商的密钥)、私钥、
.env文件、Terraform 状态及 shell 历史记录。来自
/proc/*/environ的每个进程环境。通过 Docker socket,使用一个挂载了主机根文件系统的容器,在主机上重复执行搜索。
AWS 实例角色凭据,以及 GCP 和 Azure 元数据。
GitHub Actions 和 GitLab runner 凭据文件。
Kubernetes 服务账户令牌。
然而,这个作业存在缺陷:它会查找错误的运行器密钥文件,其 URL 凭据正则表达式也有问题,而且不会收集 GCP 或 Azure 令牌。
GitHub 的审批暂缓机制与私有仓库
自 2026 年 7 月 28 日起,GitHub 会将公共仓库中可能存在恶意的工作流运行暂缓执行,直至协作者批准。我们检查过的每一次公共 Gheist 运行,涵盖包括自托管作业在内的所有变体,均处于 action_required 状态。这项控制措施发挥了作用,恶意载荷从未运行。
遗憾的是,这种暂缓机制不适用于私有仓库或 GitHub Enterprise Server。在那里,GitHub 审计日志显示,ci-sync-* 分支上的运行先完成,随后被 gheist 用户代理删除。CloudTrail 显示,这些组织自己的工作流正在这些分支上运行并承担 AWS 角色,这证明 Actions 在未经批准的情况下执行。
对防御者而言,最后这一信号无需任何 GitHub 日志即可发现 Gheist,如下所示。
同一批账户上的其他活动
此次攻击活动利用了遭入侵的 GitHub 访问权限。同一批账户还被其他行为方和攻击活动使用,这展示了失陷凭据如何在威胁行为者生态系统中扩散。我们观察到其与以下攻击活动存在重叠:
诱饵仓库(恶意软件分发)。 10 月 6 日,391 个账户将约 1,461 个仓库重命名为 cracked-software 类诱饵,例如 fl-studio-crack 和 solana-sniper-lite。此次重命名还连带删除了 610 个
ci-sync分支。其中 166 个账户从未出现在 Gheist 活动中,因此账户池比 Gheist 的活动范围更大。免费算力(加密货币挖矿)。 10 月 18 日,25 个 Gheist 账户各自在九分钟内创建了一个 "Windows RDP Runner" 仓库,试图滥用 GitHub Actions 获得免费的算力周期。
PolinRider。 一些受害者似乎感染了 PolinRider,这是一种与 DPRK 关联的恶意软件,会在构建配置文件中隐藏 JavaScript,并强制推送倒填日期的提交。10 月 19 日和 20 日,三名受害者重新推送其 Gheist 提交时,在
vite.config.js末尾数百个空白字符之后附加了一个加载器;其中两例还包含一个 api.js,package.json 会在每次 dev 和 build 之前运行它。Megalodon。 Gheist 第一阶段的 57 个账户在 5 月也成为了 Megalodon 的受害者。
我们能够追溯的凭据来源与这一情况相符:信息窃取器日志,以及在更早的供应链失陷事件中暴露的令牌,例如 3 月的 Trivy 失陷事件。
注意:Gheist 不同于 GhostAction,后者使用不同的工作流文件,并将机密信息外传至 193.32.204[.]199。
安全团队应采取哪些行动?
搜寻
查找名称为
ci-sync-后接六个随机字符的分支,其中唯一的变化是在.github/workflows/sync-check.yml新增一个文件,提交消息为ci: sync config。在 GitHub 审计日志中,查找在
ci-sync-*分支上运行、并在完成后一分钟内被删除的工作流运行,以及来自用户代理gheist的任何活动。如果你的工作流使用 OIDC 向云端进行身份验证,请检查云审计日志中主体包含
ci-sync-分支的角色承担或令牌交换记录。这表明 GitHub Actions 在攻击者分支上运行过,即使你不收集 GitHub 日志。在自托管运行器上,查找文件
.gdmp_pat,.gdmp_patg和.gdmp_sweep,以及作业日志中的字符串gdmp-pivot。
响应
轮换受影响存储库可访问的所有存储库、组织和环境密钥。删除该次运行或分支并不能消除暴露风险。
撤销用于推送这些提交的令牌,并检查这些令牌的持有者设备中是否存在信息窃取程序。
如果某个
ci-sync分支曾 在自托管运行器上运行,则应将主机及其实例角色视为已失陷。不要批准处于等待批准状态的
sync-check运行,也不要运行来自ci-sync分支的代码。
加强防护。 对包含生产密钥的环境强制设置审核人员,将 OIDC 信任策略的范围限定为受保护的分支或环境,使用 GitHub Apps 或短期细粒度令牌而非个人访问令牌,并将自托管运行器作为临时主机运行,且不提供 Docker socket 或不受限制的元数据访问权限。
失陷指标
用户代理
gheist分支
ci-sync-后面跟六个字符,与^ci-sync-[0-9a-z]{6}$匹配提交信息
ci: sync config仅添加了.github/workflows/sync-check.yml标记
toJSON(secrets) }}' | base32 -w 120和===== gdmp-pivot:;文件.gdmp_pat、.gdmp_patg、.gdmp_sweep工作流 blob SHA:
f3da2b8b357dcda02fd455d314be2a95007516a6(明文)、d09535857a741bbb976bdc084a9a021713133291(超时)、1dc5af9cce950aad1eb1546ecce8565b117540c4(分隔符)、c665b778b2d822453293003e7ca0bbb2cb08e39d(自托管作业)。环境矩阵变体因存储库而异。
Wiz 可以提供哪些帮助?
该 Threat Center 咨询公告包含一项 Event Explorer 查询,涵盖植入的提交、GitHub 审计日志中的 Gheist 活动,以及来自攻击者分支的云角色代入。Wiz Defend 使用多项规则检测此类活动,包括 "New Workflow Completed And Deleted In Short Time Span"、"Workflow Pushed With Secret Dump" 和 "Commit Created With Known Malicious Commit Message"。
来源:Hacker News · wiz.io