Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

Microsoft Entra ID Role Management Permission Grant

Back
Id1ff56009-db01-4615-8211-d4fda21da02d
RulenameMicrosoft Entra ID Role Management Permission Grant
DescriptionIdentifies when the Microsoft Graph RoleManagement.ReadWrite.Directory (Delegated or Application) permission is granted to a service principal.

This permission allows an application to read and manage the role-based access control (RBAC) settings for your company’s directory.

An adversary could use this permission to add an Microsoft Entra ID object to an Admin directory role and escalate privileges.

Ref : https://docs.microsoft.com/graph/permissions-reference#role-management-permissions

Ref : https://docs.microsoft.com/graph/api/directoryrole-post-members?view=graph-rest-1.0&tabs=http
SeverityHigh
TacticsPersistence
Impact
TechniquesT1098.003
T1078.004
Required data connectorsAzureActiveDirectory
KindScheduled
Query frequency2h
Query period2h
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Entra ID/Analytic Rules/AzureADRoleManagementPermissionGrant.yaml
Version1.1.1
Arm template1ff56009-db01-4615-8211-d4fda21da02d.json
Deploy To Azure
AuditLogs
| where Category =~ "ApplicationManagement" and LoggedByService =~ "Core Directory" and OperationName in~ ("Add delegated permission grant", "Add app role assignment to service principal")
| mv-apply TargetResource = TargetResources on
  (
      where TargetResource.type =~ "ServicePrincipal" and array_length(TargetResource.modifiedProperties) > 0 and isnotnull(TargetResource.displayName)
      | extend props = TargetResource.modifiedProperties
  )
| mv-apply Property = props on
  (
      where Property.displayName in~ ("AppRole.Value","DelegatedPermissionGrant.Scope")
      | extend DisplayName = tostring(Property.displayName), PermissionGrant = trim('"',tostring(Property.newValue))
  )
| where PermissionGrant has "RoleManagement.ReadWrite.Directory"
| mv-apply Property = props on
  (
      where Property.displayName =~ "ServicePrincipal.DisplayName"
      | extend TargetAppDisplayName = trim('"',tostring(Property.newValue))
  )
| mv-apply Property = props on
  (
      where Property.displayName =~ "ServicePrincipal.ObjectID"
      | extend TargetAppServicePrincipalId = trim('"',tostring(Property.newValue))
  )
| extend InitiatingAppName = tostring(InitiatedBy.app.displayName)
| extend InitiatingAppServicePrincipalId = tostring(InitiatedBy.app.servicePrincipalId)
| extend InitiatingUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName)
| extend InitiatingAadUserId = tostring(InitiatedBy.user.id)
| extend InitiatingIpAddress = tostring(iff(isnotempty(InitiatedBy.user.ipAddress), InitiatedBy.user.ipAddress, InitiatedBy.app.ipAddress))
| project TimeGenerated, OperationName, Result, PermissionGrant, TargetAppDisplayName, TargetAppServicePrincipalId, InitiatingAppName, InitiatingAppServicePrincipalId,
InitiatingUserPrincipalName, InitiatingAadUserId, InitiatingIpAddress, TargetResources, AdditionalDetails, CorrelationId
| extend InitiatingAccountName = tostring(split(InitiatingUserPrincipalName, "@")[0]), InitiatingAccountUPNSuffix = tostring(split(InitiatingUserPrincipalName, "@")[1])
relevantTechniques:
- T1098.003
- T1078.004
name: Microsoft Entra ID Role Management Permission Grant
requiredDataConnectors:
- dataTypes:
  - AuditLogs
  connectorId: AzureActiveDirectory
entityMappings:
- fieldMappings:
  - identifier: Name
    columnName: TargetAppDisplayName
  - identifier: AadUserId
    columnName: TargetAppServicePrincipalId
  entityType: Account
- fieldMappings:
  - identifier: Name
    columnName: InitiatingAppName
  - identifier: AadUserId
    columnName: InitiatingAppServicePrincipalId
  entityType: Account
