Flag submission system for Attack/Defense CTFs.
The server is a Flask web application that uses SQLite as its database engine. It stores flags and sends them periodically to the verification server of the competition. It also provides an easy to use interface that shows some stats and makes it possible to explore the database.
git clone https://github.com/ecavicc/flagWarehouse.git
cd flagWarehouse/server
pip3 install -r requirements.txt
Edit the parameters in config.py
WEB_PASSWORD
: the password to access the web interfaceAPI_TOKEN
: token used for communication between clients and serverTEAM_TOKEN
: token used to submit flagsFLAG_FORMAT
: string containing the regex format of the flagsYOUR_TEAM
: the ip address of your teamTEAMS
: the ip addresses of the teams in the competitionROUND_DURATION
: the duration of a round (or tick) in secondsFLAG_ALIVE
: the number of seconds a flag can be considered validSUB_PROTOCOL
: gameserver submission protocol. Valid values aredummy
(will only print flags on stdout),ccit
andfaust
SUB_LIMIT
: number of flags that can be sent to the organizers' server eachSUB_INTERVAL
SUB_INTERVAL
: interval in seconds for the submission; if the submission round takes more than the number of seconds specified, the background submission loop will not sleepSUB_URL
: the url used for the verification of the flags
There is also the environment variable FLASK_DEBUG
in run.sh: if set, any edit to the source files
(including the configuration file) while the server is running will trigger a restart with the new parameters.
Take note that the submission loop will not be restarted automatically, even in debug mode, so if you need to change
parameters that influence its behaviour, please restart the server manually.
chmod +x run.sh
./run.sh
The web interface can be accessed on port 5000. To log in, use any username and the password you set.
If the password is wrong, the server logger will display a warning containing the username and the password used, as well as the IP from which the request came from.
Given that most CTFs only last some hours and teams are usually not that big, the quickest and least painful approach would be to self host the application and to use ngrok.
If for any reason this approach doesn't suit you, you will need to make some modifications to the source code yourself;
for example, running this app as is on Heroku would probably be a bad idea since it uses SQLite
(here's why), so you'll need to use psycopg2
instead of sqlite3
in
db.py (all the queries should be compatible, though).
For any other modifications, follow the guidelines for Flask deployment of your platform of choice.
- TLDR:
python client.py -s https://dfe6-37-163-128-203.ngrok.io -u USERNAME -t TOKEN -d ./exploits/ -n THREADS
The client is a simple Python script that runs all the programs (both scripts and binaries) in a specific directory. The programs need to run only one time on one target (the target IP address is passed via argv by the client). For a basic template, please refer to example.py.
When it starts, the client automatically fetches the configuration from the server (targets, round duration etc.). When the exploits print something on the standard output, the client reads the output in real time and extracts the flags using the regex fetched from the server; as soon as the flags are found, they are sent (along with other data like the username and the timestamp) to the flagWarehouse server.
Right now, the module requests
is still needed and listed in requirements.txt. In the
future, I might use urllib
in order to avoid external dependencies.
For a list and explanation of the possible options, please refer to the CLI help.
- Attack scripts must have coherent names
- Attack scripts must have
#!/usr/bin/env python
at the beginning - Attack scripts must be executable
- Set
TEAM_TOKEN
YOUR_TEAM
FLAG_FORMAT
SUB_URL
- Strings of verification messages if necessary