Skip to main content

CTF Terminal 🚩

ctf-term - A production-ready, cross-platform terminal CTF engine with both CLI and TUI interfaces. Features local SQLite storage, importable challenge packs (YAML), salted-hash flag verification, hint penalties, and live leaderboards.

Created by: Sherin Joseph Roy • Co-Founder & Head of Products at DeepMost AI

Features

  • 🎯 Clean CLI with all essential CTF commands
  • 🖥️ Beautiful TUI built with Textual for keyboard-first navigation
  • 🔒 Secure flag verification using SHA256 salted hashes
  • 📦 Pack System - import challenges from YAML files
  • 🏆 Advanced Leaderboard with hint penalties and first blood bonuses
  • 🩸 First Blood - 10% bonus points for being the first solver
  • 💾 Local Storage - SQLite database with proper indexes
  • 🎨 Rich Output - beautiful terminal tables and formatting
  • 🌗 Themes - dark and light modes (TUI)
  • ⚡ Fast - optimized for low-end machines
  • 🧪 Tested - comprehensive test suite
  • 📊 Challenge Stats - tracking solves, hints, and performance

Quick Start

Installation

pipx install ctf-term

Or from source:

git clone <repo>
cd ctf-term
pipx install .

CLI Usage

# Initialize the app
ctf init

# Import a challenge pack
ctf import-pack ~/.ctf/packs/sample.yml

# List challenges
ctf list
ctf list --category crypto

# Show challenge details
ctf show rot13-hello

# Get a hint (view-only, no penalty yet)
ctf hint alice rot13-hello

# Submit a flag
ctf submit alice rot13-hello flag{flap}

# View leaderboard
ctf scoreboard

# Generate flag hash for pack authors
ctf make-flag-hash "flag{example}" "salt"

TUI Usage

# Launch the interactive TUI
ctf tui

Keyboard Shortcuts:

  • ? / F1 - Help
  • / - Search challenges
  • c - Filter by category
  • u - Switch/create user
  • Enter - Open challenge
  • s - Submit flag
  • h - Show hint
  • g - Go to scoreboard
  • t - Toggle theme
  • Esc - Go back / Close dialogs
  • q - Quit

Pack Authoring

YAML Schema

pack: My CTF Pack
version: 1
challenges:
  - id: unique-challenge-id
    title: Challenge Title
    category: crypto  # crypto, pwn, web, forensics, misc
    description: |
      This is the challenge description.
      Can be multi-line markdown.
    points: 100
    salt: "unique-salt-per-challenge"
    flag_hash: "sha256(salt:flag)"
    hint: "Optional hint text"
    hint_penalty: 20

Creating Flag Hashes

# Method 1: Use the CLI tool
ctf make-flag-hash "flag{my_flag}" "my_salt"

# Method 2: Manual calculation
python3 -c "import hashlib; print(hashlib.sha256(b'my_salt:flag{my_flag}').hexdigest())"

Development Mode

For local testing, you can use flag_plain which will be automatically hashed:

challenges:
  - id: test-challenge
    title: Test Challenge
    category: misc
    description: "Test description"
    points: 50
    salt: "s1"
    flag_plain: "flag{test}"  # Dev only - never commit this!
    hint: "This is a hint"
    hint_penalty: 10

⚠️ Warning: Never commit packs with flag_plain to version control!

Project Structure

ctf-term/
├── src/ctfterm/
│   ├── __init__.py
│   ├── cli.py              # CLI commands
│   ├── db.py               # Database operations
│   ├── model.py            # Data models
│   ├── packs.py            # Pack import/export
│   ├── security.py         # Flag verification
│   ├── paths.py            # Path resolution
│   ├── settings.py         # Settings management
│   ├── __main__.py         # Python module entrypoint
│   ├── tui/                # TUI implementation
│   │   ├── app.py
│   │   ├── router.py
│   │   ├── styles.tcss
│   │   ├── views/
│   │   └── widgets/
│   └── services/           # Business logic
│       ├── challenges.py
│       ├── users.py
│       ├── scoreboard.py
│       └── flags.py
├── tests/                  # Test suite
├── examples/               # Sample packs
└── pyproject.toml

Security

  • Flags are never stored in plaintext
  • Verification uses SHA256(salt:flag) only
  • Database stores salt and flag_hash
  • No network calls - completely offline
  • No dynamic code execution

Development

Setup

git clone <repo>
cd ctf-term
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate
pip install -e ".[dev]"

Running Tests

pytest
pytest --cov=src/ctfterm --cov-report=html

Code Formatting

ruff check src/ tests/
black src/ tests/

Author & Credits

Sherin Joseph Roy

Co-Founder & Head of Products at DeepMost AI

Sherin is an AI entrepreneur and product leader specializing in enterprise AI systems that connect data, automation, and intelligence. With expertise in scalable, human-centered AI solutions, he focuses on bridging research and application to solve real-world challenges.

Connect & Learn More

About DeepMost AI

DeepMost AI builds enterprise AI systems that help organizations think, decide, and grow through intelligent automation and data-driven solutions.

License

MIT License - see LICENSE file

Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new features
  4. Ensure all tests pass
  5. Submit a pull request

Acknowledgments

Built with:

Metadata

Release files for ctf-term 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ctf-term 0.1.0
File Size Uploaded
ctf_term-0.1.0.tar.gz 27.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ctf-term 0.1.0
File Interpreter ABI Platform
ctf_term-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 53.3 kB

Release files / ctf_term-0.1.0.tar.gz

Download URL ctf_term-0.1.0.tar.gz
Size 27.3 kB
Tags Source
SHA-256 checksum
How to use checksums
6c5ec40c80fbf620cae53b849c4ba20aa007643e53cb9985d489cb501fe6b7d3
BLAKE2b-256 checksum
How to use checksums
f96f1e58029e14756d49fde3009e83cacff5a9eb024582619af8709b0369e216
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.8.0 pkginfo/1.12.1.2 readme-renderer/44.0 requests/2.31.0 requests-toolbelt/1.0.0 urllib3/2.0.7 tqdm/4.67.1 importlib-metadata/8.7.0 keyring/25.6.0 rfc3986/2.0.0 colorama/0.4.6 CPython/3.12.3

Release files / ctf_term-0.1.0-py3-none-any.whl

Download URL ctf_term-0.1.0-py3-none-any.whl
Size 26.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
74bd219cda0259055b06c475b699bde8f4c7a97e133ef56b6510b7d08a7eb405
BLAKE2b-256 checksum
How to use checksums
609fb84cdaaf1bdcb7639d8daad74178095e7ddc22ea867f9e658927329dc6a1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.8.0 pkginfo/1.12.1.2 readme-renderer/44.0 requests/2.31.0 requests-toolbelt/1.0.0 urllib3/2.0.7 tqdm/4.67.1 importlib-metadata/8.7.0 keyring/25.6.0 rfc3986/2.0.0 colorama/0.4.6 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page