GhostAction 供应链攻击卷土重来:伪装“安全审计”的恶意工作流正在批量搬空 GitHub 仓库的云凭证

· 2026-10-10 15:09 · 28 阅读

原创 威胁情报中心 2026-10-10 15:09 北京

两个被入侵的维护者账户、约 40 分钟内 340+ 仓库被批量注入;本轮新增对完整 Git 历史的凭证扫描,目标直指 AWS 云凭证与 AI 服务 API 密钥。

威胁研判 · 供应链安全 · GitHub Actions

GhostAction 供应链攻击卷土重来
伪装“安全审计”的恶意工作流正在批量搬空 GitHub 仓库的云凭证

两个被入侵的维护者账户、约 40 分钟内 340+ 仓库被批量注入;本轮新增对完整 Git 历史的凭证扫描,目标直指 AWS 云凭证与 AI 服务 API 密钥。

· GhostAction · GitHub Actions 工作流注入 · Git 历史凭证窃取 · 2026.10

事件速览:2026 年 10 月 8 日,供应链攻击活动 GhostAction 的新一轮爆发被多家安全厂商捕获。攻击者利用两个被入侵的开源维护者账户,在总计约 40 分钟的两个自动化时间窗口内,向超过 340 个 GitHub 仓库批量提交了伪装成“安全审计”的恶意 GitHub Actions 工作流。与以往不同的是,本轮载荷在窃取 CI/CD Secrets 的基础上,新增了对工作目录和完整 Git 历史的凭证扫描能力,目标直指 AWS 云凭证与 AI 服务 API 密钥。截至 10 月 9 日,已有超过 500 个 GitHub 账户被确认提交了该恶意工作流,波及仓库数以万计。

01 从两条诡异的提交记录说起

10 月 8 日 13:20 UTC,开源游戏引擎 pyxel(GitHub 星标约 1.8 万)的作者 Takashi Kitao 的账户,开始向自己名下的仓库推送一个名为 security-audit.yml 的工作流文件,提交信息是再普通不过的 “Add security audit workflow”。约 24 分钟内,27 个仓库被植入该文件,仅 pyxel 仓库就收到三次提交。

8 小时后,21:10 UTC,另一位维护者 Henry Wu(henrywoo)的账户开始了更大规模的扫荡:16 分钟内,318 个仓库(39 个源仓库 + 279 个 fork)被注入同一载荷。这一窗口的最后两秒,攻击落在了 Uber 旗下的 uber/athenadriver 仓库上——henrywoo 是该项目的原作者,保留着对组织仓库的写权限。没有 PR,没有评审,恶意文件以维护者本人的身份直接推入 master,提交未签名,审计日志中没有任何异常痕迹。

这些提交呈现出鲜明的自动化特征:跨越十年未更新的“僵尸仓库”与活跃项目被无差别处理,所有载荷文件除渲染进去的 Secret 名称外逐字节一致。Socket 在 10 月 9 日的更新中确认,自 10 月 7 日以来已有超过 500 个 GitHub 账户向数以万计的仓库提交了该恶意工作流,其中包括通过被入侵贡献者触及的组织仓库。截至发稿,恶意工作流仍存在于多个受影响仓库的默认分支上,且已成功运行。

02 GhostAction:一场从未停止的供应链攻击

GhostAction 并非新面孔。2025 年 9 月,GitGuardian 首次披露了这一针对 GitHub 的大规模凭证窃取活动:攻击者入侵 FastUUID 项目维护者账户作为起点,最终波及 327 名用户、817 个仓库,窃取 3,325 个密钥,涵盖 PyPI、npm、DockerHub、GitHub、Cloudflare 令牌及 AWS 密钥、数据库凭证等,多家公司的整套 SDK 产品线同时沦陷。PyPI 事后作废了所有被盗令牌,并确认攻击者未利用其发布恶意包。

一年多过去,这条攻击链几乎没有变过,始终是四步:

1账户入侵 —— 获取维护者的有效 GitHub 凭证(最可能来自窃密木马日志或凭证库中流通的泄露 PAT,具体途径未被观测到)。

2投递前侦察 —— 扫描目标仓库现有工作流文件中的 ${{ secrets.NAME }} 引用,将精确的 Secret 名称渲染进载荷模板。

3注入 —— 以受害者身份将伪装成安全增强的工作流直接提交到默认分支,推送动作本身即触发执行。

4外泄 —— 工作流通过 curl 以明文 HTTP POST 将凭证发送到攻击者控制的服务器。

