Microsoft Entra ID Role Management Permission Grant
Id | 1ff56009-db01-4615-8211-d4fda21da02d |
Rulename | Microsoft Entra ID Role Management Permission Grant |
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 |
Severity | High |
Tactics | Persistence Impact |
Techniques | T1098.003 T1078.004 |
Required data connectors | AzureActiveDirectory |
Kind | Scheduled |
Query frequency | 2h |
Query period | 2h |
Trigger threshold | 0 |
Trigger operator | gt |
Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Entra ID/Analytic Rules/AzureADRoleManagementPermissionGrant.yaml |
Version | 1.1.1 |
Arm template | 1ff56009-db01-4615-8211-d4fda21da02d.json |
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])
id: 1ff56009-db01-4615-8211-d4fda21da02d
tactics:
- Persistence
- Impact
queryPeriod: 2h
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Entra ID/Analytic Rules/AzureADRoleManagementPermissionGrant.yaml
triggerThreshold: 0
name: Microsoft Entra ID Role Management Permission Grant
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])
severity: High
triggerOperator: gt
kind: Scheduled
relevantTechniques:
- T1098.003
- T1078.004
tags:
- SimuLand
queryFrequency: 2h
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- AuditLogs
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'
status: Available
version: 1.1.1
entityMappings:
- 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: Account
- fieldMappings:
- columnName: InitiatingIpAddress
identifier: Address
entityType: IP
{
"$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"
}
]
}