95亿次。这是LiteLLM过去一年的下载量,一个帮开发者统一管理各大语言模型接口的工具库。上周,这个数字成了安全圈的黑色幽默——版本1.82.7和1.82.8被植入后门,攻击者TeamPCP用两版迭代,把"偷密钥"做成了自动化流水线。
Endor Labs和JFrog的安全团队发现,恶意代码根本没走GitHub仓库的正门。它直接混进了PyPI的分发包,像快递包裹里塞了夹层。上游代码干净得像个样板间,用户pip install下来的却是精装修过的"凶宅"。
12行代码的"静音启动"
1.82.7版本的攻击很克制。攻击者在litellm/proxy/proxy_server.py里塞了一段base64编码的载荷,12行,模块导入时静默触发。没有弹窗,没有日志,你的Python脚本跑起来,后门就跟着启动了。
这种设计像是测试水温——看看能不能瞒过基础的安全扫描。但TeamPCP没给防御方太多反应时间。1.82.8版本直接升级成"系统级寄生":在wheel包根目录扔了一个litellm_init.pth文件。
Python的.site-packages里但凡有.pth文件,启动时自动执行。这意味着哪怕你的代码里从没写过import litellm,只要这个库躺在环境里,后门就会随Python解释器一起苏醒。
打个比方:以前是小偷等你开门进屋,现在是你每次路过楼道,他就已经蹲在墙角了。
三阶段收割:从密钥到K8s集群
载荷激活后,攻击进入流水线模式。第一阶段,释放一个凭证收割器,扫描范围堪称开发者资产的"全家福":SSH私钥、AWS/GCP/Azure的访问令牌、数据库连接字符串、加密货币钱包文件。
harvested数据用AES-256-CBC混合RSA-4096加密,打包成tpcp.tar.gz,发往一个伪装成合法项目资源的攻击者域名。加密方案的专业程度,让这次攻击看起来不像临时起意,而像有备而来的工业级操作。
第二阶段瞄准Kubernetes环境。如果检测到K8s服务账户令牌,恶意代码会快速枚举集群所有节点,然后向每个节点部署特权alpine容器,挂载host级访问权限。这不是偷数据了,是在你的基础设施里搭了个临时指挥部。
第三阶段建立持久化。一个伪装成系统遥测服务的systemd用户服务被写入系统,持续轮询二级命令控制服务器,等待下载执行更多二进制文件。后门装成了"系统自带",重启也不会消失。
一个月连破5个生态:TeamPCP的"基础设施狩猎"
这次LiteLLM事件不是孤例。过去30天,TeamPCP已经拿下GitHub Actions、Docker Hub、npm、OpenVSX五个生态。攻击目标高度聚焦:Aqua Security的Trivy、Checkmarx的KICS这类安全工具和基础设施组件。
选这些目标有讲究。安全工具通常运行在CI/CD流水线里,权限高、接触秘密多、环境敏感。攻进去一次,等于在软件生产的血管里插了根导管。
JFrog的研究人员指出,这种"基础设施狩猎"策略正在取代传统的终端用户攻击。与其钓鱼100个普通开发者,不如直接污染一个被百万开发者依赖的工具库。供应链的乘数效应,让攻击ROI(投资回报率)呈指数级放大。
TeamPCP的运作方式也有迹可循:先潜伏观察项目维护者的发布节奏,然后在版本迭代的间隙窗口快速投毒,利用PyPI等平台的信任机制完成分发。 1.82.7到1.82.8的连续两版攻击,说明他们对LiteLLM的发布流程做过功课。
目前确认的最后一个干净版本是1.82.6。如果你在过去两周内更新过LiteLLM,现在需要做的是:冻结环境、检查pip list里的版本号、审计所有可能接触过该环境的密钥有效期。
PyPI官方已经下架了这两个恶意版本,但供应链攻击的麻烦在于"已经发生的无法撤销"。那些已经被部署到生产环境的1.82.7/1.82.8,不会因为仓库里的删除而自动失效。
安全团队的建议很直接:假设你已经暴露,而不是假设你侥幸逃脱。轮换所有可能受影响的凭证,检查K8s集群里的异常容器和特权提升记录,查找任何指向tpcp.tar.gz或相关C2域名的网络流量。
这次事件暴露了一个结构性困境。LiteLLM本身是个极其实用的工具——它把OpenAI、Anthropic、Azure、本地模型等几十种接口抽象成统一的调用方式,省了大量适配代码。但正是这种"被广泛依赖",让它成了攻击者的优质标的。
开源生态的信任模型建立在"代码公开即可审计"的假设上,但现实中,pip install拉下来的是编译后的wheel,和GitHub上的源码之间隔着一层转换。TeamPCP exploit的正是这个断层:仓库干净,分发包有毒,大多数用户永远不会发现差异。
Endor Labs在分析报告中提到,他们是在对PyPI新发布包进行自动化扫描时触发的告警。这种"发布即扫描"的机制,正在成为供应链安全的新基准。但自动化扫描能 catching 的是已知模式,面对base64编码+自定义加密+多阶段载荷的组合,漏报率依然可观。
更有趣的是攻击者的"产品思维"。1.82.7到1.82.8的迭代,像是一个MVP(最小可行产品)到完整功能的演进:先验证核心机制可行,再解决"被导入才能触发"的局限,最终达成"环境存在即中招"的完全体。这种迭代速度,很多正经软件团队都自叹不如。
TeamPCP的命名来源尚无定论,但安全社区注意到他们的攻击载荷中反复出现"tpcp"标识。这个标签像是一种签名,或者说,一种对追踪者的轻蔑——知道你们在分析,不介意留下痕迹。
对于依赖LiteLLM的组织,现在最紧迫的问题是:你的环境里有没有跑着这两个版本?更深层的问题是:当工具链的每个环节都可能成为攻击面,"信任但验证"的成本,团队真的承担得起吗?
热门跟贴