文章总结: 文档复盘Trivy与LiteLLM供应链投毒案,攻击者利用凭证轮换漏洞入侵CI/CD,经篡改tag窃取下游凭证投毒PyPI。分析涵盖窃密载荷、.pth持久化等技术细节,指出Gittag可变性与传递依赖盲区。建议实施SHApinning、彻底轮换凭证并排查IOC,揭示供应链攻击链式传导的严峻态势。 综合评分: 95 文章分类: 供应链安全,恶意软件,漏洞分析,应急响应,实战经验
从 Trivy 到 LiteLLM:一周内两起供应链投毒的技术复盘
原创
imBobby imBobby
imBobby的自留地
2026年3月25日 16:47 广东
一句话概括
2026 年 3 月第三周,开源漏洞扫描器 Trivy 和 LLM 代理框架 LiteLLM 先后被同一攻击组织 TeamPCP 投毒。攻击路径:入侵安全工具的 CI/CD -> 窃取下游项目的发布凭证 -> 向包管理器投放后门。5 天内横跨 GitHub Actions、Docker Hub、npm、PyPI 和 OpenVSX 五个生态。
这不是两个独立事件,而是一条完整的供应链传导链。
前奏:2025 年 tj-actions 攻击定义了战术模板
理解 Trivy 攻击需要先理解它的前身。
2025 年 3 月,tj-actions/changed-files(CVE-2025-30066)被入侵,这是一个被超过 23,000 个仓库使用的 GitHub Action。攻击链起点在数月之前:2024 年 11 月,一名 SpotBugs 维护者在 CI 工作流中意外硬编码了个人访问令牌(PAT)。攻击者通过一个恶意 Pull Request 利用 pull_request_target 触发器窃取了这个 PAT — 该触发器允许 fork 提交的工作流访问仓库密钥。
凭借这一个 PAT,攻击者从 SpotBugs 跳转到 reviewdog(CVE-2025-30154),再到 tj-actions。载荷从 GitHub Actions Runner Worker 进程内存(/proc/<pid>/mem)中提取 CI/CD 密钥,以双重 base64 编码写入工作流日志。对于公开仓库,这些密钥对任何人可见。
CISA 在 2025 年 3 月 18 日将 CVE-2025-30066 加入已知被利用漏洞目录。攻击的实际目标是 Coinbase 的 agentkit 项目,但 Coinbase 的密钥未被成功利用。
这次攻击确立了战术模板:force-push 可变 git tag 指向恶意 commit,从 Runner 进程内存中收割 CI/CD 密钥,用这些密钥攻击下游目标。TeamPCP 在一年后将这套打法工业化。
第一阶段:Trivy — 当安全扫描器自身成为攻击载体
一次不彻底的凭证轮换引发了全部后果
3 月 1 日,Trivy 团队披露了一次早期安全事件并执行了凭证轮换。但轮换不够彻底 — 攻击者通过未被撤销的凭证保留了访问权限。
这是整条链中最关键的单点失败。后续的一切 — tag 投毒、Docker 恶意镜像、LiteLLM 沦陷、npm 蠕虫 — 都可以追溯到这次不完整的轮换。
攻击经过:3 月 19 日
UTC 时间 3 月 19 日 17:43,攻击者利用被入侵的 aqua-bot 服务账号,对 aquasecurity/trivy-action 仓库发起 force-push:77 个版本 tag 中的 76 个被指向恶意 commit(唯一干净的是 0.35.0)。aquasecurity/setup-trivy 的全部 7 个 tag 同样被篡改。随后攻击者触发发布自动化,向 Docker Hub、GHCR 和 ECR 发布了恶意 Trivy 二进制文件 v0.69.4。
恶意代码注入到 entrypoint.sh,在正常 Trivy 扫描之前静默执行。工作流日志看起来完全正常 — 扫描照常运行并输出预期结果。
Trivy 团队在 20:38 UTC 遏制了攻击,窗口约 3 小时。
载荷:三阶段凭证窃取器
载荷在源码中自称 “TeamPCP Cloud stealer”,分三步执行:
第一阶段 — 信息收割:
- 读取
/proc/<pid>/mem,从 Runner Worker 进程内存中按模式匹配搜索密钥 - 递归查找
.env、.json、.yml、.yaml中的 API key 和 token - 枚举 AWS 凭证(环境变量 + EC2/ECS 元数据端点查询 IAM 角色)
- 读取 GCP 服务账号密钥文件
- 收集 Azure 环境变量
- 检测到 Kubernetes 环境时,通过 kubectl dump 所有命名空间的 secrets
- 收集 SSH 私钥
第二阶段 — 加密: AES-256 对称加密数据,RSA-4096 非对称加密对称密钥。只有攻击者持有私钥。
第三阶段 — 外传:
- 主通道:HTTP POST 到
scan.aquasecurtiy[.]org(注意 security 的拼写错误) - 备用通道:Cloudflare Tunnel(
plug-tab-protective-relay.trycloudflare.com) - 兜底:用窃取的
INPUT_GITHUB_PAT在受害者的 GitHub 账号中创建名为tpcp-docs的公开仓库存放数据
一个值得注意的检测信号
每个恶意 commit 伪造了原始 release 的提交日期(2021、2022 年),但其 parent commit 日期为 2026 年 3 月。这在时间上不可能成立。如果你的 CI/CD 监控能检查 commit 祖先链的时间一致性,这就是一个可靠的异常指标。
涂改事件:3 月 22 日
初始入侵三天后,攻击者在不到 2 分钟内(20:31:07 至 20:32:26 UTC)批量篡改了 Aqua Security 内部 aquasec-com 组织的全部 44 个仓库:重命名为 tpcp-docs- 前缀,描述改为 “TeamPCP Owns Aqua Security”,可见性设为公开 — 暴露了 Tracee 源码、内部 Trivy 分支、CI/CD 管道、Kubernetes operator 和团队知识库。
同一天,恶意 Docker 镜像 v0.69.5 和 v0.69.6 被推送到 Docker Hub,无对应 GitHub release。
影响规模
- Mandiant 估计超过 1,000 个 SaaS 环境受到影响,可能扩展到 10,000
- StepSecurity 确认至少 45 个仓库执行了恶意版本
- 分配了 CVE-2026-33634(CVSS 9.4)
- Aqua Security 聘请 Sygnia 进行取证分析,声明商业版 Trivy 未受影响(使用有发布滞后的受控 fork)
- Microsoft 在 3 月 24 日发布了专项检测与防御指南
第二阶段:LiteLLM — 一个被入侵的扫描器如何变成 PyPI 后门
传导链
LiteLLM 的 CI 管道引用了未固定版本的 Trivy Action。当管道运行时触发了投毒后的 tag,恶意 Trivy 二进制文件在 CI 环境中执行,窃取了 LiteLLM 的 PYPI_PUBLISH token。
攻击者随后以合法维护者(krrishdholakia)身份直接向 PyPI 发布了 1.82.7 和 1.82.8。两个版本在 GitHub 上均无对应 tag 或 release — 完全绕过了正常发布流程。
1.82.7:需要 import 才触发
载荷以 base64 编码嵌入 litellm/proxy/proxy_server.py,当代码执行 import litellm.proxy 时激活。
1.82.8:.pth 文件持久化 — 无需 import
1.82.8 升级了手法,在 site-packages/ 下放置了 litellm_init.pth(34,628 字节)。这利用了 Python site 模块在解释器启动时自动处理 .pth 文件的机制。
这意味着:
- 不需要任何 import 语句。 只要包安装在环境中,
python、pip、IDE 语言服务器、任何 Python 子进程启动时都会执行载荷 .pth文件在 wheel 的 RECORD 中正确声明且 hash 匹配,pip install --require-hashes无法检测- 对应 MITRE ATT&CK T1546.018(事件触发执行:Python 启动钩子)
载荷是同一套三阶段凭证窃取器,额外增加了加密货币钱包(BTC/ETH/SOL/LTC)、Slack/Discord token、SSL 私钥和 shell 历史的扫描。检测到 Kubernetes 环境时,会在每个节点的 kube-system 中部署特权 alpine:latest Pod 并挂载宿主机文件系统。在 ~/.config/sysmon/sysmon.py 安装持久化后门,注册为 systemd 用户服务。
数据外传到 models.litellm.cloud — 这不是 LiteLLM 官方域名。
被 Fork Bomb Bug 意外拯救
这次攻击被发现的原因是攻击者的一个编程错误。
.pth 通过 subprocess.Popen 启动 Python 子进程执行载荷,但子进程启动时又会触发同一个 .pth,再次 spawn 子进程 — 指数级 fork bomb。FutureSearch 的 Callum McMahon 在 Cursor IDE 中测试一个 MCP 插件时,litellm 作为传递依赖被拉入,他的 48GB Mac 瞬间卡死:CPU 100%,htop 需要数十秒才能加载,11,000+ 个 Python 进程在运行。线索是 Cursor 在卡死期间请求网络访问权限,以及进程列表中大量 python 命令在 exec base64 编码字符串。
安全研究人员指出,如果攻击者编程水平更高一点,这个后门可能数周都不会被发现。一条被广泛转发的评论:”这次是 vibe coding 救了我们” — 有迹象表明攻击者使用了 AI 辅助编码,恰好引入了这个递归 spawn bug。
影响
- LiteLLM 每月 PyPI 下载量约 9,500 万次(日均约 340 万次)
- 暴露窗口:约 5 小时(10:39 至 ~16:00 UTC)
- LiteLLM 的核心价值 — 统一代理 100+ LLM 提供商 — 意味着它集中管理了组织整个 AI 技术栈的 API 凭证。入侵这一个库就能获取所有凭证
- 传递依赖风险极高:即使从未直接安装 litellm,只要依赖树中有任何包间接依赖它,
.pth就会在每次 Python 启动时执行 - 攻击者还利用劫持的维护者账号关闭了 GitHub issue #24512(标记为 “not planned”),并用 73 个被盗开发者账号在 102 秒内发布了 88 条 bot 评论试图混淆视听
LiteLLM 的响应
BerriAI 确认维护者的 PyPI 账号被劫持,与 Trivy 入侵有关。官方安全公告要点:
- v1.82.6 是最后一个干净版本
- 受影响版本已被 PyPI 隔离
- GitHub、Docker Hub、CircleCI、PyPI 的密钥已全部轮换
- 使用官方 Docker 代理镜像的用户不受影响(requirements.txt 中固定了版本)
TeamPCP 是谁
Wiz 将攻击归因于 TeamPCP(又名 DeadCatx3、PCPcat、ShellForce、CanisterWorm),依据:
- 凭证窃取器源码中自我标识为 “TeamPCP Cloud stealer”
- Trivy 载荷使用的 ICP 区块链 C2 地址与 CanisterWorm npm 蠕虫相同(该蠕虫利用被盗的 publish token 感染了 47 个 npm 包)
- 一致的 “TeamPCP Owns [target]” 涂改模式
已知手法包括 Docker API / Kubernetes 集群利用、供应链攻击、加密挖矿、勒索软件和自传播蠕虫。据报道以经济利益为驱动,成员主要来自美英加及西欧。
这次战役 5 天内打了 五个生态系统:GitHub Actions、Docker Hub、npm、PyPI 和 OpenVSX。
安全运营启示
1. Git tag 是可变的,不能作为信任锚点
uses: aquasecurity/[email protected] 看起来像是固定了版本,实际不是。tag 随时可以被 force-push 到任意 commit。唯一可靠的做法是 pin 到完整 commit SHA:
# 不安全 -- tag 可以被 force-pushuses: aquasecurity/[email protected]
# 安全 -- 不可变引用uses: aquasecurity/trivy-action@a1234567890abcdef1234567890abcdef12345678
Dependabot 和 Renovate 都支持自动更新 SHA pin。
2. 凭证轮换必须穷尽
Trivy 在 3 月 1 日的事件响应中执行了凭证轮换,但不够彻底,攻击者保留了残余访问权限,直接导致 3 月 19 日的全面入侵。
事件响应中的凭证轮换应遵循”假设全部泄露”原则:列出所有可能暴露的凭证并全部轮换,而非只处理已确认泄露的部分。
3. 安全工具本身是高价值目标
Trivy 运行在 CI/CD 管道中,天然拥有对代码、密钥和构建环境的高权限访问。入侵一个安全扫描器,等于入侵了所有使用它的管道。这同样适用于 CI/CD 中的任何第三方工具:linter、SAST 扫描器、代码格式化工具、依赖检查器。
4. 传递依赖是最大的盲区
LiteLLM 被投毒后,即使从未直接安装过它,只要依赖树中有任何包间接依赖 litellm,就会受影响。McMahon 的案例完美说明了这一点 — 他测试的是一个 MCP 插件,litellm 是四层之外的传递依赖。
pip freeze 看一眼实际安装了什么,依赖树几乎肯定比你想象的要深。
5. 供应链攻击已经形成链式传导
这次战役展示了一个自我放大的模式:
GitHub Actions 配置缺陷 -> 安全扫描器 CI/CD 被入侵 -> 下游项目的发布凭证被窃取 -> 包管理器被投毒 -> 最终用户环境被控制 -> 更多凭证被窃取 -> 循环
Wiz 研究员 Gal Nagli 的总结:”开源供应链正在自我吞噬。Trivy 被入侵导致 LiteLLM 被入侵,导致数万个环境的凭证落入攻击者手中,这些凭证又导致下一次入侵。我们陷入了一个循环。”
自查清单
CI/CD 层
# 检查是否引用了受影响的 trivy-action 版本grep -r "trivy-action" .github/workflows/ --include="*.yml"# 确认是 SHA pin 而非 tag 引用
# 审计工作流日志中的异常网络请求# IOC 域名: scan.aquasecurtiy.org, models.litellm.cloud, checkmarx.zone
Python 环境
# 检查是否安装了受影响的 litellm 版本pip show litellm 2>/dev/null | grep -E "^Version:"# 受影响版本: 1.82.7, 1.82.8
# 检查 .pth 持久化文件find "$(python -c 'import site; print(site.getsitepackages()[0])')" \ -name "litellm_init.pth" 2>/dev/null
# 检查持久化后门ls -la ~/.config/sysmon/sysmon.py 2>/dev/null
主机与集群
# 检查 Kubernetes 中攻击者部署的 Podkubectl get pods --all-namespaces | grep "node-setup-"
# 检查组织中是否有攻击者创建的数据外传仓库gh repo list --json name -q '.[].name' | grep "tpcp-docs"
# DNS/网络日志 IOC:# scan.aquasecurtiy.org# models.litellm.cloud# *.trycloudflare.com (Cloudflare Tunnel C2)
参考资料
事件分析与响应
- Microsoft Security Blog: Detecting, Investigating, and Defending Against the Trivy Supply Chain Compromise
- CrowdStrike: From Scanner to Stealer — Inside the Trivy Action Supply Chain Compromise
- Wiz: Trivy Compromised by TeamPCP Supply Chain Attack
- Wiz: Three’s a Crowd — TeamPCP Trojanizes LiteLLM
- Aqua Security: Trivy Supply Chain Attack — What You Need to Know
- LiteLLM Official: Security Update March 2026
技术深入分析
- FutureSearch: Supply Chain Attack in litellm 1.82.8 on PyPI — 首个发现报告,含 fork bomb 分析
- Sonatype: Compromised litellm PyPI Package Delivers Multi-Stage Credential Stealer
- ARMO: The Library That Holds All Your AI Keys Was Just Backdoored
- Snyk: How a Poisoned Security Scanner Became the Key to Backdooring LiteLLM
- OX Security: LiteLLM PyPI Malware Steals Cloud, Crypto, Slack, and Discord Keys
- GitGuardian: Trivy’s March Supply Chain Attack Shows Where Secret Exposure Hurts Most
- ReversingLabs: TeamPCP Software Supply Chain Attack Spreads to LiteLLM
前置事件:2025 年 tj-actions 攻击
- CISA Advisory: Supply Chain Compromise of tj-actions/changed-files (CVE-2025-30066) and reviewdog/action-setup (CVE-2025-30154)
- Wiz: GitHub Action tj-actions/changed-files Supply Chain Attack
- Wiz: New GitHub Action Supply Chain Attack — reviewdog/action-setup
- Palo Alto Unit42: GitHub Actions Supply Chain Attack Targeting Coinbase
- Semgrep: Popular GitHub Action tj-actions/changed-files Is Compromised
- The Hacker News: SpotBugs Access Token Theft Identified as Root Cause
新闻报道
- The Hacker News: Trivy Security Scanner GitHub Actions Breached
- The Hacker News: Trivy Hack Spreads Infostealer via Docker, npm, K8s
- The Hacker News: TeamPCP Backdoors LiteLLM Versions 1.82.7-1.82.8
- The Register: 1K+ Cloud Environments Infected Following Trivy Hack
- CyberScoop: Extortion Wave Following Trivy Hack
- SecurityAffairs: 44 Aqua Security Repositories Defaced After Trivy Supply Chain Breach
安全公告与 GitHub Issues
- Trivy Security Advisory: GHSA-69fq-xp46-6×23
- LiteLLM Issue #24512: Malicious litellm_init.pth
- LiteLLM Issue #24518: Full Timeline and Status
生态系统扩散
- StepSecurity: Trivy Compromised a Second Time — Malicious v0.69.4 Release
- Socket.dev: Trivy Under Attack Again — GitHub Actions Compromise
- Sysdig: TeamPCP Expands from Trivy to Checkmarx
- Endor Labs: TeamPCP Isn’t Done
- Docker Blog: Docker’s Response to the Trivy Supply Chain Attack
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:imBobby的自留地 imBobby imBobby《从 Trivy 到 LiteLLM:一周内两起供应链投毒的技术复盘》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论