# AZ\_CUSTOM\_PRIVILEGED\_ROLE

## Summary

|                               |                                       |
| ----------------------------- | ------------------------------------- |
| **FSProtect ACL Alias**       | AZ\_CUSTOM\_PRIVILEGED\_ROLE          |
| **Entra ID (Azure AD) Alias** | Custom Directory Role (Privileged)    |
| **Affected Object Types**     | Users, Groups, Service Principals     |
| **Exploitation Certainty**    | Certain                               |
| **Graph Permission / Role**   | Custom Role with elevated permissions |

## Description

`AZ_CUSTOM_PRIVILEGED_ROLE` represents a **custom directory role** in Microsoft Entra ID (Azure AD) that has been configured with privileged permissions. Unlike built-in roles, custom roles are created by administrators to meet specific organizational needs, but they may inadvertently include dangerous permission combinations.

**Why Custom Roles Can Be Dangerous:**

* **Permission sprawl**: Custom roles may accumulate permissions over time without proper review.
* **Unintended privilege**: Administrators may not fully understand the implications of certain permissions.
* **Bypass detection**: Security tools may not flag custom roles as privileged.
* **Audit gaps**: Custom roles may not be included in standard privilege reviews.

**Privileged Permissions to Watch For:**

| Permission                                                             | Risk                                     |
| ---------------------------------------------------------------------- | ---------------------------------------- |
| `microsoft.directory/applications/allProperties/update`                | Full control over all applications       |
| `microsoft.directory/applications/credentials/update`                  | Add credentials to all apps              |
| `microsoft.directory/applications.myOrganization/allProperties/update` | Full control over org applications       |
| `microsoft.directory/applications.myOrganization/credentials/update`   | Add credentials to org apps              |
| `microsoft.directory/servicePrincipals/allProperties/update`           | Full control over all service principals |
| `microsoft.directory/servicePrincipals/credentials/update`             | Add credentials to SPs                   |
| `microsoft.directory/groups/allProperties/update`                      | Full control over groups                 |
| `microsoft.directory/bitlockerKeys/key/read`                           | Read BitLocker recovery keys             |
| `microsoft.directory/deviceManagementPolicies/basic/update`            | Modify device management policies        |
| `microsoft.directory/deviceRegistrationPolicy/basic/update`            | Modify device registration policy        |

**Important**: Custom roles can be scoped to Administrative Units, but dangerous permissions remain dangerous regardless of scope.

## Identification

### PowerShell

#### Find All Custom Roles and Identify Privileged Permissions

```powershell
Connect-MgGraph -Scopes "RoleManagement.Read.Directory","Directory.Read.All"

# Define privileged permissions (IsAZPrivileged = true)
$privilegedPermissions = @(
    "microsoft.directory/applications/allProperties/update",
    "microsoft.directory/applications/credentials/update",
    "microsoft.directory/applications.myOrganization/allProperties/update",
    "microsoft.directory/applications.myOrganization/credentials/update",
    "microsoft.directory/servicePrincipals/allProperties/update",
    "microsoft.directory/servicePrincipals/credentials/update",
    "microsoft.directory/groups/allProperties/update",
    "microsoft.directory/bitlockerKeys/key/read",
    "microsoft.directory/deviceManagementPolicies/basic/update",
    "microsoft.directory/deviceRegistrationPolicy/basic/update"
)

# Get all custom roles (isBuiltIn = false)
$customRoles = Get-MgRoleManagementDirectoryRoleDefinition -All | Where-Object { $_.IsBuiltIn -eq $false }
Write-Host "Found $($customRoles.Count) custom roles"

# Find custom roles with privileged permissions
$privilegedCustomRoles = $customRoles | ForEach-Object {
    $perms = $_.RolePermissions.AllowedResourceActions
    $dangerous = $perms | Where-Object { $privilegedPermissions -contains $_ }
    if ($dangerous) {
        [PSCustomObject]@{
            RoleName       = $_.DisplayName
            RoleId         = $_.Id
            DangerousPerms = $dangerous -join "; "
            PermCount      = $dangerous.Count
        }
    }
}

Write-Host "Found $($privilegedCustomRoles.Count) custom roles with privileged permissions"
$privilegedCustomRoles | Format-Table -AutoSize
```

#### Find Members of Privileged Custom Roles

