Skip to content

JO-00/Mini-Local-CTF

Repository files navigation

🚩 Mini-Local-CTF Platform

A lightweight CTF (Capture The Flag) platform built with Node.js, Express, and Docker

This platform allows admins to dynamically add challenges and manages interactive environments using Docker


✨ Key Features

Multi-User Isolation

The platform handles high-concurrency environments through Docker orchestration.

  • Unique Instances: When multiple users connect to the same challenge port simultaneously, the system spawns independent containers with different ids

limitation: planning to constraint containers to a fixed amount of ressources and auto-cleanup after a certain time of inactivity in the future

  • Port Consistency: Users connect via a single designated port (e.g., 8001), but their session is isolated from others

note that each challenge has only one port for it, but that one port forks new processes

Admin Control Center

  • Dynamic Insertion: Add challenges on the fly without restarting the Node.js server.
  • Automated Validation: Depending whether the challenge is selected to be interactive or not in the admin panel, the challenge directory is checked to see if the required minimal files exist or not, otherwise the challenge isn't approved to be added

➕ Adding Challenges

here the filesystem is the source of the truth, adding a challenge requires the following steps:

1. Prepare the Directory

Place your challenge files in the appropriate category folder. For an Interactive (Docker) challenge:

  • Path: challenges/[category]/[name]/
  • Required Files:
    • Dockerfile
    • entrypoint.sh
    • start_instance.sh
    • challenge_files/flag.txt (The platform reads this to sync the DB flag)

Note that for a non Interactive Challenge, only challenge_files/flag.txt is required to exist

2. Use the Admin Panel ( add : name,category,points,description, etc )


🛠️ flow of interactive challenges

The orchestrator.sh script manages all the interactive challenges, builds the images once, and listens and forwards data bidirectionally to the correspondant challenge by relying on a challenge_configs.json to map a given port to a certain challenge

Then [category]/[challenge_name]/start_instance.sh runs a new independent container with a random id and communicates with entrypoint.sh

entrypoint.sh is simply responsible of forwarding in and out traffic inside the container only


🛠️ Tech Stack

  • Backend: Node.js & Express
  • Database: SQLite3 (Local file-based)
  • Containerization: Docker & Bash Orchestration
  • Templating: EJS (Embedded JavaScript)

🛠️ Setup & Prerequisites

1. Requirements

Ensure you have the following installed on your Linux/WSL environment:

  • Node.js (v18+)
  • Docker & Build-essential (for SQLite)
  • jq (for JSON parsing in scripts)

2. Quick Start & Testing Isolation

To launch the platform and verify that the "Spawn-on-Connection" isolation is working correctly, follow these steps:

  • A. Start the CTF Engine Ensure your scripts have the correct permissions and launch the main entry point:
# Set execution bits
chmod +x start_ctf.sh

# Launch Web Server + Orchestrator
./start_ctf.sh
  • B. Verify Multi-User Isolation

To confirm that the orchestrator is correctly spawning independent, isolated environments for every connection, perform a "Parallel Connection Test":

  1. Open Terminal Window A: Run nc localhost 8001
  2. Open Terminal Window B: Run nc localhost 8001

About

Lightweight, scalable CTF infrastructure. Container and Database and user management, and on-demand Dockerized sandboxing

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages