ZIP Slip
2024-11-5 03:23:0 Author: mp.weixin.qq.com(查看原文) 阅读量:0 收藏

有研发的同学询问zip slip漏洞的修复,碰巧最近在批量找一些cms的zip slip漏洞,提供以下两种修复方式,仅供参考:

修复方式1

private static final int DEFAULT_BUFFER_SIZE = 8192;
public static void unzip(File zipFile, File destDir, String encoding) { if (destDir.exists() && !destDir.isDirectory()) { throw new IllegalArgumentException("destDir is not a directory!"); } ZipFile zip = null; InputStream is = null; FileOutputStream fos = null; File file; String name; byte[] buff = new byte[DEFAULT_BUFFER_SIZE]; int read; ZipEntry entry; try { try { if (StringUtils.isNotBlank(encoding)) { zip = new ZipFile(zipFile, encoding); } else { zip = new ZipFile(zipFile); } Enumeration<?> en = zip.getEntries(); while (en.hasMoreElements()) { entry = (ZipEntry) en.nextElement(); name = entry.getName(); name = name.replace('/', File.separatorChar); // 防止zip包里面的使用`../..`之类的文件名,将文件解压到指定目录之外。 name = name.replace("..", ""); file = new File(destDir, name); if (entry.isDirectory()) { file.mkdirs(); } else { // 创建父目录 file.getParentFile().mkdirs(); is = zip.getInputStream(entry); fos = new FileOutputStream(file); while ((read = is.read(buff)) > 0) { fos.write(buff, 0, read); } fos.close(); is.close(); } } } finally { if (fos != null) { fos.close(); } if (is != null) { is.close(); } if (zip != null) { zip.close(); } } } catch (IOException e) { e.printStackTrace(); }
}

zip解压主要使用的是ant组件,依赖相关如下:

<dependency>    <groupId>org.apache.ant</groupId>    <artifactId>ant</artifactId>    <version>1.9.6</version></dependency><dependency>    <groupId>commons-io</groupId>    <artifactId>commons-io</artifactId>    <version>2.4</version></dependency><dependency>    <groupId>org.apache.commons</groupId>    <artifactId>commons-lang3</artifactId>    <version>3.4</version></dependency>

修复方式2

public static void unZipFiles(File zipFile,String descDir) throws IOException {    File pathFile = new File(descDir);    if (!pathFile.exists()) {        pathFile.mkdirs();    }    // 解决zip文件中有中文目录或者中文文件    ZipFile zip = new ZipFile(zipFile, Charset.forName("UTF-8"));    for (Enumeration entries = zip.entries(); entries.hasMoreElements();) {        ZipEntry entry = (ZipEntry) entries.nextElement();        String entryName = entry.getName();
Pattern pattern = Pattern.compile("[^a-zA-Z0-9_\\-\\.]"); Matcher matcher = pattern.matcher(entryName);
if(entryName.contains("../") || entryName.contains("..\\") || matcher.find()){ System.out.println("压缩包中文件名疑似不安全,详情: "+ entryName); throw new IOException("压缩包中文件名疑似不安全,详情: "+ entryName); } InputStream in = zip.getInputStream(entry); String outPath = Paths.get(descDir, entryName).toString().replaceAll("\\*", "/"); // 判断路径是否存在,不存在则创建文件路径 File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
if (!file.exists()) { file.mkdirs(); } // 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压 if (new File(outPath).isDirectory()) { continue; }
OutputStream out = new FileOutputStream(outPath); byte[] buf1 = new byte[1024]; int len; while ((len = in.read(buf1)) > 0) { out.write(buf1, 0, len); } in.close(); out.close(); } zip.close();}

修复方式2,代码直接使用java.util.zip,未使用第三方组件

另外Hutool也提供解压方法,Hutool在4.1.12之前的版本存在zip slip漏洞,这点需要注意。


文章来源: https://mp.weixin.qq.com/s?__biz=MzI2NTExNzcxNQ==&mid=2247484323&idx=1&sn=037c15e26149b5bd6c395dbdca61d08e&chksm=eaa30adfddd483c9e941f10c9eec895127269db211b26141e4991106a2b26760827d1b9d1ad0&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh