PyPI 上的 LiteLLM 1.107.0 被篡改,安装后会植入凭据窃取器和后门

Hacker News Top 新闻

摘要

PyPI 上发布的 LiteLLM 1.107.0 版本遭到入侵,通过所有平台的 wheel 包植入了凭据窃取器和远程代码执行(RCE)后门,并借助 cook.pth 和 sitecustomize.py 在每次 Python 启动时激活。SafeDep 的分析显示,该恶意源码包(sdist)与其 GitHub 标签不一致,且是在公开发布流程之外发布的;PyPI 已将该版本移除。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/10/21 15:22

# PyPI 上被篡改的 LiteLLM 1.107.0 版本植入了凭据窃取器和后门 来源:https://safedep.io/litellm-pypi-compromise-credential-stealer-backdoor/ •2026年10月21日•6分钟阅读 PyPI 上发布的 [LiteLLM 1.107.0](https://pypi.org/project/litellm/1.107.0/) 版本中包含凭据窃取器和远程代码执行后门。全部七个 wheel 包(Linux、macOS、Windows)都会将其作为三个文件安装到 `site-packages` 中。主机上任何一个 Python 进程启动时,这两个恶意组件都会运行,即使该进程从未导入过 `litellm`。上游 GitHub 源代码中并不包含这些文件。PyPI 已移除该版本。1.106.2、1.107.0rc1 和 1.107.0rc2 版本是安全的。1.107.0 锁定的配套包 `litellm-proxy-extras==0.4.110` 和 `litellm-enterprise==0.1.78` 也是干净的。 ## 攻击方式 安装 `litellm==1.107.0` 会在 `site-packages` 中放置三个文件。Python 每次启动时会加载其中两个文件。 1. `cook.pth` 导入 `cook.py`——一个凭据窃取器。它收集 SSH 密钥、云凭据、CI/CD 密钥、AI 工具令牌、浏览器密码,以及 LiteLLM 代理数据库中的 LLM 提供商密钥。它对数据进行加密后发送到 `www[.]litellm[.]dev`。 2. `sitecustomize.py` 启动一个后台守护进程。该守护进程每小时从 GitHub 上的一个文件读取服务器地址,再次运行窃取器,然后从该服务器下载并执行代码。 ## 恶意代码如何进入发布版本 1.107.0 的源码分发包(sdist)中,`pyproject.toml` 的 `maturin` 构建部分多了一行: **pyproject.toml(litellm-1.107.0.tar.gz)** ``` TOML 6行 ``` `maturin` 的 `data = "cook"` 设置会将一个 `cook/` 文件夹复制到 wheel 中的 `litellm-1.107.0.data/purelib/` 目录。pip 会将该文件夹安装到 `site-packages`。sdist 中不包含 `cook/` 文件夹,因此这一行是唯一可见的变更。 [BerriAI/litellm](https://github.com/BerriAI/litellm) 的任何公开提交中都不包含 `data = "cook"` 或 `cook/` 文件夹。 wheel 的 `RECORD` 文件列出了三个新增的文件: ``` litellm-1.107.0.dist-info/RECORD TEXT 4行 ``` ### 发布内容与其标签不匹配 标签 `v1.107.0` 指向提交 [`66c8f5b`](https://github.com/BerriAI/litellm/commit/66c8f5b1a9cefaa7c55b758f86f4ab552f2e859e)(06:59 UTC)。该提交的 `pyproject.toml` 显示 `version = "1.108.0"`。 SafeDep 通过 blob 哈希将 sdist 中的每个文件与 git 树进行了比对。sdist 匹配的是一个更晚的 `main` 提交 [`a8113b0`](https://github.com/BerriAI/litellm/commit/a8113b0dd721804c752a6f1952367fb642205224)(08:50 UTC),再加上五个被修改的文件和 `cook/` 文件夹。 被修改的四个文件是 `Cargo.toml`,各自增加了一行 `readme = "README.md"`。正常的 1.106.2 和 rc2 发布版本也有相同的修改。 第五个文件是 `pyproject.toml`,与 `a8113b0` 的对比: **pyproject.toml(a8113b0 → litellm-1.107.0.tar.gz)** ``` DIFF 11行 ``` 该修改将版本号改回 1.107.0,并将配套包锁定为 rc2 的版本号。因此,与 rc2 的依赖差异分析不会显示任何异常。 正常的 1.106.2 sdist 与其标签提交 [`49943cd`](https://github.com/BerriAI/litellm/commit/49943cd52ea46aacf8db2e5cb2b890d580fe9bb4) 一致,唯一的区别是 `Cargo.toml` 中的 `readme` 行。 ### wheel 的构建方式 恶意 wheel 的输出与正常的 BerriAI 发布流水线产物完全一致: - `WHEEL` 文件中的 `maturin` 版本为 1.9.4,与正常发布版本相同。植入文件的 `RECORD` 条目也是正确的,说明构建后未经过任何修改。 - Zip 时间戳显示各平台分别独立构建:macOS 为 11:20,Linux 为 11:21,Windows 为 11:37 UTC。 - 在 Windows wheel 中,全部 2,804 个 `.py` 文件都使用 CRLF 换行符,包括三个植入文件。Linux wheel 中则没有。在 Windows 上进行 git 检出并启用换行符转换会产生这种模式。 没有公开的 GitHub Actions 运行记录构建或发布了该版本。SafeDep 检查了 09:30 至 12:30 UTC 之间的全部 539 次运行记录。在 11:50 UTC,即 PyPI 上传约 10 分钟后,`litellm-dispatcher[bot]` 发布了 GitHub Release `v1.107.0`。1.106.2 也有相同的延迟现象。 PyPI 上 1.107.0、1.106.2 和 rc2 都没有来源证明(provenance attestation)。 SafeDep 以中高置信度评估认为:BerriAI 的私有发布流水线使用了攻击者篡改过的 git 源码构建了这些 wheel。攻击者可能利用了被盗的维护者或机器人凭据、私有分支或镜像,或者流水线构建时引用的源。使用攻击者自有机器上的被盗 PyPI 令牌来发布不太符合现有证据。只有 BerriAI 的流水线日志才能确认具体原因。 ## 载荷 1:cook.py 中的凭据窃取器 Python 启动时会执行 `site-packages` 中 `.pth` 文件里以 `import` 开头的每一行。`cook.pth` 包含 `import cook`,因此该窃取器会在主机上的每个 Python 进程中运行:包括应用程序、pip、IDE 语言服务器以及 CI 任务。 `cook.py` 将约 61 KB 的 Python 代码包装在一层 `exec(zlib.decompress(base64.b64decode('...')))` 中。解码后的代码以如下配置开头: ### 收集内容 | 模块 | 目标 | |---|---| | `sysinfo`、`netinfo` | 主机名、用户名、操作系统、IP 地址、网络设置 | | `browser_pw` | Chromium 保存的密码(使用配置文件主密钥解密,Windows 上使用 DPAPI)、Firefox 的 `logins.json` 和 `key4.db` | | `browser_hist` | 浏览器历史记录 | | `ssh_keys` | `~/.ssh/*` | | `shell_hist` | `bash` 和 `zsh` 历史、PowerShell PSReadLine、`cmd` 历史 | | `cloud_creds` | `~/.aws/credentials` 和 `config`、Azure 配置和令牌、`gcloud` 凭据、`~/.kube/config`、`~/.docker/config.json`、`gh` 的 `hosts.yml`、`rclone.conf`、`~/.netrc` | | `dev_secrets` | `$HOME` 下的 `.pem`、`.key`、`.pfx`、`.p12`、`.pk8`、`.ppk` 文件、Composer 的 `auth.json`、FileZilla 保存的服务器 | | `container_creds` | Kubernetes 服务账户令牌 | | `cicd_secrets` | GitLab runner 的 `config.toml`、Jenkins 的 `initialAdminPassword` 和 `master.key`、`.vault-token`、Terraform 的 `credentials.tfrc.json`、Packer 设置 | | `ai_devtools` | Claude Code、Claude Desktop、Cursor、Windsurf、Copilot、VS Code 的 `mcp.json`、Gemini CLI、Codex 的 `auth.json`、Continue、Aider、Goose、`opencode`、`Qwen`、Crush、`Kiro`、Zed、Hugging Face 令牌 | | `env_vars` | 自身的环境变量,以及通过 `/proc/<pid>/environ` 读取的其他进程的环境变量 | | `db_litellm` | 读取 `DATABASE_URL` 并导出 `LiteLLM_CredentialsTable` 和 `LiteLLM_ProxyModelTable` 表,其中包含 LiteLLM 代理的 LLM 提供商 API 密钥 | | `cloud_metadata` | AWS 实例元数据服务(先 IMDSv2,后 v1):实例身份和角色凭据 | | `gpg_keys`、`tls_privkey` | GPG 密钥、TLS 私钥 | ### 数据传输方式 1. 使用随机 AES-256-CBC 密钥加密 JSON 结果,再使用 RSA-OAEP 和内置的公钥对该密钥进行加密。 2. 将结果打包为 tar.gz(`hdr.json`、`data.bin`、`key.bin`),通过 POST 请求发送到 `www[.]litellm[.]dev/healthcheck`,请求头为 `X-Token: XWiA8gZNa7NcX2XRoAEb`。 3. 上传成功后,写入 `/tmp/.pc_once_72129118c59f5636c0bb` 标记文件,确保每台主机只收集一次。同时设置 `PRIVCOLLECT_ACTIVE=1` 环境变量,以避免在同一进程树中重复运行。 ## 载荷 2:sitecustomize.py 中的后门 Python 在启动时会导入 `sitecustomize`,因此该文件也会在每个 Python 进程中运行。 1. 对 `/tmp/remote_code_loader.lock` 加独占锁,确保每台主机只运行一个守护进程。 2. 调用 `fork()` 和 `setsid()`,将标准输入输出重定向到 `/dev/null`,并切换到 `/` 目录,从而脱离父进程。 3. 每小时执行以下操作: 1. 从攻击者的 GitHub 仓库读取 `domain.txt`,提取第一个形如域名的行; 2. 运行内置的窃取器副本——该副本没有"每主机仅一次"的标记文件; 3. 下载 `http://<IP>/codepy` 并使用 `exec()` 执行。 攻击者可以通过编辑 `domain.txt` 将守护进程指向新的服务器。每台受感染的主机都会执行该服务器返回的 `codepy` 内容。 在 13:40 UTC,GitHub 账号 `letters9813` 及其仓库返回了 404,即在发布约两小时后被删除。后门目前无法找到服务器地址,因此不会执行任何操作。在删除之前已经运行过该守护进程的主机可能已接收并执行了第二阶段代码。SafeDep 无法恢复该服务器地址。 ## 时间线 所有时间均为 2026-10-21 UTC。 | 时间 | 事件 | |---|---| | 06:59 | 创建标签 `v1.107.0` 提交 `66c8f5b` | | 08:50 | `main` 上的提交 `a8113b0`,发布源码的基础 | | 10:44 | 正常的 1.106.2 上传至 PyPI | | 11:20–11:37 | 恶意的 1.107.0 wheel 构建完成 | | 11:39–11:40 | 1.107.0 上传至 PyPI(全部 8 个文件) | | 11:50 | `litellm-dispatcher[bot]` 发布 GitHub Release `v1.107.0` | | 13:40 | 观测到 1.107.0 已从 PyPI 移除,`letters9813` 账号已删除 | ## 失陷指标(IOC) ### 网络指标 | 指标 | 用途 | |---|---| | `www[.]litellm[.]dev`、`hxxp://www[.]litellm[.]dev/healthcheck` | 接收窃取的数据 | | HTTP 头 `X-Token: XWiA8gZNa7NcX2XRoAEb` | 随每次上传发送 | | `raw[.]githubusercontent[.]com/letters9813/pythonclient-test/main/domain.txt` | 后门在此读取服务器地址(账号已删除) | | `hxxp://<IP>/codepy` | 下载第二阶段代码 | | Python 进程向 `169.254.169.254` 发起的请求 | 窃取 AWS 实例凭据 | ### 主机指标 | 指标 | 含义 | |---|---| | `site-packages` 中的 `cook.pth`、`cook.py`、`sitecustomize.py` | 已安装植入程序 | | `/tmp/.pc_once_72129118c59f5636c0bb` | 窃取器已上传数据 | | `/tmp/remote_code_loader.lock` | 后门守护进程已运行 | | 环境变量 `PRIVCOLLECT_ACTIVE=1` | 存在于受感染的进程中 | | 脱离的 Python 守护进程(父进程 PID 为 1、独立会话、工作目录为 `/`) | 后门循环 | ### 文件哈希(SHA-256) | 文件 | SHA-256 | |---|---| | `litellm-1.107.0.tar.gz` | `2befe2a79fb4fbbd9a543b5b40b530c8cffa8771bab22b8fb22b2e4ae3b1f819` | | `litellm-1.107.0-cp310-abi3-manylinux_2_28_x86_64.whl` | `462d0c9f67ca522d9e0e4acd245e90b36ce0d5353604a66bb7c43a1ec4a6fcf7` | | `litellm-1.107.0-cp310-abi3-manylinux_2_28_aarch64.whl` | `668169d35b87bf51324080390b1b1c5ab12bd335cfe5f1a99e3689abd5e02ae6` | | `litellm-1.107.0-cp310-abi3-musllinux_1_2_x86_64.whl` | `1bbce8caa94f01c0aaa0b7ddae51553a8a32e1ce53d96d44fe583272aff7ad00` | | `litellm-1.107.0-cp310-abi3-musllinux_1_2_aarch64.whl` | `c2e32d0ce2548aa662c18bf5001911a79fe5b30cf8357132275add02fdcde054` | | `litellm-1.107.0-cp310-abi3-macosx_10_12_x86_64.whl` | `7598727f209d717041db37f7dca271d3a7d328a279890e0e1d55375729aeb86d` | | `litellm-1.107.0-cp310-abi3-macosx_11_0_arm64.whl` | `0aaf7ba346d41ef2f40390436738b001180d5a1c03aa093f121078a9969d9a1a` | | `litellm-1.107.0-cp310-abi3-win_amd64.whl` | `12d4ccc5c6f8d35cf4f2cf233b7f3e418e863e657d81ff5f5fc9e210005b9484` | 植入的文件,来自 wheel 的 `RECORD`: | 文件 | SHA-256(URL 安全 base64) | |---|---| | `cook.pth` | `fxkWMucyBwXRVLhSBPGuVGtUOsvX6IYSKbdvUEK5K9s` | | `cook.py` | `ndCjkm-Wo364bPHuIxDZvpMTnMTr7z754u_pUxOQviU` | | `sitecustomize.py` | `NL7wT-iKydCq4EdWMLFzhoHRW5TyM6yKpG6s9ZaDBfo` | --- - pypi - python - malware - supply-chain - litellm **作者:Kunal Singh** **分享** ## SafeDep 最新博客 关注获取开源安全与工程领域的最新动态和洞察 背景 SafeDep Logo **发布代码,不是恶意代码。** 在你的机器上免费使用开源工具起步,为你的组织扩展至统一平台。

相似文章

大规模供应链攻击导致数TB凭据泄露

Ars Technica

针对开源AI工具LiteLLM的大规模供应链攻击,在三月份一个40分钟的时间窗口内,暴露了来自数千家组织的数TB凭据,其中包括Microsoft、Amazon和Cisco。安全公司CloudSEK和Hudson Rock披露了此次入侵,并将其归因于TeamPCP团伙。

数周内第二次,微软软件包被植入凭据窃取器

Ars Technica

数周内第二次,微软已验证的开源软件包被植入了凭据窃取恶意软件,影响GitHub上的73个软件包。该攻击与威胁行为者TeamPCP有关,利用被盗的OIDC令牌,并通过云基础设施横向传播。

PyPI 发布版本现在在14天后拒绝新文件上传

Lobsters Hottest

PyPI 现在拒绝向超过14天的发布版本上传新文件,这是一项安全措施,旨在防止通过篡改旧版本来实施的供应链攻击。这一变化是由 LiteLLM 和 Telnyx 遭入侵等事件推动的。