Monday, October 5, 2026

Mapping AWS credential permissions with enumerate-iam

Mapping AWS credential permissions with enumerate-iam

Inside enumerate-iam: how it brute-forces get* and list* AWS API calls to reveal exactly which IAM permissions a credential set carries, built for authorized cloud security assessments.

Toolandresriancho/enumerate-iam — Python tool that brute-forces non-destructive AWS API calls to enumerate the permissions attached to a credential set
CategoryCloud security / IAM permission enumeration (Python)
Primary UseDetermining which AWS API actions an access-key/secret-key pair (optionally with a session_token) can perform, by testing only get* and list* calls during authorized assessments
Safe UseIntended for authorized penetration tests, cloud security audits of accounts you own or have written permission to test, and defensive research into credential exposure
Telemetry NoteGenerates a high volume of read-only API calls across many AWS services, producing dense CloudTrail event patterns (numerous Get*/List* calls from one principal) that defenders can alert on as credential-enumeration behavior

When an assessor recovers a set of AWS credentials — whether from a leaked .env file, a CI runner, or a compromised instance profile — the immediate operational question is not how the credentials were obtained but what they can actually do. AWS provides no simple API to answer this for an arbitrary credential, because a principal's effective permissions are the product of IAM policies, resource policies, permission boundaries, and SCPs evaluated at request time. enumerate-iam, written by andresriancho (the author behind w3af), answers the question empirically: it probes the AWS control plane directly and reports which calls succeed. The project sits at roughly 1,260 stars on GitHub, is written in Python, and ships under a GPL-3.0 license, which signals a mature, community-vetted codebase rather than a weekend experiment.

The core technique is best described as permission brute-forcing through non-destructive discovery. The tool's README is explicit that only get* and list* API calls are ever performed, which is an important design decision from both a safety and a stealth perspective: read-only enumeration cannot mutate or destroy resources in the target account, and the call inventory is generated from AWS's own SDK documentation rather than hand-curated guesses. The sample output in the README shows the shape of the results — lines like sqs.list_queues() worked!, cloudformation.list_stack_sets() worked!, and directconnect.describe_locations() worked!, each representing a confirmed permission rather than an inferred one.

The most consequential finding the tool can produce is illustrated right at the top of the README's example output: get_account_authorization_details worked!. In an authorized engagement, that single line changes the scope of the assessment entirely, because GetAccountAuthorizationDetails returns the full IAM configuration of the account — users, groups, roles, and inline managed policies — effectively collapsing the enumeration problem into a single structured dump. The log message the tool prints for it (Run for the hills) is a fitting editorial comment on how much visibility that one call grants an assessor holding the credential.

Installation follows the standard pattern for a small Python project: clone the repository and install dependencies with pip install -r requirements.txt. There are no packaged binaries or Docker images advertised in the README, which keeps the footprint minimal and the dependency surface inspectable. Invocation takes the credential material directly as arguments (--access-key and --secret-key, with --session-token supported through the library API for role-based temporary credentials), so operators running it during an engagement should be mindful of shell history and process lists when handling live key material.

What elevates enumerate-iam above a simple script is its dual nature as a library. The README documents the import path — from enumerate_iam.main import enumerate_iam — with a four-argument signature of access_key, secret_key, session_token, and region, returning the full enumeration results as a native Python dictionary. This makes it straightforward to embed into larger assessment frameworks, reporting pipelines, or automated cloud-audit tooling, rather than parsing log lines. The author explicitly cites the lack of programmatic output in prior tools as a motivation for writing this one, alongside incomplete API coverage and poor performance at scale.

That performance concern is addressed with threads, per the README's list of improvements over the original gist by darkarnium from which the project evolved. Enumerating hundreds of API endpoints sequentially across dozens of AWS services would be intolerably slow; concurrent probing collapses that wall-clock time dramatically. The other listed improvements — a complete refactoring, improved logging, and increased API call coverage — read like a checklist of everything that separates a maintainable tool from a one-off proof of concept.

The refresh mechanism is arguably the most architecturally interesting part of the project. The full inventory of calls to test lives in enumerate_iam/bruteforce_tests.py, and that file is itself generated by enumerate_iam/generate_bruteforce_tests.py, which parses the API documentation embedded in the aws-sdk-js repository. Because AWS ships new services every quarter, the README instructs users to periodically clone aws-sdk-js, run the generator, and remove the clone afterward. This documentation-as-source approach means the tool's coverage is bounded only by AWS's own published SDK surface, not by the author's manual upkeep — a pattern other cloud tooling would do well to copy.

The README also situates the tool in a research lineage: it was released as part of the Black Hat USA 2019 presentation on Internet-Scale Analysis of AWS Cognito Security, alongside cc-lambda, a companion tool for extracting information from Common Crawl data. That context matters for understanding the intended audience. The research examined how Cognito-issued credentials behave in the wild, and enumerate-iam was the instrument for characterizing what those credentials could reach. It is, by design, an analyst's tool for authorized research and assessment.

From a defensive standpoint, the same properties that make the tool useful to assessors make it highly visible to monitoring. A run generates a broad fan of read-only calls across unrelated services — gamelift, cloudformation, directconnect, sqs — from a single identity in a short window. CloudTrail records every one of these, and detection engineering teams can build reliable behavioral alerts around exactly this signature: high cardinality of distinct Get*/List* events across services from one principal, especially when the service mix is exotic relative to that principal's normal baseline. Credential-enumeration tooling of this class is, in practice, one of the easiest attack-adjacent behaviors to detect in a mature AWS logging setup.

Where enumerate-iam fits in an authorized workflow is early post-compromise scoping: after validating that a credential is live, before deciding which resources warrant deeper review. Its read-only guarantee means it can be run against production accounts during sanctioned assessments with low risk of disruption, though operators should still coordinate, because even List calls against sensitive services can trigger alerts or, in edge cases, application-side webhooks. It is not a privilege-escalation tool — it escalates nothing and modifies nothing — it is a measurement instrument that converts an opaque credential into a concrete permission inventory.

The honest caveats are the ones inherent to black-box probing. The tool reports which calls succeeded, not why, so explicit Allow statements and silent default-deny failures look adjacent in the output; effective permissions mediated by resource conditions or Deny overrides on specific ARNs may be mischaracterized as absent. Coverage also depends on keeping bruteforce_tests.py regenerated against the current aws-sdk-js documentation, so a stale checkout will silently miss newer services. Neither caveat undermines the tool's value — they simply define what it is: a fast, safe, library-friendly way to turn unknown AWS credentials into an actionable permission map, which is exactly the first question every cloud security team should be able to answer.

Official project repository for andresriancho/enumerate-iam.
Download Tool

Educational analysis for authorized security professionals. Use only in controlled, authorized environments.

Share articleFacebookXLinkedIn

Continue exploring

Browse all articles →

0 comentários:

Post a Comment

Note: Only a member of this blog may post a comment.