Pipeline β what happens when you press β³ Pull & Recon
/api/v1/challenges) lists every challenge with id, name, category, description, connection info and attachments; all files are downloaded. Offline mode instead ingests a folder of per-challenge zips.Automated recon by file type
Any file
filetype + MIME detection, size, tail hex dumpstringsin ASCII, UTF-16LE, UTF-16BE and UTF-32 encodingsexiftoolfull metadata dump (scanned + decoded)binwalksignature sweep across the WHOLE file, not just the header- Embedded/appended file detection + automatic carve (
binwalk -e,foremost) - Magic-byte / header sanity check; corrupted PNGs are auto-repaired and flagged for viewing
- OpenSSL
Salted__detection + decrypt attempts with common CTF passphrases
Images
zsteg -a(PNG/BMP LSB across all channels)steghide extractwith empty password (JPG/BMP/WAV)- Headless stegsolve β every channel Γ bit-plane in both bit orders, extracted and grepped; plane PNGs saved for eyeballing
- QR / barcode decoding (
zbarimg) on the image and on each bit-plane pngcheckchunk validation (finds tampered IHDR/CRC)
Audio
- Spectrogram rendered (
sox) + OCR'd (tesseract) β catches flags drawn in the spectrum - Morse decoded from the amplitude envelope (and from reversed audio)
- PCM sample LSB extraction, both bit orders, per channel
- DTMF tone decoding (Goertzel)
- Reversed-audio spectrogram + re-analysis
Documents
- Office (docx/xlsx/pptx/odt): unzipped, all XML scanned incl.
docProps/custom.xml _rels/*.relsexternal Targets extracted (next-stage URLs)- Embedded media pulled out and recursed for stego
- PDF: text extraction + metadata scan
Archives
- zip/7z/tar/gz/bz2/zst extracted and scanned recursively
- RAR5 via
bsdtar(7z cannot read RAR5) - Encrypted archives detected and reported (never brute forced)
Network captures
tsharkprotocol hierarchy- HTTP requests: methods, hosts, URIs
- Header mining: User-Agent, Cookie, Referer, Authorization, Server (2025's challenge 3 hid base64 in the User-Agent)
- DNS queries (exfiltration channel)
- Plaintext credentials (FTP/HTTP basic/telnet)
--export-objectsfor http/smb/tftp/imf, then recon on everything extracted- TCP stream following (first 20 streams)
Memory dumps
volatility3triage: OS detection, thenpslist,cmdline,filescan,envars,netscan,hashdump,consoles(Windows) orlinux.bashhistory- Strings-first fast path β flags often sit in plaintext in RAM
Git repositories
- Commit messages and author/committer fields (a classic hiding spot)
- Full history diff (
git log -p --all) - Stashes, reflog, all branches and packed-refs (finds unmerged/deleted branches)
- Dangling and unreferenced objects (
git fsck+cat-fileover all blobs)
Disk / filesystem images
sleuthkit: partition table (mmls), recursive file list incl. DELETED files (fls -r), content recovery (icat),fsstat- RAID reconstruction: XOR-rebuild a missing RAID5 member across surviving disks, plus RAID0 concat (
raid_rebuild.py) foremost/photoreccarving fallback;testdiskfor partition repair
Hidden document content
- White / near-white / background-coloured text,
vanishruns, tiny font sizes - Cropped images: the full original is extracted (crop only hides it visually) β hit in both 2023 and 2025
- PDF: text layer regardless of colour, embedded images pulled out
Web targets
- Core:
robots.txt,sitemap.xml,security.txt,.htaccess(opt-in deep list adds .env/.git/backups/swagger/admin⦠via CTF_WEB_DEEP) - Follows robots.txt Disallow entries, sitemap URLs and page links, then probes
.bak/.old/~/.savevariants of each - Scans headers, cookies (JWT/base64 decoded), and every HTML comment
- Reports credentials left in page source or JS
- Reports any 200/401/403/500 that differs from the homepage baseline, and all redirects
Decoders (applied recursively, automatically)
Bases
base64, base64url, base32, base45 (RFC 9285), base58, base62, base85, ascii85, base91
Numeric
hex, binary, octal (escapes + triplets), decimal char codes
Substitution
all 25 Caesar rotations, ROT47, Atbash, Affine (all 312 valid keys), reversed text, frequency-shift guess
Keyed
VigenΓ¨re β including a known-plaintext crib attack: because flags start with a fixed prefix, a flag-shaped token reveals the key (this is exactly NZCSC 2024's Substitute Teacher). Keys that the crib cannot verify are reported as notes, never auto-submitted.
Transposition
Rail fence (2β10 rails)
Classical
Bacon, tap code, T9 keypad, NATO phonetic, Morse
Esoteric
Brainfuck (interpreted), JSFuck / JJEncode / AAEncode detection with the decode command
Stego in text
Zero-width Unicode (ZWSP/ZWNJ), trailing-whitespace stego
Other
single-byte XOR (all 255 keys), URL-decode, HTML entities
Layering
All of the above are applied recursively until a flag appears or the decodings are exhausted β so hex β base91 β text or base64 β Caesar chains resolve automatically. Successfully-reversed encodings are always explored another layer, even when the intermediate looks like noise.
Tools installed for agents
Stego / images
steghide, outguess, stegseek, zsteg, zbarimg (QR), ImageMagick, pngcheck, tesseract (OCR), Pillow (bit-planes)
Forensics
binwalk, foremost, exiftool, volatility3, tshark/Wireshark CLI, sleuthkit (mmls/fls/icat), testdisk/photorec, RAID rebuild, bsdtar, 7z, qpdf, poppler
Wireless / cracking
aircrack-ng (WPA handshakes + wordlist), john (zip2john/pdf2john), hash length-extension (hashext.py)
Reverse engineering
Ghidra 12 headless (auto-decompiles every function to C), radare2, objdump, gdb, strings/xxd; monodis for .NET IL (full ILSpy on-demand)
Crypto
pycryptodome, openssl, gpg, python (sympy-free RSA maths), the decoder library above
Pwn
pwntools (incl. cyclic), gdb, python
Web / network
curl, requests, sqlmap, nmap, node (JS evaluation), WebFetch
Cracking
john the ripper (with zip2john/pdf2john) β used only with wordlists found inside the challenge; blind brute force is prohibited
Audio
sox, ffmpeg, numpy (DSP: morse envelope, DTMF Goertzel, sample LSB)
What the AI agents can do
- Internet access β follow links, fetch external URLs, download files, read JS, chase multi-stage challenges across hosts
- Vision β agents can open and actually look at images: photos, spectrograms, extracted bit-planes, repaired PNGs, QR codes
- Full shell on the server inside the toolchain container (root β can apt/pip install anything mid-event)
- Ghidra headless decompilation, and the ability to write and run exploit scripts
- Post findings and queue flags to the shared board, and check whether a challenge is already solved
- Install anything on demand β root + internet in the container, so agents can
pip install/apt-get install/ build from source whatever a challenge needs (this is separate from the CTFd offline gate)
Operating rules
- Agents never ask questions β they act autonomously and work around problems.
- No brute forcing. Password/flag/keyspace guessing is prohibited; it is never the intended solution and risks lockout. Enumerating documented ID ranges (IDOR) and completing a cipher key from known plaintext are not brute force.
- Challenges are treated as completely unrelated to each other.
- Flags are queued, never submitted directly by agents β the submitter owns the rate-limit budget.
- Malformed flags are rejected locally so they never consume a submission slot.
Everything above runs on the server inside the ctf-kit container.
Recon is deliberately layered: the pure-python fast lane always runs first and cannot hang, and every
external tool is timeout-wrapped and isolated, so a single broken tool can never take down the run.