Analyzing ZIP Encryption: When to Act


At a local CTF last month, I encountered an encrypted ZIP file with 45 minutes remaining. Running unzip only showed password:. The challenge description had no obvious hints. I initially didn’t use zip2john. That decision cost me 15 minutes. This article isn’t a tool manual—it’s a battle log about “when and how to make the right call.”

30 Minutes Into CTF, ZIP Won’t Open — Three Wrong Decisions I Made

Situation Log

  • Category: Forensics 200pt
  • Time Limit: 2 hours
  • Distributed File: secret.zip (2.3MB)
  • zipinfo output:
  Archive:  secret.zip
  Zip file size: 2345678 bytes, number of entries: 1
  -rw-r--r--  3.0 unx   524288 bx stor 25-Jan-15 12:34 flag.txt

The bx indicator. I didn’t realize at this point that this signified AES encryption.

Approaches I Tried (Failure Log)

1. Manual Guessing with unzip -P (5 minutes wasted)

bash

unzip -P ctf2025 secret.zip
unzip -P password secret.zip
unzip -P flag secret.zip

Why I tried it: In a past challenge, password worked
Why it failed: I wasn’t even doing dictionary attacks. Just random guessing
What was wrong: Baseless hope that “maybe it’s a simple password”

2. Searching for Hints with strings (6 minutes wasted)

bash

strings secret.zip | grep -i flag
strings secret.zip | grep -i hint

Why I tried it: Thought there might be hints in ZIP comments or metadata
Why it failed: AES-encrypted ZIPs fully encrypt contents. No plaintext appears
What was wrong: Assumed “there must be hints” without checking encryption type

3. Binary Editor Structure Check (4 minutes wasted)

bash

hexdump -C secret.zip | head -20
```

I stared at the PK header feeling like I understood something. Nothing actually progressed.

### Signs of Falling Into a Rabbit Hole

Around this point, I checked the clock—15 minutes had passed. Panic started setting in. I was convinced "I must be missing something." I re-read the challenge description three times. Peeked at the Discord writeup channel. Someone had already gotten first blood.

**I was completely stuck**. I had never once checked the encryption format, and some strange pride about "this problem isn't worth using tools for" was clouding my judgment.

## The Decisive Observation That Led to Using zip2john

### The Decisive Point I Observed

I calmed down and ran `zipinfo -v secret.zip`:
```
encryption method: AES-256

The moment I saw that line, everything changed.

  • AES encryption: Not something you can break with manual guessing
  • No hints in challenge text: No password generation rules or suggestions
  • Other participants’ progress: Already 3 teams solved it → it’s not unsolvable

In other words, I concluded it was “designed to be cracked with a straightforward dictionary attack.” Only then did zip2john come to mind as an option.

Why I Rejected Other Tools

I had three tools available:

Decision Factorzip2johnhashcatfcrackzip
Initial Setup Time0 sec (pre-installed)GPU setup requiredDictionary specification tedious
GPU DependencyNoneYesNone
Configuration ComplexityLowMedium-HighMedium
CTF Responsiveness

hashcat would be fastest with a GPU environment, but I was using a cloud CPU instance that day. I wanted to fight with a tool that works right now rather than spend time on GPU setup.

fcrackzip was also an option, but I’d made mistakes with dictionary file path specification in the past. I felt john‘s --wordlist option was more intuitive.

Under These Conditions, zip2john Is the Only Choice

  • CPU environment only: No GPU available
  • Dictionary attack assumption: Expecting meaningful passwords, not brute force
  • AES ZIP: fcrackzip is fast for ZipCrypto, but john is stable for AES
  • Short time limit: 30 minutes remaining. No time to fiddle with settings

When NOT to Use It

Conversely, I’d choose different tools under these conditions:

  • Long password assumption: Random 20+ character strings → hashcat + GPU
  • GPU available: If CUDA environment is ready, hashcat is overwhelmingly faster
  • Mass rule application: john‘s rule files are powerful, but hashcat offers more flexibility

Since I was expecting a “CTF-like password” (event name + year, etc.), I judged zip2john would be sufficient.

Real Obstacles I Hit After Deploying zip2john

Hash Extraction Mistake

The first command I executed:

bash

zip2john secret.zip

Hashes flooded the terminal and I thought “huh?” I forgot to redirect.

The correct way:

bash

zip2john secret.zip > hash.txt

I wasted a minute on this basic mistake. When you’re panicking, you mess up the fundamentals.

Multiple File ZIP Problem (didn’t apply this time)

In a different past challenge, there were multiple files in the ZIP, each encrypted with different passwords. In that case, zip2john outputs multiple lines. When feeding it to john, only the first line gets processed and I mistakenly thought “it won’t crack.”

This time there was only one file, so no problem.

Why John Won’t Crack

bash

john hash.txt

Executed. Waited a few seconds. Nothing.

The default dictionary (password.lst) didn’t catch anything. I panicked and tried --incremental mode, but AES processing time was heavy and barely progressed.

Gap between theory and practice: AES has long verification time per password. Brute force on CPU isn’t realistic.

CTF passwords are “human.” I should have assumed meaningful character strings, not completely random ones.

The Dictionary Strategy That Became the Deciding Factor

Words Extracted from Challenge Text

Re-reading the challenge description:

“Welcome to LocalCTF 2025! Find the secret in our archive.”

Keywords:

  • LocalCTF
  • 2025
  • secret
  • archive

I manually created a dictionary combining these:

bash

cat > custom.txt <<EOF
LocalCTF
localctf
LocalCTF2025
localctf2025
LOCALCTF2025
Secret2025
archive2025
EOF

