Analytic rule catalog
[Entra ID] Application Granted Administrative Permission to Assign Microsoft Entra ID Roles
Back
| Id | ef34b272-930c-41c8-a682-8c2093cd2024 |
| Rulename | [Entra ID] Application Granted Administrative Permission to Assign Microsoft Entra ID Roles |
| Description | Detects when an application receives permission to assign Microsoft Entra ID roles. This can enable directory privilege escalation and should be reviewed immediately. |
| Severity | High |
| Tactics | Persistence Impact PrivilegeEscalation |
| Techniques | T1098.003 |
| 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/eDCRule/Analytic%20Rules/%5BEntra%20ID%5D%20Application%20Granted%20Administrative%20Permission%20to%20Assign%20Microsoft%20Entra%20ID%20Roles.yaml |
| Version | 1.0.0 |
| Arm template | ef34b272-930c-41c8-a682-8c2093cd2024.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))
| extend TargetAppDisplayName = tostring(iff(isnotempty(TargetAppDisplayName), TargetAppDisplayName, TargetAppServicePrincipalId))
| extend
InitiatingAccountName = tostring(split(InitiatingUserPrincipalName, "@")[0]),
InitiatingAccountUPNSuffix = tostring(split(InitiatingUserPrincipalName, "@")[1])
| extend Initiator = InitiatingAccountName, Target = TargetAppDisplayName
| extend
Source_Network_IPLocation = ""
| project
Alert_Category_en = "Entra ID",
Alert_SubCategory_en = "Anomaly Identity Privilege Modification",
Alert_Name_en = "Application Granted Administrative Permission to Assign Microsoft Entra ID Roles",
Alert_Description_en = strcat("At Taiwan time", format_datetime(datetime_utc_to_local(TimeGenerated, "Asia/Taipei"), "yyyy-MM-dd HH:mm:ss"), ". ", "EntraID:", "", ". ", "detected source user/service principal ", iff(isnotempty(InitiatingUserPrincipalName), InitiatingUserPrincipalName, InitiatingAppName), " granted application: ", TargetAppDisplayName, ".", " administrative permission to assign Microsoft Entra ID roles: ", ActivityDisplayName, ". Source IP: ", InitiatingIpAddress, ", source location: ", Source_Network_IPLocation),
Alert_TriageStep_en = strcat(
"1. Confirm whether the operating user/service principal: ",
iff(isnotempty(InitiatingUserPrincipalName), InitiatingUserPrincipalName, InitiatingAppName),
", source IP: ",
InitiatingIpAddress,
" is abnormal. ",
"2. Review the authorized target application ",
TargetAppDisplayName,
" authorization content: ",
ActivityDisplayName,
" to determine whether it is an expected operation or maintenance task."
),
Alert_Containment_en = strcat(
"1. If determined to be unauthorized or suspicious privilege escalation, immediately remove the permissions from target application: ",
TargetAppDisplayName,
" and disable it.",
"2. Perform risk handling for the initiator ",
iff(isnotempty(InitiatingUserPrincipalName), InitiatingUserPrincipalName, InitiatingAppName),
" (revoke sessions/force re-authentication, and suspend directory management permissions if necessary)."
),
Alert_Remediation_en =
"1. Strengthen application and permission governance: apply least privilege and administrator approval processes for high-risk Graph/Directory permissions, and include Service Principal credential/permission changes in regular audits. "
"2. Strengthen detection and automation: establish automated response (SOAR) for notification/source blocking/user verification.",
Alert_Time_TW = datetime_utc_to_local(TimeGenerated, "Asia/Taipei"),
Alert_Time_UTC0 = TimeGenerated,
Event_Action = ActivityDisplayName,
Event_Status = Result,
Event_Description = PermissionGrant,
Source_Identity_FullName = iff(isnotempty(InitiatingUserPrincipalName), InitiatingUserPrincipalName, InitiatingAppName),
Source_Identity_ID = iff(isnotempty(InitiatingAadUserId), InitiatingAadUserId, InitiatingAppServicePrincipalId),
Source_Identity_Type = iff(isnotempty(InitiatingUserPrincipalName), "User", "Service"),
Source_Network_IPAddress = InitiatingIpAddress,
Source_Network_IPLocation = Source_Network_IPLocation,
Target_Identity_FullName = TargetAppDisplayName,
Target_Identity_ID = TargetAppServicePrincipalId,
Target_Identity_Type = "Service",
Target_Resource_ID = "",
Target_Resource_Name = "Microsoft Entra ID",
Target_Resource_Type = "Microsoft Entra ID"
entityMappings:
- entityType: Account
fieldMappings:
- columnName: Source_Identity_FullName
identifier: FullName
- entityType: IP
fieldMappings:
- columnName: Source_Network_IPAddress
identifier: Address
- entityType: CloudApplication
fieldMappings:
- columnName: Target_Identity_FullName
identifier: Name
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))
| extend TargetAppDisplayName = tostring(iff(isnotempty(TargetAppDisplayName), TargetAppDisplayName, TargetAppServicePrincipalId))
| extend
InitiatingAccountName = tostring(split(InitiatingUserPrincipalName, "@")[0]),
InitiatingAccountUPNSuffix = tostring(split(InitiatingUserPrincipalName, "@")[1])
| extend Initiator = InitiatingAccountName, Target = TargetAppDisplayName
| extend
Source_Network_IPLocation = ""
| project
Alert_Category_en = "Entra ID",
Alert_SubCategory_en = "Anomaly Identity Privilege Modification",
Alert_Name_en = "Application Granted Administrative Permission to Assign Microsoft Entra ID Roles",
Alert_Description_en = strcat("At Taiwan time", format_datetime(datetime_utc_to_local(TimeGenerated, "Asia/Taipei"), "yyyy-MM-dd HH:mm:ss"), ". ", "EntraID:", "", ". ", "detected source user/service principal ", iff(isnotempty(InitiatingUserPrincipalName), InitiatingUserPrincipalName, InitiatingAppName), " granted application: ", TargetAppDisplayName, ".", " administrative permission to assign Microsoft Entra ID roles: ", ActivityDisplayName, ". Source IP: ", InitiatingIpAddress, ", source location: ", Source_Network_IPLocation),
Alert_TriageStep_en = strcat(
"1. Confirm whether the operating user/service principal: ",
iff(isnotempty(InitiatingUserPrincipalName), InitiatingUserPrincipalName, InitiatingAppName),
", source IP: ",
InitiatingIpAddress,
" is abnormal. ",
"2. Review the authorized target application ",
TargetAppDisplayName,
" authorization content: ",
ActivityDisplayName,
" to determine whether it is an expected operation or maintenance task."
),
Alert_Containment_en = strcat(
"1. If determined to be unauthorized or suspicious privilege escalation, immediately remove the permissions from target application: ",
TargetAppDisplayName,
" and disable it.",
"2. Perform risk handling for the initiator ",
iff(isnotempty(InitiatingUserPrincipalName), InitiatingUserPrincipalName, InitiatingAppName),
" (revoke sessions/force re-authentication, and suspend directory management permissions if necessary)."
),
Alert_Remediation_en =
"1. Strengthen application and permission governance: apply least privilege and administrator approval processes for high-risk Graph/Directory permissions, and include Service Principal credential/permission changes in regular audits. "
"2. Strengthen detection and automation: establish automated response (SOAR) for notification/source blocking/user verification.",
Alert_Time_TW = datetime_utc_to_local(TimeGenerated, "Asia/Taipei"),
Alert_Time_UTC0 = TimeGenerated,
Event_Action = ActivityDisplayName,
Event_Status = Result,
Event_Description = PermissionGrant,
Source_Identity_FullName = iff(isnotempty(InitiatingUserPrincipalName), InitiatingUserPrincipalName, InitiatingAppName),
Source_Identity_ID = iff(isnotempty(InitiatingAadUserId), InitiatingAadUserId, InitiatingAppServicePrincipalId),
Source_Identity_Type = iff(isnotempty(InitiatingUserPrincipalName), "User", "Service"),
Source_Network_IPAddress = InitiatingIpAddress,
Source_Network_IPLocation = Source_Network_IPLocation,
Target_Identity_FullName = TargetAppDisplayName,
Target_Identity_ID = TargetAppServicePrincipalId,
Target_Identity_Type = "Service",
Target_Resource_ID = "",
Target_Resource_Name = "Microsoft Entra ID",
Target_Resource_Type = "Microsoft Entra ID"
id: ef34b272-930c-41c8-a682-8c2093cd2024
queryFrequency: 2h
alertDetailsOverride:
alertDynamicProperties: []
status: Available
severity: High
relevantTechniques:
- T1098.003
version: 1.0.0
kind: Scheduled
tactics:
- Persistence
- Impact
- PrivilegeEscalation
requiredDataConnectors:
- dataTypes:
- AuditLogs
connectorId: AzureActiveDirectory
description: |
Detects when an application receives permission to assign Microsoft Entra ID roles. This can enable directory privilege escalation and should be reviewed immediately.
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/eDCRule/Analytic%20Rules/%5BEntra%20ID%5D%20Application%20Granted%20Administrative%20Permission%20to%20Assign%20Microsoft%20Entra%20ID%20Roles.yaml
triggerOperator: gt
name: '[Entra ID] Application Granted Administrative Permission to Assign Microsoft Entra ID Roles'
triggerThreshold: 0
queryPeriod: 2h
{
"$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/ef34b272-930c-41c8-a682-8c2093cd2024')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/ef34b272-930c-41c8-a682-8c2093cd2024')]",
"properties": {
"alertDetailsOverride": {
"alertDynamicProperties": []
},
"alertRuleTemplateName": "ef34b272-930c-41c8-a682-8c2093cd2024",
"customDetails": null,
"description": "Detects when an application receives permission to assign Microsoft Entra ID roles. This can enable directory privilege escalation and should be reviewed immediately.\n",
"displayName": "[Entra ID] Application Granted Administrative Permission to Assign Microsoft Entra ID Roles",
"enabled": true,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "Source_Identity_FullName",
"identifier": "FullName"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "Source_Network_IPAddress",
"identifier": "Address"
}
]
},
{
"entityType": "CloudApplication",
"fieldMappings": [
{
"columnName": "Target_Identity_FullName",
"identifier": "Name"
}
]
}
],
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/eDCRule/Analytic%20Rules/%5BEntra%20ID%5D%20Application%20Granted%20Administrative%20Permission%20to%20Assign%20Microsoft%20Entra%20ID%20Roles.yaml",
"query": "AuditLogs\n| where Category =~ \"ApplicationManagement\"\n and LoggedByService =~ \"Core Directory\"\n 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\"\n and array_length(TargetResource.modifiedProperties) > 0\n 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\n DisplayName = tostring(Property.displayName),\n 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| extend TargetAppDisplayName = tostring(iff(isnotempty(TargetAppDisplayName), TargetAppDisplayName, TargetAppServicePrincipalId))\n| extend\n InitiatingAccountName = tostring(split(InitiatingUserPrincipalName, \"@\")[0]),\n InitiatingAccountUPNSuffix = tostring(split(InitiatingUserPrincipalName, \"@\")[1])\n| extend Initiator = InitiatingAccountName, Target = TargetAppDisplayName\n| extend\n Source_Network_IPLocation = \"\"\n| project\n Alert_Category_en = \"Entra ID\",\n Alert_SubCategory_en = \"Anomaly Identity Privilege Modification\",\n Alert_Name_en = \"Application Granted Administrative Permission to Assign Microsoft Entra ID Roles\",\n Alert_Description_en = strcat(\"At Taiwan time\", format_datetime(datetime_utc_to_local(TimeGenerated, \"Asia/Taipei\"), \"yyyy-MM-dd HH:mm:ss\"), \". \", \"EntraID:\", \"\", \". \", \"detected source user/service principal \", iff(isnotempty(InitiatingUserPrincipalName), InitiatingUserPrincipalName, InitiatingAppName), \" granted application: \", TargetAppDisplayName, \".\", \" administrative permission to assign Microsoft Entra ID roles: \", ActivityDisplayName, \". Source IP: \", InitiatingIpAddress, \", source location: \", Source_Network_IPLocation),\n Alert_TriageStep_en = strcat(\n \"1. Confirm whether the operating user/service principal: \",\n iff(isnotempty(InitiatingUserPrincipalName), InitiatingUserPrincipalName, InitiatingAppName),\n \", source IP: \",\n InitiatingIpAddress,\n \" is abnormal. \",\n \"2. Review the authorized target application \",\n TargetAppDisplayName,\n \" authorization content: \",\n ActivityDisplayName,\n \" to determine whether it is an expected operation or maintenance task.\"\n ),\n Alert_Containment_en = strcat(\n \"1. If determined to be unauthorized or suspicious privilege escalation, immediately remove the permissions from target application: \",\n TargetAppDisplayName,\n \" and disable it.\",\n \"2. Perform risk handling for the initiator \",\n iff(isnotempty(InitiatingUserPrincipalName), InitiatingUserPrincipalName, InitiatingAppName),\n \" (revoke sessions/force re-authentication, and suspend directory management permissions if necessary).\"\n ),\n Alert_Remediation_en =\n \"1. Strengthen application and permission governance: apply least privilege and administrator approval processes for high-risk Graph/Directory permissions, and include Service Principal credential/permission changes in regular audits. \"\n \"2. Strengthen detection and automation: establish automated response (SOAR) for notification/source blocking/user verification.\",\n Alert_Time_TW = datetime_utc_to_local(TimeGenerated, \"Asia/Taipei\"),\n Alert_Time_UTC0 = TimeGenerated,\n Event_Action = ActivityDisplayName,\n Event_Status = Result,\n Event_Description = PermissionGrant,\n Source_Identity_FullName = iff(isnotempty(InitiatingUserPrincipalName), InitiatingUserPrincipalName, InitiatingAppName),\n Source_Identity_ID = iff(isnotempty(InitiatingAadUserId), InitiatingAadUserId, InitiatingAppServicePrincipalId),\n Source_Identity_Type = iff(isnotempty(InitiatingUserPrincipalName), \"User\", \"Service\"),\n Source_Network_IPAddress = InitiatingIpAddress,\n Source_Network_IPLocation = Source_Network_IPLocation,\n Target_Identity_FullName = TargetAppDisplayName,\n Target_Identity_ID = TargetAppServicePrincipalId,\n Target_Identity_Type = \"Service\",\n Target_Resource_ID = \"\",\n Target_Resource_Name = \"Microsoft Entra ID\",\n Target_Resource_Type = \"Microsoft Entra ID\"\n",
"queryFrequency": "PT2H",
"queryPeriod": "PT2H",
"severity": "High",
"status": "Available",
"subTechniques": [
"T1098.003"
],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"Impact",
"Persistence",
"PrivilegeEscalation"
],
"techniques": [
"T1098"
],
"templateVersion": "1.0.0",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}