This repository contains the gameserver we used to organize our first attack-defense CTF - saarCTF 2020. If you want to build your own CTF with this framework: contact us for additional explanations.
This CTF infrastructure was build in a two-years-effort by @MarkusBauer, with additional contributions by Jonas Bushart, Patrick Schmelzeisen, Niklas Beierl, and Simon Einzinger.
- Central databases: PostgresSQL, Redis, RabbitMQ
- Central gameserver (folder
controlserver): Tick timer, dispatches checker scripts, calculate ranking and create scoreboard - Checker script workers (folder
checker_runner): Run the checker scripts - Submission Server: Accept flags from the participants
- VPN Server: Wireguard/OpenVPN servers for each team with additional monitoring / IPTables controller / tcpdump.
- Setup a PostgreSQL database, a redis database and a RabbitMQ server (see below).
make depsnpm install && npm run build- Write
config.yaml(see config.sample.yaml) alembic upgrade head
Scoreboard and submission server need additional setup:
- cd scoreboard
- npm install && npm run build
- Flag submission server build instructions
export FLASK_APP=controlserver/app.py is required for most commands. So is either run.sh or . venv/bin/activate.
- Main server:
flask run --host=0.0.0.0 - Celery worker:
celery -A checker_runner.celery_cmd worker -Ofair -E -Q celery,tests,broadcast --concurrency=16 --hostname=ident@%h - Celery control panel:
celery -A checker_runner.celery_cmd flower --port=5555
# Warning: Binds to all interfaces by default!
apt install rabbitmq-server
rabbitmqctl add_vhost saarctf
rabbitmqctl add_user saarctf 123456789
rabbitmqctl set_permissions -p saarctf saarctf '.*' '.*' '.*'
rabbitmqctl set_user_tags saarctf administrator
rabbitmq-plugins enable rabbitmq_management
systemctl restart rabbitmq-serverRepeat if necessary.
Current format: SAAR\{[A-Za-z0-9-_]{32}\}.
Example: SAAR{8VHsWgEACAD-_wAAfQScbWZat3KXyYe9}
controlserver: The main components (timer, scoreboard, scoring, dispatcher, ...)checker_runner: The celery worker code running the checker scriptsgamelib
To test, copy config.sample.yaml to config.yaml and adjust if needed.
To deploy, you can use environment variables:
SAARCTF_CONFIGpath to config.json fileSAARCTF_CONFIG_DIRfolder where config.json is located, and additional files will be stored (VPN config, VPN secrets etc). Default: root of this repository.- Set
SAARCTF_NO_RLIMITif you have to run checkers without limit (e.g. Chromium)
The formulas to compute offensive/defensive/SLA scores are on the webpage,
including a description of the details.
On the gameserver side, there are several factors you can use to adjust scores (all in config.json "scoring":{...}):
nop_team_id: you cannot submit flags from this teamflags_rounds_valid(default 10) more ticks means a bigger initial peak for new exploits, less ticks mean more time pressureoff_factorscale offensive points up/down by this factordef_factorscale defensive points up/down by this factorsla_factorscale SLA points up/down by this factor Note that the defensive score formula contains a reference to SLA points, thus, thesla_factoralso influences defensive scores.
Suggestions for saarCTF are default settings (1/10/1.0/1.0/1.0). Suggestions for our small workshop are (0/20/2.5/1.5/1.0).
We support enochecker services in alpha state. How? Configure a service like this:
checker_timeout: your tick time (at least 60 seconds with current code)checker_runner:eno:EnoCheckerRunneror a subclassrunner_config:{"url": "http://localhost:5008"}checker_subprocess: falsechecker_script_dir: emptychecker_script: empty
Set as usual:
flag_ids:['custom', 'custom', ...]for every putflag that uses attack_infonum_payloads: number of flag variantsflags_per_tick: number of flag variants
Checkout config.sample.yaml, section runner.
Please have enough celery workers available, we suggest teams*services.
For type checking do make check.
To prepare unit tests, copy config.sample.json to config.test.json and configure:
- an empty postgresql database (will be wiped during tests)
- an empty redis database
- a working rabbitmq connection
Then you can do make tests.
The docker setup is more or less proof-of-concept, we run things bare-metal.
There are many more things implemented here, for example VPN / network handling, which require additional setup.
Also, there are many utilities (in /scripts) which might help you with typical situations.
Most of the stuff has little documentation so far.