mag1c7
- 关注
漏洞描述
DeepJavaLibrary(DJL) 是一个开源的、高级的、引擎无关的 Java 深度学习框架。DJL 旨在让 Java 开发者易于上手和使用。DJL 提供了原生的 Java 开发体验,并且像其他常规 Java 库一样运作。(AWS开源项目)
DJL 提供了用于提取 tar 和 zip 模型归档的工具,这些归档在加载模型以供 DJL 使用时会用到。发现这些工具存在问题,未能在提取过程中防止绝对路径遍历。
Deep Java Library (DJL)is an open-source, high-level, engine-agnostic Java framework for deep learning. DJL is designed to be easy to get started with and simple to use for Java developers. DJL provides a native Java development experience and functions like any other regular Java library.
DJL provides utilities for extracting tar and zip model archives that are used when loading models for use with DJL. These utilities were found to contain issues that do not protect against absolute path traversal during the extraction process.[1]
漏洞条件
版本
<= 0.31.1
压缩包的创建和解压,分别在==默认分隔符不同的==操作系统(Windows/Linux)进行
漏洞定位
ai.djl.util.TarUtils#untar
ublic static void untar(InputStream is, Path dir, boolean gzip) throws IOException {
InputStream bis;
if (gzip) {
bis = new GzipCompressorInputStream(new BufferedInputStream(is));
} else {
bis = new BufferedInputStream(is);
}
bis = CloseShieldInputStream.wrap(bis);
try (TarArchiveInputStream tis = new TarArchiveInputStream(bis)) {
TarArchiveEntry entry;
while ((entry = tis.getNextEntry()) != null) {
String entryName = ZipUtils.removeLeadingFileSeparator(entry.getName());
if (entryName.contains("..")) {
throw new IOException("Malicious zip entry: " + entryName);
}
Path file = dir.resolve(entryName).toAbsolutePath();
if (entry.isDirectory()) {
Files.createDirectories(file);
} else {
Path parentFile = file.getParent();
if (parentFile == null) {
throw new AssertionError("Parent path should never be null: " + file);
}
Files.createDirectories(parentFile);
Files.copy(tis, file, StandardCopyOption.REPLACE_EXISTING);
}
}
}
}
漏洞复现
环境配置
引入maven依赖:Maven Repository: ai.djl » api » 0.31.0
创建访问点:
import ai.djl.util.TarUtils;
@PostMapping("/CVE-2025-0851")
public void CVE20250851(@RequestParam MultipartFile file, @RequestParam boolean gzip) {
try{
InputStream fis = file.getInputStream();
//这里只关系根路径"C:/"即可,anyPath可以是任意路径
Path base = Paths.get("C:/anyPath");
TarUtils.untar(fis,base,gzip);
}catch (Exception e){
e.printStackTrace();
}
}
Kali:创建恶意tar包
此时Windows对应路径:
测试
使用curl访问测试点:url -X POST -F "file=@hack.tar" -F "gzip=false" http://192.168.23.1:8081/CVE-2025-0851
进入untar(...):发现获取到entry.name 的分割符是/
,与上述内容一致
进入removeLeadingFileSeparator(...):windows操作系统的分割符是\
从而绕过检测
回到untar:发现生成的最终绝对路径与anyPath
无关,只与dir.root
和entryName
有关; 这是因为当entryName
中开头存在分隔符时dir.resolve(entryName).toAbsolutePath()
会将entryName
识别成“绝对路径”,所以会和dir.root
("C:\")拼接。若开头不存在分隔符则会被识别成“相对路径”,会和dir.path
拼接。
最终结果:因为服务器权限不足而导致失败,从报错可见,的确是尝试访问了对应的目录
换一个低权限路径尝试:当我将上述base
路径改成E:/Temp
,会出现以下内容;(curl命令不变)
成功!
总结:因为不同操作系统的分割符不同,攻击者在与不同于服务器操作系统的环境中构造tar包,并发送后能够绕过removeLeadingFileSeparator(...)
从而导致最终Path生成的是攻击者控制的绝对路径,造成绝对路径遍历(不同于用../
的相对路径遍历)
补充
反过来操作也可以[1]
it is possible to create an archive on a Windows system, and when extracted on a MacOS or Linux system, write artifacts outside the intended destination during the extraction process. The reverse is also true for archives created on MacOS/Linux systems and extracted on Windows systems.
漏洞修复
升级到最新版本
补丁:[api] fix issue in Tar/Zip Utils that resulted in incorrect artifact … · deepjavalibrary/djl@7d197ba
Reference
[1] Path traversal issue in Deep Java Library · Advisory · deepjavalibrary/djl
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)