IAM Vulnerable is to use Terraform to create your own vulnerable by design AWS IAM privilege escalation playground.. IAM Vulnerable uses the Terraform binary and your AWS credentials to deploy over 250 IAM resources into your selected AWS account. Within minutes, you can start learning how to identify and exploit vulnerable IAM configurations that allow for privilege escalation.
Recommended Approach
Quick Start
This quick start outlines an opinionated approach to getting IAM Vulnerable up and running in your AWS account as quickly as possible. You might have many of these steps already completed, or you might want to tweak things to work with your current configuration. Check out the Other Use Cases section in this repository for some additional configuration options.
aws sts get-caller-identity
.git clone https://github.com/BishopFox/iam-vulnerable
cd iam-vulnerable/
terraform init
export TF_VAR_aws_local_profile=PROFILE_IN_AWS_CREDENTIALS_FILE_IF_OTHER_THAN_DEFAULT
export TF_VAR_aws_local_creds_file=FILE_LOCATION_IF_NON_DEFAULT
terraform plan
terraform apply
cp ~/.aws/credentials ~/.aws/credentials.backup
tail -n +7 aws_credentials_file_example | sed s/111111111111/$(aws sts get-caller-identity | grep Account | awk -F\" '{print $4}')/g >> ~/.aws/credentials
Cleanup
Whenever you want to remove all of the IAM Vulnerable-created resources, you can run these commands:
cd iam-vulnerable/
terraform destroy
What resources were just created?
The Terraform binary just used your default AWS account profile credentials to create:
By default, every role created by this Terraform module is assumable by the user or role you used to run Terraform.
assume_role_policy
ARN, see Other Use Cases.How much is this going to cost?
Deploying IAM vulnerable in its default configuration will cost nothing. See the next section to learn how to enable non-default modules that do incur cost, and how much each module will cost per month if you deploy it.
IAM Vulnerable groups certain resources together in modules. Some of the modules are enabled by default (the ones that don’t have any cost implications), and others are disabled by default (the ones that incur cost if deployed). This way, you can enable specific modules as needed.
For example, when you are ready to play with the exploit paths like ssm:StartSession
that involve resources outside of IAM, you can deploy and tear down these resources on demand by uncommenting the module in the iam-vulnerable/main.tf
file, and re-running terraform apply
:
Uncomment the next four lines to create an ec2 instance and related resources
module “ec2” {
source = “./modules/non-free-resources/ec2”
aws_assume_role_arn = (var.aws_assume_role_arn != “” ? var.aws_assume_role_arn : data.aws_caller_identity.current.arn)
}
After you uncomment the ec2
module, run:
terraform init
terraform apply
You have now deployed the required components to try the SSM privesc paths.
There is no cost to anything deployed within free-resources
:
Name | Default Status | Estimated Cost | Description |
---|---|---|---|
privesc-paths | Enabled | None | Contains all of the IAM privesc paths |
tool-testing | Enabled | None | Contains test cases that evaluate the capabilities of the different IAM privesc tools |
Deploying these additional modules can result in cost:
Name | Default Status | Estimated Cost | Description | Required for |
---|---|---|---|---|
EC2 | Disabled | 💲 $4.50/month | Creates an EC2 instance and a security group that allows SSH from anywhere | ssm-SendCommand ssm-StartSession ec2InstanceConnect-SendSSHPublicKey |
Lambda | Disabled | 🙂 Monthly cost depends on usage (cost should be zero) | Creates a Lambda function | Lambda-EditExistingLambdaFunctionWithRole |
Glue | Disabled | 💲💲💲💲 $4/hour | Creates a Glue dev endpoint | Glue-UpdateExistingGlueDevEndpoint |
SageMaker | Disabled | Not sure yet | Creates a SageMaker notebook | sageMakerCreatePresignedNotebookURL |
CloudFormation | Disabled | 🙂 $0.40/month for the secret created via CloudFormation. Nothing or barely nothing for the stack itself | Creates a CloudFormation stack that creates a secret in secret manager | privesc-cloudFormationUpdateStack |
Supported Privilege Escalation Paths
Path Name | IAM Vulnerable Profile Name | Non-Default Modules Required | Exploitation References |
---|---|---|---|
Category: IAM Permissions on Other Users | |||
IAM-CreateAccessKey | privesc4 | None | 🦊 Well, That Escalated Quickly – Privesc 04 🔒 s3cur3.it IAMVulnerable – Part 3 |
IAM-CreateLoginProfile | privesc5 | None | 🦊 Well, That Escalated Quickly – Privesc 05 🔒 s3cur3.it IAMVulnerable – Part 3 |
IAM-UpdateLoginProfile | privesc6 | None | 🦊 Well, That Escalated Quickly – Privesc 06 🔒 s3cur3.it IAMVulnerable – Part 3 |
Category: PassRole to Service | |||
CloudFormation-PassExistingRoleToCloudFormation | privesc20 | None | 🦊 Well, That Escalated Quickly – Privesc 20 |
CodeBuild-CreateProjectPassRole | privesc-codeBuildProject | None | |
DataPipeline-PassExistingRoleToNewDataPipeline | privesc21 | None | 🦊 Well, That Escalated Quickly – Privesc 21 |
EC2-CreateInstanceWithExistingProfile | privesc3 | None | 🦊 Well, That Escalated Quickly – Privesc 03 🔒 s3cur3.it IAMVulnerable – Part 2 |
Glue-PassExistingRoleToNewGlueDevEndpoint | privesc18 | None | 🦊 Well, That Escalated Quickly – Privesc 18 |
Lambda-PassExistingRoleToNewLambdaThenInvoke | privesc15 | None | 🦊 Well, That Escalated Quickly – Privesc 15 |
Lambda-PassRoleToNewLambdaThenTrigger | privesc16 | None | 🦊 Well, That Escalated Quickly – Privesc 16 |
SageMaker-CreateNotebookPassRole | privesc-sageNotebook | None | 🦏 AWS IAM Privilege Escalation – Method 2 |
SageMaker-CreateTrainingJobPassRole | privesc-sageTraining | None | |
SageMaker-CreateProcessingJobPassRole | privesc-sageProcessing | None | |
Category: Permissions on Policies | |||
IAM-AddUserToGroup | privesc13 | None | 🦊 Well, That Escalated Quickly – Privesc 13 |
IAM-AttachGroupPolicy | privesc8 | None | 🦊 Well, That Escalated Quickly – Privesc 08 |
IAM-AttachRolePolicy | privesc9 | None | 🦊 Well, That Escalated Quickly – Privesc 09 |
IAM-AttachUserPolicy | privesc7 | None | 🦊 Well, That Escalated Quickly – Privesc 07 |
IAM-CreateNewPolicyVersion | privesc1 | None | 🦊 Well, That Escalated Quickly – Privesc 01 🔒 s3cur3.it IAMVulnerable – Part 1 |
IAM-PutGroupPolicy | privesc11 | None | 🦊 Well, That Escalated Quickly – Privesc 11 |
IAM-PutRolePolicy | privesc12 | None | 🦊 Well, That Escalated Quickly – Privesc 12 |
IAM-PutUserPolicy | privesc10 | None | 🦊 Well, That Escalated Quickly – Privesc 10 |
IAM-SetExistingDefaultPolicyVersion | privesc2 | None | 🦊 Well, That Escalated Quickly – Privesc 02 🔒 s3cur3.it IAMVulnerable – Part 2 |
Category: Privilege Escalation using AWS Services | |||
EC2InstanceConnect-SendSSHPublicKey | privesc-instanceConnect | EC2 | |
CloudFormation-UpdateStack | privesc-cfUpdateStack | CloudFormation | |
Glue-UpdateExistingGlueDevEndpoint | privesc19 | Glue | 🦊 Well, That Escalated Quickly – Privesc 19 |
Lambda-EditExistingLambdaFunctionWithRole | privesc17 | Lambda | 🦊 Well, That Escalated Quickly – Privesc 17 🔒 s3cur3.it IAMVulnerable – Part 4 |
SageMakerCreatePresignedNotebookURL | privesc-sageUpdateURL | Sagemaker | 🦏 AWS IAM Privilege Escalation – Method 3 |
SSM-SendCommand | privesc-ssm-command | EC2 | |
SSM-StartSession | privesc-ssm-session | EC2 | |
STS-AssumeRole | privesc-assumerole | None | |
Category: Updating an AssumeRole Policy | |||
IAM-UpdatingAssumeRolePolicy | privesc14 | None | 🦊 Well, That Escalated Quickly – Privesc 14 |
terraform.tfvars
configuredterraform.tfvars.example
to terraform.tvvars
#aws_local_profile = "profile_name"
and enter the profile name you’d like to useaws_credentails_file_example
file, you can use this command to generate an AWS credentials file that works with your non-default profile name (Thanks @scriptingislife)nondefaultuser
with the profile name you are using):tail -n +7 aws_credentials_file_example | sed -e "s/111111111111/$(aws sts get-caller-identity | grep Account | awk -F\" '{print $4}')/g;s/default/nondefaultuser/g" >> ~/.aws/credentials
terraform.tfvars.example
to terraform.tvvars
#aws_assume_role_arn = "arn:aws:iam::112233445566:user/you"
and enter the ARN you’d like to useOnce created, each of the privesc roles will be assumable by the principal (ARN) you specified.
If you have configured AWS CLI profiles that assume roles into other accounts, you will want to specify the profile name AND manually specify the ARN you’d like to use to assume into the different roles.
In the example below, the resources will be created in the account that is tied to "prod-cross-org-access-role"
, but each role that Terraform creates can be accessed by "arn:aws:iam::112233445566:user/you"
, which belongs to another account.
aws_local_profile = “prod-cross-org-access-role”
aws_assume_role_arn = “arn:aws:iam::112233445566:user/you”
Kali Linux 2024.4, the final release of 2024, brings a wide range of updates and…
This Go program applies a lifetime patch to PowerShell to disable ETW (Event Tracing for…
GPOHunter is a comprehensive tool designed to analyze and identify security misconfigurations in Active Directory…
Across small-to-medium enterprises (SMEs) and managed service providers (MSPs), the top priority for cybersecurity leaders…
The free and open-source security platform SecHub, provides a central API to test software with…
Don't worry if there are any bugs in the tool, we will try to fix…