Skip to content

About

tools for speedrunning CTFs

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

CTF Toolbox

Self-hosted, browser-based workbench for solving CTFs — by hand, automatically, or driven by an AI agent.
One ./ctf up, one dashboard, every tool with a web GUI.

🇬🇧 English · 🇮🇹 Italiano

CI Docker Compose Ports 19000+, localhost REST + MCP License: MIT


CTF Toolbox is a Docker Compose stack with the tools people actually use during a Capture The Flag — steganalysis, forensics, encoding/crypto, web, OSINT, reversing, password cracking — each with a web interface, behind a dashboard that lists them by phase of work.

At its core is StegSuite, an analysis workbench that takes the challenge files, runs 84 analyzers recursively, hunts the flag, cracks what is locked and tells you how it got there. It works per CTF: create the event, drop in its challenges, let the autosolver take the easy ones and keep working on the rest — yourself, or through an AI agent connected over MCP.

Contents

✨ Features

  • Ready on start — ./ctf up creates .env, starts the core, waits until StegSuite is healthy and prints where to go.
  • One CTF = one project — a CTF holds its challenges and its flag format; a flag in that format marks the challenge solved; a scoreboard shows them all.
  • Autosolver — analyzes every unsolved challenge, a few at a time.
  • 84 analyzers, recursive: metadata, strings/encodings/esolangs, image stego (LSB, steghide, outguess, zsteg…), OCR/QR, audio (spectrogram, morse, DTMF, SSTV, WAV LSB/levels), network (tshark, TLS with keys/keylog, streams, DNS tunnels), archives/office/email/git, ELF.
  • Cracking built in — ZIP (ZipCrypto + AES via hashcat), PDF, steghide, known-plaintext (bkcrack), wordlists smallest → largest, rules and masks.
  • Explains the solution — every flag comes with the chain of files that led to it and the tool output that shows it; Markdown report (EN/IT) and an AI transcript to continue by hand.
  • API-first — everything the GUI does is a REST endpoint; the same surface is an MCP server for AI agents.
  • Isolated — everything on 127.0.0.1, ports 19000+ from .env, heavy tools behind Compose profiles, the reversing sandbox has no internet.

🚀 Quick start

git clone https://github.com/dexRand/ctf-docker.git
cd ctf-docker
./ctf up
[*] Attendo che StegSuite sia pronto.... ok

  Pronto. Da qui:
    Dashboard   http://localhost:19001/
    StegSuite   http://localhost:19014/     crea una CTF e trascina gli allegati
    API         http://localhost:19014/api/docs
    IA (MCP)    ./ctf mcp

The first start builds StegSuite once (a few minutes). Add tools with profiles, e.g. ./ctf up web rev (ZAP + reversing sandbox). ./ctf urls lists everything.

🧭 How it works

flowchart LR
  you([You]) -->|browser| dash[Homepage dashboard]
  you -->|browser| ss[StegSuite GUI]
  agent([AI agent]) -->|MCP| api
  cli([./ctf scan / scripts]) -->|REST| api
  ss --> api[StegSuite API]
  api --> pipe[analysis pipeline<br/>84 analyzers · flag hunt · cracking]
  pipe --> data[(./data<br/>projects · files · reports)]
  api --> svc[service catalog]
  svc -.-> tools[CyberChef · ZAP · Wireshark · SageMath ·<br/>SpiderFoot · Whisper · rev sandbox · …]
Loading

StegSuite walks the file tree in discovery order: for each file it runs the analyzers that apply (by type, not by name), stores their output, hunts flags in it, adds extracted files as children and recurses. In auto mode it then cracks locked files with the small wordlists and analyzes what they unlock.

