ZIP Slip

admin 2024年11月4日23:19:00评论8 views字数 2735阅读9分7秒阅读模式

有研发的同学询问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漏洞,这点需要注意。

原文始发于微信公众号(代码审计SDL):ZIP Slip

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月4日23:19:00
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   ZIP Sliphttp://cn-sec.com/archives/3355154.html

发表评论

匿名网友 填写信息