Last reviewed

Advanced

Cloud Security Lab Setup

Build vulnerable cloud environments for practicing AWS, Azure, and GCP penetration testing. Learn cloud misconfigurations in a safe, controlled setting.

Cost Warning

Cloud labs incur real costs! Always set billing alerts and destroy resources when not in use. Use free tier where possible and monitor spending closely.

Guardrail Before Deployment

Create a budget alert, verify the caller identity, and confirm the account, subscription, or project contains no production data before deploying any intentionally vulnerable cloud scenario.

Lab Runbook

Use this page as a controlled lab build, not a production hardening guide. Validate isolation before running exercises and write down the cleanup command before starting.

High risk Advanced 1-3 hr

Plan

4 GB local, provider dependent; 20 GB local. Variable. Isolation: Dedicated lab account/subscription/project with budget alerts.

Build

  • - Dedicated cloud account
  • - Billing alerts
  • - Scenario deployment

Validate

  • - Caller identity is the lab account
  • - Budget alerts fire below your limit
  • - CloudTrail or activity logs capture actions

Exercise

Run only the exercises tied to this lab and save screenshots, command output, logs, and timestamps outside disposable VMs.

Clean Up

  • - Run scenario destroy command
  • - Check every enabled region
  • - Review cost explorer before closing session

Vulnerable Cloud Labs

AWS

CloudGoat (AWS)

Rhino Security's "Vulnerable by Design" AWS deployment. Multiple attack scenarios.

  • ✓ IAM privilege escalation
  • ✓ EC2 SSRF to metadata
  • ✓ Lambda exploitation
  • ✓ S3 misconfiguration
GitHub →
Azure

AzureGoat

Vulnerable Azure environment with common misconfigurations.

  • ✓ Storage account exposure
  • ✓ App Service vulnerabilities
  • ✓ Managed Identity abuse
  • ✓ Key Vault misconfig
GitHub →
GCP

GCPGoat

Intentionally vulnerable Google Cloud Platform deployment.

  • ✓ Compute Engine misconfig
  • ✓ Cloud Storage exposure
  • ✓ IAM escalation
  • ✓ Metadata service abuse
GitHub →
K8s

Kubernetes Goat

Interactive Kubernetes security learning platform with 20+ scenarios.

  • ✓ Container escape
  • ✓ RBAC misconfig
  • ✓ Secret exposure
  • ✓ Network policies
GitHub →

CloudGoat Setup (AWS)

Prerequisites

bash
# Install required tools in isolated environments
pipx install awscli
pipx install boto3

# Install Terraform from the official HashiCorp repository or package manager
# Verify the current supported version at developer.hashicorp.com/terraform/install
terraform version

# Configure AWS credentials
aws configure
# Enter: AWS Access Key, Secret Key, Region (us-east-1), Output (json)

# Confirm you are in the dedicated lab account
aws sts get-caller-identity

# Create a low monthly cost guardrail before deployment
aws budgets create-budget   --account-id <account-id>   --budget '{"BudgetName":"LabBudget","BudgetLimit":{"Amount":"25","Unit":"USD"},"TimeUnit":"MONTHLY","BudgetType":"COST"}'   --notifications-with-subscribers file://budget-alert.json
# Install required tools in isolated environments
pipx install awscli
pipx install boto3

# Install Terraform from the official HashiCorp repository or package manager
# Verify the current supported version at developer.hashicorp.com/terraform/install
terraform version

# Configure AWS credentials
aws configure
# Enter: AWS Access Key, Secret Key, Region (us-east-1), Output (json)

# Confirm you are in the dedicated lab account
aws sts get-caller-identity

# Create a low monthly cost guardrail before deployment
aws budgets create-budget   --account-id <account-id>   --budget '{"BudgetName":"LabBudget","BudgetLimit":{"Amount":"25","Unit":"USD"},"TimeUnit":"MONTHLY","BudgetType":"COST"}'   --notifications-with-subscribers file://budget-alert.json

