CCT2019 — for1
A multi-stage forensics challenge involving EXIF analysis, ZIP extraction, steganography, and Enigma machine decryption.
01 Challenge Overview
We're given a JPEG image and told to extract hidden information. The challenge involves multiple layers of obfuscation: EXIF metadata, embedded ZIP archives, steganography, and finally Enigma cipher decryption.
02 Stage 1: EXIF Metadata Analysis
First, let's identify the file type and examine its metadata:
file for1.jpg
# JPEG image data, JFIF standard 1.01, 514x480, components 3
Running exiftool reveals critical metadata:
Artist : Ed
Copyright : CCT 2019
Description : .--- ..- ... - .- .-- .- .-. -- ..- .--. .-. .. --. .... - ..--..
Author : Ed
The Description field contains Morse code! Decoding it:
.--- ..- ... - .- .-- .- .-. -- ..- .--. .-. .. --. .... - ..--..
→ JUSTAWARMPRIGHTI?
→ JUST A WARM PRIGHTI?
03 Stage 2: StegoVeritas Extraction
Using StegoVeritas to analyze the image for hidden data:
stegoveritas for1.jpg
StegoVeritas discovers trailing data appended after the JPEG end-of-file marker. This data is a ZIP archive:
Trailing Data Discovered... Saving
The extraction reveals:
7212.zip— An encrypted ZIP archivefakeflag.txt— An empty file (decoy)
04 Stage 3: ZIP Password Cracking
The ZIP file 7212.zip is password-protected. Using the password password (a common default):
unzip 7212.zip
# password: password
Inside fakeflag.txt:
I didn't say it would be easy, Neo. Peer into the Matrix. See what others
cannot and witness the truth. Though I caution that it may be more than what
you expect.
- Morpheus
PW: Z10N0101
05 Stage 4: Steghide Extraction
Using the password from Stage 3 with steghide on the original image:
steghide extract -sf for1.jpg
Enter passphrase: Z10N0101
wrote extracted data to "archive.zip"
Steghide successfully extracts a hidden ZIP archive from the image using the passphrase Z10N0101.
06 Stage 5: Second ZIP Extraction
unzip archive.zip
# password: 0ni0n_0f_0bfu5c@ti0n
This extracts three files:
cipher.txt— The ciphertextconfig.txt— Enigma machine configurationflag.zip— The final encrypted ZIP
07 Stage 6: Enigma Machine Decryption
The Configuration
config.txt contains the Enigma machine settings:
C G. VI VII VIII. AMTU RING AM BY CH DR EL FX GO IV JN KU PS QT WZ
Parsing this:
- Reflector: C-Thin
- Rotors: Gamma, VI, VII, VIII
- Ring settings: R I N G
- Initial position: AMTU
- Plugboard: AM BY CH DR EL FX GO IV JN KU PS QT WZ
The Ciphertext
cipher.txt:
FSXL PXTH EKYT DJXS PYMO JLAY VPRP VO
Per the challenge update, replace with:
JHSL PGLW YSQO DQVL PFAO TPCY KPUD TF
Decryption Script
from enigma.machine import EnigmaMachine
import enigma.plugboard
enigma.plugboard.MAX_PAIRS = 13
machine = EnigmaMachine.from_key_sheet(
rotors='Gamma VI VII VIII',
reflector='C-Thin',
ring_settings='R I N G',
plugboard_settings='AM BY CH DR EL FX GO IV JN KU PS QT WZ')
machine.set_display('AMTU')
ciphertext = 'JHSL PGLW YSQO DQVL PFAO TPCY KPUD TF'.replace(' ', '')
plaintext = machine.process_text(ciphertext)
print(plaintext.lower())
# ctfforensicsisnotrealforensics
The decrypted text is: ctfforensicsisnotrealforensics
flag.zip archive.
08 Stage 7: Final Flag Extraction
unzip flag.zip
# password: ctfforensicsisnotrealforensics
cat flag.txt
# CCT{flag}
09 Key Takeaways
- EXIF metadata — Always check image metadata for hidden messages (Morse code, base64, etc.)
- Trailing data — Data appended after JPEG EOF markers can contain entire archives
- Steghide — Uses passphrases to extract hidden data from images
- Enigma machine — Historical cipher that appears in CTF challenges; use
py-enigmalibrary - Multi-layer challenges — Each stage's output is the key/input for the next stage
- Pop culture references — Movie quotes (The Matrix) can hint at passwords