真正变化的是基础设施与载荷能力。2025 年 9 月,外泄端点是 bold-dhawan.45-139-104-115.plesk.page 等域名(指向 45.139.104.115);而自 2026 年 9 月初起,端点切换为裸 IP 193.32.204.199(80 端口,及 3000 端口的 /api/workflow/receive?inj=<id> 接口),不再产生 DNS 查询,基于域名的防御手段被整体绕过。2025 年版旧载荷至今仍在与新载荷并行投递。

图1 | GhostAction 攻击链全景流程图(图源:根据 Socket、StepSecurity 披露信息整理自绘)

03 解剖“安全审计”:一个工作流里的两套窃取引擎

以 pyxel 仓库 commit 97670a55 中的完整载荷为样本,这个名为 “Security Audit” 的工作流触发条件为 workflow_dispatch + 无任何分支/路径过滤的 push,整个任务只做一件事——收集凭证并外泄。其内部由两代技术拼接而成。

图2 | “Security Audit”恶意工作流内部数据流(图源:根据 Socket 披露的载荷代码整理自绘)

3.1 继承自 2025 年的部分:点名窃取 Actions Secrets

载荷中的这段逻辑是 GhostAction 的标志性手法:

out="REPO=$GITHUB_REPOSITORY"

[ -n "CARGO_REGISTRY_TOKEN=${{ secrets.CARGO_REGISTRY_TOKEN }}&PERSONAL_ACCESS_TOKEN=${{ secrets.PERSONAL_ACCESS_TOKEN }}&PYPI_PASSWORD=${{ secrets.PYPI_PASSWORD }}&PYPI_USERNAME=${{ secrets.PYPI_USERNAME }}" ] && out="$out&..."

投递前侦察的成果在这里兑现:pyxel 的载荷中精确写死了四个 Secret 名称——crates.io 发布令牌、GitHub 个人访问令牌、PyPI 用户名与密码,恰好覆盖该项目双注册中心的全部发布凭证。这类凭证的价值在于,攻击者可以冒用一个用户已信任的项目的名义发布恶意版本,把单点账户失陷放大为下游供应链事件。若侦察未发现任何 Secret,模板会优雅降级为空判断 [ -n "" ](athenadriver、pyllama、chatllama 等仓库即是如此),工作流照常运行。

3.2 本轮新增的部分:把工作树和 Git 历史翻个底朝天

从 fetch-depth: 0 开始的一切都是新能力,也是本轮升级的核心:

- uses: actions/checkout@v4

with:

fetch-depth: 0# 拉取全部分支与标签,而非默认的浅克隆

grepped=$(grep -rEiho "<13种凭证正则>" --exclude-dir=.git . 2>/dev/null | sort -u)

gl=$(git log -p --all 2>/dev/null | head-200000)

hist=$(echo"$gl" | grep -oiE "<13种凭证正则>" | sort -u | head-300)

ctx=$(grep -rEi -B2 -A2 "AKIA[0-9A-Z]{16}|ASIA[0-9A-Z]{16}" --exclude-dir=.git . 2>/dev/null | head-150)

hctx=$(echo"$gl" | grep -Ei -B2 -A2 "AKIA[0-9A-Z]{16}|ASIA[0-9A-Z]{16}" | head-150)

五个变量分工明确:grepped 扫工作树,gl 缓存全量历史的补丁文本,hist 在历史中重跑同一套正则,ctx/hctx 则对 AWS 密钥做专门的上下文捕获。

fetch-depth: 0 是整个设计的支点:它让 Runner 拿到仓库的每一个分支和标签,git log -p --all 随之可以读取完整历史的补丁文本——哪怕某个密钥 2019 年提交后第二天就被删除,哪怕它只存在于一条早已废弃的分支或旧标签上,也会被原样收割。这正是维护者最可能误以为“已经清理干净”的那类凭证。

3.3 AWS 密钥配对:从“孤儿 ID”到可用凭证

两组上下文捕获是新增部分中最具针对性的设计。AKIA/ASIA 只是密钥标识符,本身无法通过认证;真正的 40 位 Secret Access Key 在实践中往往就躺在它上下一两行——.env 文件、AWS credentials 文件、Terraform 变量文件或 CI 配置块里。载荷对每个 AWS Access Key ID 抓取前后两行上下文,并用 AKIA_CTX_START / AKIA_CTX_END 分隔符包裹,以便接收端单独解析,从而重建完整可用的 AWS 密钥对,而非收回来一堆无法使用的孤立 ID。

3.4 十三类凭证正则:AI 密钥成为一等目标

工作树与历史两个扫描通道共用以下 13 个正则模式:

类别

模式

对应凭证