Deploy CloudGoat

bash
# Clone and setup
git clone https://github.com/RhinoSecurityLabs/cloudgoat.git
cd cloudgoat
pip3 install -r requirements.txt
chmod +x cloudgoat.py

# Configure
./cloudgoat.py config profile
./cloudgoat.py config whitelist --auto

# Deploy a scenario
./cloudgoat.py create iam_privesc_by_rollback

# List available scenarios
./cloudgoat.py list all
# Clone and setup
git clone https://github.com/RhinoSecurityLabs/cloudgoat.git
cd cloudgoat
pip3 install -r requirements.txt
chmod +x cloudgoat.py

# Configure
./cloudgoat.py config profile
./cloudgoat.py config whitelist --auto

# Deploy a scenario
./cloudgoat.py create iam_privesc_by_rollback

# List available scenarios
./cloudgoat.py list all

Destroy When Done

bash
# Always destroy resources to avoid charges!
./cloudgoat.py destroy iam_privesc_by_rollback

# Or destroy all scenarios
./cloudgoat.py destroy all
# Always destroy resources to avoid charges!
./cloudgoat.py destroy iam_privesc_by_rollback

# Or destroy all scenarios
./cloudgoat.py destroy all

Local Kubernetes Lab

Free Local Option

Use Minikube or Kind to run Kubernetes locally at no cost. Perfect for learning container security without cloud expenses.

Kubernetes Goat with Minikube

bash
# Install Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# Start cluster
minikube start --driver=docker --memory=4096

# Install Kubernetes Goat
git clone https://github.com/madhuakula/kubernetes-goat.git
cd kubernetes-goat
chmod +x setup-kubernetes-goat.sh
./setup-kubernetes-goat.sh

# Access the dashboard
minikube service kubernetes-goat-home
# Install Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# Start cluster
minikube start --driver=docker --memory=4096

# Install Kubernetes Goat
git clone https://github.com/madhuakula/kubernetes-goat.git
cd kubernetes-goat
chmod +x setup-kubernetes-goat.sh
./setup-kubernetes-goat.sh

# Access the dashboard
minikube service kubernetes-goat-home

Terraform Vulnerable Configs

Deploy specific vulnerable configurations for targeted practice:

S3 Public Bucket

hcl
# main.tf - Vulnerable S3
resource "aws_s3_bucket" "vuln" {
  bucket = "vuln-bucket-${random_id.id.hex}"
}

resource "aws_s3_bucket_public_access_block" "vuln" {
  bucket = aws_s3_bucket.vuln.id
  block_public_acls       = false
  block_public_policy     = false
  ignore_public_acls      = false
  restrict_public_buckets = false
}
# main.tf - Vulnerable S3
resource "aws_s3_bucket" "vuln" {
  bucket = "vuln-bucket-${random_id.id.hex}"
}

resource "aws_s3_bucket_public_access_block" "vuln" {
  bucket = aws_s3_bucket.vuln.id
  block_public_acls       = false
  block_public_policy     = false
  ignore_public_acls      = false
  restrict_public_buckets = false
}

EC2 with IMDS v1

hcl
# main.tf - SSRF-vulnerable EC2
resource "aws_instance" "vuln" {
  ami           = data.aws_ami.amazon_linux.id
  instance_type = "t3.micro"
  
  # Vulnerable: IMDSv1 enabled
  metadata_options {
    http_tokens = "optional"
  }
}
# main.tf - SSRF-vulnerable EC2
resource "aws_instance" "vuln" {
  ami           = data.aws_ami.amazon_linux.id
  instance_type = "t3.micro"
  
  # Vulnerable: IMDSv1 enabled
  metadata_options {
    http_tokens = "optional"
  }
}

SadCloud (NCC Group)

Terraform-based tool that deploys intentionally vulnerable AWS infrastructure covering 22+ services.

bash
# Clone SadCloud
git clone https://github.com/nccgroup/sadcloud.git
cd sadcloud

# Install dependencies
pip install -r requirements.txt

# Deploy specific modules (e.g., vulnerable S3 and IAM)
terraform init
terraform plan -var="s3_public=true" -var="iam_excessive=true"
terraform apply -auto-approve

# ALWAYS destroy when done
terraform destroy -auto-approve
# Clone SadCloud
git clone https://github.com/nccgroup/sadcloud.git
cd sadcloud

# Install dependencies
pip install -r requirements.txt

# Deploy specific modules (e.g., vulnerable S3 and IAM)
terraform init
terraform plan -var="s3_public=true" -var="iam_excessive=true"
terraform apply -auto-approve

# ALWAYS destroy when done
terraform destroy -auto-approve

SadCloud Covers:

• S3 misconfigurations
• EC2/VPC issues
• IAM over-permissioning
• Lambda misconfig
• RDS exposure
• CloudTrail gaps
• ElasticSearch open
• ECS/EKS issues
• SQS/SNS exposure
GitHub: nccgroup/sadcloud →

Detection & Monitoring (Purple Team)

Enable cloud-native detection services to see what your attacks look like from a defender's perspective. This turns your cloud lab into a purple team exercise.

AWS Detection Stack

  • CloudTrail — Enable in all regions, log to S3
  • GuardDuty — Threat detection (free 30-day trial)
  • Security Hub — Centralized security findings
  • AWS Config — Track configuration changes
bash
# Enable CloudTrail (CLI)
aws cloudtrail create-trail \
  --name lab-trail \
  --s3-bucket-name lab-cloudtrail-logs \
  --is-multi-region-trail

aws cloudtrail start-logging --name lab-trail

# Enable GuardDuty
aws guardduty create-detector --enable

# After attacking, check findings:
aws guardduty list-findings --detector-id <ID>
aws cloudtrail lookup-events --lookup-attributes \
  AttributeKey=EventName,AttributeValue=GetSecretValue
# Enable CloudTrail (CLI)
aws cloudtrail create-trail \
  --name lab-trail \
  --s3-bucket-name lab-cloudtrail-logs \
  --is-multi-region-trail

aws cloudtrail start-logging --name lab-trail

# Enable GuardDuty
aws guardduty create-detector --enable

# After attacking, check findings:
aws guardduty list-findings --detector-id <ID>
aws cloudtrail lookup-events --lookup-attributes \
  AttributeKey=EventName,AttributeValue=GetSecretValue

Azure Detection Stack

  • Microsoft Sentinel — Cloud SIEM (free tier available)
  • Entra ID Logs — Sign-in and audit logs
  • Defender for Cloud — Security posture management
  • Activity Log — Management plane operations
bash
# Enable Azure Activity Log diagnostic setting
az monitor diagnostic-settings create \
  --name lab-diag \
  --resource /subscriptions/<sub-id> \
  --logs '[{"category":"Administrative","enabled":true}]' \
  --workspace <log-analytics-id>

# After attacking, query Sentinel:
# SecurityEvent | where EventID == 4625
# AzureActivity | where OperationNameValue contains "vault"
# SigninLogs | where ResultType != 0
# Enable Azure Activity Log diagnostic setting
az monitor diagnostic-settings create \
  --name lab-diag \
  --resource /subscriptions/<sub-id> \
  --logs '[{"category":"Administrative","enabled":true}]' \
  --workspace <log-analytics-id>

# After attacking, query Sentinel:
# SecurityEvent | where EventID == 4625
# AzureActivity | where OperationNameValue contains "vault"
# SigninLogs | where ResultType != 0

Purple Team Workflow

Run your cloud attack (e.g., IAM escalation in CloudGoat), then immediately review CloudTrail logs and GuardDuty findings. Document which attacks generated alerts and which went undetected — this is the core of purple team assessment.

