LiteLLM 1.107.0 遭投毒:GitHub 令牌被盗引发供应链后门
攻击者利用被盗的 GitHub CLI 令牌,将植入后门的 LiteLLM 1.107.0 推送至 PyPI 和 Docker,这是该 AI 网关一年内第二次供应链失守。

LiteLLM 又被攻陷了。10月21日,攻击者向 PyPI、Docker Hub 和 GHCR 推送了一个木马化版本 1.107.0,在这款部署极为广泛的 AI 网关中捆绑了凭证窃取器和每小时信标回连的远控木马。恶意 PyPI 包在被隔离前存活约两小时;被投毒的 Docker 标签(1.107.0、latest、main-latest、main-stable)存活时间稍长。如果你在该时间窗口内拉取了未锁定版本的构建,请假定你的密钥已经泄露,并据此行动。
这是 LiteLLM 在一年之内第二次遭遇供应链入侵。继2026年3月的事件之后(CloudSEK 估计该事件可能波及超过2,500家机构和434,000条 CI/CD 流水线),项目加固了发布流程:私有发布仓库、不可变 Docker 标签、镜像签名。但这些都没能阻止这次事件,因为攻击者是凭有效凭证大摇大摆走进来的。这才是问题的关键,而且它比任何仿冒包都更加棘手。
已确认的、被宣称的与尚无人知的信息
我们来梳理一下现有证据,因为其中的空白会影响你的应对方式。
- 已确认(多家独立研究人员证实):被投毒的文件、自动执行机制、外泄端点,以及数小时内被盗 AWS 凭证即被滥用的情况,相关细节由 Aikido、Wiz 和 Socket 记录。
- 被宣称(由 LiteLLM 提出):入侵路径——Claude Code 将 GitHub CLI 的 OAuth 令牌嵌入响应体,这些响应体又被写入 LiteLLM 日志,并从一个面向互联网的内部部署中被外泄。
- 未知:该内部部署如何变得可被公网访问、攻击者如何进入、受害者总数,以及3月的攻击者是否卷土重来。
- 存在争议:关于归因。.pth 技术与被归因于 TeamPCP 的3月攻击手法相似,但 Socket 表示证据无法将二者联系起来。
攻击链:一个泄露的令牌,引出一个签名的投毒版本
据 The Hacker News 报道,事情始于10月19日:LiteLLM 临时放宽了发布权限,以便两名内部工程师为客户推送每日的 bug 修复回合。攻击者手握三组开发者 GitHub CLI 凭证(其中一组具备运行工作流的权限),并使用某个 GitHub 组织所有者的令牌,关闭了分支保护并强制推送了恶意变更。
接下来是最巧妙的部分:他们运行了合法的发布工作流,但将其指向一个仿冒仓库 Berri-AI/litellm,而非 BerriAI/litellm。只差一个连字符。由于流水线本身是真的,投毒产物最终带着签名,并通过正常渠道发布。如果你自己也在运行 CI/CD,这一点应该让你警觉:签名验证只能证明制品来自该流水线,并不能证明流水线指向的是正确的源代码。
“经过全面调查,我们发现了一些具体情况:Claude Code 会把用户的 GitHub CLI OAuth 令牌嵌入响应体中,而在响应体被记录的情况下,这些令牌可能出现在 LiteLLM 日志里。”LiteLLM 在其安全公告中如此表示。
维护者的工作假设是:攻击者在一个暴露于公网的 LiteLLM 内部部署中发现了一个“不起眼、名字很奇怪的非预期用户账户”,从其日志中提取了这些 OAuth 令牌,并用它们对付发布工作流。该部署为何会暴露在公网上尚不清楚——LiteLLM 推测是某个最近已修补的漏洞所致。在得到证实之前,请将其视为未经证实的说法。
载荷内部:cook.pth、cook.py 与每小时一次的 C2 循环
这个恶意软件本身是一条精巧的小型攻击链,值得深入理解,因为其中的技术原语具有普遍性。据 The Register 和 The Hacker News 报道,Aikido 研究员 Ilyas Makari 对其进行了梳理:
cook.pth——一个 Python 路径文件。.pth 中任何以import开头的行,都会在每次解释器启动时执行。这里导入的是cook。无需用户操作,也无需导入 LiteLLM;只要运行 Python 就会触发。cook.py——自行解混淆后运行一个名为privcollect的窃密例程,搜刮浏览器、开发工具、云和 AI 工具的密钥,然后将战利品 POST 到litellm[.]dev/healthcheck。sitecustomize.py——在 Linux 和 macOS 上于解释器启动时自动执行。它从一个已被删除的 GitHub 死信箱(github[.]com/letters9813)获取domain.txt,若响应有效,则从<domain>/codepy拉取第二阶段载荷。
Makari 描述了其持久化机制:守护进程在 /tmp/remote_code_loader.lock 处加锁以避免重复实例,然后无限循环——每小时从一个 GitHub 原始文件中获取当前 C2 域名,再从中下载并执行一个 Python 载荷。Wiz 的研究人员 Benjamin Read 和 Rami McCarthy 指出,这种同时使用双 .pth 加 sitecustomize.py 的做法,似乎是首次有文档记录的野外同时使用这两种技术的案例。Wiz 还指出,在 GitHub 于协调世界时下午1:30左右将其删除之前,该死信文本文件里只有测试值——这算是一点侥幸,但这种设计意味着 C2 很容易被重新指向。

窃密器的覆盖范围,正是这件事从软件包事件变成云端事件的关键。据 The Register 报道,Wiz 称该信息窃取器运行16个模块,涵盖浏览器(Chrome、Firefox、Edge、Safari 的凭证和 Cookie)、来自 ~/.aws/ 的 AWS 材料、环境变量,以及 EC2/ECS 实例元数据。据 CSO Online 报道,Aikido 还补充了 Kubernetes 服务账户令牌,以及来自 GitLab 和 Jenkins 的 CI/CD 密钥。
后续行动:近实时的 LLMjacking
Wiz 观察到,在数据外泄约4.5小时后,被盗凭证开始被滥用。在协调世界时下午4:20至5:01之间,攻击者从两个 IP——168.100.8[.]57 和 165.227.201[.]8——验证了从被入侵的 CI 运行器和 Kubernetes 节点上窃取的 AWS 实例角色凭证。
“每个凭证都先通过 sts:GetCallerIdentity 检查,随后调用 bedrock:ListFoundationModels 和 ListModels,这与 LLMjacking 的行为一致,”Wiz 表示。“在少数环境中,攻击者还枚举了 IAM(ListRoles、ListUsers、ListAccessKeys),并进行了一般性侦察(ListAccounts、DescribeTrails 等)。”
这是一个快速而有目的的变现循环:窃取密钥、验证密钥、检查它们能调用哪些 Bedrock 模型来烧钱。如果你关注过类似某个 OpenAI 模型花掉了陌生人测试用 ETH的案例,就会知道如今自动化的密钥滥用成本有多低。
是3月那个攻击者吗?证据指向“未经证实”
很想把这次事件归咎于 TeamPCP——毕竟 .pth 加载器的手法与2026年3月被归因于他们的手法如出一辙——但 Socket 明确拒绝将两者联系起来,并在接受 The Hacker News 采访时表示,两场攻击使用的嵌入式 RSA 公钥不同,外泄实现不同,后门行为也不同。3月被盗的凭证是否在此扮演了角色,尚未得到验证。同一操作者使用新工具的可能性依然存在,只是尚未确立。
那么,信任 AI 网关还值得吗?
这里有一笔令人不适的账。LiteLLM 每周下载量约2300万次,而且按其设计,它位于贵组织拥有的每一个模型 API 密钥、云身份和数据库连接字符串旁边。IDC 的 Sakshi Grover 在接受 CSO Online 采访时称,“AI 网关属于特权级企业基础设施”——集中化的模型访问提升了治理水平,但也“集中了信任”。IDC 7月的调查发现,95% 的企业已在生产环境中运行至少一个企业自有资金支持的、启用了智能体的工作流。这意味着大量的爆炸半径都依附在一个 PyPI 项目之上。
JFrog 研究员 Guy Korolevski 在 The Hacker News 上提出了一个相关观点:一次投毒安装就足以让攻击者向下游推送恶意代码,而一个看起来干净的源代码仓库,对你实际安装的制品几乎没有说明作用——因此,请在版本进入构建之前,验证具体的 wheel 文件并审查版本。作为一个在 CTF 比赛中熬过无数个夜晚、专门利用这类隐性信任的人,我的看法是:仅靠锁定版本是不够的(标签本身已被投毒),但锁定版本加上哈希校验,再加上对新发布版本设置隔离观察期,就足以挡住这次攻击。对于权限如此之高的基础设施,将 LLM 流量自行托管或做代理已不再是偏执,而是一项合理的控制措施。工程成本是真实存在的;因为一个 .pth 文件被触发,就重建你整个环境中每一台 CI 运行器,代价同样真实。
检测与响应:今天该做什么
如果你在协调世界时上午11:39至下午1:23之间通过 pip 安装了 1.107.0,或在上午11:46至下午2:20之间拉取了受影响的 Docker/GHCR 标签,那么你就在受影响范围内。以下是 Makari 在 The Register 上给出的快速排查建议:
# Exfil already fired if this exists:
ls /tmp/.pc_once_*
# C2 daemon ran (or is still running) if this exists:
ls /tmp/remote_code_loader.lock
# Malicious artifacts:
find / -name 'cook.pth' -o -name 'cook.py' 2>/dev/null
find / -name 'sitecustomize.py' -path '*litellm*' 2>/dev/null
- 回滚到 v1.106.2——据 The Register 报道,这是最近的安全版本——并隔离任何运行过 1.107.0 的主机,包括代理容器和 CI 运行器(这是 Socket 的建议)。
- 在出口处封锁
litellm[.]dev/healthcheck以及raw.githubusercontent.com/letters9813这个死信箱;对任何获取/codepy的进程发出告警。 - 轮换受影响主机可触及的所有凭证:云密钥、浏览器中保存的密钥、K8s 服务账户令牌、GitLab/Jenkins 密钥,以及模型服务商密钥。LiteLLM 自己的建议是:将该环境视为已被入侵;仅删除软件包并不足够,因为远控木马可能仍驻留在系统中。
- 在 CloudTrail 中审计来自异常主体的、先后出现的
sts:GetCallerIdentity与bedrock:ListFoundationModels调用,并将 Wiz 提到的两个 IP 与你的日志进行比对。 - 今后:锁定精确版本,依据已知良好的制品校验 wheel 哈希,并让新发布版本在进入构建前经历一段观察期。
LiteLLM 表示事件已得到控制,企业私有注册表的客户未受影响;联合创始人 Krrish 公开承认此次攻击前所未有,并征求反馈。这说法也合情合理。但一年之内两次、从两扇不同的门进入,教训依然成立:当一个软件包掌握着你整个 AI 资产的所有钥匙时,它的发布流水线就是你的攻击面,无论你是否愿意接受这一点。
来源
本文参考了以下报道与公告:


