安全公司Wiz公布了一份完整的事后分析:一场代号Gheist的行动用五周时间,把窃取来的GitHub令牌变成了一条流水线——在能触及的每个仓库里提交一个专门偷秘密的工作流,最终在850多个被盗账号上植入了13500个分支,个人项目和企业私有仓库都没能幸免。
![]()
它偷的不只是组织机密和云凭证。Wiz特别点出,这套工具会专门搜寻AI服务商的密钥:Anthropic、Hugging Face、Groq、NVIDIA。跑在CI里的智能体密钥,正是它的购物清单。
四步走完一次投毒
Gheist的工具链先拿一个偷来的令牌(来源是信息窃取器日志和此前的供应链事件),枚举它能碰到的所有仓库,然后植入一个名为ci-sync-XXXXXX的分支,里面只有一个工作流,提交信息写着ci: sync config,没有签名。
这个工作流只有两行:把环境变量和密钥上下文打印到日志里,先做base32编码。随后工具通过GitHub的API取回日志,再删掉这次运行记录。
四个细节值得记住:
- base32编码绕过了密钥掩码。GitHub只在密钥原样出现时才打码,编码之后掩码什么也看不见,你的密钥就"安全"地打印给了攻击者。
permissions: {}在这里保护不了任何东西。它限制的是自动生成的GITHUB_TOKEN,不是secrets上下文。网上流传的一半加固建议,防的是另一种攻击。- 环境矩阵。工具会列出仓库的部署环境,于是环境级密钥——通常是生产环境、通常是压箱底的那批——也会被打印出来。
- 全程没有C2。秘密从GitHub自己的API出去,来自GitHub自己的IP,用的是你签发的令牌。没有攻击者域名可封,没有外传主机可告警,通道就是平台本身。
在自托管运行器上,载荷走得更远:搜索31种令牌格式,包括私钥、.env文件、Terraform状态、/proc/*/environ、Docker套接字、Kubernetes令牌,以及专门的AI服务商密钥。Wiz指出这个变种还有bug——运行器路径写错、正则失效、没有GCP/Azure收集——但这反而更糟:这套行动是一个还在持续迭代、不断加功能的产品。
公开仓库与私有仓库的不对称
整份分析里最耐人寻味的一点:公开仓库基本被GitHub一道安静的护栏救了。自7月28日起,公开仓库中首次贡献者的工作流运行会停在action_required状态,等待协作者批准——Wiz检查的每一次公开仓库Gheist运行都卡在那里,载荷从未执行。
这道拦截不适用于私有仓库和GitHub Enterprise Server。在那里,工作流跑了,密钥被倒空了,Wiz还通过CloudTrail证实了攻击者用偷来的云凭证完成了后续的AWS角色代入。你从没配置过的那道护栏保护了你的开源项目;私有仓库里什么也没有,而秘密恰恰住在那里。
另外两个发现:恶意工作流里的permissions: {}是攻击者自己加的,纯属装饰,因为secrets根本不看这个;约三分之二的涉事账号此后已从GitHub消失,说明响应正在进行,而行动本身一直演化到10月24日。
五分钟自查
提交信息在公开历史里可搜,但噪音很大,正常同步脚本到处都是,所以它只能当线索,不能当结论:
gh api 'search/commits?q="ci: sync config"' --jq '.total_count'
真正的自查是查自己账号下被植入的分支,遍历仓库、匹配分支名模式:
gh repo list --limit 200 --json nameWithOwner --jq '.[].nameWithOwner' | while read r; do gh api "repos/$r/branches" --paginate --jq '.[].name' 2>/dev/null | grep -E '^ci-sync-[0-9a-z]{6}$' && echo " ↑ HIT in $r"; done
组织层面(仅限组织所有者,审计日志API不对个人账号开放):查运行完成后一分钟内被删除的工作流记录,这是Gheist的清理特征;再查用户代理为gheist的记录。
还有一招不依赖GitHub日志的云端排查:OIDC角色代入的会话或主体里含ci-sync-。GitHub的OIDC主体包含ref,植入的分支名会一路带进CloudTrail,用aws cloudtrail lookup-events查AssumeRoleWithWebIdentity再grep即可。
一旦命中:轮换该仓库能看到的所有密钥——删掉运行记录不等于没被倒出去;吊销推送用的令牌;检查令牌所有者的机器有没有信息窃取器,因为令牌就是从那里来的。
为下一次加固
按成本从低到高:给环境级密钥强制要求审核人,废掉环境矩阵;把OIDC信任策略限定在受保护分支,废掉ci-sync-*的角色代入;用GitHub Apps或细粒度短时令牌替代经典PAT,缩小一个被盗令牌的触达范围;自托管运行器做成一次性、不给Docker套接字、不给无限制元数据,废掉主机跳板。
还有一条:永远不要批准停在action_required里的同步检查运行——那是陷阱的正门。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.