Skip to content

Commit 8c769b8

Browse files
committed
added some writeups and docs
1 parent dab13d1 commit 8c769b8

File tree

6 files changed

+1200
-0
lines changed

6 files changed

+1200
-0
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
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.

content/posts/Tulip_Setup.md

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
---
2+
date: '2024-04-19T12:00:00Z'
3+
draft: false
4+
title: 'Tulip setup for A/D CTFs'
5+
summary: "Tulip is a traffic analyzer tool made for A/D CTFs, this post walks you throught all the important steps requied to deploy Tulip painlessly (hopefully)."
6+
7+
categories:
8+
- docs
9+
keywords:
10+
- attack-defense
11+
- infra
12+
author: bhackari
13+
---
14+
15+
# Setup tulip on the VM
16+
17+
### Tulip specific configurations
18+
19+
Clone the repo
20+
```
21+
$ git clone https://github.com/OpenAttackDefenseTools/tulip.git
22+
$ cd tulip
23+
```
24+
25+
---
26+
27+
Edit `services/api/configurations.py` with the correct `tick_length`, `start_date`, `vm_ip`, and the `services`
28+
29+
---
30+
31+
```
32+
$ cp .env.example .env
33+
```
34+
35+
edit `.env` with the correct `FLAG_REGEX`, `TICK_START`, `TICK_LENGTH` and
36+
change `TRAFFIC_DIR_HOST` to point to the correct folder containing the pcaps (in our case `/ready_pcaps`)
37+
38+
---
39+
40+
If you want tulip to listen on a different port (e.g. port 4444) edit `docker-compose.yml`
41+
and under the `frontend` service change
42+
```yml
43+
ports:
44+
- "3000:3000"
45+
```
46+
to
47+
```yml
48+
ports:
49+
- "4444:3000"
50+
```
51+
52+
**WARNING:**
53+
(if you host tulip on the vulnbox and don't change the web interface port you risk other teams to steal flags throght tulip. Yep, they know tulip default port is 3000)
54+
55+
---
56+
57+
```
58+
$ docker compose up -d --build
59+
```
60+
61+
Tulip is now running.
62+
63+
---
64+
65+
### Packet capturing
66+
67+
Save these scripts:
68+
69+
`/create-pcap.sh`
70+
```bash
71+
#!/bin/sh
72+
# -i game : game is the wireguard network interface, change it as needed
73+
74+
mkdir -p /pcaps
75+
mkdir -p /ready_pcaps
76+
chmod 777 /pcaps
77+
chmod 777 /ready_pcaps
78+
79+
tcpdump -G 120 -w /pcaps/myfile-%Y-%m-%d_%H.%M.%S.pcap -i game -z '/post-rotate.sh' port not 22
80+
```
81+
82+
`/post-rotate.sh`
83+
```bash
84+
#!/bin/sh
85+
mkdir -p /ready_pcaps/
86+
mv $1 /ready_pcaps/
87+
```
88+
89+
Then disable the apparmor profile for tcpdump
90+
```
91+
$ apt install apparmor-utils
92+
$ aa-complain /usr/bin/tcpdump
93+
```
94+
95+
Now in a tmux or screen:
96+
```
97+
$ chmod +x /create-pcap.sh
98+
$ chmod +x /post-rotate.sh
99+
$ /create-pcap.sh
100+
```
101+
102+
While `create-pcap.sh` is running, `ready_pcaps` will be populated with the network pcaps and
103+
Tulip will show them on the web interface.s
104+
105+
---
106+
# Setup Tulip on a dedicated VPS
107+
108+
## On the vps
109+
110+
Clone the repo
111+
```
112+
$ git clone https://github.com/OpenAttackDefenseTools/tulip.git
113+
$ cd tulip
114+
```
115+
116+
---
117+
118+
Edit `services/api/configurations.py` with the correct `tick_length`, `start_date`, `vm_ip`, and the `services`
119+
120+
---
121+
122+
```
123+
$ cp .env.example .env
124+
```
125+
126+
edit `.env` with the correct `FLAG_REGEX`, `TICK_START` and `TICK_LENGTH`
127+
128+
---
129+
130+
If you want tulip to only listen on `localhost:3000` instead of `0.0.0.0:3000`, then edit `docker-compose.yml`
131+
and under the `frontend` service change
132+
```yml
133+
ports:
134+
- "3000:3000"
135+
```
136+
to
137+
```yml
138+
ports:
139+
- "127.0.0.1:3000:3000"
140+
```
141+
142+
---
143+
144+
```
145+
$ docker compose up -d --build
146+
```
147+
148+
Tulip is now running.
149+
150+
---
151+
152+
## On the vulnbox
153+
154+
Save these scripts:
155+
156+
`/create-pcap.sh`
157+
```bash
158+
#!/bin/sh
159+
# -i game : game is the wireguard network interface, change it as needed
160+
161+
mkdir -p /pcaps
162+
mkdir -p /ready_pcaps
163+
chmod 777 /pcaps
164+
chmod 777 /ready_pcaps
165+
166+
tcpdump -G 120 -w /pcaps/myfile-%Y-%m-%d_%H.%M.%S.pcap -i game -z '/post-rotate.sh' port not 22
167+
```
168+
169+
`/post-rotate.sh`
170+
```bash
171+
#!/bin/sh
172+
mkdir -p /ready_pcaps/
173+
mv $1 /ready_pcaps/
174+
```
175+
176+
Then disable the apparmor profile for tcpdump
177+
```
178+
$ apt install apparmor-utils
179+
$ aa-complain /usr/bin/tcpdump
180+
```
181+
182+
Now in a tmux or screen:
183+
```
184+
$ chmod +x /create-pcap.sh
185+
$ chmod +x /post-rotate.sh
186+
$ /create-pcap.sh
187+
```
188+
189+
While `create-pcap.sh` is running, `ready_pcaps` will be populated with the network pcaps.
190+
191+
---
192+
193+
## Send pcaps to tulip
194+
195+
The last thing is to send the pcaps to tulip, there are two ways to do it :
196+
- 1: The vps has ssh access to the vulnbox, and can scp the pcaps
197+
- 2: The vps is not in the vpn, so no access to the vulnbox. In this case the vulnbox will have ssh access to the vps (this could be hardened)
198+
199+
---
200+
201+
### `Case 1`:
202+
First create an ssh key in the vps and add it in the vulbox.
203+
Then, on the vps save the script `take-pcap.sh`:
204+
```bash
205+
#!/usr/bin/bash
206+
207+
IP_VULNBOX=10.32.55.2
208+
209+
while true
210+
do
211+
rsync -avz --remove-source-files root@$IP_VULNBOX:/ready_pcaps/* CHANGE_ME_TRAFFIC_DIR_HOST
212+
sleep 10 # tweak this as you like
213+
done
214+
```
215+
216+
Now open a tmux and run this script, tulip will receive the pcaps.
217+
218+
---
219+
220+
### `Case 2`:
221+
First create an ssh key in the vulnbox and add it in the vps.
222+
Then, on the vulnbox save the script `take-pcap.sh`:
223+
```bash
224+
#!/usr/bin/bash
225+
226+
IP_VPS=10.32.55.2 # remember to change this
227+
228+
while true
229+
do
230+
rsync -avz --remove-source-files /ready_pcaps/* root@$IP_VPS:CHANGE_ME_TRAFFIC_DIR_HOST
231+
sleep 10 # tweak this as you like
232+
done
233+
```
234+
235+
Now open a tmux and run this script, tulip will receive the pcaps.
236+
237+
---
238+
239+
`CHANGE_ME_TRAFFIC_DIR_HOST` is the absolute path to the `TRAFFIC_DIR_HOST` value in the `.env` you wrote when configuring tulip.

0 commit comments

Comments
 (0)