- fieldMappings:
  - identifier: FullName
    columnName: InitiatingUserPrincipalName
  - identifier: Name
    columnName: InitiatingAccountName
  - identifier: UPNSuffix
    columnName: InitiatingAccountUPNSuffix
  entityType: Account
- fieldMappings:
  - identifier: AadUserId
    columnName: InitiatingAadUserId
  entityType: Account
- fieldMappings:
  - identifier: Address
    columnName: InitiatingIpAddress
  entityType: IP
triggerThreshold: 0
id: 1ff56009-db01-4615-8211-d4fda21da02d
tactics:
- Persistence
- Impact
version: 1.1.1
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Entra ID/Analytic Rules/AzureADRoleManagementPermissionGrant.yaml
queryPeriod: 2h
kind: Scheduled
tags:
- SimuLand
queryFrequency: 2h
severity: High
status: Available
description: |
  'Identifies when the Microsoft Graph RoleManagement.ReadWrite.Directory (Delegated or Application) permission is granted to a service principal.
  This permission allows an application to read and manage the role-based access control (RBAC) settings for your company's directory.
  An adversary could use this permission to add an Microsoft Entra ID object to an Admin directory role and escalate privileges.
  Ref : https://docs.microsoft.com/graph/permissions-reference#role-management-permissions
  Ref : https://docs.microsoft.com/graph/api/directoryrole-post-members?view=graph-rest-1.0&tabs=http'  
query: |
  AuditLogs
  | where Category =~ "ApplicationManagement" and LoggedByService =~ "Core Directory" and OperationName in~ ("Add delegated permission grant", "Add app role assignment to service principal")
  | mv-apply TargetResource = TargetResources on
    (
        where TargetResource.type =~ "ServicePrincipal" and array_length(TargetResource.modifiedProperties) > 0 and isnotnull(TargetResource.displayName)
        | extend props = TargetResource.modifiedProperties
    )
  | mv-apply Property = props on
    (
        where Property.displayName in~ ("AppRole.Value","DelegatedPermissionGrant.Scope")
        | extend DisplayName = tostring(Property.displayName), PermissionGrant = trim('"',tostring(Property.newValue))
    )
  | where PermissionGrant has "RoleManagement.ReadWrite.Directory"
  | mv-apply Property = props on
    (
        where Property.displayName =~ "ServicePrincipal.DisplayName"
        | extend TargetAppDisplayName = trim('"',tostring(Property.newValue))
    )
  | mv-apply Property = props on
    (
        where Property.displayName =~ "ServicePrincipal.ObjectID"
        | extend TargetAppServicePrincipalId = trim('"',tostring(Property.newValue))
    )
  | extend InitiatingAppName = tostring(InitiatedBy.app.displayName)
  | extend InitiatingAppServicePrincipalId = tostring(InitiatedBy.app.servicePrincipalId)
  | extend InitiatingUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName)
  | extend InitiatingAadUserId = tostring(InitiatedBy.user.id)
  | extend InitiatingIpAddress = tostring(iff(isnotempty(InitiatedBy.user.ipAddress), InitiatedBy.user.ipAddress, InitiatedBy.app.ipAddress))
  | project TimeGenerated, OperationName, Result, PermissionGrant, TargetAppDisplayName, TargetAppServicePrincipalId, InitiatingAppName, InitiatingAppServicePrincipalId,
  InitiatingUserPrincipalName, InitiatingAadUserId, InitiatingIpAddress, TargetResources, AdditionalDetails, CorrelationId
  | extend InitiatingAccountName = tostring(split(InitiatingUserPrincipalName, "@")[0]), InitiatingAccountUPNSuffix = tostring(split(InitiatingUserPrincipalName, "@")[1])  
