2026 年 3 月,开源 AI 网关 LiteLLM 遭遇供应链投毒攻击,影响版本 1.82.7 和 1.82.8。该事件之所以引起安全社区高度关注,不仅因为 LiteLLM 本身月下载量达 9500 万、总下载量超 4.8 亿次,更因为攻击者采用了极为隐蔽的持久化技术,使得一次简单的 pip install 即可导致主机环境被全面渗透。本文将从攻击链技术分解的角度,剖析恶意代码的植入路径、payload 行为特征,并给出可落地的供应链安全审计参数与检测清单。

攻击向量分析:从 PyPI 发布环节突破

LiteLLM 供应链攻击的核心突破点在于发布环节。与传统依赖 GitHub Release 进行分发的开源项目不同,LiteLLM 的部分版本直接向 PyPI 提交了恶意构建产物,绕过了项目官方的 GitHub 发行流程。攻击者获取了 PyPI 的发布令牌(可能是通过钓鱼、凭证泄露或其他方式),从而能够以项目维护者身份上传带有后门的 wheel 包。

这种攻击方式之所以致命,是因为绝大多数开发者和 CI/CD 流水线默认信任 PyPI 官方仓库,认为从 PyPI 直接安装的包即为可信版本。当用户执行 pip install litellm 时,如果恰好拉取到被污染的 1.82.7 或 1.82.8 版本,恶意代码便在不知不觉中进入目标环境。值得注意的是,攻击者选择了 proxy 组件作为突破口 ——LiteLLM 的 proxy/proxy_server.py 是整个项目中最常用的模块之一,许多用户部署 AI 网关时必须加载该模块,这为 payload 的自动触发提供了天然条件。

恶意代码注入机制:两阶段 payload 演进

第一阶段:proxy_server.py 直接注入

在版本 1.82.7 中,攻击者将 base64 编码的恶意 payload 直接嵌入到 litellm/proxy/proxy_server.py 文件内部。当任何代码导入该模块时,Python 解释器会执行模块加载逻辑,此时隐藏在代码中的 payload 被解码并写入临时文件,随后被执行。整个过程发生在 import 阶段,不需要任何显式的函数调用。

这种注入方式的技术关键在于利用了 Python 模块导入时的代码执行特性。攻击者将 payload 经过 base64 编码后嵌入正常代码字符串中,通过字符串解码、文件写入、子进程执行三步完成恶意代码的投放。由于 proxy_server.py 是 LiteLLM proxy 功能的入口模块,几乎所有使用 proxy 的用户都会在服务启动时触发这段代码。

第二阶段:litellm_init.pth 持久化劫持

如果說 1.82.7 版本的攻击依赖显式的模块导入,那么 1.82.8 版本的进化则展现了更为深入的持久化思路。攻击者新增了一个名为 litellm_init.pth 的文件到 site-packages 目录。.pth 文件是 Python 的一项特性,允许开发者在 site-packages 目录放置包含 Python 代码的文件,这些代码会在每次 Python 解释器启动时自动执行 —— 无论是否真正导入该包。

这意味着即使用户只是运行 pip list、python -c "print (1)",甚至在 IDE 中打开包含该环境的 Python 项目,litellm_init.pth 中的代码都会触发。攻击者利用这一特性实现了攻击面的极大扩展:不仅限于使用 LiteLLM 的应用,任何在相同 Python 环境中运行的工具都可能成为 payload 的受害者。理论上,攻击者可以窃取该 Python 解释器可访问的所有凭证、SSH 密钥、云配置以及 Kubernetes 访问令牌。

Payload 行为特征与攻击链还原

凭证窃取范围

安全研究人员的分析表明,LiteLLM 恶意 payload 的主要目标是大规模凭证收集。具体而言,payload 会扫描以下几类敏感资源:首先是环境变量,遍历全部环境变量并筛选出包含 KEY、TOKEN、SECRET、PRIVATE 等关键字的变量;其次是 AWS 凭证,包括~/.aws/credentials 和~/.aws/config 中的访问密钥和会话令牌;再次是 SSH 私钥,扫描~/.ssh/ 目录下所有以 id_开头的私钥文件;此外还有 Kubernetes 配置,读取~/.kube/config 中的集群访问凭证,以及 CI/CD 流水线中常见的各类 API 令牌和部署密钥。

数据外传与持久化

窃取到的凭证数据会被打包为 tar.gz 格式,通过 HTTP 请求外传至攻击者控制的 C2 服务器。外传过程通常采用分阶段策略:先收集元数据建立目标画像,再根据价值评估决定是否完整外传。在持久化层面,攻击者在受感染系统上注册名为 "System Telemetry Service" 的 systemd 服务或用户级服务,实现机器重启后仍能保持控制权。该服务的实现伪装成系统监控服务,名称本身即体现了攻击者试图规避管理员注意的意图。

横向移动能力

由于 LiteLLM 常被部署在 Kubernetes 集群中作为 AI 流量网关,攻击者还设计了针对容器编排环境的横向移动能力。payload 能够检测所在容器的 Service Account 令牌,并利用该令牌访问 Kubernetes API Server,实现集群内部的服务间横向渗透。这意味着单一节点的失陷可能导致整个 AI 基础设施的全面沦陷。

供应链安全审计工程化检查清单

面对此类供应链攻击,单纯依赖事件响应远远不够,需要将安全审计嵌入软件生命周期的各个环节。以下检查清单可直接应用于工程化环境:

依赖版本核验与锁定

在依赖管理层面,必须执行以下操作:第一,核查当前环境安装的 LiteLLM 具体版本,使用 pip show litellm 或 pip list | grep litellm 确认版本号,若版本为 1.82.7 或 1.82.8 立即进入应急响应流程;第二,在 requirements.txt 或 pyproject.toml 中严格锁定依赖版本,使用 == 精确指定而非 >=,避免自动升级到恶意版本;第三,搭建私有 PyPI 镜像或使用 PyPI 镜像代理,在镜像层实施版本白名单机制,仅同步经过安全评估的版本。

文件系统异常检测

针对 pth 文件持久化机制,建议部署以下检测规则:第一,扫描 site-packages 目录下所有.pth 文件,使用 find /path/to/site-packages -name "*.pth" -exec ls -la {} ; 列出详细信息,特别关注名称包含 litellm 或异常命名的文件;第二,监控新增.pth 文件的创建行为,可通过文件系统审计规则(auditd 规则或 OSQuery)实现实时告警;第三,检查 systemd 服务列表,使用 systemctl list-units --type=service | grep -i telemetry 确认是否存在名为 System Telemetry Service 的可疑服务。

网络行为监控

在网络层面,需要关注的异常指标包括:第一,审查所有出站 HTTP/HTTPS 连接,重点关注非标准端口或指向可疑域名的流量,IOC 中已知 C2 域名包括类似 checkmarx.zone 的域名模式;第二,分析 TLS 元数据,恶意外传通常产生异常的证书链和 SNI 特征;第三,部署 DNS 安全日志,监控解析到已知恶意域名的查询行为。

凭证轮换与访问控制

应急处置阶段的核心动作是凭证止损:第一,立即轮换在受影响环境中使用过的所有凭证,包括 AWS 访问密钥、GitHub 个人访问令牌、PyPI API 令牌、Kubernetes 集群凭证等;第二,审查云平台 IAM 角色绑定,撤销非必要的过度权限,遵循最小权限原则;第三,检查 GitHub 仓库的部署密钥和 Webhook secret,确保攻击者未利用窃取的凭证建立持久化后门。

CI/CD 流水线加固

由于 CI/CD 环境通常持有高权限凭证,必须作为重点加固对象:第一,在所有 CI/CD 流水线中加入依赖完整性校验步骤,使用 pip hash -r 或自定义脚本比对包签名;第二,优先使用虚拟环境(venv 或 conda)隔离项目依赖,避免全局 Python 环境被污染;第三,CI/CD runner 的凭证应配置为短期临时凭证,避免长期有效令牌泄露后造成持续影响。

结语

LiteLLM 供应链攻击事件深刻揭示了开源 AI 基础设施面临的现实威胁。从技术分解角度看,攻击者巧妙利用了 Python 生态的发布机制和运行时特性,通过两阶段 payload 实现了从单点渗透到全环境控制的技术升级。对抗此类威胁,需要将供应链安全从「事后响应」转向「事前预防」,在依赖引入、版本管理、运行时监控三个层面建立纵深防御体系。唯有将审计检查清单固化为自动化流水线的一部分,才能在攻击发生前构建起真正的安全屏障。

资料来源:本文技术细节参考了 Securelist、Kaspersky、NetSPI、Mend.io 等安全研究机构发布的 LiteLLM 供应链攻击分析报告及 IOC 披露信息。