The same two-byte trick that broke ESET’s antivirus in 2004 still works today — against 50 of 51 engines on VirusTotal. The industry had 22 years to fix it.
TL;DR
- CVE-2026-0866 (CERT/CC VU#976247): a malformed ZIP that declares
Method=0(uncompressed) while the payload is actually DEFLATE-compressed- AV engines trust the header and scan compressed bytes as raw data — signatures never match
- 50 of 51 engines on VirusTotal fail to detect the malware; only Kingsoft catches it
- The payload is recoverable in 6 lines of Python using standard
zlib- Discovered by Chris Aziz (Bombadil Systems); GitHub PoC is public
- WinRAR and 7-Zip show an error — only automated scanning pipelines are blind
Why This Matters
Zombie ZIP isn’t a vulnerability in an obscure tool. It’s a flaw in how the security industry collectively decided to parse a 40-year-old file format.
Email gateways, cloud sandboxes, EDR products, and SIEM ingestion pipelines all scan ZIP attachments as part of their core function. When 98% of them can be bypassed with a header that says “trust me, this is uncompressed”, every ZIP-based malware delivery chain gets a free pass.
This matters most in environments that rely on gateway scanning as a primary defense layer — which is most enterprise environments.
The ZIP Format: What You Need to Know
Before getting into the attack, a quick primer on how ZIP files are structured. ZIP isn’t a single compressed blob — it’s a structured container with metadata that describes each embedded file.
A ZIP archive has three main components:
[Local File Header 1] [File Data 1][Local File Header 2] [File Data 2]...[Central Directory][End of Central Directory Record (EOCD)]Local File Header
Each file inside the ZIP gets its own Local File Header immediately before its data. The structure starts with the signature PK\x03\x04 and contains:
Offset Length Field0 4 Signature (0x04034b50 = "PK\x03\x04")4 2 Version needed to extract6 2 General purpose bit flag8 2 Compression method ← THE KEY FIELD10 2 Last mod file time12 2 Last mod file date14 4 CRC-3218 4 Compressed size22 4 Uncompressed size26 2 File name length28 2 Extra field length30 var File name? var Extra field? var File dataThe compression method field (bytes 8–9) tells the parser how to handle the file data that follows. The two most common values:
| Value | Method | Meaning |
|---|---|---|
0x0000 | STORED | Data is uncompressed — read as-is |
0x0008 | DEFLATE | Data is compressed — run through inflate |
Central Directory
At the end of the archive, the Central Directory contains a summary record for each file. It duplicates the compression method field and is what most tools use to build a file listing.
The Parser’s Trust Assumption
Here’s the architectural decision that creates the vulnerability: most ZIP parsers — and almost all security scanning engines — read the compression method from the header and use it to decide how to process the subsequent bytes. If Method says 0 (STORED), they treat the bytes as raw data. They do not verify that the declared method matches the actual data structure.
How Zombie ZIP Works
The Zombie ZIP technique exploits this trust directly:
Step 1: Create a normal ZIP file containing a malicious payload. The payload is DEFLATE-compressed as usual — Method=0x0008, data is compressed.
Step 2: Patch the compression method field in the Local File Header from 0x0008 to 0x0000. Two bytes. The actual file data — the DEFLATE-compressed payload — is left completely unchanged.
Step 3: Leave the Central Directory untouched, or patch it to match. The inconsistency between declared method and actual data is now baked in.
Before (normal ZIP): Local File Header: compression_method = 0x0008 (DEFLATE) File data: [DEFLATE-compressed payload]
After (Zombie ZIP): Local File Header: compression_method = 0x0000 (STORED) ← patched File data: [DEFLATE-compressed payload] ← unchangedWhat the AV Engine Sees
The scanning engine reads the Local File Header. Compression method = 0x0000. It concludes: “this file is uncompressed, scan the raw bytes.”
It then scans the raw bytes — which are DEFLATE-compressed data. DEFLATE-compressed data looks like high-entropy binary noise to a scanner. Malware signatures are written against decompressed, recognizable byte patterns. The scanner finds nothing, reports the archive as clean, and passes it through.
What a Purpose-Built Loader Sees
An attacker’s custom loader doesn’t care what the header says. It just calls zlib.decompress() on the file data regardless of the declared method. The DEFLATE stream decompresses perfectly — the payload was never damaged, only mislabeled.
The PoC from Bombadil Systems demonstrates this in six lines:
import zipfile, zlib
with open("zombie.zip", "rb") as f: raw = f.read()
# Locate and decompress the "stored" entry directly via zlib# (bypassing the declared Method=0 header)payload = zlib.decompress(raw[offset:], -15) # raw deflate streamThe payload comes out byte-perfect. The AV saw noise. The loader sees the original file.
CVE-2026-0866 and the Ghost of CVE-2004-0935
The first time this class of vulnerability was documented was 2004 — CVE-2004-0935 affected ESET Anti-Virus versions before 1.020. The exact same mechanism: ZIP header declares uncompressed, actual content is compressed, ESET scanned the compressed bytes and missed the malware.
ESET fixed their product. The rest of the industry apparently didn’t notice, or didn’t prioritize it.
22 years later, Chris Aziz at Bombadil Systems rediscovered the same technique and tested it against VirusTotal’s full engine set. The result:
| Result | Count |
|---|---|
| Failed to detect | 50 engines |
| Detected correctly | 1 engine (Kingsoft) |
| Detection rate | ~2% |
CERT/CC assigned VU#976247 and the CVE got its number: CVE-2026-0866. The name “Zombie ZIP” comes from the concept of a long-dead vulnerability rising from the grave — same trick, different year, same result.
Why WinRAR and 7-Zip Error Out
If Zombie ZIP bypasses AV engines, why does opening it in WinRAR or 7-Zip produce an error instead of silently executing the payload?
Because WinRAR and 7-Zip follow the ZIP spec. When they see Method=0, they attempt to read the file data as raw uncompressed bytes. The data is actually a DEFLATE stream — it starts with a DEFLATE header byte, not valid file content. The decompressed “file” is garbage. The extractor reports a CRC mismatch or corrupt archive.
This is the key distinction:
| Tool | Behavior with Zombie ZIP |
|---|---|
| WinRAR | CRC error / extraction failure |
| 7-Zip | Reports corrupt archive |
| Windows Explorer | Extraction error |
| AV engine (scanner mode) | Scans “raw” bytes, reports clean |
| Email gateway | Passes the file through |
| Cloud sandbox | Marks as clean |
| Custom loader | Decompresses correctly, executes |
The attack isn’t designed to trick end users — it’s designed to bypass the automated scanning layer before the file reaches the user. The attacker delivers the ZIP via phishing, the gateway scans it and passes it, and then the attached dropper (not WinRAR) handles the actual extraction.
Attack Chain in Practice
A realistic deployment scenario targeting enterprise email:
[1] Payload Preparation - Pack malicious executable (e.g., Cobalt Strike beacon, AsyncRAT) into a normal DEFLATE-compressed ZIP - Patch Local File Header: bytes 8-9 from 0x08 0x00 → 0x00 0x00 - Result: Zombie ZIP, 50/51 AV engines blind
[2] Phishing Delivery - Attach Zombie ZIP to a spearphishing email - Lure: "Q1 invoice", "contract review", "security update" - Send through email infrastructure that avoids reputation blocks
[3] Gateway Processing - Email gateway receives message, scans attachment - ZIP parser reads Method=0, scans DEFLATE bytes as raw data - No signatures match — attachment flagged as clean - Email delivered to recipient inbox
[4] User Interaction - User opens ZIP — sees error (archive appears corrupt) - But: phishing email includes instructions: "If the file shows an error, run the included setup.exe first" - Or: a JavaScript dropper / macro opens the ZIP using a custom extraction routine rather than shell association
[5] Payload Execution - Custom loader decompresses via raw zlib (ignores method header) - Malicious executable extracted to %TEMP% and launched - AV/EDR never scanned the actual payload bytesThe “open setup.exe if you see an error” social engineering step is not hypothetical — it mirrors the ClickFix technique covered in The ‘Fix’ Is the Exploit: ClickFix, FileFix and Pastejacking Attacks Explained, which conditions users to run things when software appears broken.
Detection
Zombie ZIP detection falls into two categories: file-based (static) and behavioral.
YARA Rule — Header Method Mismatch
rule ZombieZIP_Method_Mismatch{ meta: description = "Detects ZIP with STORED method declaration over DEFLATE data" author = "Hive Security" date = "2026-03-13" reference = "CVE-2026-0866"
strings: // Local File Header signature $lfh_sig = { 50 4B 03 04 } // Method = STORED (0x0000) at correct offset $method_stored = { 50 4B 03 04 ?? ?? ?? ?? 00 00 } // DEFLATE magic bytes (common start of deflate stream) $deflate_magic = { 78 9C } // zlib wrapper (default compression) $deflate_raw = { 78 DA } // zlib best compression $deflate_min = { 78 01 } // zlib no compression (but still zlib)
condition: $lfh_sig at 0 and $method_stored at 0 and ( $deflate_magic in (30..256) or $deflate_raw in (30..256) or $deflate_min in (30..256) )}This catches the most common variant: a ZIP whose first entry declares STORED but whose file data begins with a zlib header (78 9C, 78 DA, or 78 01).
Header Validation in Python
For integration into custom pipelines, a simple structural validator:
import struct
def is_zombie_zip(path: str) -> bool: """Return True if ZIP declares STORED but data looks like DEFLATE.""" with open(path, "rb") as f: sig = f.read(4) if sig != b"PK\x03\x04": return False f.seek(8) # compression method offset method = struct.unpack("<H", f.read(2))[0] f.seek(30) # skip to file data (min header size, no name/extra) data_start = f.read(2)
# Method=STORED but data starts with zlib magic return method == 0 and data_start in (b"\x78\x9c", b"\x78\xda", b"\x78\x01")Behavioral Indicators
Beyond static file analysis, watch for:
- Process calling
zliborinflateAPIs on a file that was never extracted via standard shell — unusual decompression path - ZIP attachment delivered to mailbox + CRC error on open + executable spawned shortly after — delivery chain correlation
WinRARorexplorer.exereporting ZIP error + new process underOUTLOOK.EXEor browser — user opened broken ZIP, something else ran
What You Can Do Today
1. Update Security Products
Vendors are actively pushing fixes. Ensure your email gateway, EDR, and endpoint AV are on the latest signatures and engine versions. Check vendor advisories for explicit CVE-2026-0866 coverage.
2. Deploy the YARA Rule
Add the YARA rule above to your scanning pipeline — email gateway, file upload endpoint, EDR custom rule engine (CrowdStrike, Defender for Endpoint, and SentinelOne all support custom YARA). This catches the known PoC variant.
3. Test Your Stack Against VirusTotal’s Baseline
Upload a benign test file packaged as a Zombie ZIP (no malicious payload — just a text file with a patched header) to your internal scanning tools. If they report clean, your pipeline is blind to this technique.
4. Email Gateway: Reject Malformed Archives
Most enterprise email gateways support a policy to reject or quarantine structurally malformed ZIP files. Enable it. The tradeoff: some legitimate (badly authored) ZIP tools produce non-spec archives that will get caught. Evaluate the false positive rate in your environment.
5. Don’t Rely on Gateway Scanning Alone
Zombie ZIP is a reminder that file format parsing is an arms race. Layered defense means:
- Gateway scanning (catch known-bad)
- Sandbox detonation (catch suspicious-behavior)
- EDR behavioral monitoring (catch post-execution)
- User awareness (recognize social engineering cues like “run this if you see an error”)
No single layer is reliable alone.
Related Posts
- The ‘Fix’ Is the Exploit: ClickFix, FileFix and Pastejacking Attacks Explained — Zombie ZIP delivery often relies on social engineering to overcome the “corrupt archive” error; ClickFix-style conditioning makes users execute the dropper anyway
- The Digital Parasite: How Attacker Tradecraft Evolved in 2026 — Broader context on how evasion techniques like Zombie ZIP fit into modern attacker workflows
- Purple Teaming on a Budget: Free Tools and Frameworks That Actually Work — Framework for testing whether your detection stack would catch Zombie ZIP before production exposure
Sources
- New ‘Zombie ZIP’ technique lets malware slip past security tools — BleepingComputer
- Analyzing “Zombie Zip” Files (CVE-2026-0866) — SANS ISC Diary
- zombie-zip GitHub PoC — Bombadil Systems
- ‘Zombie ZIP’ slips malware past 98% of antivirus engines — SC World
- Zombie ZIP flaw exposes antivirus blind spot in malformed archives — Guru3D
- Malformed ZIP Files Allows Attackers to Bypass Antivirus and EDR — CyberSecurityNews
- CERT/CC Vulnerability Note VU#976247