2026 年 3 月,全球最流行的开源漏洞扫描工具 Trivy 再次成为供应链攻击的目标。攻击者通过篡改 GitHub Actions 发布标签,在短短数小时内成功渗透了数千个 CI/CD 流水线,批量窃取各类凭证信息。这并非 Trivy 首次遭受攻击 —— 事实上,这是同一攻击者在一个月内的第二次入侵,而第一次攻击的处置不当为第二次攻击埋下了伏笔。
高价值目标:Trivy 为何成为众矢之的
Trivy 是 Aqua Security 开发的开源漏洞扫描工具,被广泛用于检测容器镜像、Kubernetes 配置、云基础设施和代码仓库中的安全漏洞。由于其使用场景涵盖开发测试流水线和生产安全扫描,Trivy 在全球拥有海量用户群体,包括众多企业级开发团队和安全运维人员。这种广泛的采用使其成为攻击者眼中极具诱惑力的目标 —— 一旦攻破 Trivy 的供应链,就能够影响到使用该工具的无数下游项目。
攻击者深谙此道。2026 年 3 月初,TeamPCP(又称 DeadCatx3、PCPcat、ShellForce)首次对 Trivy 发起攻击,成功从 Trivy 的构建环境中窃取了大量凭证。这些凭证本应在首次事件后被全部轮换,但由于轮换流程并非原子性操作,攻击者可能获取到了新生成的凭证,为后续攻击保留了入口。
第一次攻击的教训:未完成的遏制
2026 年 3 月 1 日,安全研究员 Paul McCarty 首次披露 Trivy v0.69.4 版本存在后门。Aqua Security 随即展开调查并发布公告,确认攻击者通过被入侵的凭证发布了恶意版本和被篡改的 GitHub Actions。然而,官方在事件后的处置存在致命缺陷 —— 虽然旋转了部分密钥和令牌,但整个过程并非一次性完成,攻击者得以在轮换期间获取到新生成的凭证。
这种不彻底的处置为攻击者留下了持续访问的窗口。Aqua Security 后续承认:“我们对第一起事件的遏制不够完整,攻击者可能已经获知了新轮换的令牌。” 正是这个未修补的漏洞,让攻击者在短短三周后卷土重来。
标签篡改:攻击链的核心环节
2026 年 3 月下旬,TeamPCP 发动了第二次攻击,这次的手段更加隐蔽和精准。与第一次直接发布恶意版本不同,攻击者将目光投向了 GitHub Actions 的版本标签机制。
在 aquasecurity/trivy-action 仓库中,攻击者强制推送了 75 个标签(占全部 76 个标签的 99%),将这些标签重定向到包含恶意代码的提交。GitHub Actions 的版本标签通常被开发者用于引用特定版本的 Action,例如使用 aquasecurity/trivy-action@v0.10 或 aquasecurity/trivy-action@latest。当工作流执行时,GitHub 会自动拉取标签指向的代码。由于标签可以被强制推送更新,攻击者无需创建新版本就能让所有使用该标签的工作流执行恶意代码。
这种攻击方式的危害在于其隐蔽性。开发者的 CI/CD 配置文件本身没有任何变化,使用的仍是熟悉的标签引用,但实际执行的却是攻击者精心准备的恶意脚本。更糟糕的是,由于标签篡改发生在 Trivy 官方仓库,任何依赖该 Action 的外部工作流都会在毫不知情的情况下执行恶意代码,这使得检测变得极为困难。
信息窃取 payload 技术分析
攻击者注入的恶意脚本具备全面的情报收集能力。恶意代码伪装成正常的 Trivy 入口脚本,但在实际扫描功能执行前,首先进行大规模的环境侦察和数据窃取。
在凭证收集方面,恶意脚本针对多个关键领域进行扫描:SSH 私钥和公钥及相关配置文件、AWS、GCP、Azure、Kubernetes 和 Docker 的云服务凭证、环境变量中的敏感信息、.env 文件及其变体、PostgreSQL、MySQL、MariaDB、MongoDB 和 Redis 的数据库配置凭证、包管理器和 Vault 的认证令牌、Terraform、Jenkins、GitLab CI 等 CI/CD 工具的配置文件、TLS 私钥、VPN 配置以及 Slack 和 Discord 的 Webhook 令牌。
除文件扫描外,恶意脚本还具备内存凭证提取能力。它会扫描 GitHub Actions Runner.Worker 进程内存区域,搜索特定格式的 JSON 字符串 "<name>":{ "value": "<secret>", "isSecret":true},这正是 GitHub 存储 secrets 的内部格式。这种技术使得即使凭证未写入磁盘,攻击者仍能从运行中的进程内存提取敏感信息。
收集到的数据被加密并打包为 tpcp.tar.gz,随后上传到 typosquatted 命令与控制服务器 scan.aquasecurtiy [.] org(注意域名中 securtiy 的拼写错误)。如果外传失败,恶意软件会在受害者 GitHub 账户中创建一个名为 tpcp-docs 的公开仓库,将窃取的数据上传至该仓库作为备用传输通道。
为实现持久化驻留,恶意软件还会投放 Python 载荷至~/.config/systemd/user/sysmon.py,并将其注册为 systemd 用户服务。该载荷会定期连接远程服务器检查并下载额外的恶意模块,为攻击者提供对受感染设备的持续访问能力。
攻击规模与影响范围
根据安全研究机构的分析,此次攻击影响范围极广。恶意 Trivy 版本(v0.69.4)在发布后约三小时内保持活跃,而被篡改的 GitHub Actions 标签则持续了长达十二小时。考虑到 Trivy 在全球数万个组织中的广泛使用,估算受影响的 CI/CD 工作流数量达到数万的量级。
任何在此期间使用受影响版本或标签运行 Trivy 扫描的组织,都可能已经向攻击者暴露了所有存储在 CI/CD 环境中的凭证。这包括云服务 API 密钥、容器仓库认证信息、部署令牌、SSH 密钥以及各类业务敏感凭证。安全研究人员建议,所有在此窗口期使用过受影响 Trivy 版本的企业,应将自身环境视为已完全沦陷,并立即轮换所有相关凭证。
攻击者归属:TeamPCP 的云计算威胁
研究人员通过分析恶意代码中的字符串特征,确认此次攻击的幕后黑手为 TeamPCP 威胁组织。在窃取凭证的 Python 脚本末尾,攻击者留下了 "TeamPCP Cloud stealer" 的注释,这成为关键的归因证据。
TeamPCP 是已知的云原生威胁组织,专门针对配置不当的 Docker API、Kubernetes 集群、Ray 仪表板和 Redis 服务器发起攻击。该组织此前曾使用类似的供应链攻击技术,其攻击手法以利用云环境中的配置漏洞和窃取云服务凭证著称。
后续攻击:CanisterWorm 的蠕虫化传播
值得注意的是,Trivy 攻击事件并未止步于凭证窃取。安全研究人员发现,TeamPCP 在同一时期部署了名为 CanisterWorm 的新型自传播蠕虫。该蠕虫专门针对 npm 包生态系统,通过窃取的 npm 认证令牌,在短短 60 秒内篡改了 28 个 npm 包。
CanisterWorm 使用去中心化的命令与控制机制,利用 Internet Computer (ICP) canisters 作为死 Drops 解析器,提供额外载荷的 URL。这种架构设计使得攻击基础设施极难被关闭,因为只有 canister 的控制者才能移除它,任何执法尝试都需要通过治理提案和网络投票才能实现。
事件反思
Trivy 攻击事件揭示了现代软件供应链的脆弱性。即使是拥有专业安全团队和维护良好信誉的开源项目,也可能因为处置流程中的一个疏漏而遭受二次攻击。标签篡改这种看似低级的攻击手法,在 CI/CD 流水线的信任模型下具有巨大的破坏力。对于依赖第三方 Actions 的组织而言, pinning 到精确的提交哈希而非可变更的标签,已经成为必须遵循的安全最佳实践。
资料来源:BleepingComputer 报道(Wiz、Socket 安全分析);Aqua Security 官方披露。