Compromised LiteLLM 1.107.0 on PyPI Installs a Credential Stealer and Backdoor
TL;DR · AI 摘要
LiteLLM 1.107.0版本在PyPI上被植入凭证窃取器和后门,PyPI已移除该版本。
核心要点
- LiteLLM 1.107.0版本在PyPI上被植入凭证窃取器和后门
- PyPI已移除该恶意版本及所有相关轮子文件
- cook.py文件会收集SSH密钥、云凭证和CI/CD秘密
结构提纲
按章节快速跳转。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- LiteLLM供应链攻击事件
- 攻击机制
- 凭证窃取器cook.py
- 远程代码执行后门
- 受影响版本
- 1.107.0
- 处理措施
- PyPI移除恶意版本
金句 / Highlights
值得收藏与分享的关键句。
LiteLLM 1.107.0版本在PyPI上被植入凭证窃取器和后门
cook.py文件会收集SSH密钥、云凭证和CI/CD秘密
PyPI已移除该恶意版本及所有相关轮子文件
PyPI 上被篡改的 LiteLLM 1.107.0 安装凭证窃取器和后门 - 实时开源软件供应链安全
页眉部分:保持黑色背景 —— 仅文章正文区域采用提升的阅读表面,使阅读区域呈现为独立面板
返回博客
社交图标
内容
标题
PyPI 上被篡改的 LiteLLM 1.107.0 安装凭证窃取器和后门
标签
- 安全
Kunal Singh
•
2026年10月21日
6分钟阅读
主内容区域:采用提升的阅读表面(#101318,Material-dark 领域),使浅色文字在真实基底上呈现而非纯黑背景 —— 长篇阅读时眩光显著减少。布局:文章列居中对齐,真实留白分隔,目录浮动在右侧留白区(无分隔边框 —— 通过留白实现区域分离)
目录(移动端显示在内容上方,桌面端显示在右侧留白区)
目录:右侧留白区的静默链接列表。该轨道自带较暗色调,与正文文字形成独立区域(无边框 —— 通过色调边缘实现区域划分)。包含 CTA 时,轨道变为固定高度列:目录列表可滚动,卡片保持固定。在 lg 屏幕下,轨道堆叠在文章上方,因此在此处折叠为单行条,而非将首段推离屏幕。
本页内容
6个部分
在桌面端,CTA 与侧边栏自身边缘对齐,而非内嵌在目录文本列中:额外宽度使文字换行减少,因此卡片更短,且看起来固定在轨道底部。其上方的空白是此处的边距,而非滚动区域内的内边距,因此在列表滚动时保持稳定。
博客内容
lg:pr-8 保持全出血内容(小部件、代码块、表格)远离目录面板,目录面板自身的背景从列边缘开始。正文文本已通过其 48rem 的度量内嵌;全出血元素则未内嵌。无轨道时无需清除任何内容,因此列直接移除该内边距。
内容。排版规则位于 src/assets/styles/blog-prose.css 中,采用扁平化 .blog-prose <el> 规则,而非旧版内联 prose-* / [&_…] 修饰符字符串 —— 该字符串编译为约 40 个复杂选择器,Chrome iOS(WKWebView)在每次滚动重计算时都会重新匹配,导致页面空白。保留基础 prose prose-lg prose-invert 重置。正文文本在此文件中被限制在可读度量内;代码块、表格和嵌入内容则故意横跨整列。
PyPI 上发布的 LiteLLM 1.107.0 版本包含凭证窃取器和远程代码执行后门。所有七个轮子(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 启动时都会加载其中两个文件。
- cook.pth 导入 cook.py,这是一个凭证窃取器。它收集 SSH 密钥、云凭证、CI/CD 秘密、AI 工具令牌、浏览器密码以及 LiteLLM 代理数据库中的 LLM 提供商密钥。它会加密数据并发送到 www.litellm[.]dev。
- sitecustomize.py 启动一个后台守护进程。每小时,该守护进程从 GitHub 文件中读取一个服务器地址,重新运行窃取器,并从该服务器下载并执行代码。
植入物如何进入发布版本
1.107.0 源代码分发包(sdist)中的 pyproject.toml 文件在 maturin 构建部分多了一行:
标题栏
pyproject.toml(litellm-1.107.0.tar.gz)
复制
单个滚动容器:边距 + 代码滚动一起
行边距
1
2
3
4
5
6
代码 —— 去除所有表达式代码的 chrome
[
tool
.
maturin
]
...
python-source =
"."
data =
"cook"
# <-- 注入
python-packages = [
"litellm_cli"
]
# 合法(上游存在)状态栏
TOML
6 行
maturin 的 data = "cook" 设置会将 cook/ 文件夹复制到 wheel 中的 litellm-1.107.0.data/purelib/ 目录。pip 会将该文件夹安装到 site-packages 中。
sdist 版本会省略 cook/ 文件夹,因此这行是唯一可见的修改。BerriAI/litellm 的公开提交中没有任何包含 data = "cook" 或 cook/ 文件夹的内容。
wheel 的 RECORD 文件列出了新增的三个文件:
litellm-1.107.0.dist-info/RECORD
litellm-1.107.0.data/purelib/cook.pth 12 字节 "import cook"
litellm-1.107.0.data/purelib/cook.py 22252 字节 exec(zlib.decompress(b64decode(...)))
litellm-1.107.0.data/purelib/sitecustomize.py 25509 字节 loader/backdoor + 嵌入式窃取器文本
4 行
发布版本与标签不匹配
标签 v1.107.0 指向 commit 66c8f5b(UTC 时间 06:59)。其 pyproject.toml 文件中版本号为 "1.108.0"。SafeDep 通过 blob 哈希将每个 sdist 文件与 git 树进行比对。该 sdist 文件匹配的是稍后的一个 main 提交 a8113b0(UTC 时间 08:50),以及五个修改过的文件和 cook/ 文件夹。
其中四个修改的文件是 Cargo.toml,新增了 readme = "README.md" 的行。合法的 1.106.2 和 rc2 版本也有相同的修改。第五个是 pyproject.toml,与 a8113b0 的对比如下:
pyproject.toml(a8113b0 → litellm-1.107.0.tar.gz)
7
8
9
10
11
-
version = "1.108.0"
+
version = "1.107.0"
-
"litellm-proxy-extras==0.4.111",
-
"litellm-enterprise==0.1.79",
+
"litellm-proxy-extras==0.4.110", # 与 1.107.0rc2 的相同版本
+
"litellm-enterprise==0.1.78",
+
data = "cook" # 注入点
...
-
version = "1.108.0" # 第二个版本字段
+
version = "1.107.0"差异
11 行
该修改将版本号回退到 1.107.0,并将配套包固定到 rc2 的版本。因此,与 rc2 的依赖差异显示没有异常。合法的 1.106.2 sdist 除了 Cargo.toml 的 readme 行外,与标签提交 49943cd 完全匹配。
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 checkout 会产生这种模式。
没有公开的 GitHub Actions 运行构建或发布该版本。SafeDep 检查了 UTC 时间 09:30 至 12:30 之间的所有 539 次运行。UTC 时间 11:50(即 PyPI 上传后约 10 分钟),litellm-dispatcher[bot] 发布了 GitHub 版本 v1.107.0。1.106.2 也出现了相同的延迟。PyPI 对 1.107.0、1.106.2 或 rc2 没有出处证明。
SafeDep 以中等到高等置信度评估认为,BerriAI 的私有发布管道从攻击者修改的 Git 源代码构建了这些 wheel 文件。攻击者可能使用了被入侵的维护者或机器人凭证、私有分支或镜像,或管道构建所引用的来源。从攻击者自己的机器上使用被盗的 PyPI 令牌与证据的匹配度较低。只有 BerriAI 的管道日志能够确认具体原因。
载荷 1:cook.py 中的凭证窃取器
启动时,Python 会运行 site-packages 中每个以 import 开头的 .pth 文件中的代码行。cook.pth 包含 import cook,因此窃取器会在主机上的每个 Python 进程中运行:应用程序、pip、IDE 语言服务器和 CI 任务。
cook.py 使用一层 exec(zlib.decompress(base64.b64decode('...'))) 包裹了约 61 KB 的 Python 代码。解码后的代码以以下配置开头:
cook.py(已解码)
PC_URL
=
'http://www.litellm.dev/healthcheck'
PC_TOKEN
=
'XWiA8gZNa7NcX2XRoAEb'
# 作为 X-Token 请求头发送
PC_PUBKEY
=
'-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvxRBQMVXDXVskKS47haU ...'
# RSA-4096
PC_ONCE_PATH
=
'/tmp/.pc_once_72129118c59f5636c0bb'
PC_ASYNC
=
True
# 在守护线程中运行
PC_MODULES
=
[
'sysinfo'
,
'netinfo'
,
'browser_pw'
,
'browser_hist'
,
'ssh_keys'
,
'shell_hist'
,
'cloud_creds'
,
'dev_secrets'
,
'container_creds'
,
'cicd_secrets'
,
'ai_devtools'
,
'env_vars'
,
'db_litellm'
,
'cloud_metadata'
,
'gpg_keys'
,
'tls_privkey'
]PYTHON
10 行
它收集的内容
模块
目标
sysinfo,
netinfo主机名、用户、操作系统、IP 地址、网络设置
browser_pwChromium 保存的密码(使用配置文件主密钥解密,Windows 上使用 DPAPI)。Firefox
logins.json和
key4.dbbrowser_hist浏览器历史记录
ssh_keys~/.ssh/*shell_histbashzsh历史记录,PowerShell PSReadLine,
cmd历史记录
cloud_creds~/.aws/credentialsconfig,Azure 配置文件和令牌,
gcloud凭证,
~/.kube/config~/.docker/config.jsonghhosts.ymlrclone.conf~/.netrcdev_secrets.pem.key.pfx.p12.pk8.ppk文件位于
$HOME下,Composer
auth.json,FileZilla 保存的服务器
container_credsKubernetes 服务账户令牌
cicd_secretsGitLab runner
config.toml,Jenkins
initialAdminPasswordmaster.key.vault-token,Terraform
credentials.tfrc.json,Packer 配置
ai_devtoolsClaude Code,Claude Desktop,Cursor,Windsurf,Copilot,VS Code
mcp.json,Gemini CLI,Codex
,Continue,Aider,Goose,
opencodeQwen,Crush,
Kiro,Zed,Hugging Face 令牌
env_vars自身环境变量及其他进程的环境变量通过
/proc/<pid>/environdb_litellm读取
DATABASE_URL并转储
LiteLLM_CredentialsTableLiteLLM_ProxyModelTabletables,用于存储 LiteLLM 代理的 LLM 提供商 API 密钥
cloud_metadataAWS 实例元数据服务(IMDSv2,然后是 v1):实例身份和角色凭证
gpg_keystls_privkeyGPG 密钥、TLS 私钥
数据传输方式
- 它使用随机生成的 AES-256-CBC 密钥对 JSON 结果进行加密,并使用 RSA-OAEP 算法和嵌入的公钥对密钥进行加密。
- 它将结果打包为 tar.gz 格式(包含 hdr.json、data.bin、key.bin),并通过 POST 请求发送至 www.litellm[.]dev/healthcheck,请求头为 X-Token: XWiA8gZNa7NcX2XRoAEb。
- 上传成功后,它会在 /tmp/ 下创建 .pc_once_72129118c59f5636c0bb 文件,确保每台主机仅收集一次数据。同时设置 PRIVCOLLECT_ACTIVE=1,避免同一进程树中重复运行。
载荷 2:sitecustomize.py 中的后门
Python 启动时会导入 sitecustomize,因此该文件会在每个 Python 进程中运行。
sitecustomize.py
GITHUB_RAW_URL
=
"https://raw.githubusercontent.com/letters9813/pythonclient-test/main/domain.txt"
CODE_PATH
=
"/codepy"
LOOP_INTERVAL
=
3600
LOCK_FILE
=
"/tmp/remote_code_loader.lock"5 行代码
- 它对 /tmp/remote_code_loader.lock 文件加排他锁,确保每台主机仅运行一个守护进程。
- 它调用 fork() 和 setsid(),将标准输入输出重定向到 /dev/null,并将工作目录切换至 /,以脱离父进程。
- 每小时执行一次:从攻击者 GitHub 仓库读取 domain.txt,提取第一行看起来像域名的内容,运行嵌入的窃取器(无每主机唯一标记),下载 http://<domain>/codepy 并通过 exec() 执行。
攻击者可通过编辑 domain.txt 指向新服务器。每个受感染主机将执行该服务器返回的 codepy 代码。UTC 时间 13:40,letters9813 GitHub 账号及其仓库返回 404,距离发布约两小时后。后门现在无法找到服务器地址,不再执行操作。删除前已运行守护进程的主机可能已接收并执行了第二阶段代码。SafeDep 无法恢复服务器地址。
时间线
所有时间均为 2026-10-21 UTC 时间。
时间
事件
06:59
标签
v1.107.0提交
66c8f5b创建
08:50
a8113b0提交至
main,作为发布源代码的基础
10:44
合法版本 1.106.2 上传至 PyPI
11:20 至 11:37
恶意版本 1.107.0 轮子文件构建
11:39 至 11:40
1.107.0 上传至 PyPI(共 8 个文件)
11:50
litellm-dispatcher[bot]发布 GitHub 版本
13:40
观察到:1.107.0 从 PyPI 下架,
letters9813账号被删除
感染迹象
网络
指标
目的
www.litellm[.]devhxxp://www.litellm[.]dev/healthcheck接收窃取数据
HTTP 请求头
X-Token: XWiA8gZNa7NcX2XRoAEb每次上传时发送
raw.githubusercontent[.]com/letters9813/pythonclient-test/main/domain.txt后门在此读取服务器地址(账号已删除)
hxxp://<domain>/codepy第二阶段代码下载
来自 Python 进程的请求
169.254.169.254AWS 实例凭证窃取
主机
含义
cook.pthcook.pysitecustomize.py位于
site-packages植入已安装
/tmp/.pc_once_72129118c59f5636c0bb窃取器已上传数据
/tmp/remote_code_loader.lock后门守护进程已运行
环境变量
PRIVCOLLECT_ACTIVE=1存在于受感染进程
Detached Python 守护进程(父进程 PID 1,独立会话,工作目录
/)
后门循环
文件哈希值(SHA-256)
文件
SHA-256
litellm-1.107.0.tar.gz2befe2a79fb4fbbd9a543b5b40b530c8cffa8771bab22b8fb22b2e4ae3b1f819litellm-1.107.0-cp310-abi3-manylinux_2_28_x86_64.whl462d0c9f67ca522d9e0e4acd245e90b36ce0d5353604a66bb7c43a1ec4a6fcf7litellm-1.107.0-cp310-abi3-manylinux_2_28_aarch64.whl668169d35b87bf51324080390b1b1c5ab12bd335cfe5f1a99e3689abd5e02ae6litellm-1.107.0-cp310-abi3-musllinux_1_2_x86_64.whl1bbce8caa94f01c0aaa0b7ddae51553a8a32e1ce53d96d44fe583272aff7ad00litellm-1.107.0-cp310-abi3-musllinux_1_2_aarch64.whlc2e32d0ce2548aa662c18bf5001911a79fe5b30cf8357132275add02fdcde054litellm-1.107.0-cp310-abi3-macosx_10_12_x86_64.whl7598727f209d717041db37f7dca271d3a7d328a279890e0e1d55375729aeb86dlitellm-1.107.0-cp310-abi3-macosx_11_0_arm64.whl0aaf7ba346d41ef2f40390436738b001180d5a1c03aa093f121078a9969d9a1alitellm-1.107.0-cp310-abi3-win_amd64.whl12d4ccc5c6f8d35cf4f2cf233b7f3e418e863e657d81ff5f5fc9e210005b9484由于 Windows 使用 CRLF 换行符,植入的文件哈希值会有所不同:
Linux 和 macOS
Windows
7f191632e7320705d154b85204f1ae546b543acbd7e8861229b76f5042b92bdb84dc8c82c0a4a4a62552ef826b49fcc86d1a5c4a5d0f2c06665723f93d129d7d9dd0a3926f96a37eb86cf1ee2310d9be93139cc4ebef3ef9e2efe9531390be2503ac2a8b752605d1d7710979c17ff18b03dd978203ba23ba97fd8ce3d6f897ea34bef04fe88ac9d0aae0475630b1738681d15b94f233ac8aa46eacf5968305fab6122440d0d9cb1eb1ade9933f49214da8c31288de7710c076c2680dfa528465<section style="background: radial-gradient(62.11% 67.66% at 50% 0.09%, #004039 0%, #000000 100%);"> <div class="mx-auto max-w-[748px] min-h-[160px] p-14 flex items-center border-t border-b border-l border-r border-neutral-700" > <div class="flex flex-col md:flex-row md:items-center md:justify-between gap-10 w-full"> <div class="flex-1"> <span class="text-xl md:text-2xl text-white">保护您的代码</span><br /> <span class="text-xl md:text-2xl text-white">阻止恶意软件包</span> </div> <div class="flex-shrink-0"> <CTAButton /> </div> </div> </div> </section>
- pypi
- python
- malware
- supply-chain
- litellm
分类和社交分享部分
作者信息
作者
#### Kunal Singh
safedep.io
社交分享
分享
左侧:带高亮文本的标题
SafeDep 博客最新动态
右侧:描述
关注获取开源安全与工程的最新动态和见解
左侧栏
分类
伪造提交将预安装植入器推送到 hugo-paper 和 mevn-cli
摘要
攻击者向 hugo-paper 和 mevn-cli 的默认分支推送了伪造提交。在任一仓库中运行 npm install 或 bun install 会下载并运行来自...
页脚
ASOS 应用攻击:攻击者利用推送通知发送勒索信
攻击者进入了 ASOS 用于向客户发送消息的平台,并向手机推送了勒索信。以下是已确认的信息、仅被声称的信息以及客户应采取的行动。
右侧栏
MALFEX 将其 npm 安装器迁移到 musllinux 平台
litellm-1.107.0-cp310-abi3-musllinux_1_2_x86_64.whl1bbce8caa94f01c0aaa0b7ddae51553a8a32e1ce53d96d44fe583272aff7ad00litellm-1.107.0-cp310-abi3-musllinux_1_2_aarch64.whlc2e32d0ce2548aa662c18bf5001911a79fe5b30cf8357132275add02fdcde054litellm-1.107.0-cp310-abi3-macosx_10_12_x86_64.whl7598727f209d717041db37f7dca271d3a7d328a279890e0e1d55375729aeb86dlitellm-1.107.0-cp310-abi3-macosx_11_0_arm64.whl0aaf7ba346d41ef2f40390436738b001180d5a1c03aa093f121078a9969d9a1alitellm-1.107.0-cp310-abi3-win_amd64.whl12d4ccc5c6f8d35cf4f2cf233b7f3e418e863e657d81ff5f5fc9e210005b9484由于 Windows 使用 CRLF 换行符,植入的文件哈希值会有所不同:
Linux 和 macOS
Windows
7f191632e7320705d154b85204f1ae546b543acbd7e8861229b76f5042b92bdb84dc8c82c0a4a4a62552ef826b49fcc86d1a5c4a5d0f2c06665723f93d129d7d9dd0a3926f96a37eb86cf1ee2310d9be93139cc4ebef3ef9e2efe9531390be2503ac2a8b752605d1d7710979c17ff18b03dd978203ba23ba97fd8ce3d6f897ea34bef04fe88ac9d0aae0475630b1738681d15b94f233ac8aa46eacf5968305fab6122440d0d9cb1eb1ade9933f49214da8c31288de7710c076c2680dfa528465<section style="background: radial-gradient(62.11% 67.66% at 50% 0.09%, #004039 0%, #000000 100%);"> <div class="mx-auto max-w-[748px] min-h-[160px] p-14 flex items-center border-t border-b border-l border-r border-neutral-700" > <div class="flex flex-col md:flex-row md:items-center md:justify-between gap-10 w-full"> <div class="flex-1"> <span class="text-xl md:text-2xl text-white">保护您的代码</span><br /> <span class="text-xl md:text-2xl text-white">阻止恶意软件包</span> </div> <div class="flex-shrink-0"> <CTAButton /> </div> </div> </div> </section>
- pypi
- python
- malware
- supply-chain
- litellm
分类和社交分享部分
作者信息
作者
#### Kunal Singh
safedep.io
社交分享
分享
左侧:带高亮文本的标题
SafeDep 博客最新动态
右侧:描述
关注获取开源安全与工程的最新动态和见解
左侧栏
分类
伪造提交将预安装植入器推送到 hugo-paper 和 mevn-cli
摘要
攻击者向 hugo-paper 和 mevn-cli 的默认分支推送了伪造提交。在任一仓库中运行 npm install 或 bun install 会下载并运行来自...
页脚
ASOS 应用攻击:攻击者利用推送通知发送勒索信
攻击者进入了 ASOS 用于向客户发送消息的平台,并向手机推送了勒索信。以下是已确认的信息、仅被声称的信息以及客户应采取的行动。
右侧栏
MALFEX 将其 npm 安装器迁移到 musllinux 平台
tensorlake 0.5.144 npm 被入侵 发布微型沙伊-胡卢德蠕虫
[email protected] 在 npm 安装过程中运行了微型沙伊-胡卢德蠕虫。维护者账号通过 GitHub 网页界面提交了恶意载荷,官方发布流程将其发布。
查看所有博客
GitHub 行动号召板块 - Figma 规格:1200×651
背景图片
背景模糊覆盖层
内容容器 - Figma 规格:392×326 带 26px 间距
Logo
标题
发布代码。
并非恶意软件。
描述
从本地开源工具免费开始,扩展到组织的统一平台。
行动号召按钮
在 GitHub 上星标
预约演示