AWS - STS Privesc

Reading time: 5 minutes

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

STS

sts:AssumeRole

Every role is created with a role trust policy, this policy indicates who can assume the created role. If a role from the same account says that an account can assume it, it means that the account will be able to access the role (and potentially privesc).

For example, the following role trust policy indicates that anyone can assume it, therefore any user will be able to privesc to the permissions associated with that role.

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

You can impersonate a role running:

bash
aws sts assume-role --role-arn $ROLE_ARN --role-session-name sessionname

Potential Impact: Privesc to the role.

caution

Note that in this case the permission sts:AssumeRole needs to be indicated in the role to abuse and not in a policy belonging to the attacker.
With one exception, in order to assume a role from a different account the attacker account also needs to have the sts:AssumeRole over the role.

sts:GetFederationToken

With this permission it's possible to generate credentials to impersonate any user:

bash
aws sts get-federation-token --name <username>

This is how this permission can be given securely without giving access to impersonate other users:

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VisualEditor0",
      "Effect": "Allow",
      "Action": "sts:GetFederationToken",
      "Resource": "arn:aws:sts::947247140022:federated-user/${aws:username}"
    }
  ]
}

sts:AssumeRoleWithSAML

A trust policy with this role grants users authenticated via SAML access to impersonate the role.

An example of a trust policy with this permission is:

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "OneLogin",
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::290594632123:saml-provider/OneLogin"
      },
      "Action": "sts:AssumeRoleWithSAML",
      "Condition": {
        "StringEquals": {
          "SAML:aud": "https://signin.aws.amazon.com/saml"
        }
      }
    }
  ]
}

To generate credentials to impersonate the role in general you could use something like:

bash
aws sts  assume-role-with-saml --role-arn <value> --principal-arn <value>

But providers might have their own tools to make this easier, like onelogin-aws-assume-role:

bash
onelogin-aws-assume-role --onelogin-subdomain mettle --onelogin-app-id 283740 --aws-region eu-west-1 -z 3600

Potential Impact: Privesc to the role.

sts:AssumeRoleWithWebIdentity

This permission grants permission to obtain a set of temporary security credentials for users who have been authenticated in a mobile, web application, EKS... with a web identity provider. Learn more here.

For example, if an EKS service account should be able to impersonate an IAM role, it will have a token in /var/run/secrets/eks.amazonaws.com/serviceaccount/token and can assume the role and get credentials doing something like:

bash
aws sts assume-role-with-web-identity --role-arn arn:aws:iam::123456789098:role/<role_name> --role-session-name something --web-identity-token file:///var/run/secrets/eks.amazonaws.com/serviceaccount/token
# The role name can be found in the metadata of the configuration of the pod

Federation Abuse

AWS - Federation Abuse

IAM Roles Anywhere Privesc

AWS IAM RolesAnywhere allows workloads outside AWS to assume IAM roles using X.509 certificates. But when trust policies aren't properly scoped, they can be abused for privilege escalation.

This policy lacks restrictions on which trust anchor or certificate attributes are allowed. As a result, any certificate tied to any trust anchor in the account can be used to assume this role.

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "rolesanywhere.amazonaws.com"
      },
      "Action": [
        "sts:AssumeRole",
        "sts:SetSourceIdentity",
        "sts:TagSession"
      ]
    }
  ]
}

To privesc, the aws_signing_helper is required from https://docs.aws.amazon.com/rolesanywhere/latest/userguide/credential-helper.html

Then using a valid certificate the attacker can pivot into the higher privilege role

bash
aws_signing_helper credential-process \
  --certificate readonly.pem \
  --private-key readonly.key \
  --trust-anchor-arn arn:aws:rolesanywhere:us-east-1:123456789012:trust-anchor/ta-id \
  --profile-arn arn:aws:rolesanywhere:us-east-1:123456789012:profile/default \
  --role-arn arn:aws:iam::123456789012:role/Admin

References

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks