Skip to content

Repository files navigation

A better zip bomb

Paper: WOOT '19 (13th USENIX Workshop on Offensive Technologies), August 2019 Author: David Fifield Project: https://www.bamsoftware.com/hacks/zipbomb/ Paper materials: See ./paper/ directory


Overview

This is a non-recursive zip bomb generator. Unlike traditional recursive zip bombs (like the famous 42.zip), this project's bombs do not require nested zip files — they simply compress a kernel and let multiple file entries in the zip archive reference the same compressed data region. This makes the bombs effective even for decompressors that do not recursively extract.

By optimizing the ratio of file count to compressed kernel size, extremely high expansion rates can be achieved with very small compression ratios.


Example Bombs

Filename Compressed Size Uncompressed Size Compression Ratio Description How to Get
zbsm.zip 42 KB 5.5 GB 130,000× Non-recursive, single layer ✅ Pre-generated (zip/)
zblg.zip 10 MB 281 TB 28,000,000× Largest non-Zip64 bomb ✅ Pre-generated (zip/)
zbxl.zip 46 MB 4.5 PB 98,000,000× Exceeds 42.zip size ✅ Pre-generated (zip/)
zbxxl.zip 2.8 GB 18 EB (2⁶⁴) Reaches 64-bit limit ⚙ Generated by make zbxxl.zip
zbbz2.zip 4.3 GB bzip2 algorithm variant ⚙ Generated by make zbbz2.zip

Comparison: The classic 42.zip is 42 KB → 4.5 PB (but only effective with recursive extraction).

The zip/ directory contains pre-generated zbsm.zip, zblg.zip, and zbxl.zip examples (can be analyzed with ratio, but do not extract). Other bombs are large; generate them on demand with make. The generation only produces the compressed archive file itself and does not occupy the extracted space.


Project Structure

zipbomb/
├── zipbomb              # Main program: Python 3 script, generates zip bombs
├── zipbomb-20190702.zip # Complete snapshot of the 2019-07-02 initial release
├── Makefile             # Build system, contains recipes for various bombs
├── ratio                # Compression ratio calculator: calculates zip compression/extract ratio
├── optimize.R           # R optimization script: calculates optimal file count and kernel size parameters
├── optimize.out         # Pre-calculated output of optimize.R
├── LICENSE              # Public Domain dedication
├── README.md            # This file
├── README.zh.md         # Chinese translation (extended with detailed explanations)
├── .gitignore           # Ignores huge bombs generated by make, keeps zip/ samples
├── .gitattributes       # Scripts use LF line endings, zip marked as binary
├── website/             # Project website (bamsoftware.com/hacks/zipbomb) full archive
│   ├── Abetterzipbomb-webpage.jpg
│   ├── Abetterzipbomb-webpage.pdf
│   └── A better zip bomb.md
└── zip/                 # Pre-generated example bomb files
    ├── zbsm.zip         # 42 KB → 5.5 GB
    └── zblg.zip         # 10 MB → 281 TB

Subdirectories

zipbomb/
├── paper/               # WOOT '19 academic paper supplementary materials
│   ├── data/            # Compression rate benchmark data and C source code
│   ├── figures/         # Asymptote chart source code
│   ├── samples/         # Parser compatibility test samples
│   ├── zipbomb.bib      # Paper bibliography
│   ├── zipbomb.tex      # Paper LaTeX body
│   └── reviews-woot19.txt  # Peer review feedback
└── website/             # Project website (bamsoftware.com/hacks/zipbomb) full archive
    ├── Abetterzipbomb-webpage.jpg
    ├── Abetterzipbomb-webpage.pdf
    └── A better zip bomb.md   # Full website archive

Core Principles

Why traditional recursive zip bombs are no longer effective?

Modern decompression software (such as Info-ZIP unzip 6.0, 7-Zip, etc.) typically does not support recursive extraction — that is, when encountering a .zip file during extraction, it does not automatically continue extracting. Therefore, the nested layering of 42.zip is ineffective for these software.

This project's method: File Overlap

A core feature of the Zip format is that multiple file entries can point to the same block of compressed data in the archive. Using this feature:

  1. Generate a highly compressed kernel — a DEFLATE stream of repeated bytes, compressed to a very small size (e.g., 1 byte representing several MB of data)
  2. Create many file entries — each entry's file header and CRC-32 still take space, but they all reference the same compressed kernel
  3. Multiply gains — if there are n files, each extracting to u bytes, total output = n × u. Since the compressed kernel only needs to be stored once, the compression ratio is close to n times the single-file compression ratio

Quoting Technique

When the number of files is large, each file's local file header (30 bytes) and central directory header (46 bytes) themselves take up a lot of space. The quoting technique uses DEFLATE's uncompressed blocks to "quote" adjacent file headers as part of its own data, thereby recycling this overhead space and further amplifying the expansion effect.

Three Construction Methods

