Skip to content

IAM Unauthenticated Enumeration

4 min read Created May 24, 2026 Last updated May 24, 2026

AWS error messages differ between non-existent principals and valid ones that simply lack permissions. This allows confirming whether a username or role exists without any credentials. You only need a valid AWS account to make API calls against the target. The target account logs nothing useful during this phase because the operations happen on resources you control. Use this technique early in an engagement. It works when you have no foothold in the target environment. Map IAM principals before attempting credential attacks.

  • Your own AWS account (any tier) to perform policy-based principal validation
  • Target account ID (obtainable from public S3 buckets, error messages, or OSINT)
  • Wordlist tuned to the target's naming conventions (check their GitHub, job posts)
  • Confirmed user ARNs for credential spray and public key exposure hunting

Error-Based User Enumeration

quiet-riot brute-forces IAM principal names using resource-based policy insertion errors. It runs from your attacker machine and requires its own AWS account to perform the checks. The tool constructs principal ARNs and attaches them to a resource-based policy on a resource in your account. AWS validates principal ARNs at write time. A non-existent principal causes an error. A valid principal causes no error or returns AccessDenied based on your account permissions.

┌──(kali㉿kali)-[~]
└─$ git clone https://github.com/righteousgambit/quiet-riot
┌──(kali㉿kali)-[~]
└─$ cd quiet-riot
┌──(kali㉿kali)-[~]
└─$ python3 -m venv .venv && source .venv/bin/activate
┌──(kali㉿kali)-[~]
└─$ pip install -r requirements.txt
┌──(kali㉿kali)-[~]
└─$ quiet_riot --scan_type 4.2 --wordlist /usr/share/seclists/Usernames/Names/names.txt --threads 30 --profile $PROFILE
Explain command
--scan_type 4.2 Enumerate IAM users only (4 = all principals, 4.1 = roles, 4.2 = users).
--wordlist Wordlist of names to try.
--threads Number of concurrent threads.
┌──(kali㉿kali)-[~]
└─$ quiet_riot --scan_type 4.1 --wordlist wordlist.txt --threads 30 --profile $PROFILE

The tool attempts to insert a test principal ARN into a resource-based policy. A MalformedPolicyDocumentException means the principal does not exist (AWS rejects non-existent principal ARNs in policies). No exception (or AccessDenied) means the principal exists. When you confirm a hit, record the full ARN including the account ID. Users and roles have different attack surfaces. Users can carry long-lived access keys that may be exposed in code repositories or environment variables. Roles require a trust relationship to assume and are targeted via cross-account access or SSRF chains. Prioritize confirmed user ARNs for credential hunting. Check GitHub, GitLab, and public S3 buckets for access keys tied to those usernames.

Note on sts:AssumeRole Error Discrimination

The sts:AssumeRole AccessDenied-vs-NoSuchEntity oracle is no longer reliable. AWS now returns AccessDenied regardless of whether the target role exists. Use the resource-based policy technique via quiet-riot instead. This change affects all tooling that relied on the STS error difference. If a tool or write-up references the STS oracle approach, treat its output as unreliable. The resource-based policy technique is the confirmed working method for unauthenticated principal enumeration.

Wordlists for IAM Enumeration

Common IAM role name patterns to try. Most AWS environments use predictable names tied to their service stack. Prioritize names that match technology you have already identified for the target. If the target uses Terraform, try terraform and terraform-backend. CI/CD pipelines almost always have a dedicated IAM role. GitHub Actions deployments commonly use a role named github-actions or a close variant. Check the target's public GitHub repos, job postings, and LinkedIn to infer naming patterns before running a full wordlist. Service-specific roles follow patterns like ec2-role or lambda-execution-role. Cross-account roles often include words like cross-account, audit, or the partner organization's name.

admin
Administrator
AdminRole
OrganizationAccountAccessRole
ReadOnlyAccess
PowerUserAccess
ec2-role
lambda-role
ecs-task-role
github-actions
deploy
ci-cd
terraform
s3-access
rds-access
cross-account
audit
security
devops

See IAM Authenticated Enumeration for full enumeration once you have credentials. Principal names confirmed here feed directly into that workflow. A confirmed user ARN also reveals the target account ID, which is useful for scoping further attacks. Combine confirmed principals with credential spray, public key exposure checks, or assume-role attempts from other accounts.