cd /projects
Active PythonSecurityCTFCryptographyCLI

CTF Toolkit

A batteries-included CLI for capture-the-flag competitions

CTF Toolkit cover

01. Overview

Capture the Flag competitions have a repeating problem: the first 20 minutes of any challenge are spent running the same recon and decoding commands you ran last week. Identify the encoding, decode the layers, check for steganography, fingerprint the cipher, try the common attacks — all before you even get to the interesting part.

This toolkit started as a collection of one-off scripts I kept copy-pasting between CTF directories. Over time it grew into a structured CLI with subcommands for each category, a local SQLite-backed flag tracker, and a templating system for common exploit structures.

02. Feature Set

ctf decode

Detects and recursively strips Base16/32/58/64/85, URL, HTML, and Morse encoding layers.

ctf freq

English frequency analysis and index-of-coincidence test for classical substitution ciphers. Auto-suggests candidate keys for Vigenère.

ctf steg

Wraps zsteg, stegdetect, and custom LSB extraction into a single command. Handles BMP, PNG, WAV.

ctf fmt

Generates format-string exploit templates given offset and target address. Supports 32- and 64-bit.

ctf hash

Identifies hash types with hashid, queries common rainbow table APIs, and optionally dispatches to hashcat with a wordlist.

ctf note

Per-challenge note store backed by SQLite. Track flags, partial solutions, and hints with timestamps.

03. How It Was Built

CLI framework

The toolkit is built with Python's click library, which provides clean subcommand registration, help generation, and type-checked argument parsing. Each category lives in its own module under ctftoolkit/commands/, and the main entry point registers them automatically by scanning the directory — adding a new subcommand is as simple as dropping a new file.

Encoding detection

Automatic encoding identification turned out to be harder than expected. Base64 and Base32 overlap in character set; some Base58-encoded strings look like valid hex. The detection pipeline applies a ranked set of heuristics — character set analysis, length divisibility, padding presence — and confirms each candidate by attempting to decode it and checking if the result is printable ASCII or known binary magic bytes. Layers are unwrapped recursively up to a configurable depth (default: 8).

Steganography pipeline

Rather than reimplement steg tools, the module shells out to installed binaries (zsteg, stegdetect, binwalk) and aggregates their outputs into a structured JSON report. The LSB extractor is native Python using Pillow and handles all common bit-plane orderings that CTF challenge authors tend to use.

Distribution and install

Packaged with pyproject.toml using the Hatchling build backend. Installable from the repo with pip install -e . or as a global tool via pipx install. Optional dependencies (hashcat integration, numpy for signal-processing tasks) are declared as extras.

04. Sample Output

$ ctf decode "U2FsdGVkX1+Vp8..."
Attempting layer 1: base64
✓ base64  →  "Salted__[binary]"
Detected: OpenSSL-encrypted blob (AES-256-CBC)
No further decodable layers. Final output saved to output.bin

$ ctf steg suspicious.png
Running: zsteg, stegdetect, LSB extractor
[zsteg]   b1,r,lsb,xy → "CTF{h1dd3n_1n_pl41n_s1ght}"
[LSB]     RGB planes 0,1,2 — no readable ASCII
✓ Flag candidate found. Logged to challenge notes.

05. Lessons Learned

  • Encoding detection can't be purely heuristic — confirming by attempting a round-trip decode and sanity-checking the output cut false positives from ~30% to under 5%.
  • Shelling out to external tools is fine, but you must handle missing binaries gracefully — not every CTF box has zsteg installed.
  • The note tracker has been the most-used feature in actual competitions. Even simple persistence across terminal sessions is underrated.
  • Packaging with pyproject.toml and publishing to a private PyPI-compatible index (via Cloudflare R2) makes distribution to team members trivial.