How Results Changed with Rule Application

bash

john hash.txt --wordlist=custom.txt

Result: Nothing.

Next, applying john rules:

bash

john hash.txt --wordlist=custom.txt --rules=Single
```

**3 seconds later, cracked**.
```
localctf2025     (secret.zip/flag.txt)

--rules=Single is a ruleset that tries uppercase/lowercase conversion, number addition, and simple substitutions. Far faster than writing all patterns manually.

Command Log to Flag Capture

With actual execution times:

bash

# 18:23:45
zipinfo -v secret.zip
# → Confirmed AES-256 (10 sec)

# 18:24:00
zip2john secret.zip > hash.txt
# → Hash extraction (5 sec)

# 18:24:10
john hash.txt
# → Default dictionary failed (30 sec)

# 18:25:00
# Dictionary creation (2 min)

# 18:27:15
john hash.txt --wordlist=custom.txt --rules=Single
# → Cracked successfully in 3 sec

# 18:27:20
unzip -P localctf2025 secret.zip
# → Extracted flag.txt

# 18:27:25
cat flag.txt
# FLAG{z1p_crypt0_1s_n0t_s3cur3}
```

**Total time**: About 4 minutes. If I hadn't wasted the initial 15 minutes, I could have solved it much faster.

## Difficulty Prediction Visible from Understanding ZIP Encryption Internal Structure

### ZipCrypto vs AES

You can distinguish them from `zipinfo` output:

- **ZipCrypto** (old encryption): `encryption method: ZipCrypto`
  - Known vulnerabilities
  - Can be cracked quickly with `fcrackzip`
  - In CTF, "beginner level"

- **AES** (modern encryption): `encryption method: AES-256`
  - Cryptographically strong
  - Brute force unrealistic
  - In CTF, a sign of "dictionary attack assumption"

### Meaning of Hash Structure

Looking at `zip2john` output:
```
secret.zip/flag.txt:$zip2$*0*3*0*...*$/zip2$

Information contained within:

  • salt: Unique value per password
  • iteration: How many times hash calculation repeats
  • Part of encrypted data: Used for verification

Why it takes time: AES intentionally increases computational cost. Several milliseconds to tens of milliseconds per password. Testing 10,000 passwords takes several minutes.

CTF-Specific Design Philosophy

When ZIP encryption is used in CTF challenges, in most cases:

  • Encryption strength itself isn’t the essence
  • Testing “awareness”: Can you generate a dictionary from the challenge text?
  • Just an obstacle: The flag is in flag.txt, ZIP is just the gate

In other words, it’s designed so that “if you can choose the right tool and prepare the right dictionary, you can break through in minutes.” Conversely, without proper judgment, you waste time.

Fastest Action Flow for Next Time Under Same Conditions

Based on this experience, I created a checklist for myself:

ZIP Encryption Encounter Checklist

  1. Check zipinfo (10 sec)

bash

   zipinfo -v target.zip

Always check encryption format. Strategy changes depending on AES or ZipCrypto.

  1. AES determination → zip2john route confirmed
  2. Check for hints (30 sec)
    • Challenge description
    • Filename
    • Other distributed files
  3. 5-minute limit on manual exploration
    • Don’t go deep if there are no obvious hints
    • strings and hexdump are time thieves
  4. Deploy zip2john (immediate execution)

bash

   zip2john target.zip > hash.txt
  1. Determine dictionary priority (try in this order)
    1. Challenge keyword dictionary
    2. rockyou.txt (common password collection)
    3. CTF-specific dictionary (ctf, flag, admin, etc.)
    4. Rule application (--rules=Single)
  2. Re-evaluate direction within 15 minutes
    • Won’t crack → dictionary is wrong OR there’s an alternative solution
    • Need to decide whether to switch to another challenge

When I practiced this flow at the next CTF, I broke through the same pattern challenge in 3 minutes. Zero time spent hesitating.

zip2john is powerful, but when to use it is the hardest part. More than how to use the tool, the decision of “should I use this tool now” determines victory or defeat in CTF. I hope this article serves as decision-making material for someone out there.


Further Reading

If you’re looking to expand your CTF forensics toolkit beyond ZIP encryption analysis, I’ve compiled a comprehensive guide covering essential tools for file analysis, steganography, and data extraction. You can find the complete overview in CTF Forensics Tools: The Ultimate Guide for Beginners, which walks through the most commonly used utilities in competition scenarios.

ZIP files aren’t the only containers hiding flags in CTF challenges. Image-based steganography is equally common, and understanding how to detect and extract hidden data from visual files can significantly improve your solve rate. For techniques on embedding and retrieving concealed information from image files, check out steghide in CTF: How to Hide and Extract Data, which covers practical steganography workflows I’ve used in real competitions.

Another frequent pattern in forensics challenges involves QR codes and barcodes embedded in images or documents. When you encounter these, knowing how to quickly decode them can save valuable time during a CTF. My article zbarimg in CTF: QR/Barcode Decoding Techniques and Common Challenge Patterns demonstrates the decision-making process for handling encoded visual data.

PNG files also appear regularly in CTF challenges, often with corrupted headers or manipulated chunk structures designed to test your understanding of file formats. If you need to verify PNG integrity or repair broken image files, I recommend reading pngcheck in CTF: How to Analyze and Repair PNG Files, which covers the diagnostic approaches that have helped me identify file corruption during time-pressured competitions.

For additional forensics tools and techniques beyond what’s covered here, explore the full collection at alsavaudomila.com, where I document hands-on CTF experiences with various analysis utilities.

Leave a Reply

Your email address will not be published. Required fields are marked *