```powershell
# Get role assignments for privileged custom roles
$results = foreach ($role in $privilegedCustomRoles) {
    $assignments = Get-MgRoleManagementDirectoryRoleAssignment -Filter "roleDefinitionId eq '$($role.RoleId)'" -ExpandProperty Principal
    foreach ($a in $assignments) {
        [PSCustomObject]@{
            RoleName      = $role.RoleName
            PrincipalName = $a.Principal.AdditionalProperties.displayName
            PrincipalId   = $a.PrincipalId
            PrincipalType = ($a.Principal.AdditionalProperties.'@odata.type' -replace '#microsoft.graph.', '')
            Scope         = $a.DirectoryScopeId
        }
    }
}

$results | Export-Csv -Path ".\PrivilegedCustomRoleAssignments.csv" -NoTypeInformation -Encoding UTF8
$results | Format-Table -AutoSize
```

## Exploitation

An attacker with a privileged custom role can abuse the granted permissions based on what the role includes. The exploitation technique depends on which privileged permissions are assigned to the custom role.

### Abuse Application Credentials Permission

If the custom role has `microsoft.directory/applications/credentials/update` or `microsoft.directory/applications.myOrganization/credentials/update`, the attacker can add credentials to applications and authenticate as the associated service principal.

For detailed exploitation techniques and attack scenarios, see [AZ\_ADD\_SECRET](https://gitlab.com/forestall/fsprotect-knowledge-base/-/blob/main/edges/AZ_ADD_SECRET/README.md).

### Abuse Application Full Control Permission

If the custom role has `microsoft.directory/applications/allProperties/update` or `microsoft.directory/applications.myOrganization/allProperties/update`, the attacker has full control over applications including adding credentials, modifying configuration, and changing owners.

For detailed exploitation techniques and attack scenarios, see [AZ\_ADD\_SECRET](https://gitlab.com/forestall/fsprotect-knowledge-base/-/blob/main/edges/AZ_ADD_SECRET/README.md) and [AZ\_ADD\_OWNER](https://gitlab.com/forestall/fsprotect-knowledge-base/-/blob/main/edges/AZ_ADD_OWNER/README.md).

### Abuse Service Principal Credentials Permission

If the custom role has `microsoft.directory/servicePrincipals/credentials/update` or `microsoft.directory/servicePrincipals/allProperties/update`, the attacker can add credentials directly to service principals.

For detailed exploitation techniques and attack scenarios, see [AZ\_ADD\_SECRET](https://gitlab.com/forestall/fsprotect-knowledge-base/-/blob/main/edges/AZ_ADD_SECRET/README.md).

### Abuse Groups Full Control Permission

If the custom role has `microsoft.directory/groups/allProperties/update`, the attacker has full control over groups including modifying membership, owners, and settings.

For detailed exploitation techniques and attack scenarios, see [AZ\_MG\_ADD\_MEMBER](https://gitlab.com/forestall/fsprotect-knowledge-base/-/blob/main/edges/AZ_MG_ADD_MEMBER/README.md).

### Abuse BitLocker Keys Read Permission

If the custom role has `microsoft.directory/bitlockerKeys/key/read`, the attacker can read BitLocker recovery keys for all devices in the tenant, enabling offline access to encrypted drives.

### Abuse Device Policy Permissions

If the custom role has `microsoft.directory/deviceManagementPolicies/basic/update` or `microsoft.directory/deviceRegistrationPolicy/basic/update`, the attacker can modify device management and registration policies, potentially allowing unauthorized device enrollment or weakening device security controls.

## Mitigation

* **Audit all custom roles** and their permissions:
  * Go to **Microsoft Entra ID** -> **Roles and administrators** -> **Custom roles**.
  * Review each custom role's permissions.
* **Apply least privilege**: Remove unnecessary privileged permissions from custom roles.
  * Avoid `allProperties/allTasks` permissions.
  * Use specific actions instead of broad permissions.
* **Regular access reviews** for custom role assignments:
  * Go to **Identity Governance** -> **Access Reviews**.
  * Review users and service principals with custom role assignments.
* **Document custom roles**: Maintain documentation of why each custom role exists and what permissions it requires.
* **Use built-in roles when possible**: Prefer built-in roles over custom roles to benefit from Microsoft's security guidance.
* **Monitor custom role changes**: Alert on modifications to custom role definitions.

## Detection

Detect custom role abuse in **Audit logs**.

* Go to **Microsoft Entra ID** -> **Audit logs**.
* Filter by activities:
  * **Add custom role definition**
  * **Update custom role definition**
  * **Add role assignment**
  * Activities matching the permissions in your custom roles

Monitor for:

* New custom role creation with privileged permissions.
* Permission additions to existing custom roles.
* Role assignments to custom roles with privileged permissions.
* Actions performed by users with privileged custom roles.

## References

* [Create and Assign Custom Roles in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/custom-create)
* [Microsoft Entra Custom Roles](https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/custom-overview)
* [Microsoft Entra Built-in Roles](https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/permissions-reference)
* [Role-based Access Control in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/overview)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.forestall.io/fsprotect/edges/azure/az_custom_privileged_role.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
