Setup the submitter (server)
The submitter is the tool that collects flags from farm clients, sends them to the checksystem, monitors the usage of quotas and shows the stats about the accepted and rejected flags. It is being configured and run by the team’s admin at the start of the competition. After that, team members can use a web interface to watch the exploits’ results and stats.
Clone the repo on a local server or on a dedicated VPS and enter the server direcrory
$ git clone https://github.com/DestructiveVoice/DestructiveFarm
$ cd DestructiveFarm/server/
Submitter general configuration
Edit config.py
according to the rules of your specific competition
TEAMS
ip addresses of all the teams (generated using a format string)FLAG_FORMAT
the regex the server will use to identify the flags in the traffic generated by the exploitsSUBMIT_FLAG_LIMIT
max number of flag the server will try to send in aSUBMIT_PERIOD
FLAG_LIFETIME
flags older than this period, not yet sent, will be discardedSERVER_PASSWORD
password to access the front-end control page of the submitter .SYSTEM_PROTOCOL
the name of your protocol (see Protocols)SYSTEM_HOST
IP address of the flag checker (only for TCP protocols)SYSTEM_URL
URL of the flag checker (only for HTTP protocols)SYSTEM_PORT
port number used by the flag checker for incoming trafficSYSTEM_TOKEN
authentication token (only for HTTP protocols)
Protocols
A protocol defines the interaction standard between the submitter and the flag checker hosted by the competition host. It is specific to the competition and it is usually explicitly outlined in the rules.
The comunication protocols usually are either based on a HTTP
session or a simple TCP
connection.
The folder protocols/
already contains 4 examples of both cases pulled from real competitions.
You need to make one specific for your competition.
Regardless of the type of the connection, first you need to map all the possible server response to a FlagStatus
.
RESPONSES = {
FlagStatus.QUEUED: ['timeout', 'game not started', 'try again later','game over', 'is not up', 'no such flag'],
FlagStatus.ACCEPTED: ['accepted', 'congrat'],
FlagStatus.REJECTED: ['bad', 'wrong', 'expired', 'unknown', 'your own', 'too old', 'not in database', 'already submitted','invalid flag'],
}
After that, the submit_flags(flags, config)
function must be configured to craft a request to the checker for each flag present in the flags
parameter, listen for a response by the server and update the staus of each flag based on the RESPONSES
defined before.
Destructive Farm will invoke your function whenever its needed.
HINT: Most protocols are very similar, copy one of the examples and adapt it to your competition
Running the submitter
Once everything is set up you can run the server by running:
$ ./start_server.sh
This script can be edited to change the port used by the service by addding --port=1234
.
By default Flask will use port 5000
DestructiveFarm maintains persistence in the file flags.sqlite
.
Deleting the file will result in the removal of all flags collected up to this point.
Setup the farm client
A farm client is a tool that periodically runs the exploit to attack other teams and looks after their work. It can be run by each participant on their laptop after they’ve written an exploit.
Clone the same repo on the client that will run the exploit and enter the client folder
$ git clone https://github.com/DestructiveVoice/DestructiveFarm
$ cd DestructiveFarm/client/
The exploit
The exploit is a script that steals flags from some service of other teams. It is written by a participant during the competition and should accept the victim’s host (IP address or domain) as the first command-line argument, attack them and print flags to stdout.
The first argument can be retrieved with sys.argv[1]
You should find an example called spl_example.py
from where you can start to build your own.
The client
The client will be in constant comunication with the server and it will periodically run the exploit providing the address of the victim. The frequency and number of invocations depends on the server configuration shown here.
The only 2 parameters required by the client are the name of the expoit and the address of the submitter server (the same address and port you use to reach the front-end)
./start_sploit.py my_exploit.py -u serverAddress.com:5000
The system will automatically extract the flags from your exploit’s output based on the FLAG_FORMAT
you provided here and send them to the server.
The server will automatically detect duplicates and it will try to submit the flags in multiple occasions until either the state of the flag becomes ACCEPTED
or the lifetime of the flag is exceeded.