|
| 1 | +--- |
| 2 | +date: '2024-04-19T12:01:00Z' |
| 3 | +draft: false |
| 4 | +title: 'DestructiveFarm setup for A/D CTFs' |
| 5 | +summary: "DestructiveFarm is a popular tool used in CTFs and |
| 6 | +what it does is running exploits every tick to retrieve flags and |
| 7 | +automatically submit them to the checker." |
| 8 | + |
| 9 | +categories: |
| 10 | + - docs |
| 11 | +keywords: |
| 12 | + - attack-defense |
| 13 | + - infra |
| 14 | +author: bhackari |
| 15 | +--- |
| 16 | + |
| 17 | +# Setup the submitter (server) |
| 18 | + |
| 19 | +The submitter is the tool that collects flags from [farm clients](#setup-an-exploit-farm-client), 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. |
| 20 | + |
| 21 | +Clone the repo on a local server or on a dedicated VPS and enter the server direcrory |
| 22 | +``` |
| 23 | +$ git clone https://github.com/DestructiveVoice/DestructiveFarm |
| 24 | +$ cd DestructiveFarm/server/ |
| 25 | +``` |
| 26 | + |
| 27 | +--- |
| 28 | + |
| 29 | +### Submitter general configuration |
| 30 | + |
| 31 | +Edit `config.py` according to the rules of your specific competition |
| 32 | +- `TEAMS` ip addresses of all the teams (generated using a format string) |
| 33 | +- `FLAG_FORMAT` the regex the server will use to identify the flags in the traffic generated by the exploits |
| 34 | +- `SUBMIT_FLAG_LIMIT` max number of flag the server will try to send in a `SUBMIT_PERIOD` |
| 35 | +- `FLAG_LIFETIME` flags older than this period, not yet sent, will be discarded |
| 36 | +- `SERVER_PASSWORD` password to access the front-end control page of the submitter |
| 37 | +. |
| 38 | +- `SYSTEM_PROTOCOL` the name of your protocol (see [Protocols](#protocols)) |
| 39 | +- `SYSTEM_HOST` IP address of the flag checker (only for TCP protocols) |
| 40 | +- `SYSTEM_URL` URL of the flag checker (only for HTTP protocols) |
| 41 | +- `SYSTEM_PORT` port number used by the flag checker for incoming traffic |
| 42 | +- `SYSTEM_TOKEN` authentication token (only for HTTP protocols) |
| 43 | + |
| 44 | +--- |
| 45 | + |
| 46 | +### Protocols |
| 47 | + |
| 48 | +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. |
| 49 | + |
| 50 | +The comunication protocols usually are either based on a `HTTP` session or a simple `TCP` connection. |
| 51 | +The folder `protocols/` already contains 4 examples of both cases pulled from real competitions. |
| 52 | +You need to make one specific for your competition. |
| 53 | + |
| 54 | +Regardless of the type of the connection, first you need to map all the possible server response to a `FlagStatus`. |
| 55 | +``` |
| 56 | +RESPONSES = { |
| 57 | + FlagStatus.QUEUED: ['timeout', 'game not started', 'try again later','game over', 'is not up', 'no such flag'], |
| 58 | + FlagStatus.ACCEPTED: ['accepted', 'congrat'], |
| 59 | + FlagStatus.REJECTED: ['bad', 'wrong', 'expired', 'unknown', 'your own', 'too old', 'not in database', 'already submitted','invalid flag'], |
| 60 | +} |
| 61 | +``` |
| 62 | +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. |
| 63 | + |
| 64 | +Destructive Farm will invoke your function whenever its needed. |
| 65 | + |
| 66 | +**HINT:** |
| 67 | +Most protocols are very similar, copy one of the examples and adapt it to your competition |
| 68 | + |
| 69 | +--- |
| 70 | + |
| 71 | +### Running the submitter |
| 72 | + |
| 73 | +Once everything is set up you can run the server by running: |
| 74 | +``` |
| 75 | +$ ./start_server.sh |
| 76 | +``` |
| 77 | +This script can be edited to change the port used by the service by addding `--port=1234`. |
| 78 | +By default Flask will use port `5000` |
| 79 | + |
| 80 | +DestructiveFarm maintains persistence in the file `flags.sqlite`. |
| 81 | +Deleting the file will result in the removal of all flags collected up to this point. |
| 82 | + |
| 83 | +--- |
| 84 | + |
| 85 | +# Setup the farm client |
| 86 | + |
| 87 | +A farm client is a tool that periodically runs the exploit to attack other teams and looks after their work. |
| 88 | +It can be run by each participant on their laptop after they've written an exploit. |
| 89 | + |
| 90 | +Clone the same repo on the client that will run the exploit and enter the **client** folder |
| 91 | +``` |
| 92 | +$ git clone https://github.com/DestructiveVoice/DestructiveFarm |
| 93 | +$ cd DestructiveFarm/client/ |
| 94 | +``` |
| 95 | + |
| 96 | +--- |
| 97 | + |
| 98 | +### The exploit |
| 99 | + |
| 100 | +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. |
| 101 | + |
| 102 | +The first argument can be retrieved with `sys.argv[1]` |
| 103 | + |
| 104 | +You should find an example called `spl_example.py` from where you can start to build your own. |
| 105 | + |
| 106 | +--- |
| 107 | + |
| 108 | +### The client |
| 109 | + |
| 110 | +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](#submitter-general-configuration). |
| 111 | + |
| 112 | +The only 2 parameters required by the client are the **name of the expoit** and the **address** of the submitter [server](#setup-the-submitter-server) (the same address and port you use to reach the front-end) |
| 113 | + |
| 114 | +``` |
| 115 | +./start_sploit.py my_exploit.py -u serverAddress.com:5000 |
| 116 | +``` |
| 117 | + |
| 118 | +The system will automatically **extract the flags** from your exploit's output based on the `FLAG_FORMAT` you provided [here](#submitter-general-configuration) and send them to the server. |
| 119 | + |
| 120 | +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. |
0 commit comments