Query Details

Granting Of High Risk Privilege Escalation Permissions To Service Principal

Query

id: c44269aa-9879-42d9-a8f4-56a93bb8c6ac
name: Granting of High-Risk Privilege Escalation Permissions to Service Principal
version: 1.0.4
kind: Scheduled
description: |
  This rule identifies when a Service Principal is granted specific, high-risk Application Permissions for Microsoft Graph that can lead to immediate tenant-wide privilege escalation.

  The query monitors AuditLogs for successful "Add app role assignment to service principal" operations. It specifically looks for the addition of the following sensitive permission GUIDs:
  * RoleManagement.ReadWrite.Directory (9e3f62cf...): Allows the app to grant itself or others any role, including Global Administrator.
  * AppRoleAssignment.ReadWrite.All (06b708a9...): Allows the app to grant additional permissions to applications, enabling a path to grant the permission above.
  * Application.ReadWrite.All (1bfefb4e...): Allows the app to modify other applications, potentially adding credentials to run as a highly privileged identity.

  If an attacker compromises an account with the ability to grant admin consent (or compromises an existing Service Principal with AppRoleAssignment.ReadWrite.All), they can assign these permissions to a backdoor Service Principal to achieve persistence and full dominance over the Entra ID tenant.
severity: High
queryFrequency: 31m
queryPeriod: 31m
triggerOperator: gt
triggerThreshold: 0
tactics:
- Persistence
query: |-
  let DangerousAPIPermissions = dynamic({
      "9e3f62cf-ca93-4989-b6ce-bf83c28f9fe8": "RoleManagement.ReadWrite.Directory -> Directly promote any user to global admin",
      "06b708a9-e830-4db3-a914-8e69da51d44f": "AppRoleAssignment.ReadWrite.All -> Grant RoleManagement.ReadWrite.Directory, then promote to global admin",
      "1bfefb4e-e0b5-418b-a88f-73c46d2cc8e9": "Application.ReadWrite.All -> Act as another entity e.g. a global admin user"
      });
  AuditLogs
  | where OperationName == "Add app role assignment to service principal"
  | where Result =~ "success"
  | mv-expand TargetResources
  | where TargetResources.displayName == "Microsoft Graph"
  | mv-expand TargetResources.modifiedProperties
  | where TargetResources_modifiedProperties.displayName == "AppRole.Id"
  // This permission was not part of this application before
  | where isnull(TargetResources_modifiedProperties.oldValue)
  // The new permission is part of the dangerous API permissions
  | extend NewAPIPermission = trim('"', tostring(TargetResources_modifiedProperties.newValue))
  | extend PotentialImpact = DangerousAPIPermissions[NewAPIPermission]
  | where isnotempty(PotentialImpact)
  | extend UserAgent = iff(AdditionalDetails[0].key == "User-Agent", tostring(AdditionalDetails[0].value), "")
  | extend ServicePrincipalDisplayName = parse_json(tostring(parse_json(tostring(TargetResources.modifiedProperties))[6].newValue))
  | extend ServicePrincipalObjectID = parse_json(tostring(parse_json(tostring(TargetResources.modifiedProperties))[5].newValue))
  | extend InitiatingUserOrApp = iff(isnotempty(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName))
  | extend InitiatingIpAddress = iff(isnotempty(InitiatedBy.user.ipAddress), tostring(InitiatedBy.user.ipAddress), tostring(InitiatedBy.app.ipAddress))
suppressionEnabled: false
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: false
    reopenClosedIncident: false
    lookbackDuration: 5h
    matchingMethod: AllEntities
    groupByEntities: []
    groupByAlertDetails: []
    groupByCustomDetails: []
eventGroupingSettings:
  aggregationKind: SingleAlert
alertDetailsOverride:
  alertDescriptionFormat: |-
    A high impact Graph API permission was granted to an application.

    The granted API permission was {{PotentialImpact}} 

    Please verify if this API permission is needed by this application and if so make sure to add it to the watchlist "HighRiskApps"
  alertDynamicProperties: []
customDetails:
  AddedPermission: NewAPIPermission
  ServicePrincipal: ServicePrincipalDisplayName
  ServicePrincipalId: ServicePrincipalObjectID
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: FullName
    columnName: InitiatingUserOrApp
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: InitiatingIpAddress
suppressionDuration: 5h

Explanation

This query is designed to detect when a Service Principal in Microsoft Entra ID (formerly Azure AD) is granted high-risk permissions that could lead to privilege escalation across the tenant. Here's a simplified breakdown of what the query does:

  1. Purpose: It identifies when specific, sensitive permissions are added to a Service Principal, which could allow an attacker to gain extensive control over the tenant if they compromise an account with admin consent capabilities.

  2. Monitored Permissions: The query looks for the addition of three specific permissions:

    • RoleManagement.ReadWrite.Directory: Allows the app to assign any role, including Global Administrator.
    • AppRoleAssignment.ReadWrite.All: Enables the app to grant additional permissions, potentially leading to the above permission.
    • Application.ReadWrite.All: Allows the app to modify other applications, possibly adding credentials to act as a highly privileged identity.
  3. Data Source: The query examines the AuditLogs for successful operations where an app role is assigned to a Service Principal.

  4. Detection Logic:

    • It checks if the operation was successful and if the permission was not previously assigned.
    • It identifies if the new permission is one of the high-risk permissions listed.
    • It captures details such as the user or app that initiated the change, the IP address, and the Service Principal involved.
  5. Severity and Frequency: The rule is marked with high severity and runs every 31 minutes. An alert is triggered if any such permission assignment is detected.

  6. Alerting: When a high-risk permission is granted, an alert is generated with details about the potential impact. It suggests verifying the necessity of the permission and considering adding the application to a watchlist if needed.

  7. Incident Management: The rule creates incidents for each detection without grouping multiple events into a single alert.

Overall, this query helps security teams monitor and respond to potential privilege escalation risks by keeping track of sensitive permission assignments to Service Principals.

Details

Fabian Bader profile picture

Fabian Bader

Released: February 5, 2026

Tables

AuditLogs

Keywords

ServicePrincipalMicrosoftGraphApplicationPermissionsAuditLogsUserAgentIPAddress

Operators

letdynamicwhere===~mv-expandisnullextendtrimtostringisnotemptyiffparse_json

Actions