🏁 Working on a CTF

  1. Create the CTF on the StegSuite home: name + flag format (DUCTF{...}, or a regex such as FLAG-[0-9a-f]{8}).
  2. Add challenges: one upload (one or more files) = one challenge, with an optional category. It is analyzed right away.
  3. Autosolve: one click analyzes every open challenge, 2 at a time. A flag in the CTF's format marks the challenge ✓ solved.
  4. Keep going on the open ones: the challenge page shows the file tree, every tool's output, locked files (choose wordlists, rules, mask, or a known plaintext), an embedded terminal in the project folder, the flag route graph, the report and the AI transcript. Re-run any tool on any file, with a password if you found one.

Without a CTF, the home page still takes files and analyzes them as a single project (--auto runs everything, --check waits for you before cracking).

🤖 AI agents (MCP)

StegSuite is an MCP server at /api/v1/mcp (Streamable HTTP). With Claude Code:

./ctf mcp      # prints the exact command, e.g.
claude mcp add --transport http ctf http://127.0.0.1:19014/api/v1/mcp

The agent gets 19 tools: create/list CTFs, scoreboard, add challenges (files by URL or base64), autosolve, analyze, status, flags with their route, report, transcript, read a file, run analyzers on a file, locked files, crack, wordlists, edit a challenge, and the list of the other toolbox services (toolbox_services) with their URLs and whether they are up. Typical loop:

create_ctf → add_challenge(start) → project_status … → get_flags
           ↘ no flag: get_transcript → run_tools / crack / read_file

🧰 Tools

Phase Tool URL What it is for Profile
Dashboard Homepage http://localhost:19001 Every tool, grouped by phase, with live status core
Analysis StegSuite http://localhost:19014 CTFs/challenges, 84 analyzers, flag hunt, cracking, reports, REST + MCP core
Analysis Terminal http://localhost:19022 VS Code in the browser (code-server, suite theme) on ./data/projects: file tree, hex editor, PDF/SQLite viewers, asm/smali/solidity syntax, terminals stegsuite (every tool, cdp <project>) and rev (sandbox) · Ctrl+` terminal core
Analysis FileBrowser http://localhost:19012 Browse ./data: projects, extracted files, reports core
Crypto/Encoding CyberChef http://localhost:19002 Base64, XOR, RSA, hashes, JWT and much more core
Web mitmproxy http://localhost:19003 Intercept and rewrite HTTP(S) · proxy on :19004 core
Utility IT-Tools http://localhost:19011 Encoders, converters, hashes, regex core
Recon Dork generator http://localhost:19019 Curated dorks + the Google Hacking Database, from a target (no scraping) core
Web OWASP ZAP http://localhost:19005/zap Web scanner with in-browser GUI · proxy on :19006 · extra add-ons web
Recon SpiderFoot http://localhost:19007/spiderfoot/ OSINT automation recon
Crypto SageMath http://localhost:19010 Jupyter notebooks for crypto and math crypto
Forensics Wireshark http://localhost:19008 Packet analysis with a web GUI forensics
Cracking Hashtopolis http://localhost:19016 Distributed hashcat (agents via voucher) crack
Audio Whisper-WebUI http://localhost:19017 Speech-to-text with timestamps (SRT/VTT) audio
Rev/Pwn rev sandbox http://localhost:19018 Web terminal for ELF/PE/APK: Ghidra headless, radare2, gdb, strace/ltrace, upx, apktool, jadx, pwntools, qemu-user · no internet rev
Rev/Pwn rev workbench http://localhost:19020 Browser workbench: auto report (rev-report), Unicorn emulation + brute (emulate), angr symbolic execution rev

Every upstream image is pinned by digest (tag@sha256:…), so a new machine runs exactly what was tested; python3 tools/pin_images.py shows newer builds and --write updates them. Three images are built locally: StegSuite (app/Dockerfile), ZAP with extra add-ons (zap/Dockerfile) and the rev sandbox (rev/Dockerfile).

🔬 StegSuite

