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
- ...
- Have at least one ssh key with the label
type=adminin your project (HETZNER's WEBSITE) - Set
HCLOUD_TOKENandHETZNERDNS_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/configgenpoetry install(once)poetry run configgen --teams 4 --routers 2 --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/packerpacker build bambichecker.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.samplefor reference) cd /bambictf/terraformterraform initterraform apply
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; doneTODO ask Lucas about loops and stuff