CloudGoat: Learning Cloud Penetration Testing by Breaking Things on Purpose
Hook
Most cloud security tools help you lock down infrastructure. CloudGoat does the opposite: it deliberately deploys vulnerable AWS and Azure resources so you can learn to exploit them. With over 3,500 stars, it's become the de facto training ground for cloud penetration testers.
Context
Cloud security training has a practical problem: you can't practice exploiting real vulnerabilities without either breaking production systems or spending weeks building your own vulnerable lab. Traditional cybersecurity training relied on intentionally vulnerable applications like DVWA or WebGoat, but these never adequately covered cloud-specific attack vectors like IAM privilege escalation, S3 bucket enumeration, or Lambda function abuse.
Rhino Security Labs, a penetration testing firm specializing in cloud security, built CloudGoat to solve this gap. Rather than documenting theoretical attack patterns, they needed a way to train their own staff and the broader security community on actual cloud exploitation techniques. The tool emerged from their internal needs: a repeatable, safe way to deploy realistic vulnerable environments that mirror the misconfigurations they encounter during real engagements. CloudGoat isn't about teaching you to write exploits—it's about understanding how cloud services interact, where trust boundaries fail, and how attackers chain seemingly minor misconfigurations into full account compromise.
Technical Insight
CloudGoat's architecture is surprisingly straightforward: it's a Python CLI wrapper around Terraform modules, each representing a distinct penetration testing scenario. When you deploy a scenario, CloudGoat generates a Terraform configuration, provisions AWS or Azure resources, and returns credentials or endpoints you'll use as your initial foothold. The genius is in what it doesn't do—rather than building custom provisioning logic, it leverages Terraform's state management and industry-standard cloud APIs.
Each scenario lives in its own directory under the scenarios/ folder, containing Terraform files and a markdown walkthrough. For example, the 'iam_privesc_by_rollback' scenario creates an AWS environment where an attacker can exploit IAM policy version rollback to escalate privileges. The Terraform code creates actual IAM users, roles, and policies with specific misconfigurations:
# CloudGoat command to deploy a scenario
./cloudgoat.py create iam_privesc_by_rollback
# Output includes credentials for initial access
# IAM User: chris
# Access Key ID: AKIAIOSFODNN7EXAMPLE
# Secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
# Now you use AWS CLI to enumerate and exploit
aws iam list-attached-user-policies --user-name chris
aws iam list-policy-versions --policy-arn arn:aws:iam::123456789:policy/cg-policy
aws iam get-policy-version --policy-arn arn:aws:iam::123456789:policy/cg-policy --version-id v1
# Discover that v1 has AdministratorAccess, current version doesn't
aws iam set-default-policy-version --policy-arn arn:aws:iam::123456789:policy/cg-policy --version-id v1
# Privilege escalation complete
The tool maintains a local SQLite database tracking deployed scenarios, their Terraform state files, and metadata. This state management is critical—CloudGoat needs to remember what resources belong to which scenario so cleanup doesn't leave orphaned EC2 instances running up your AWS bill. When you run ./cloudgoat.py destroy <scenario_name>, it calls terraform destroy using the preserved state.
What makes CloudGoat particularly effective for learning is the progression of scenario complexity. 'iam_privesc_by_rollback' is relatively straightforward—enumerate policies, spot the misconfiguration, exploit. But scenarios like 'rce_web_app_defender' require multiple steps: exploit SSRF to access EC2 metadata, extract IAM credentials, enumerate Lambda functions, discover code injection vulnerabilities, and pivot to additional resources. Each scenario teaches specific attack patterns you'll encounter in real penetration tests.
The multi-cloud support reveals CloudGoat's modular design philosophy. AWS scenarios live in scenarios/aws/, Azure scenarios in scenarios/azure/, each with provider-specific Terraform configurations. Adding a new scenario means creating a new Terraform module and registering it in CloudGoat's scenario manifest. The Python CLI handles scenario listing, creation, destruction, and configuration management, but the actual cloud resources and their misconfigurations are pure Infrastructure as Code.
# Listing available scenarios
./cloudgoat.py list scenarios
# CloudGoat outputs:
# cloud_breach_s3 - Exploit S3 bucket misconfigurations
# ec2_ssrf - Server-Side Request Forgery to metadata service
# iam_privesc_by_attachment - Privilege escalation via policy attachment
# lambda_privesc - Exploiting Lambda execution roles
# rce_web_app_defender - Multi-stage attack chain
This Terraform-first approach has significant pedagogical benefits. Learners aren't just running exploits against a black box—they can examine the actual IAM policies, security group rules, and resource configurations that create vulnerabilities. You're learning what misconfigurations look like in Infrastructure as Code, which directly translates to recognizing problems in real Terraform repositories during security reviews.
Gotcha
CloudGoat's Windows incompatibility is more than a minor inconvenience—it's a complete blocker for Windows users without WSL2. The tool relies on bash scripts and Unix path conventions that don't translate cleanly. If your penetration testing workstation runs Windows natively, you'll need to set up WSL2 or use a Linux VM, adding friction to getting started.
The bigger operational gotcha is resource management during active exploitation. CloudGoat tracks only the initial Terraform-deployed resources. When you're working through a scenario and create additional resources as part of your attack chain—launching new EC2 instances, creating Lambda functions, or uploading files to S3—CloudGoat won't know about these. Running destroy will remove the original scenario infrastructure but leave your manually-created resources running. You need to manually clean up anything you created during exploitation, or accept surprise AWS bills. The tool warns about this limitation, but it's easy to forget in the heat of working through a complex attack scenario. More fundamentally, running CloudGoat requires absolute discipline about environment isolation. These are genuinely vulnerable resources. Deploy 'cloud_breach_s3' in a production AWS account, and you've just created an intentionally public S3 bucket containing sensitive-looking data. Use a dedicated sandbox account with billing alerts and no connection to production infrastructure—period.
Verdict
Use CloudGoat if you're preparing for offensive cloud security roles, studying for certifications like OSCP or the AWS Security Specialty with a penetration testing focus, or training security teams on real-world cloud attack patterns. It's invaluable for moving beyond theoretical knowledge to hands-on exploitation skills, and the Terraform-based scenarios teach you to recognize vulnerable IaC patterns. The tool shines when you have a dedicated AWS or Azure sandbox account and the discipline to follow recommended safety practices. Skip it if you're looking for defensive security tools, don't have access to isolated cloud accounts for testing, or need Windows-native tooling. Also avoid CloudGoat if you're just starting with cloud services—these scenarios assume foundational AWS/Azure knowledge and focus on exploitation rather than basic administration. If you're learning cloud security from a defensive posture first, start with AWS Well-Architected Framework or Azure Security Benchmark, then return to CloudGoat when you're ready to think like an attacker.