# AWS - STS Privesc

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

## STS

### `sts:AssumeRole`

Ogni ruolo viene creato con una **policy di trust del ruolo**, questa policy indica **chi può assumere il ruolo creato**. Se un ruolo dello **stesso account** dichiara che un account può assumerlo, significa che l'account sarà in grado di accedere al ruolo (e potenzialmente **privesc**).

Ad esempio, la seguente policy di trust del ruolo indica che chiunque può assumerlo; di conseguenza **qualsiasi utente potrà effettuare privesc** alle autorizzazioni associate a quel ruolo.
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "sts:AssumeRole"
}
]
}
```
Puoi impersonare un ruolo eseguendo:
```bash
aws sts assume-role --role-arn $ROLE_ARN --role-session-name sessionname
```
**Impatto potenziale:** Privesc sul ruolo.

> [!CAUTION]
> Nota che in questo caso il permesso `sts:AssumeRole` deve essere **indicata nel ruolo da abusare** e non in una policy appartenente all'attaccante.\
> Con un'eccezione, per **assumere un ruolo da un account diverso** l'account dell'attaccante **deve anche** possedere il **`sts:AssumeRole`** su quel ruolo.


### `sts:AssumeRoleWithSAML`

Una trust policy con questo ruolo concede **agli utenti autenticati tramite SAML l'accesso per impersonare il ruolo.**

Un esempio di trust policy con questo permesso è:
```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"
}
}
}
]
}
```
Per generare credentials per impersonare il role in generale potresti usare qualcosa del genere:
```bash
aws sts  assume-role-with-saml --role-arn <value> --principal-arn <value>
```
Ma i **provider** potrebbero avere i loro **strumenti** per semplificare questo, come [onelogin-aws-assume-role](https://github.com/onelogin/onelogin-python-aws-assume-role):
```bash
onelogin-aws-assume-role --onelogin-subdomain mettle --onelogin-app-id 283740 --aws-region eu-west-1 -z 3600
```
**Impatto potenziale:** Privesc to the role.

### `sts:AssumeRoleWithWebIdentity`

Questa autorizzazione permette di ottenere un set di credenziali di sicurezza temporanee per **utenti che sono stati autenticati in un'app mobile, un'applicazione web, EKS...** con un provider di identità web. [Per saperne di più.](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html)

Ad esempio, se un **EKS service account** dovrebbe essere in grado di **impersonate an IAM role**, avrà un token in **`/var/run/secrets/eks.amazonaws.com/serviceaccount/token`** e può **assume the role and get credentials** facendo qualcosa del genere:
```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

{{#ref}}
../../aws-basic-information/aws-federation-abuse.md
{{#endref}}

### IAM Roles Anywhere Privesc

AWS IAM RolesAnywhere permette a workload esterni ad AWS di assumere IAM roles usando certificati X.509. Tuttavia, quando le trust policies non sono correttamente circoscritte, possono essere sfruttate per privilege escalation.

Per capire questo attacco, è necessario spiegare cos'è una trust anchor. Una trust anchor in AWS IAM RolesAnywhere è l'entità radice di fiducia; contiene il certificato pubblico di una Certificate Authority (CA) registrata nell'account in modo che AWS possa validare i certificati X.509 presentati. In questo modo, se il certificato del client è stato emesso da quella CA e la trust anchor è attiva, AWS lo riconosce come valido.

Inoltre, un profile è la configurazione che definisce quali attributi del certificato X.509 (come CN, OU o SAN) verranno trasformati in session tags, e questi tag saranno poi confrontati con le condizioni della trust policy.

Questa policy manca di restrizioni su quali trust anchor o attributi del certificato siano consentiti. Di conseguenza, qualsiasi certificato legato a qualsiasi trust anchor nell'account può essere usato per assumere questo role.
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "rolesanywhere.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:SetSourceIdentity",
"sts:TagSession"
]
}
]
}

```
Per privesc, è richiesto `aws_signing_helper` da https://docs.aws.amazon.com/rolesanywhere/latest/userguide/credential-helper.html

Poi, usando un certificato valido, l'attacker può pivot nel ruolo con privilegi più elevati
```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
```
Il trust anchor verifica che il certificato `readonly.pem` del client provenga dalla sua CA autorizzata, e all'interno di questo certificato `readonly.pem` si trova la chiave pubblica che AWS usa per verificare che la firma sia stata effettuata con la corrispondente chiave privata `readonly.key`.

Il certificato fornisce anche attributi (come CN o OU) che il profilo `default` trasforma in tag, che la trust policy del role può usare per decidere se autorizzare l'accesso. Se nella trust policy non ci sono condizioni, quei tag non hanno utilità e l'accesso viene concesso a chiunque abbia un certificato valido.

Perché questo attacco sia possibile, sia il trust anchor che il profilo `default` devono essere attivi.

### Riferimenti

- [https://www.ruse.tech/blogs/aws-roles-anywhere-privilege-escalation](https://www.ruse.tech/blogs/aws-roles-anywhere-privilege-escalation)

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