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.
The Vagrantfile in the ansible/
folder is used for local testing only (to ensure your ansible playbook does not contain any syntax errors before running them with packer on a paid VM).
This setup combines a lot of other services/repositories.
- Engine: EnoEngine
- Checker Library: enochecker
- Registration Page/Scoreboard: EnoLandingPage
- Moloch (Traffic Analysis): EnoMoloch
- ELK (Log Analysis): EnoELK
- 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
- Create
./terraform/terraform.tfvars
:
hcloud_token = "..."
ovh_dyndns_password = "..."
- Initialize terraform:
(cd terraform; terraform init)
- Generate wireguard configs for the internal network
(cd ./config/internal_router; ./gen_keys.sh $CHECKERS_COUNT)
- Generate wireguard configs for the game network
(cd ./config/wireguard_router; ./gen_keys.sh $TEAMS_COUNT)
- Generate passwords for the vulnboxes:
(cd ./config/passwords; ./gen_passwords.sh $TEAMS_COUNT)
- Create SSH keys for router -> moloch
(ssh-keygen -t ed25519 -f ./config/moloch_keys/moloch_key -C "tcpdump@router")
- Build images
export HCLOUD_TOKEN="..."
(cd packer; packer build bambichecker.json)
(cd packer; packer build bambiengine.json)
(cd packer; packer build bambirouter.json)
(cd packer; packer build bambivulnbox.json)
(cd packer; packer build bambielk.json)
- Have at least one ssh key with the label
type=admin
in your project (HETZNER's WEBSITE) - Set
HCLOUD_TOKEN
andHETZNERDNS_TOKEN
- Create
./ansible/config_bambi.yml
- 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
) - Build configs
cd /bambictf/config
./gen_config.sh
- Ship everything to the EnoCTFPortal:
cp -r ./export/ /services/EnoCTFPortal/data/teamdata
(or whereever it is)
- Builds VMs
cd /bambictf/packer
packer 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
- set
vpn_floating_ip_only = false
- set
internal_floating_ip_only = false
- set
cd /bambictf/terraform
terraform init
terraform 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; done
TODO ask Lucas about loops and stuff