Area Analyzers
Identify / metadata file, exiftool, identify, ffprobe, pdfinfo, pdfid
Text & encodings strings, markup-text (SVG/HTML/XML text nodes), xxd/hexyl/hexdump, decode (base64/32/58/62/85/91/45, hex, binary, rot13 + Caesar/Atbash with a known prefix, A1Z26, URL, quoted-printable, uuencode, Brainfuck/Ook!, high-bit, nested), blobs (base64/hex blocks → files/text), pdftotext, morse-text
PDF & keyboards pdf (encrypted → auto-crack), pdf-images (embedded pictures → OCR), pdf-attachments (embedded files), usb-hid (HID keyboard reports → typed text)
Text stego & esolangs zero-width (ZW chars, two-symbol whitespace, trailing spaces), whitespace (interpreter), case-bits (binary + Bacon), homoglyph, chef (recipes with unknown quantities), sqlite (table text: history, cookies, app data)
Image stego zsteg, lsb-carve, lsb-bits (raw-byte LSB), msb-bits (MSB plane), stepic, psimage, steghide, outguess, jsteg, openstego, png-chunks, png-idat (zstd/deflate IDAT), png-pixels, pixel-bytes (pixels that are another file, chains followed), bit-planes, color-map (few-colour images → distinct colours + index grey), faint (semi-transparent overlays: high-pass + OCR), channel-remap (+ palette-index repaint), image-enhance
Vision ocr (tesseract, EN + IT fallback, denoise + O/0 fixes), qr, gif-frames (frames, diffs, delay bits)
Audio / radio spectrogram, waveform, wav-lsb, wav-levels, morse, dtmf, sstv (Scottie S1/S2), eas (SAME/EAS + AFSK via multimon-ng)
Network pcap (protocols, HTTP/DNS fields, comments, reassembled UDP/TCP streams, base64 split one token per packet, text in source ports, DNS tunnels, DNS tunnels per destination server, evil bit RFC 3514, HTTP objects, TLS with a key or a TLS 1.3 keylog, HTTP/2, query parameters leaked one per request (hex/base64/XOR), Wi-Fi SSIDs decoded), usb-hid (keyboard reports), wpa (handshake to hashcat 22000)
Archives & documents 7z, nested-archive, tar-chain (chains of nested tars, in memory), binwalk (scan/extract), foremost, office (OOXML/ODF + macros), olevba (VBA source + decoded strings), eml, git (history, reflog, every object), disk (sleuthkit: partitions, fls/icat), android-boot (boot.img kernel + ramdisk cpio), ds-store (macOS folder file names, deleted too), openssl (Salted__ + sibling password), cryptojs (U2FsdGVkX1… + the strings of the same file)
Windows evtx (event logs as text, base64 pieces joined into the flag), sam (local hashes + hashcat), winreg (Run/RecentDocs/TypedPaths/UserAssist from a hive), firefox-logins (saved logins via libnss3), GPP cpassword decrypted (in markup-text)
Repair pngcheck, png-repair (chunks), image-repair (JPEG/BMP/GIF headers, junk prefix, BMP height), jpeg-dqt (wiped quantization tables), byte-swap (16/32-bit word-swapped files)
Binaries elf (sections, dynamic info, checksec), readelf, objdump

Flag hunt — every tool output is scanned in several views (raw, UTF-16, URL-decoded, whitespace-collapsed, one level of inline base64/hex, XOR of string pairs) for the common CTF prefixes (picoCTF, flag, CTF, HTB, DUCTF, ictf, tjctf, lactf, SEKAI, …), rot13 twins, OCR-damaged braces, the CTF's own format and an optional global FLAG_PATTERN. Duplicates, rot13 twins and fragments of a longer flag collapse into one.

Cracking — fcrackzip, hashcat (zip2hashcat, ZipCrypto + AES, rules, masks), pdfcrack, stegseek, bkcrack (known plaintext). Wordlists from ./wordlists (mounted), uploads (persisted) and the full rockyou.txt in the image, tried smallest → largest. Auto mode only uses lists ≤ AUTO_CRACK_MAX_MB within AUTO_CRACK_BUDGET_S, so a false "locked" can't stall a challenge. A password hint in a sibling file (psw: …) and the descriptive metadata of the challenge (EXIF/XMP Title, Comment, Author…, PNG text chunks) are tried first, automatically.

