Platform assessment

Cloud CTF challenges need API surface. Before building anything, it is worth assessing what each hosting option actually provides and where it breaks down.

What cloud challenges require

The attack techniques in scope (IAM privilege escalation, bucket misconfiguration, Lambda credential exfiltration, service account key abuse) all interact with cloud provider APIs. A challenge that cannot provide those APIs teaches tool syntax at best. The participant learns to run a command, not to understand why it works.

At minimum, viable cloud challenge infrastructure needs:

  • An API layer that behaves like the target cloud provider (AWS, GCP, Azure)

  • Per-participant isolation, or at least per-session state that does not bleed across runs

  • Enough compute to run the simulated services without collapse

  • A teardown mechanism that actually fires

Root-Me

Root-Me hosts Docker-based challenges in its Realistic category. A challenge packaged as a Docker Compose file with LocalStack (AWS simulation) is technically submittable.

Viable for:

  • Beginner-tier challenges using S3 and basic IAM (LocalStack basic services run under 1 GB)

  • Network challenges that capture cloud API traffic as PCAP

Not viable for:

  • Multi-service scenarios (LocalStack Pro services, cross-service pivots)

  • GCP or Azure simulation (no equivalent to LocalStack with comparable coverage)

  • Per-participant isolation: Root-Me does not provision separate environments per player

The practical ceiling is one service, one misconfiguration, one flag. That is a reasonable beginner challenge and an unsatisfying intermediate one.

TryHackMe

TryHackMe allocates 0.5-1 GiB RAM and 1 CPU core to uploaded VMs. LocalStack does not fit at any useful level of functionality within those constraints. Cloud simulation on TryHackMe means writing a thin Python mock of an API, which teaches participants to interact with your mock, not with cloud behaviour.

Not viable for cloud CTF challenges beyond cosmetic approximations.

Self-hosted on Hetzner

Hetzner provides root VPS access at low cost with a straightforward API for provisioning and teardown.

A CX22 instance (4 vCPU, 8 GB RAM, around €5-6/month) comfortably runs LocalStack with Pro services enabled, handles CTFd for challenge management, and has headroom for a few simultaneous participants. A CX32 (8 vCPU, 16 GB RAM) handles more concurrent load if challenges are shared rather than isolated.

Per-participant isolation is achievable two ways:

  • Provision a fresh Hetzner instance per participant via the Hetzner Cloud API, run the challenge environment, tear it down after the session or on a timer

  • Run isolated Docker networks per participant on a single host, which is simpler but shares the underlying system

Auto-destroy is straightforward: a systemd timer or a Lambda-equivalent (Hetzner’s own scheduled actions, or a small cron job) tears down the environment after a fixed window.

What this enables that platforms cannot:

  • Realistic multi-service attack chains (Lambda to EC2, GCP SA key to project owner)

  • GCP and Azure simulation alongside AWS

  • State persistence across a session without reboot surprises

  • Full control over what is exposed, what is logged, and what the participant can observe

The cost of self-hosting is setup and maintenance overhead. The benefit is a challenge environment that does not require the participant to mentally translate from “this Docker mock” to “how this actually works”.

Recommendation

Scenario

Option

Beginner single-service challenge for Root-Me

Root-Me Docker with LocalStack

Intermediate or advanced multi-service challenge

Self-hosted Hetzner

TryHackMe cloud challenge

Not recommended

Workshop or team exercise with per-participant isolation

Self-hosted Hetzner with API-provisioned instances

Start with Root-Me for the simpler challenges in the inventory. Build toward Hetzner as the complexity increases. Running both in parallel is reasonable: Root-Me for breadth and discoverability, Hetzner for depth.