AWS

AKIA[0-9A-Z]{16}

长期访问密钥 ID

AWS

ASIA[0-9A-Z]{16}

STS 临时访问密钥 ID

AWS

(?:aws_)?secret(?:_access)?_key

 + 40 字符

Secret Access Key(按变量名匹配)

AWS

aws_session_token

 + 100 字符以上

STS 会话令牌

AI 服务

sk-ant-…

Anthropic API Key

AI 服务

sk-proj-…

OpenAI 项目密钥

AI 服务

sk-or-(v1-)?…

OpenRouter 密钥

代码托管

ghp_[A-Za-z0-9]{36}

GitHub 经典 PAT

代码托管

github_pat_…{60,}

GitHub 细粒度 PAT

代码托管

glpat-…

GitLab PAT

SaaS/云 API

AIza[A-Za-z0-9_-]{35}

Google / Firebase / GCP API Key

SaaS/云 API

xox[baprs]-…

Slack 各类令牌

SaaS/云 API

SG\.…\.…

SendGrid API Key

模式清单与受害仓库画像高度吻合:henrywoo 名下星标最高的 pyllama(约 2,800 星)与 chatllama(约 1,200 星)均为机器学习项目,其贡献者与 fork 者恰恰最常持有 AWS 密钥与各家 AI 服务密钥。

3.5 带内遥测与单次请求外泄

两类窃取结果拼接进同一个变量,一次 HTTP POST 全部带走。更有意思的是 URL 中的查询标记:模板渲染了具名 Secret 的仓库 POST 到 /?c=monami,仅有历史扫描结果的 POST 到 /?c=new——攻击者无需打开请求体,仅凭 URL 就能把回传数据按“含金量”分拣。同时,无论是否有所收获,每次运行都会回传仓库标识符,攻击者因此持有一份“可触达执行环境”的实时地图。所有流量走明文 HTTP 直连裸 IP,产生不了任何可供域名安全设备检查的 DNS 记录。

04 运行取证:三个仓库,三种结局

uber/athenadriver —— 外泄确认成功