GUI — terminal-themed, EN/IT, file tree, per-tool output with ANSI colours, image/audio/video previews, live log (WebSocket), embedded terminal (xterm.js), force-directed graph of the flag route, report and transcript, responsive.

A solved project

🐞 Rev sandbox

Three ways into the same isolated ELF/PE/APK sandbox (profile rev):

  • terminal (:19018) — plain web shell with the tool menu (menu), no internet
  • workbench (:19020) — upload a binary and it runs rev-report automatically; emulate a function with Unicorn (also brute-forcing the first argument) or solve it with angr
  • VS Code (:19022, term) — its rev terminal profile runs docker exec into this sandbox; panes and tabs come from VS Code

Rev workbench

⌨️ CLI

./ctf up [profile…]     # core (+ profiles), waits until ready
./ctf up-all            # every profile (several GB of images)
./ctf down | status | logs <service> | list
./ctf urls              # every service and its URL (ports from .env)
./ctf open <service>    # open in the browser (stegsuite, zap, rev, wireshark…)
./ctf mcp               # connect an AI agent
./ctf pull <url>…       # download challenge attachments into ./data/pull
./ctf scan <file>…      # analyze with StegSuite, print flags (exit 1 on error)
./ctf reports           # browse ./data in FileBrowser
./ctf dork [target]     # dork generator (--update syncs the GHDB)
./ctf geo <photo>…      # photo-geolocate: EXIF/GPS, sun position, OCR, map links
./ctf test [-j 3]       # regression + real CTF challenges (see below)
./ctf ui-smoke          # headless-browser smoke test of the SPA

🔌 API

OpenAPI/Swagger at http://localhost:19014/api/docs; the guide with examples is docs/API.md. Highlights:

CTFs GET/POST /ctfs · GET/PATCH/DELETE /ctfs/{cid} · POST /ctfs/{cid}/challenges · POST/GET/DELETE /ctfs/{cid}/autosolve
Challenges POST /projects · GET/PATCH/DELETE /projects/{pid} · `POST /projects/{pid}/start
Results /findings · /runs · /events · /flags (chain + evidence) · /summary · `/report?format=md
Work POST /projects/{pid}/files/{fid}/run (re-run tools, optional password) · /locked · POST /crack (queued per file) · GET /cracks · DELETE /cracks/{id} · /wordlists
Stateless GET /tools · POST /tools/{tool} (one tool on one file)
Toolbox GET /services (other tools: URL + up) · POST /mcp

A stdlib client lives in tools/stegsuite_client.py.

⚙️ Configuration

Everything comes from .env (created from .env.example on first run).

Variable Purpose
BIND_ADDR Interface every port is published on — default 127.0.0.1 (local only)
*_PORT Host port of each service (19000+); links, dashboard and API follow them
STEGSUITE_API_KEY Require a key on the API/MCP (header, cookie or ?key=)
FLAG_PATTERN Extra global flag regex (a CTF's own format is set per CTF)
MAX_DEPTH, HEAVY_TOOLS, TOOL_WORKERS, MAX_UPLOAD_MB Recursion depth, concurrent heavy tools, analyzers run in parallel per file, upload cap
AUTO_CRACK_MAX_MB, AUTO_CRACK_BUDGET_S, CRACK_BUDGET_S, HASHCAT_RULES Cracking limits and rules
CRACK_WORKERS Manual cracks run at the same time; the rest wait in the crack queue
OCR_LANGS, OCR_EXTRA_LANGS, OCR_MAX_DIM OCR languages and downscaling
RETENTION_DAYS, RATE_LIMIT_RPM, RATE_LIMIT_BURST Auto-delete old projects, per-IP rate limit
MITMWEB_PASSWORD, HASHTOPOLIS_*, PUID/PGID/TZ Other services

Memory: the core runs comfortably with ~4 GB free. The mem_limit caps add up to ~6 GB for the core and ~25 GB with every profile (whisper 6 GB, rev and StegSuite 4 GB each), so start profiles as you need them.

🔒 Security model

  • Local by default: every port is published on 127.0.0.1 (BIND_ADDR). Several tools (ZAP, Wireshark, mitmweb, the dashboard with the Docker socket) have no strong authentication: expose them only on a network you trust.
  • Untrusted files: analyzers run inside the StegSuite container with timeouts that kill the whole process group; git repositories from archives run with their config neutralised; the report renderer escapes everything and keeps only http(s)/same-origin links.
  • Running binaries: only in the rev sandbox — internal network without egress, cap_drop: ALL (+ SYS_PTRACE), no-new-privileges, pid/memory limits.
  • API key (optional) protects REST, WebSockets and MCP; secrets stay in .env (git-ignored) and StegSuite only receives the variables it needs.

🧪 Testing against real CTFs

Every change is checked against real challenges, not only unit tests:

app/tests/run_unit.sh          # 340+ pytest tests inside the StegSuite image
./ctf test -j 3                # 33 fixture cases + 35 real challenges + writeup check
./ctf test -j 3 --extra        # + 45 more real challenges (picoCTF, TJCTF, DUCTF, ImaginaryCTF, WaniCTF, TCP1P…)
./ctf test --only-new --gaps   # known gaps: the backlog of techniques to add
./ctf lint                     # static analysis in containers: ruff, bandit, vulture, jscpd

Real challenges are downloaded from public archives/write-ups (picoCTF, OliCyber/ITS, SekaiCTF, DownUnderCTF, TJCTF, ImaginaryCTF, LA CTF, UIUCTF…) with their documented flags — see docs/CHALLENGES.md. --json-out records per-challenge timings to compare performance.

🩺 Troubleshooting

Symptom Fix
./ctf up waits and StegSuite never answers ./ctf logs stegsuite; first build can take minutes
A tool shows down on the dashboard its profile is not started: ./ctf up <profile>
Port already in use change that *_PORT in .env; links follow automatically
401 from the API STEGSUITE_API_KEY is set: the GUI asks once; scripts read it from .env
SageMath asks for a token ./ctf logs sagemath
mitmweb login password MITMWEB_PASSWORD (default mitm)
Out of memory stop heavy profiles (whisper, rev, forensics), lower HEAVY_TOOLS

📂 Project layout

compose.yaml          services (project "ctf"), profiles, x-base anchor
ctf                   CLI wrapper
.env.example          ports and configuration
app/                  StegSuite: backend/ (FastAPI), frontend/ (Vue 3), tests/, Dockerfile
  backend/analyzers/  one module per analyzer + util.py (shared helpers)
  backend/            pipeline, jobs, flaghunt, crackflow, report, ctfs, mcp_server, api/
config/               homepage dashboard, dork generator, filebrowser, whisper, zap
rev/                  reversing sandbox image (ttyd + Ghidra headless + tools) + rev-report/emulate/angr and the web workbench
zap/                  ZAP image with extra add-ons
tools/                stegsuite_client, scan, check_consistency, dork, photo-geolocate
osint/                separate OSINT area (compose override, own README)
docs/                 API.md, ADDING-A-TOOL.md, CHALLENGES.md, screenshots
tasks/                plans and status

🤝 Contributing

  • New analyzer: docs/ADDING-A-TOOL.md — one module in app/backend/analyzers/, shared helpers from util.py, a unit test, and if possible a real challenge in app/tests/real_challenges.py.
  • New service: update compose.yaml, .env.example, the dashboard (config/homepage/services.yaml), the SERVICES table in ctf, the catalog in app/backend/services.py and this README — python3 tools/check_consistency.py tells you what is missing (CI runs it).
  • Conventions and rules for agents: AGENTS.md.

📄 License

MIT — see LICENSE. The Agent Skills under .opencode/skills/ come from addyosmani/agent-skills (MIT, see .opencode/ATTRIBUTION.md); third_party/zip2hashcat.py keeps its own MIT notice.

About

tools for speedrunning CTFs

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages