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
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.
| 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.
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
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
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.
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:
- 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)
- Create many file entries — each entry's file header and CRC-32 still take space, but they all reference the same compressed kernel
- Multiply gains — if there are
nfiles, each extracting toubytes, total output =n × u. Since the compressed kernel only needs to be stored once, the compression ratio is close tontimes the single-file compression ratio
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.
| 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.
- Python 3 (standard library only) — Run main program
zipbombandratio. The script is completely self-contained: DEFLATE compression kernel, CRC-32 combination calculation (crc32_combineapproach, implemented with GF(2) matrix) are all done in pure Python, no third-party libraries likecrcmodorzlibare needed, and no C programs likebulk_deflate.cneed to be compiled. - R (optional) — Only needed if you want to run
optimize.Rto recalculate parameter optimization;optimize.outalready contains pre-calculated results.
Note: Early project documentation mentioned dependencies on
crcmodand C sourcebulk_deflate.c, but the currentzipbombscript has been changed to pure Python implementation, and these external dependencies have been removed.
./ratio zip/zbsm.zip zip/zblg.zip# 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 allWindows users: If
makeis not installed or the command ispythoninstead ofpython3, you can call the script directly (redirect output to a file):python zipbomb --mode=quoted_overlap --num-files=250 --compressed-size=21179 > zbsm.zipThe 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.
The bombs in this project have been tested in the following zip parsers:
- Info-ZIP unzip 6.0 (Linux)
- Python 3.7
zipfilemodule - Go 1.12
archive/zip - Node.js
yauzl - Nail (parser generator)
- Android 9.0
libziparchive(onlyzbsm.zip) - sunzip (Mark Adler's streaming decompressor)
See ./paper/samples/README for details.
- Do not directly extract these zip bomb files! They will instantly fill your disk
- Do not double-click to open with file manager — many file managers will automatically extract in the background to preview content
- If testing, do so in an isolated environment (such as RAM disk or container)
- This project is for security research and educational purposes only
- WOOT '19 Paper: A better zip bomb — David Fifield
(related materials in
./paper/) - 42.zip: Classic recursive zip bomb
- Russ Cox: Zip Files All The Way Down
- Gynvael Coldwind: Ten thousand security pitfalls: The ZIP file format
- CVE-2019-9670: Zimbra mail server zip bomb vulnerability (quoted overlap technique)
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
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.
- 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, seeLICENSEfile andzipbombscript 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/; thewebsite/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 (seerecursive/README.md), unrelated to this project's code, for research on zip parser robustness only.