# AWS - IAM Post Exploitation

{{#include ../../../../banners/hacktricks-training.md}}

## IAM

For more information about IAM access:

{{#ref}}
../../aws-services/aws-iam-enum.md
{{#endref}}

## Confused Deputy Problem

If you **allow an external account (A)** to access a **role** in your account, you will probably have **0 visibility** on **who can exactly access that external account**. This is a problem, because if another external account (B) can access the external account (A) it's possible that **B will also be able to access your account**.

Therefore, when allowing an external account to access a role in your account it's possible to specify an `ExternalId`. This is a "secret" string that the external account (A) **need to specify** in order to **assume the role in your organization**. As the **external account B won't know this string**, even if he has access over A he **won't be able to access your role**.

<figure><img src="../../../images/image (95).png" alt=""><figcaption></figcaption></figure>

However, note that this `ExternalId` "secret" is **not a secret**, anyone that can **read the IAM assume role policy will be able to see it**. But as long as the external account A knows it, but the external account **B doesn't know it**, it **prevents B abusing A to access your role**.

Example:

```json
{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Principal": {
      "AWS": "Example Corp's AWS Account ID"
    },
    "Action": "sts:AssumeRole",
    "Condition": {
      "StringEquals": {
        "sts:ExternalId": "12345"
      }
    }
  }
}
```

> [!WARNING]
> For an attacker to exploit a confused deputy he will need to find somehow if principals of the current account can impersonate roles in other accounts.

### Unexpected Trusts

#### Wildcard as principal

```json
{
  "Action": "sts:AssumeRole",
  "Effect": "Allow",
  "Principal": { "AWS": "*" }
}
```

This policy **allows all AWS** to assume the role.

#### Service as principal

```json
{
  "Action": "lambda:InvokeFunction",
  "Effect": "Allow",
  "Principal": { "Service": "apigateway.amazonaws.com" },
  "Resource": "arn:aws:lambda:000000000000:function:foo"
}
```

This policy **allows any account** to configure their apigateway to call this Lambda.

#### S3 as principal

```json
"Condition": {
"ArnLike": { "aws:SourceArn": "arn:aws:s3:::source-bucket" },
    "StringEquals": {
        "aws:SourceAccount": "123456789012"
    }
}
```

If an S3 bucket is given as a principal, because S3 buckets do not have an Account ID, if you **deleted your bucket and the attacker created** it in their own account, then they could abuse this.

#### Not supported

```json
{
  "Effect": "Allow",
  "Principal": { "Service": "cloudtrail.amazonaws.com" },
  "Action": "s3:PutObject",
  "Resource": "arn:aws:s3:::myBucketName/AWSLogs/MY_ACCOUNT_ID/*"
}
```

A common way to avoid Confused Deputy problems is the use of a condition with `AWS:SourceArn` to check the origin ARN. However, **some services might not support that** (like CloudTrail according to some sources).

### Credential Deletion 
With any of the following permissions — `iam:DeleteAccessKey`, `iam:DeleteLoginProfile`, `iam:DeleteSSHPublicKey`, `iam:DeleteServiceSpecificCredential`, `iam:DeleteInstanceProfile`, `iam:DeleteServerCertificate`, `iam:DeleteCloudFrontPublicKey`, `iam:RemoveRoleFromInstanceProfile` — an actor can remove access keys, login profiles, SSH keys, service-specific credentials, instance profiles, certificates or CloudFront public keys, or disassociate roles from instance profiles. Such actions can immediately block legitimate users and applications and cause denial-of-service or loss of access for systems that depend on those credentials, so these IAM permissions must be tightly restricted and monitored.

```bash
# Remove Access Key of a user
aws iam delete-access-key \
  --user-name <Username> \
  --access-key-id AKIAIOSFODNN7EXAMPLE

## Remove ssh key of a user
aws iam delete-ssh-public-key \
  --user-name <Username> \
  --ssh-public-key-id APKAEIBAERJR2EXAMPLE
```

### Identity Deletion
With permissions like `iam:DeleteUser`, `iam:DeleteGroup`, `iam:DeleteRole`, or `iam:RemoveUserFromGroup`, an actor can delete users, roles, or groups—or change group membership—removing identities and associated traces. This can immediately break access for people and services that depend on those identities, causing denial-of-service or loss of access, so these IAM actions must be tightly restricted and monitored.

```bash
# Delete a user
aws iam delete-user \
  --user-name <Username>

# Delete a group
aws iam delete-group \
  --group-name <Username>

# Delete a role
aws iam delete-role \
  --role-name <Role>
```

### 
With any of the following permissions — `iam:DeleteGroupPolicy`, `iam:DeleteRolePolicy`, `iam:DeleteUserPolicy`, `iam:DeletePolicy`, `iam:DeletePolicyVersion`, `iam:DeleteRolePermissionsBoundary`, `iam:DeleteUserPermissionsBoundary`, `iam:DetachGroupPolicy`, `iam:DetachRolePolicy`, `iam:DetachUserPolicy` — an actor can delete or detach managed/inline policies, remove policy versions or permissions boundaries, and unlink policies from users, groups, or roles. This destroys authorizations and can alter the permissions model, causing immediate loss of access or denial-of-service for principals that depended on those policies, so these IAM actions must be tightly restricted and monitored.

```bash
# Delete a group policy
aws iam delete-group-policy \
  --group-name <GroupName> \
  --policy-name <PolicyName>

# Delete a role policy
aws iam delete-role-policy \
  --role-name <RoleName> \
  --policy-name <PolicyName>
```

### Federated Identity Deletion
With `iam:DeleteOpenIDConnectProvider`, `iam:DeleteSAMLProvider`, and `iam:RemoveClientIDFromOpenIDConnectProvider`, an actor can delete OIDC/SAML identity providers or remove client IDs. This breaks federated authentication, preventing token validation and immediately denying access to users and services that rely on SSO until the IdP or configurations are restored.

```bash
# Delete OIDCP provider
aws iam delete-open-id-connect-provider \
  --open-id-connect-provider-arn arn:aws:iam::111122223333:oidc-provider/accounts.google.com

# Delete SAML provider
aws iam delete-saml-provider \
  --saml-provider-arn arn:aws:iam::111122223333:saml-provider/CorporateADFS
```

### Illegitimate MFA Activation
With `iam:EnableMFADevice`, an actor can register an MFA device on a user’s identity, preventing the legitimate user from signing in. Once an unauthorized MFA is enabled the user can be locked out until the device is removed or reset (note: if multiple MFA devices are registered, sign-in requires only one, so this attack will have no effect on denying access).

```bash
aws iam enable-mfa-device \
  --user-name <Username> \
  --serial-number arn:aws:iam::111122223333:mfa/alice \
  --authentication-code1 123456 \
  --authentication-code2 789012
```

### Certificate/Key Metadata Tampering
With `iam:UpdateSSHPublicKey`, `iam:UpdateCloudFrontPublicKey`, `iam:UpdateSigningCertificate`, `iam:UpdateServerCertificate`, an actor can change status or metadata of public keys and certificates. By marking keys/certificates inactive or altering references, they can break SSH authentication, invalidate X.509/TLS validations, and immediately disrupt services that depend on those credentials, causing loss of access or availability.

```bash
aws iam update-ssh-public-key \
  --user-name <Username> \
  --ssh-public-key-id APKAEIBAERJR2EXAMPLE \
  --status Inactive

aws iam update-server-certificate \
  --server-certificate-name <Certificate_Name> \
  --new-path /prod/
```

### `iam:Delete*`

The IAM wildcard iam:Delete* grants the ability to remove many kinds of IAM resources—users, roles, groups, policies, keys, certificates, MFA devices, policy versions, etc. —and therefore has a very high blast radius: an actor granted iam:Delete* can permanently destroy identities, credentials, policies and related artifacts, remove audit/evidence, and cause service or operational outages. Some examples are

```bash
# Delete a user
aws iam delete-user --user-name <Username>

# Delete a role
aws iam delete-role --role-name <RoleName>

# Delete a managed policy
aws iam delete-policy --policy-arn arn:aws:iam::<ACCOUNT_ID>:policy/<PolicyName>
```

### `iam:EnableMFADevice`

An actor granted the iam:EnableMFADevice action can register an MFA device on an identity in the account, provided the user did not already have one enabled. This can be used to interfere with a user’s access: once an attacker registers an MFA device, the legitimate user may be prevented from signing in because they do not control the attacker-registered MFA.

This denial-of-access attack only works if the user had no MFA registered; if the attacker registers an MFA device for that user, the legitimate user will be locked out of any flows that require that new MFA. If the user already has one or more MFA devices under their control, adding an attacker-controlled MFA does not block the legitimate user — they can continue to authenticate using any MFA they already have.

To enable (register) an MFA device for a user an attacker could run:
```bash
aws iam enable-mfa-device \
  --user-name <Username> \
  --serial-number arn:aws:iam::111122223333:mfa/alice \
  --authentication-code1 123456 \
  --authentication-code2 789012
```

## References

- [https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html)

{{#include ../../../../banners/hacktricks-training.md}}