Cost Management Tips

Automated Teardown Script

Create a scheduled reminder or script to destroy resources. Forgotten cloud labs are the #1 cause of surprise bills.

Dedicated Lab Account Only

Do not deploy vulnerable cloud scenarios inside a personal or production account. Use a dedicated account, subscription, or project with no production data, a strict budget alert, and an identity you can disable after the exercise.

Destroy-All Script

bash
#!/bin/bash
# destroy-lab.sh - Run after every practice session
echo "[*] Destroying CloudGoat scenarios..."
cd ~/cloudgoat && ./cloudgoat.py destroy all 2>/dev/null

echo "[*] Destroying Terraform resources..."
for dir in ~/labs/terraform/*/; do
  cd "$dir" && terraform destroy -auto-approve 2>/dev/null
done

echo "[*] Checking for running EC2 instances..."
aws ec2 describe-instances --filters Name=instance-state-name,Values=running \
  --query 'Reservations[].Instances[].InstanceId' --output text

echo "[*] Check your billing dashboard: https://console.aws.amazon.com/billing/"
echo "[!] Done. Verify no resources remain in the AWS console."  
#!/bin/bash
# destroy-lab.sh - Run after every practice session
echo "[*] Destroying CloudGoat scenarios..."
cd ~/cloudgoat && ./cloudgoat.py destroy all 2>/dev/null

echo "[*] Destroying Terraform resources..."
for dir in ~/labs/terraform/*/; do
  cd "$dir" && terraform destroy -auto-approve 2>/dev/null
done

echo "[*] Checking for running EC2 instances..."
aws ec2 describe-instances --filters Name=instance-state-name,Values=running \
  --query 'Reservations[].Instances[].InstanceId' --output text

echo "[*] Check your billing dashboard: https://console.aws.amazon.com/billing/"
echo "[!] Done. Verify no resources remain in the AWS console."  

Set Billing Alerts

Configure alerts at $5, $10, $25 to catch runaway costs early.

Use Free Tier

AWS/Azure/GCP offer free tiers. Stay within limits.

Destroy Resources

Always terraform destroy after practice sessions.

Troubleshooting FAQ

CloudGoat deploy fails with permission errors
  • Ensure your AWS credentials have admin permissions (or at minimum: IAM, EC2, S3, Lambda, RDS)
  • Check AWS region is set: aws configure get region
  • Some scenarios need specific regions — check the scenario README
  • Run aws sts get-caller-identity to verify credentials are working
Terraform state lock or "resource already exists"
  • Force unlock: terraform force-unlock LOCK_ID
  • Import existing resource: terraform import aws_instance.example i-1234567890
  • Nuclear option: delete terraform.tfstate and manually clean up in AWS console
  • Always run terraform destroy before re-deploying
Unexpected cloud charges appeared
  • Run the destroy-all script immediately (see Cost Management section)
  • Check all regions — resources may have been created in non-default regions
  • Review AWS Cost Explorer or Azure Cost Analysis for breakdown
  • Set up billing alerts before deploying any lab resources
  • Contact cloud provider support — they sometimes waive accidental charges for lab/learning use

Operational Safety Baseline

Apply these rules before running any lab command on this page.

  • Work only on systems you own or have explicit authorization to test.
  • Keep vulnerable services off your home LAN and off public interfaces.
  • Take clean snapshots before every exercise and before every vulnerable configuration change.
  • Use dedicated cloud accounts, subscriptions, and projects with billing alerts before deployment.
  • Write down the teardown command before you run the setup command.

Validation Checkpoints

  • -Caller identity is the lab account
  • -Budget alerts fire below your limit
  • -CloudTrail or activity logs capture actions
  • -No resources remain after teardown

Cleanup And Rollback

  • -Run scenario destroy command
  • -Check every enabled region
  • -Review cost explorer before closing session