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 exploits
  • SUBMIT_FLAG_LIMIT max number of flag the server will try to send in a SUBMIT_PERIOD
  • FLAG_LIFETIME flags older than this period, not yet sent, will be discarded
  • SERVER_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 traffic
  • SYSTEM_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.