{
	"id": "6ef76da5-9a50-4222-a859-c4b0ce9fc081",
	"created_at": "2026-04-06T00:08:36.462161Z",
	"updated_at": "2026-04-10T03:19:59.621431Z",
	"deleted_at": null,
	"sha1_hash": "cd95188f829a766b60b482dbcff5e0c10a0a1fdb",
	"title": "Assume the Worst: Enumerating AWS Roles through ‘AssumeRole’ - Rhino Security Labs",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 583367,
	"plain_text": "Assume the Worst: Enumerating AWS Roles through\r\n‘AssumeRole’ - Rhino Security Labs\r\nBy Spencer Gietzen\r\nPublished: 2018-08-29 · Archived: 2026-04-05 23:43:27 UTC\r\nDisclaimer: As always, use Pacu and similar AWS pentesting tools responsibly.\r\nOnly test against your own AWS accounts, or those you are authorized for.\r\nIntroduction: AWS IAM Roles\r\nAmazon Web Services (AWS) IAM roles are sets of permissions that serve as a common way to delegate access to\r\nusers or services. Roles can be bestowed to internal and external IAM users, AWS services, applications, and even\r\nexternal user accounts outside of AWS. Roles leveraged by users enable additional permissions for certain tasks.\r\nApplications using roles gain the access needed to transact with AWS services without the need to permanently\r\nembed an AWS key. Anytime additional access needs to be temporarily granted, IAM roles are a common go-to\r\nsolution.\r\nAssuming IAM roles is the process of obtaining the set of permissions designated by the role, along with the\r\ncorresponding temporary credentials. When an entity assumes a role, the Security Token Service (STS) issues a\r\nset of role credentials which serve as a security token to access the environment. Assuming a role can occur via\r\nthe AWS Management Console, or programmatically via PowerShell, the AWS CLI, or the SDK’s for various\r\nprogramming languages. For more granular control, additional policies can also be applied to the request to\r\nfurther limit the role permissions. Requests made after the role is assumed are performed with this new identity,\r\nalthough CloudTrail logs can be used to discern the underlying entity.\r\nAWS Account ID Exposure\r\nAWS account IDs uniquely identify every AWS account and are more sensitive than you might think. While\r\ndivulging the ID does not directly expose an account to compromise, an attacker can leverage this information in\r\nother attacks. A reasonable effort should be made to keep AWS account IDs private, but in practice, they are often\r\nexposed to the public unintentionally.\r\nAccount IDs are commonly leaked via:\r\nScreenshots\r\nGitHub and other code repositories\r\nMany AWS error messages (even access denied)\r\nPublic EBS snapshots (EC2 -\u003e Snapshots -\u003e Public Snapshots)\r\nPublic AMIs (EC2 -\u003e AMIs -\u003e Public images)\r\nRDS public snapshots (RDS -\u003e Snapshots -\u003e All Public Snapshots)\r\nPeople looking for troubleshooting help online and posting their ID\r\nhttps://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration\r\nPage 1 of 5\n\nIf an attacker has your ID, various attack scenarios become feasible, including resource enumeration (identifying\r\nexisting roles, users, etc.), Lambda function invocation, and IAM role assumption.\r\nThis post — and the accompanying script we have released – address using an AWS account ID to identify\r\nexisting roles. As an extension of this concept, attackers can go a step further and assume misconfigured IAM\r\nroles to gain unauthorized access.\r\nIAM Role Enumeration\r\nAWS verbose error messages disclose whether a role exists or not, allowing us to enumerate role names. During\r\nthe testing process, we identified information leakage in the AWS responses, but we didn’t know if an account\r\nwould be locked out after multiple failed attempts to assume a role. We ultimately discovered that a user could\r\nproduce an arbitrary number of requests, making this enumeration technique highly scalable. It should also be\r\nnoted that if AWS was blocking an account after a certain period, this would make the brute forcing process more\r\ndifficult, but not impossible. By running this attack through a fragmented set of nodes and accounts, an attacker\r\ncan bypass any IP or account-based blocking that may be in effect.\r\nSimply enumerating role names can reveal:\r\nwhich AWS services a company is using internally\r\ninternal software/stacks\r\nnames of IAM users (to target for social engineering)\r\n3rd party integrations being used (which could potentially be targeted separately)\r\nA few common integrations we have observed include CloudSploit, Okta, and Datadog.\r\nOnce roles are enumerated, one can try to assume any open roles and pilfer the role credentials.\r\nIf you try to assume a role that you don’t have permissions to, AWS will output an error similar to:\r\nAn error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::0123456789\r\nThis error message indicates that the role exists, but its assume role policy document does not allow you to\r\nassume it. By running the same command, but targeting a role that does not exist, AWS will return:\r\nAn error occurred (AccessDenied) when calling the AssumeRole operation: Not authorized to perform sts\r\nSurprisingly, this process works cross-account. Given any valid AWS account ID and a well-tailored wordlist, you\r\ncan enumerate the account’s existing roles without restrictions.\r\nHijacking Misconfigured Roles\r\nLike other AWS IAM policies, the AssumeRole permissions are very flexible and, if misconfigured, could lead to\r\nunintended consequences.  For example, if the access role “AWS”: “*” is associated and any user from any\r\naccount may be able to assume the role (given that they have the correct AWS Account ID and Role Name).\r\nhttps://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration\r\nPage 2 of 5\n\nWhile this is the non-default state and a relatively rare occurrence, we’ve identified (and properly reported)\r\nupwards of 50 instances of accounts with global permissions for AssumeRole.\r\nA poorly configured AssumeRole policy that allows any authenticated AWS user to assume it and retrieve\r\ntemporary credentials.\r\nAWS 'AssumeRole' Enumeration Script\r\nWe have created a standalone script to allow you to enumerate roles against a target account. By default, it comes\r\nwith a 1100+ word wordlist with some common/generic role names. When a role is discovered, the script will\r\nalert you. If one is discovered and it is misconfigured to allow role-assumption from a wide group, the script is\r\ncapable of automatically assuming the discovered role and outputting the issued credentials.\r\nThe script has just been released on GitHub. Pacu — the AWS exploitation framework — now also contains this\r\nfunctionality with a dedicated module.\r\nAll that is required is the account ID of your target account – they are all over the internet.\r\nUsage: assume_role_enum.py [-h] [-p PROFILE] [-w WORD_LIST] -i ACCOUNT_ID\r\nNote: The keys used must have the “sts:AssumeRole” permission on any resource (*) to be able to assume a\r\nmisconfigured role. Lacking this permission, roles can still be identified, but not assumed.\r\nOptional arguments:\r\n -h, --help show this help message and exit\r\n -p PROFILE, --profile PROFILE\r\nhttps://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration\r\nPage 3 of 5\n\nThe AWS CLI profile to use for making API calls. This\r\n is usually stored under ~/.aws/credentials. You will\r\n be prompted by default.\r\n -w WORD_LIST, --word-list WORD_LIST\r\n File path to a different word list to use. There is a\r\n default word list with 1100+ words. The word list\r\n should contain words, one on each line, to use to try\r\n and guess IAM role names. Role names ARE case-\r\n sensitive.\r\n -i ACCOUNT_ID, --account-id ACCOUNT_ID\r\n The AWS account ID of the target account (12 numeric\r\n characters).\r\nThe following screenshot demonstrates the tool in use in a mock environment. It begins enumerating roles and\r\nfinds the restricted roles named “5” and “ADS”, as well as a misconfigured role named “APIGateway”. The script\r\ntries to assume the role for a minimum of one hour, then assumes it and displays the JSON-formatted role\r\ncredentials. A summary of the results are then displayed.\r\nhttps://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration\r\nPage 4 of 5\n\nDemonstrating using the script to successfully enumerate and assume a role. The issued role credentials are then\r\ndisplayed.\r\nIn addition to our default list of known users and roles to look for, check out this list that Daniel Grzelak (@dagrz)\r\ncreated, which includes many known 3rd party integrations.\r\nPrevention\r\nUnless AWS reduces the verbosity of the error messages returned after a failed role assumption, attackers will be\r\nable to enumerate role names using this method. Thankfully, mitigating an attack of this nature simply involves\r\navoiding a few simple configuration errors.\r\nThree actionable steps to take to protect your environment:\r\n1. Require strict AssumeRole policies that specifically list only the AWS service or IAM user/account that\r\nneeds the additional access\r\n2. Don’t use common, guessable names for your AWS resources\r\n3. Avoid exposing your AWS account ID to the public\r\nThis bruteforcing technique and script will generate a large amount of “iam:AssumeRole” CloudTrail logs in the\r\naccount you are using for enumeration. Any account you target will not see anything in their CloudTrail logs until\r\nyou successfully assume a misconfigured role, so that means enumeration is completely log-free on the target\r\naccount.\r\nConclusion\r\nAssuming IAM roles in AWS is a common option for delegating permissions, but when improperly configured,\r\nthis functionality can expose an AWS account to potential compromise.\r\nThe standalone enumeration script that automates this process is now available on GitHub.\r\nIf you are interested in leveraging other common AWS misconfigurations, try out Pacu – the open source AWS\r\nexploitation framework — which incorporates this script as a dedicated module, called “enum_assume_role”.\r\nIf you need a safe, inexpensive AWS infrastructure to test out these new tools, consider CloudGoat — the\r\nvulnerable-by-design AWS environment.\r\nSpecial thanks to Henry Hang for some great insight during our research into this enumeration method.\r\nSource: https://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration\r\nhttps://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration\r\nPage 5 of 5",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration"
	],
	"report_names": [
		"assume-worst-aws-assume-role-enumeration"
	],
	"threat_actors": [],
	"ts_created_at": 1775434116,
	"ts_updated_at": 1775791199,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/cd95188f829a766b60b482dbcff5e0c10a0a1fdb.pdf",
		"text": "https://archive.orkl.eu/cd95188f829a766b60b482dbcff5e0c10a0a1fdb.txt",
		"img": "https://archive.orkl.eu/cd95188f829a766b60b482dbcff5e0c10a0a1fdb.jpg"
	}
}