triggerOperator: gt
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2024-01-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/1ff56009-db01-4615-8211-d4fda21da02d')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/1ff56009-db01-4615-8211-d4fda21da02d')]",
      "properties": {
        "alertRuleTemplateName": "1ff56009-db01-4615-8211-d4fda21da02d",
        "customDetails": null,
        "description": "'Identifies when the Microsoft Graph RoleManagement.ReadWrite.Directory (Delegated or Application) permission is granted to a service principal.\nThis permission allows an application to read and manage the role-based access control (RBAC) settings for your company's directory.\nAn adversary could use this permission to add an Microsoft Entra ID object to an Admin directory role and escalate privileges.\nRef : https://docs.microsoft.com/graph/permissions-reference#role-management-permissions\nRef : https://docs.microsoft.com/graph/api/directoryrole-post-members?view=graph-rest-1.0&tabs=http'\n",
        "displayName": "Microsoft Entra ID Role Management Permission Grant",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "TargetAppDisplayName",
                "identifier": "Name"
              },
              {
                "columnName": "TargetAppServicePrincipalId",
                "identifier": "AadUserId"
              }
            ]
          },
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "InitiatingAppName",
                "identifier": "Name"
              },
              {
                "columnName": "InitiatingAppServicePrincipalId",
                "identifier": "AadUserId"
              }
            ]
          },
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "InitiatingUserPrincipalName",
                "identifier": "FullName"
              },
              {
                "columnName": "InitiatingAccountName",
                "identifier": "Name"
              },
              {
                "columnName": "InitiatingAccountUPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "InitiatingAadUserId",
                "identifier": "AadUserId"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "InitiatingIpAddress",
                "identifier": "Address"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Entra ID/Analytic Rules/AzureADRoleManagementPermissionGrant.yaml",
        "query": "AuditLogs\n| where Category =~ \"ApplicationManagement\" and LoggedByService =~ \"Core Directory\" and OperationName in~ (\"Add delegated permission grant\", \"Add app role assignment to service principal\")\n| mv-apply TargetResource = TargetResources on\n  (\n      where TargetResource.type =~ \"ServicePrincipal\" and array_length(TargetResource.modifiedProperties) > 0 and isnotnull(TargetResource.displayName)\n      | extend props = TargetResource.modifiedProperties\n  )\n| mv-apply Property = props on\n  (\n      where Property.displayName in~ (\"AppRole.Value\",\"DelegatedPermissionGrant.Scope\")\n      | extend DisplayName = tostring(Property.displayName), PermissionGrant = trim('\"',tostring(Property.newValue))\n  )\n| where PermissionGrant has \"RoleManagement.ReadWrite.Directory\"\n| mv-apply Property = props on\n  (\n      where Property.displayName =~ \"ServicePrincipal.DisplayName\"\n      | extend TargetAppDisplayName = trim('\"',tostring(Property.newValue))\n  )\n| mv-apply Property = props on\n  (\n      where Property.displayName =~ \"ServicePrincipal.ObjectID\"\n      | extend TargetAppServicePrincipalId = trim('\"',tostring(Property.newValue))\n  )\n| extend InitiatingAppName = tostring(InitiatedBy.app.displayName)\n| extend InitiatingAppServicePrincipalId = tostring(InitiatedBy.app.servicePrincipalId)\n| extend InitiatingUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName)\n| extend InitiatingAadUserId = tostring(InitiatedBy.user.id)\n| extend InitiatingIpAddress = tostring(iff(isnotempty(InitiatedBy.user.ipAddress), InitiatedBy.user.ipAddress, InitiatedBy.app.ipAddress))\n| project TimeGenerated, OperationName, Result, PermissionGrant, TargetAppDisplayName, TargetAppServicePrincipalId, InitiatingAppName, InitiatingAppServicePrincipalId,\nInitiatingUserPrincipalName, InitiatingAadUserId, InitiatingIpAddress, TargetResources, AdditionalDetails, CorrelationId\n| extend InitiatingAccountName = tostring(split(InitiatingUserPrincipalName, \"@\")[0]), InitiatingAccountUPNSuffix = tostring(split(InitiatingUserPrincipalName, \"@\")[1])\n",
        "queryFrequency": "PT2H",
        "queryPeriod": "PT2H",
        "severity": "High",
        "status": "Available",
        "subTechniques": [
          "T1098.003",
          "T1078.004"
        ],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Impact",
          "Persistence"
        ],
        "tags": [
          "SimuLand"
        ],
        "techniques": [
          "T1078",
          "T1098"
        ],
        "templateVersion": "1.1.1",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}