StepSecurity 提取了恶意运行的日志(Run ID 37846728441,由注入提交后 3 秒触发)。日志显示 checkout 拉取了仓库全部 13 个分支和 20 个标签——包括 henry.wu/* 开发分支和一个名为 s3-bucket-compromised-2023-03 的分支,全部进入历史扫描范围。三段 grep 执行后,日志中出现一行 OK:工作流脚本本身不打印任何输出,这是 C2 服务器的 HTTP 响应体被 curl -s 回显进了日志。21:26:04Z,运行开始后仅 4 秒,POST 已送达并被确认接收。同一份日志还暴露了两个细节:AWS Secret Key 正则因使用了 POSIX ERE 不支持的非捕获组 (?:...) 而部分失配(日志中的 grep: warning 即源于此),但所有字面量前缀模式工作正常;本次运行的 GITHUB_TOKEN 权限仅为 contents: read,工作流自身无法推送或发布——权限提升完全依赖偷到的凭证,这正是 pyxel 发布令牌的价值所在。

kitao/pyxel —— 攻击者回来“手动按了按钮”

pyxel 的恶意工作流共运行 5 次且全部成功:3 次由攻击者推送触发,2 次为手动 workflow_dispatch(13:36:32Z 与 13:42:35Z),均在每次工作流更新后立即从被入侵的 kitao 会话发起。自动化扫荡之外,这是明确的“人在回路”操作——攻击者手动重跑外泄工作流以验证或重复收集。

typecho-fans/plugins —— 一个配置项拦断了攻击链

该仓库自 9 月 5 日起就被 xxyangyoulin 账户注入了旧版载荷。10 月 7 日,攻击者先后推送一个零文件变更的空提交(“Update Github Actions Security workflow”)和一次三行 README 修改(“Trigger security scan”),目的纯粹是重新触发工作流。但两次运行全部卡在 action_required 状态——该仓库启用了工作流运行审批,外泄未能执行。一个设置,击穿了整条攻击链。

05 影响面研判

  • 爆炸半径不取决于个人项目,而取决于凭证能写到哪。 henrywoo 因原作者身份保有 Uber 组织仓库写权限,一次个人账户失陷直接把载荷送进了财富 500 强代码库。

图3 | Socket 的 AI 扫描器将 uber/athenadriver 被注入恶意工作流的版本识别并标记为“已知恶意软件 / 供应链风险”(图源:Socket)

  • pyxel 是暴露面最高的目标。 约 1.8 万星、966 个 fork,Rust + Python 双语言,经 PyPI 与 crates.io 双渠道分发;载荷中点名的四个 Secret 正是两个注册中心的发布凭证加一个 GitHub PAT。
  • 279 个被注入的 fork 构成次生风险。 若启用 Actions,后续推送即可触发凭证收割;下游 fork 在新建或与上游同步时也会继承恶意工作流,而私有 fork 和下游镜像最为危险——真正被提交进仓库的凭证恰恰集中在私有仓库里。
  • 发布凭证的暴露窗口仍然敞开。 截至发稿,未观测到利用被盗凭证在 PyPI 或 crates.io 发布恶意版本:pyxel 最后版本为 8 月 12 日的 v2.9.9(失陷前),其 crates.io 发布停留在 2019 年,athenadriver 最后发布于 2024 年 3 月。但只要相关令牌未轮换,风险就持续存在——这与 2025 年波次的情况如出一辙,当时同样“只偷不用”,而“尚未滥用”从来不是凭证安全的证据。
  • 规模仍在扩大。 截至 10 月 9 日,GitHub 代码搜索显示默认分支上仍存活的恶意工作流覆盖 378 个仓库,其中 182 个带有 AKIA_CTX_START 历史扫描标记,88 个带有 ?c=monami 标记(即具名 Secret 已被模板化并外泄);该数字不含 fork,henrywoo 名下 279 个被感染 fork 需额外计入。

06 自查与应急处置建议

快速自查

在 GitHub 代码搜索中检查以下特征(登录后 Code 标签页):

"AKIA_CTX_START"path:.github/workflows

"c=monami"

"193.32.204.199"path:.github/workflows

org:组织名 "AKIA_CTX_START"

零命中是好迹象;任何命中即意味着存在被感染仓库或携带恶意工作流的 fork。若仓库自 2026 年 8 月 31 日以来出现过名为 “Security Audit”(security-audit.yml)或 “Github Actions Security”(github_actions_security.yml)的工作流,应按已确认失陷处置:所有已配置的 Actions Secret 与 Git 历史中存在的任何凭证都已被提供给攻击者,且工作流每次运行都会回连——哪怕一无所获。

若载荷中渲染了具名 Secret(Set A 暴露)

  1. 轮换文件中点名的每一个 Secret;对个人访问令牌应吊销而非轮换;
  2. 审查 PyPI / crates.io / npm 等注册中心在暴露窗口内的发布历史,比对发布产物与自有构建输出;
  3. 检查注入工作流的运行记录,任何已完成的运行均视为对应 Secret 已被外泄。

若载荷扫描了仓库(Set B 暴露)

  1. 用 git log -p --all 扫描完整历史而非仅当前 HEAD,包含不可达对象与废弃分支/标签;
  2. 凡是在历史中出现过的凭证,无论当前树中是否存在,一律按已暴露处理并轮换,覆盖上述全部 13 类;
  3. 对历史中发现过 AWS 密钥的,回溯审查暴露窗口及之后的 CloudTrail 日志,排查新增 IAM 用户、访问密钥与异常区域活动。

两种情况通用

  1. 从所有分支(不止默认分支)删除恶意工作流并回滚提交,包括组织仓库;
  2. 将被入侵账户视为完全失陷:吊销全部会话、PAT、OAuth 授权与 SSH 密钥,启用防钓鱼多因素认证并重新登记;
  3. 审查组织审计日志中的推送窗口,按账户权限枚举而非按预期排查所有可写仓库的工作流新增记录;
  4. 在出口日志(含自托管 Runner 网段)中排查与 193.32.204.199 的连接并实施阻断;
  5. 开启 GitHub Secret Scanning 的推送保护,要求外部协作者的工作流运行需审批——本轮事件中,审批门是唯一被观测到直接阻断外泄的控制项;
  6. fork 所有者:在任何来自受影响命名空间的 fork 上启用 Actions 前,先检查是否存在 .github/workflows/security-audit.yml;
  7. 清理完成前不要发布任何新版本:若配置了发布类 Secret,应假定攻击者已能以你的身份发包。

07 技术附录

7.1 MITRE ATT&CK 技术映射

战术

技术 ID

技术名称

本事件中的体现

初始访问 / 持久化

T1078

Valid Accounts(有效账户)

使用被入侵的维护者 GitHub 账户(henrywoo、kitao、xxyangyoulin)直接推送恶意提交

初始访问

T1195.002

Supply Chain Compromise: Compromise Software Supply Chain(供应链攻陷)

向开源仓库注入恶意工作流,窃取发布凭证,可向下游包生态扩散

防御规避

T1036

Masquerading(伪装)

恶意工作流伪装为“Security Audit”“Github Actions Security”等安全增强,提交信息同样伪装

凭证访问

T1552.001

Unsecured Credentials: Credentials In Files(文件中凭证)

正则扫描工作树与完整 Git 历史中的 13 类硬编码凭证

凭证访问

T1552

Unsecured Credentials(非安全存储凭证)

窃取 GitHub Actions 环境中注入的 CI/CD Secrets

凭证访问

T1528

Steal Application Access Token(窃取应用访问令牌)

窃取 GitHub/GitLab PAT、PyPI/crates.io/npm 发布令牌、Slack/SendGrid/Google 等服务令牌

收集

T1119

Automated Collection(自动化收集)

通过 grep + git log -p --all 对仓库工作树与全量历史进行自动化正则收割,并对 AWS 密钥做上下文配对

命令与控制

T1071.001

Application Layer Protocol: Web Protocols(Web 协议)

通过明文 HTTP POST 与 C2 通信,直连裸 IP 规避 DNS 层检测

数据外泄

T1041

Exfiltration Over C2 Channel(经 C2 通道外泄)

窃取数据经 curl 单次 POST 外泄至硬编码 IP 193.32.204.199

7.2 失陷指标(IoC)

网络指标

类型

值

说明

C2 IP

193.32.204[.]199

(80、3000 端口)

当前外泄端点;任何来自 Runner 的连接均确认数据已送出

外泄 URL

hxxp://193.32.204[.]199/?c=monami

、/?c=new

monami = 仓库存在具名 Secret;new = 仅历史扫描

API 接口

193.32.204[.]199:3000/api/workflow/receive?inj=<id>

接收端点

历史 C2

45.139.104[.]115

、170.39.218[.]2、*.oast.fun

既往波次端点,适用于历史日志回溯

历史域名

bold-dhawan.45-139-104-115.plesk[.]page

、carte-avantage[.]com、objective-hopper.45-139-104-115.plesk[.]page

2025 年波次外泄域名

主机 / 代码指标

类型

值

恶意工作流路径

.github/workflows/security-audit.yml

、.github/workflows/github_actions_security.yml、.github/workflows/security-check.yml

工作流 / 任务名

“Security Audit”(job: audit);“Github Actions Security”(job: send-secrets,步骤 “Prepare Cache Busting”)

提交信息

Add security audit workflow

、Update security audit workflow、Add/Update Github Actions Security workflow、Add security check workflow、Trigger security scan

POST 体标记

REPO=

、AKIA_CTX_START、AKIA_CTX_END

被入侵账户

henrywoo

、kitao、xxyangyoulin(受害者账户,非攻击者持有账号)

审计日志排查要点:维护者身份直接向默认分支提交工作流文件(绕过 PR)、新建“audit”工作流上的 workflow_dispatch 事件、数分钟内跨多仓库的密集未签名提交。

08 参考链接

1. Socket — New GhostAction Wave Hits Hundreds of Repos, Expanding Beyond CI/CD Secrets to Cloud Credentials
https://socket.dev/blog/ghostaction-cloud-credentials

2. StepSecurity — GhostAction Returns: Malicious “Security Audit” Workflows Now Mine Credentials from Entire Git Histories
https://stepsecurity.io/blog/ghostaction-returns

3. GitGuardian — The GhostAction Campaign: 3,325 Secrets Stolen Through Compromised GitHub Workflows(2025 年 9 月首次披露)
https://blog.gitguardian.com/ghostaction-campaign-3-325-secrets-stolen/

4. StepSecurity — GhostAction Campaign: Over 3,000 Secrets Stolen Through Malicious GitHub Workflows(2025 年 9 月)
https://www.stepsecurity.io/blog/ghostaction-campaign-over-3-000-secrets-stolen-through-malicious-github-workflows

5. The Hacker News — Credential-Stealing GitHub Actions Workflows Planted in Tens of Thousands of Repositories
https://thehackernews.com/2026/10/credential-stealing-github-actions.html

6. BleepingComputer — Hackers steal 3,325 secrets in GhostAction GitHub supply chain attack
https://www.bleepingcomputer.com/news/security/hackers-steal-3-325-secrets-in-ghostaction-github-supply-chain-attack/

7. FreeBuf — 泛滥的供应链攻击又一例:GhostAction 行动窃取凭证信息事件解析(2025 年 9 月)
https://www.freebuf.com/news/448136.html

阅读原文

跳转微信打开

本文转载自微信公众号「奇安信威胁情报中心」,查看原文。版权归原作者所有,如有侵权请联系删除。