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 challengesc- Filter by categoryu- Switch/create userEnter- Open challenges- Submit flagh- Show hintg- Go to scoreboardt- Toggle themeEsc- Go back / Close dialogsq- 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
saltandflag_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
- 🌐 Portfolio: sherinjosephroy.link
- 💼 LinkedIn: linkedin.com/in/sherin-roy-deepmost
- 🐦 X (Twitter): @SherinSEF
- 🐘 Mastodon: @sherinjoesphroy
- 💻 GitHub: github.com/Sherin-SEF-AI
- 📧 Contact: sherinjosephroy.link/contact
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:
- Fork the repository
- Create a feature branch
- Add tests for new features
- Ensure all tests pass
- 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)
| File | Size | Uploaded | |
|---|---|---|---|
| ctf_term-0.1.0.tar.gz | 27.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|