This is the setup used in our BambiCTF and ENOWARS competitions.
It uses ansible and packer to prepare images for Hetzner Cloud and terraform to create the infrastructure.
This setup combines a lot of other services/repositories.
- Engine: EnoEngine
- Checker Library: enochecker3
- Registration Page/Scoreboard: EnoCTFPortal
- Arkime (Traffic Analysis): EnoArkime
- ELK (Log Analysis): EnoELK
Due to implementation details, currently you have to be aware of the following limits:
- number of teams: 250
- number of routers: 255
- ...
- [Optional] create a puppetmaster-VM on Hetzner, for shared working/debugging and run everything there
- Have at least one ssh key with the label
type=admin
in your project (HETZNER's WEBSITE) - Set
HCLOUD_TOKEN
andHETZNERDNS_TOKEN
inDockerfile
by including the lines
ENV HETZNERDNS_TOKEN="..."
ENV HCLOUD_TOKEN="..."
- Create
./ansible/config_bambi.yml
vulnerable_services:
WASP: git@github.com:enowars/service-wasp.git
djbooth: git@github.com:enowars/service-DJ_Booth.git
switzerland: git@github.com:enowars/service-switzerland.git
teapot: git@github.com:enowars/service-teapot.git
github_ssh_keys:
- Trolldemorted
- domenukk
- ldruschk
- MMunier
vulnbox_access_time: "2024-07-09T20:00:00"
network_open_time: "2024-07-09T21:00:00"
network_close_time: "2024-07-09T22:00:00"
- Obtain a private ssh ed25519 key that can clone your repositories (
cp ~/.ssh/id_ed25519 .
) - Run the container (
docker compose up -d
) - Invoke a bash in the container (
docker compose exec bambictf bash
) - If you use Windows: Fix the private key permissions with
chmod 400 ./id_ed25519
- Build configs
cd /bambictf/configgen
poetry install
(once)poetry run configgen --teams 6 --routers 2 --checkers 3 --dns test.bambi.ovh
- Ship everything to the EnoCTFPortal:
cp -r ./export/portal /services/EnoCTFPortal/data/teamdata
(or whereever it is)
- Builds VMs
cd /bambictf/packer
packer build bambichecker.json
packer build bambielk.json
packer build bambiengine.json
packer build bambirouter.json
packer build bambivulnbox.json
- Note down vulnbox snapshot id, pass to EnoCTFPortal (
curl -H "Authorization: Bearer $HCLOUD_TOKEN" 'https://api.hetzner.cloud/v1/images?type=snapshot'
) - Create
./terraform/terraform.tfvars
(see./terraform/terraform.tfvars.sample
for reference) cd /bambictf/terraform
terraform init
terraform apply
The time set in ./ansible/config_bambi.yml
should take care. Otherwise call
iptables -A FORWARD -o router -j ACCEPT
(on every gateway)
iptables -A INPUT -i internal -p tcp -m tcp --dport 5001 -j ACCEPT
on engine
iptables -A FORWARD -d 192.168.1.0/32 -i team+ -o internal -p tcp -m tcp --dport 5001 -j ACCEPT
iptables -A FORWARD -d 192.168.1.0/32 -i router -o internal -p tcp -m tcp --dport 5001 -j ACCEPT
on every router
while true; do rsync /services/data/*.json benni@bambi.enoflag.de:/services/EnoCTFPortal_bambi7/scoreboard; sleep 5; done
TODO ask Lucas about loops and stuff
- terraform easily takes 30-60 minutes
- build more configs than you actually expect, to have a safeguard
- to add a new team during the CTF
- increase teamcount in terraform and run
terraform apply
- add new team on EnoEngine
ctf.json
, and reapply config (see there)
- increase teamcount in terraform and run