Construction File Overlap Method Parser Compatibility Compression Efficiency
Full overlap All files point to the same kernel, same starting offset Lowest (most parsers don't support) Optimal
Quoted overlap Files are offset in the archive, later ones quote previous file headers as data Medium Good
No overlap Each file has its own compressed kernel Highest Lowest

zbsm.zip and zblg.zip use quoted overlap construction and have been tested to extract correctly in 7 mainstream zip parsers.


Dependencies

  • Python 3 (standard library only) — Run main program zipbomb and ratio. The script is completely self-contained: DEFLATE compression kernel, CRC-32 combination calculation (crc32_combine approach, implemented with GF(2) matrix) are all done in pure Python, no third-party libraries like crcmod or zlib are needed, and no C programs like bulk_deflate.c need to be compiled.
  • R (optional) — Only needed if you want to run optimize.R to recalculate parameter optimization; optimize.out already contains pre-calculated results.

Note: Early project documentation mentioned dependencies on crcmod and C source bulk_deflate.c, but the current zipbomb script has been changed to pure Python implementation, and these external dependencies have been removed.


Usage

Calculate compression ratio of existing zip bombs

./ratio zip/zbsm.zip zip/zblg.zip

Generate custom bombs

# Generate bomb similar to zbsm.zip (42KB)
make zbsm.zip

# Generate largest non-Zip64 bomb (10MB)
make zblg.zip

# Generate extreme bomb (46MB, requires Zip64)
make zbxl.zip

# Generate all example bombs
make all

Windows users: If make is not installed or the command is python instead of python3, you can call the script directly (redirect output to a file):

python zipbomb --mode=quoted_overlap --num-files=250 --compressed-size=21179 > zbsm.zip

The generation action only writes out the zip archive file itself (very small size) and does not occupy the extracted space, so it can be executed safely.


Compatibility Testing

The bombs in this project have been tested in the following zip parsers:

  • Info-ZIP unzip 6.0 (Linux)
  • Python 3.7 zipfile module
  • Go 1.12 archive/zip
  • Node.js yauzl
  • Nail (parser generator)
  • Android 9.0 libziparchive (only zbsm.zip)
  • sunzip (Mark Adler's streaming decompressor)

See ./paper/samples/README for details.


Security Warning

  1. Do not directly extract these zip bomb files! They will instantly fill your disk
  2. Do not double-click to open with file manager — many file managers will automatically extract in the background to preview content
  3. If testing, do so in an isolated environment (such as RAM disk or container)
  4. This project is for security research and educational purposes only

References


zipbomb usage

optimize.R is an R script that computes optimal parameters for the zipbomb script, for zip bombs of various sizes. optimize.out is pregenerated output of optimize.R. Rscript optimize.R | tee optimize.out The optimized parameters are what you see in Makefile.

ratio is a Python 3 script that computes the compression ratio of zip files listed on the command line. $ make zbsm.zip zblg.zip zbxl.zip $ python3 ratio zbsm.zip zblg.zip zbxl.zip zbsm.zip 5461307620 / 42374 128883.45730872705 +51.102 dB zblg.zip 281395456244934 / 9893525 28442385.9286689 +74.54 dB zbxl.zip 4507981427706459 / 45876952 98262444.01996146 +79.924 dB

zipbomb usage

The required options are the number of files you want the zip bomb to contain, --num-files=100 and the size of the kernel, which can be either a specific compressed size, or a maximum uncompressed size. --compressed-size=1000 --max-uncompressed-size=20000

The script can run in one of three main modes: --mode=no_overlap --mode=full_overlap --mode=quoted_overlap (default) In quoted_overlap mode, you can additionally enable extra-field quoting; you need to provide a 4-digit hexadecimal tag type: --mode=quoted_overlap --extra=9999

You can choose either DEFLATE or bzip2 as the compression algorithm. --algorithm=deflate (default) --algorithm=bzip2 There are limitations when using bzip2. If you use bzip2 in quoted_overlap mode, you must also use --extra, because bzip2 does not have its own way of quoting local file headers. And the argument to the --compressed-size must be congruent to 14 mod 32 when used with bzip2.

Enable Zip64 support for zip bombs that need it (more than 0xfffe files or files larger than 0xfffffffe bytes). The script will crash somewhere if the output needs Zip64 but the option isn't enabled. --zip64 The need for Zip64 isn't detected automatically because I wanted to decide in advance whether a particular zip bomb should use Zip64 or not (and get an error if my calculations were wrong), and because it's slightly tricky to predict whether the maximum file size will exceed the threshold in quoted_overlap mode, where files get longer the more of them that are added (the optimize.R script does this calculation, though).

The default filename alphabet is 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ. You can change it with the --alphabet option. --alphabet=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

If you need the zip bomb to contain certain ordinary files in addition to the bomb files, you can provide one or more template zip files. --template=other.zip The --num-files option is in addition to whatever files are in the template.

Copyright and License

  • Code (zipbomb, ratio, Makefile, optimize.R, etc.): Author David Fifield (david@bamsoftware.com, project homepage https://www.bamsoftware.com/hacks/zipbomb/), released into the public domain, see LICENSE file and zipbomb script header declaration.
  • Paper / Official introduction (website/A better zip bomb.md): The author's formal draft of "A better zip bomb" published at USENIX WOOT 2019, originally released at https://www.bamsoftware.com/hacks/zipbomb/; the website/ directory in this repository is an archived copy (the original has no explicit copyright statement, copyright belongs to the author).
  • Chinese translation: The Chinese translation in website/ is from 「北岸冷若冰霜」(zerosun.top, https://zerosun.top/2019/07/07/A-better-zip-bomb/).
  • Classic recursive bomb 42.zip: From unforgettable.dk (see recursive/README.md), unrelated to this project's code, for research on zip parser robustness only.

About

用于测试解压缩软件容错性与防病毒引擎扫描深度的 Zip 压缩包炸弹(ZIP Bomb)验证项目。 A ZIP bomb proof-of-concept project for testing decompression utility tolerance and antivirus engine resilience.

Topics

Resources

Stars

28 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages