# AWS - IAM & STS Enum non authentifié

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

## Énumérer les rôles et les noms d'utilisateur dans un compte

### ~~Brute-Force d'Assumer un Rôle~~

> [!CAUTION]
> **Cette technique ne fonctionne plus** car que le rôle existe ou non, vous obtenez toujours cette erreur :
>
> `An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::947247140022:user/testenv is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::429217632764:role/account-balanceasdas`
>
> Vous pouvez **tester cela en exécutant** :
>
> `aws sts assume-role --role-arn arn:aws:iam::412345678909:role/superadmin --role-session-name s3-access-example`

Tenter d'**assumer un rôle sans les autorisations nécessaires** déclenche un message d'erreur AWS. Par exemple, si non autorisé, AWS pourrait renvoyer :
```ruby
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::012345678901:user/MyUser is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::111111111111:role/aws-service-role/rds.amazonaws.com/AWSServiceRoleForRDS
```
Ce message confirme l'existence du rôle mais indique que sa politique d'assumption ne permet pas votre assumption. En revanche, essayer de **prendre un rôle inexistant entraîne une erreur différente** :
```less
An error occurred (AccessDenied) when calling the AssumeRole operation: Not authorized to perform sts:AssumeRole
```
Il est intéressant de noter que cette méthode de **distinction entre les rôles existants et non existants** est applicable même entre différents comptes AWS. Avec un ID de compte AWS valide et une liste de mots ciblée, on peut énumérer les rôles présents dans le compte sans faire face à des limitations inhérentes.

Vous pouvez utiliser ce [script pour énumérer les principaux potentiels](https://github.com/RhinoSecurityLabs/Security-Research/tree/master/tools/aws-pentest-tools/assume_role_enum) en abusant de ce problème.

### Politiques de confiance : Brute-Force des rôles et utilisateurs inter-comptes

Configurer ou mettre à jour la **politique de confiance d'un rôle IAM implique de définir quels ressources ou services AWS sont autorisés à assumer ce rôle** et à obtenir des identifiants temporaires. Si la ressource spécifiée dans la politique **existe**, la politique de confiance est enregistrée **avec succès**. Cependant, si la ressource **n'existe pas**, une **erreur est générée**, indiquant qu'un principal invalide a été fourni.

> [!WARNING]
> Notez que dans cette ressource, vous pourriez spécifier un rôle ou un utilisateur inter-compte :
>
> - `arn:aws:iam::acc_id:role/role_name`
> - `arn:aws:iam::acc_id:user/user_name`

Voici un exemple de politique :
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::216825089941:role/Test"
},
"Action": "sts:AssumeRole"
}
]
}
```
#### GUI

C'est l'**erreur** que vous trouverez si vous utilisez un **rôle qui n'existe pas**. Si le rôle **existe**, la politique sera **enregistrée** sans aucune erreur. (L'erreur concerne la mise à jour, mais cela fonctionne également lors de la création)

![](<../../../images/image (153).png>)

#### CLI
```bash
### You could also use: aws iam update-assume-role-policy
# When it works
aws iam create-role --role-name Test-Role --assume-role-policy-document file://a.json
{
"Role": {
"Path": "/",
"RoleName": "Test-Role",
"RoleId": "AROA5ZDCUJS3DVEIYOB73",
"Arn": "arn:aws:iam::947247140022:role/Test-Role",
"CreateDate": "2022-05-03T20:50:04Z",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::316584767888:role/account-balance"
},
"Action": [
"sts:AssumeRole"
]
}
]
}
}
}

# When it doesn't work
aws iam create-role --role-name Test-Role2 --assume-role-policy-document file://a.json
An error occurred (MalformedPolicyDocument) when calling the CreateRole operation: Invalid principal in policy: "AWS":"arn:aws:iam::316584767888:role/account-balanceefd23f2"
```
Vous pouvez automatiser ce processus avec [https://github.com/carlospolop/aws_tools](https://github.com/carlospolop/aws_tools)

- `bash unauth_iam.sh -t user -i 316584767888 -r TestRole -w ./unauth_wordlist.txt`

Notre utilisation de [Pacu](https://github.com/RhinoSecurityLabs/pacu) :

- `run iam__enum_users --role-name admin --account-id 229736458923 --word-list /tmp/names.txt`
- `run iam__enum_roles --role-name admin --account-id 229736458923 --word-list /tmp/names.txt`
- Le rôle `admin` utilisé dans l'exemple est un **rôle dans votre compte à être usurpé** par pacu pour créer les politiques dont il a besoin pour l'énumération

### Privesc

Dans le cas où le rôle était mal configuré et permet à quiconque de l'assumer :
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "sts:AssumeRole"
}
]
}
```
L'attaquant pourrait simplement le supposer.

## Fédération OIDC de tiers

Imaginez que vous parvenez à lire un **workflow Github Actions** qui accède à un **rôle** à l'intérieur d'**AWS**.\
Cette confiance pourrait donner accès à un rôle avec la **politique de confiance** suivante :
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<acc_id>:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
}
}
}
]
}
```
Cette politique de confiance peut être correcte, mais le **manque de plus de conditions** devrait vous inciter à vous méfier.\
C'est parce que le rôle précédent peut être assumé par **QUICONQUE de Github Actions** ! Vous devriez spécifier dans les conditions d'autres éléments tels que le nom de l'organisation, le nom du dépôt, l'environnement, la branche...

Une autre mauvaise configuration potentielle est d'**ajouter une condition** comme suit :
```json
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:org_name*:*"
}
```
Notez que **wildcard** (\*) avant le **deux-points** (:). Vous pouvez créer une org telle que **org_name1** et **assumer le rôle** depuis une action Github.

## Références

- [https://www.youtube.com/watch?v=8ZXRw4Ry3mQ](https://www.youtube.com/watch?v=8ZXRw4Ry3mQ)
- [https://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration/](https://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration/)

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