• 惊爆:当Python代码遇到zip解压炸弹,未做防护的你后悔莫及!


    zip解压炸弹

    在文章的开头,让我们先来介绍一下zip解压炸弹是个什么妖怪!

    解压炸弹是指解压缩后能够产生巨大的数据量的可疑压缩文件!默认设置是文件扫描中产生500MB以上解压数据的是“解压炸弹”,实时监控中是100MB,邮件监控是30MB。这样的压缩文件解压缩可能对解压程序造成严重负担或崩溃(可能用来攻击压缩软件以及占用大量电脑资源,或者杀毒软件的解压缩功能)。解压炸弹内,还可能存在病毒,解压中会自启动窃取用户信息

    如何制作解压炸弹

     42.zip 是很有名的zip炸弹。一个42KB的文件,解压完其实是个4.5PB的“炸弹”。zip炸弹文件中有大量刻意重复的数据,这种重复数据在压缩的时候是可以被丢弃的,这也就是压缩后的文件其实并不大的原因。

    这一百多万个最终文件,每个大小为 4.3 GB 。因此整个解压过程结束以后,会得到 1048576 * 4.6 GB = 4508876.8 GB也就是 4508876.8 ÷ 1024 ÷ 1024 = 4.5 PB这需要特殊的压缩算法和工具,但我们可以通过Python做一个简单的zip解压炸弹:

    # -*- coding: utf-8 -*-
    import os
    
    def make_boom(file_path, file_num, string_len):
        if not os.path.exists(file_path):
            os.mkdir(file_path)
        os.chdir(file_path)
        for i in range(file_num):
            with open('boom%d.txt' % i, 'w',encoding='utf-8') as f:
                f.write('Boom' * string_len)
    
    make_boom('zip_boom', 1000, 1000 * 1000)
    

      我们快速创建1000个boom文件,每个文件中写入了一百万个boom,制作出了一个3.72GB的文件夹,然后只用7z工具的极限压缩效果,最终得到的zip文件只有4.8MB。

    开始捣乱

    我们自己制作的zip解压炸弹准备完毕,现在我们要找地方去黑别人的服务器了。找谁呢?刚好最近报了一个网易云课堂的Java微专业,他们每次提交打压的时候都是上传zip文件,然后老师获取到文件后解压进行批改,如图:

     

    现在只要我提交附件,就可以静等批改作业的老师,把我按在地上摩擦了。(当然我肯定不会提交的...)这么大的一个网站,居然都没有对zip解压炸弹进行上传检查,可见大家日常开发过程中,存在多么大的安全隐患啊!

    日常校验

    正如刚才拿网易云课堂进行的上传演示,日常开发中我们对压缩文件的校验,主要分为类型、大小的校验。比如我们Flask开发时,会通过flask_wtf校验文件类型:

    from flask_wtf.file import FileField, 
        FileRequired, FileAllowed
    allow_type = ['zip', 'rar', '7z']
    
    class UploadForm(FlaskForm):
        zip_file = FileField('请上传文件:',
                             validators=[FileRequired(),
                             FileAllowed(allow_type)])
        submit = SubmitField()
    

      同样的,会通过设置Flask最大文本长度对上传文件的大小进行校验

    from flask import Flask
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'Breeze Python'
    app.config['UPLOAD_PATH'] = os.path.join(app.root_path, 'uploads')
    app.config['MAX_CONTENT_LENGTH'] = 30 * 1024 * 1024  # 30Mb
    

      或者在文件读写过程中,通过os.path.getsize(filePath)来校验文件大小。但如果你只做了如上方式,那么恭喜你一大波zip解压炸弹正向你赶来...

    正确方式

    那么,我们可以通过什么方式来对zip解压炸弹进行预防呢?其实很简单:

    1. 文件数量
    2. 动态解析文件总大小

    先上代码看看:

    import zipfile
    import os
    
    def unzip(filename: str):
        # 限制最大文件数100
        max_file_num = 100
        # 设置解压内容最大值(一般平均最大的压缩率20,再高就很可能是异常文件了!)
        max_file_size = 1024 * 1024 * 100 * 20
        total_size = 0
        to_zip_file = zipfile.ZipFile(filename)
        dirname = filename.replace('.zip', '')
        # 校验文件总数量
        if len(to_zip_file.filelist) > max_file_num:
            raise ValueError("压缩文件的数量超过了上限")
        # 校验解压文件内容最大值
        for file in to_zip_file.filelist:
            total_size += file.file_size
            if total_size > max_file_size:
                raise IOError("压缩包内容异常")
        # 判断文件夹重复则退出
        if os.path.exists(dirname):
            print(f'{dirname} dir has already existed')
            return -1
        else:
            # 创建文件夹,并解压
            os.mkdir(dirname)
            to_zip_file.extractall(dirname)
            to_zip_file.close()
    
    unzip('zip_boom.zip')
    

      比如刚才的网易云课堂,学生做的解题答案,一个类加几个依赖文件了不起了。所以我们通过设置压缩包最大解压文件数进行检测。我们再设置原始文件的最大内存上限(一般平均最大的压缩率不会超过20,再高就很可能是异常文件了!),起到二次校验的作用,最终达到zip解压炸弹的安全防护。日常开发过程中,软件的安全、可信要时刻放在首要位置。

    请牢记,今天偷的懒,就是明天流的泪啊!

    注意:如果你是打算找python高薪工作的话。我建议你多写点真实的企业项目积累经验。不然工作都找不到,当然很多人没进过企业,怎么会存在项目经验呢? 所以你得多找找企业项目实战多练习下撒。如果你很懒不想找,也可以进我的Python交流圈:1156465813。群文件里面有我之前在做开发写过的一些真实企业项目案例。你可以拿去学习,不懂都可以在裙里找我,有空会耐心给你解答下

    我们快速创建1000个boom文件,每个文件中写入了一百万个boom,制作出了一个3.72GB的文件夹,然后只用7z工具的极限压缩效果,最终得到的zip文件只有4.8MB。

     



    开始捣乱

  • 相关阅读:
    myeclipse自动生成相应对象接收返回值的快捷键
    JavaEE学习记录(一)--软件系统体系结构
    通过Java编码获取String分行字符串的内容
    长款或短款的处理(二)
    现金清查中的长款短款的简单解释(一)
    mybatis 的mapper配置文件sql语句中, 有时用到 大于, 小于等等
    <c:forEach items="${list}" var="tt" varStatus="status"> 的相关大小长度
    svn 提交 working copy is not up-to-date
    svn: Working copy 'D:workspaceweb....images' is too old (format 10, created by Subversion 1.6
    mybatis generator eclipse插件的安装
  • 原文地址:https://www.cnblogs.com/shuchongzeishuai/p/13882989.html
Copyright © 2020-2023  润新知