Analytic rule catalog
Threat Essentials - Multiple admin membership removals from newly created admin
Back
| Id | 199978c5-cd6d-4194-b505-8ef5800739df |
| Rulename | Threat Essentials - Multiple admin membership removals from newly created admin. |
| Description | This query detects when newly created Global admin removes multiple existing global admins which can be an attempt by adversaries to lock down organization and retain sole access. Investigate reasoning and intention of multiple membership removal by new Global admins and take necessary actions accordingly. |
| Severity | Medium |
| Tactics | Impact |
| Techniques | T1531 |
| Required data connectors | AzureActiveDirectory |
| Kind | Scheduled |
| Query frequency | 1h |
| Query period | 7d |
| Trigger threshold | 0 |
| Trigger operator | gt |
| Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/SecurityThreatEssentialSolution/Analytic%20Rules/Threat_Essentials_MultipleAdmin_membership_removals_from_NewAdmin.yaml |
| Version | 1.0.2 |
| Arm template | 199978c5-cd6d-4194-b505-8ef5800739df.json |
let lookback = 7d;
let timeframe = 1h;
let GlobalAdminsRemoved = AuditLogs
| where TimeGenerated > ago(timeframe)
| where Category =~ "RoleManagement"
| where AADOperationType in~ ("Unassign", "RemoveEligibleRole")
| where ActivityDisplayName has_any ("Remove member from role", "Remove eligible member from role")
| mv-expand TargetResources
| mv-expand TargetResources.modifiedProperties
| extend displayName_ = tostring(TargetResources_modifiedProperties.displayName)
| where displayName_ =~ "Role.DisplayName"
| extend RoleName = tostring(parse_json(tostring(TargetResources_modifiedProperties.oldValue)))
| where RoleName =~ "Global Administrator" // Add other Privileged role if applicable
| extend InitiatingApp = tostring(parse_json(tostring(InitiatedBy.app)).displayName)
| extend Initiator = iif(isnotempty(InitiatingApp), InitiatingApp, tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName))
| where Initiator != "MS-PIM" and Initiator != "MS-PIM-Fairfax" // Filtering PIM events
| extend Target = tostring(TargetResources.userPrincipalName)
| summarize RemovedGlobalAdminTime = max(TimeGenerated), TargetAdmins = make_set(Target) by OperationName, RoleName, Initiator, Result;
let GlobalAdminsAdded = AuditLogs
| where TimeGenerated > ago(lookback)
| where Category =~ "RoleManagement"
| where AADOperationType in~ ("Assign", "AssignEligibleRole")
| where ActivityDisplayName has_any ("Add eligible member to role", "Add member to role") and Result =~ "success"
| mv-expand TargetResources
| mv-expand TargetResources.modifiedProperties
| extend displayName_ = tostring(TargetResources_modifiedProperties.displayName)
| where displayName_ =~ "Role.DisplayName"
| extend RoleName = tostring(parse_json(tostring(TargetResources_modifiedProperties.newValue)))
| where RoleName =~ "Global Administrator" // Add other Privileged role if applicable
| extend InitiatingApp = tostring(parse_json(tostring(InitiatedBy.app)).displayName)
| extend Initiator = iif(isnotempty(InitiatingApp), InitiatingApp, tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName))
| where Initiator != "MS-PIM" and Initiator != "MS-PIM-Fairfax" // Filtering PIM events
| extend Target = tostring(TargetResources.userPrincipalName)
| summarize AddedGlobalAdminTime = max(TimeGenerated) by OperationName, RoleName, Target, Initiator, Result;
GlobalAdminsAdded
| join kind= inner GlobalAdminsRemoved on $left.Target == $right.Initiator
| where AddedGlobalAdminTime < RemovedGlobalAdminTime
| extend NoofAdminsRemoved = array_length(TargetAdmins)
| where NoofAdminsRemoved > 1
| project AddedGlobalAdminTime, Initiator, Target, RemovedGlobalAdminTime, TargetAdmins, NoofAdminsRemoved
| extend Name=split(Target, "@")[0], UPNSuffix=split(Target, "@")[1]
id: 199978c5-cd6d-4194-b505-8ef5800739df
entityMappings:
- fieldMappings:
- columnName: Name
identifier: Name
- columnName: UPNSuffix
identifier: UPNSuffix
entityType: Account
severity: Medium
status: Available
requiredDataConnectors:
- dataTypes:
- AuditLogs
connectorId: AzureActiveDirectory
kind: Scheduled
query: |
let lookback = 7d;
let timeframe = 1h;
let GlobalAdminsRemoved = AuditLogs
| where TimeGenerated > ago(timeframe)
| where Category =~ "RoleManagement"
| where AADOperationType in~ ("Unassign", "RemoveEligibleRole")
| where ActivityDisplayName has_any ("Remove member from role", "Remove eligible member from role")
| mv-expand TargetResources
| mv-expand TargetResources.modifiedProperties
| extend displayName_ = tostring(TargetResources_modifiedProperties.displayName)
| where displayName_ =~ "Role.DisplayName"
| extend RoleName = tostring(parse_json(tostring(TargetResources_modifiedProperties.oldValue)))
| where RoleName =~ "Global Administrator" // Add other Privileged role if applicable
| extend InitiatingApp = tostring(parse_json(tostring(InitiatedBy.app)).displayName)
| extend Initiator = iif(isnotempty(InitiatingApp), InitiatingApp, tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName))
| where Initiator != "MS-PIM" and Initiator != "MS-PIM-Fairfax" // Filtering PIM events
| extend Target = tostring(TargetResources.userPrincipalName)
| summarize RemovedGlobalAdminTime = max(TimeGenerated), TargetAdmins = make_set(Target) by OperationName, RoleName, Initiator, Result;
let GlobalAdminsAdded = AuditLogs
| where TimeGenerated > ago(lookback)
| where Category =~ "RoleManagement"
| where AADOperationType in~ ("Assign", "AssignEligibleRole")
| where ActivityDisplayName has_any ("Add eligible member to role", "Add member to role") and Result =~ "success"
| mv-expand TargetResources
| mv-expand TargetResources.modifiedProperties
| extend displayName_ = tostring(TargetResources_modifiedProperties.displayName)
| where displayName_ =~ "Role.DisplayName"
| extend RoleName = tostring(parse_json(tostring(TargetResources_modifiedProperties.newValue)))
| where RoleName =~ "Global Administrator" // Add other Privileged role if applicable
| extend InitiatingApp = tostring(parse_json(tostring(InitiatedBy.app)).displayName)
| extend Initiator = iif(isnotempty(InitiatingApp), InitiatingApp, tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName))
| where Initiator != "MS-PIM" and Initiator != "MS-PIM-Fairfax" // Filtering PIM events
| extend Target = tostring(TargetResources.userPrincipalName)
| summarize AddedGlobalAdminTime = max(TimeGenerated) by OperationName, RoleName, Target, Initiator, Result;
GlobalAdminsAdded
| join kind= inner GlobalAdminsRemoved on $left.Target == $right.Initiator
| where AddedGlobalAdminTime < RemovedGlobalAdminTime
| extend NoofAdminsRemoved = array_length(TargetAdmins)
| where NoofAdminsRemoved > 1
| project AddedGlobalAdminTime, Initiator, Target, RemovedGlobalAdminTime, TargetAdmins, NoofAdminsRemoved
| extend Name=split(Target, "@")[0], UPNSuffix=split(Target, "@")[1]
name: Threat Essentials - Multiple admin membership removals from newly created admin.
queryPeriod: 7d
description: |
'This query detects when newly created Global admin removes multiple existing global admins which can be an attempt by adversaries to lock down organization and retain sole access.
Investigate reasoning and intention of multiple membership removal by new Global admins and take necessary actions accordingly.'
tactics:
- Impact
triggerOperator: gt
triggerThreshold: 0
relevantTechniques:
- T1531
version: 1.0.2
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/SecurityThreatEssentialSolution/Analytic%20Rules/Threat_Essentials_MultipleAdmin_membership_removals_from_NewAdmin.yaml
tags:
- DEV-0537
queryFrequency: 1h
{
"$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/199978c5-cd6d-4194-b505-8ef5800739df')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/199978c5-cd6d-4194-b505-8ef5800739df')]",
"properties": {
"alertRuleTemplateName": "199978c5-cd6d-4194-b505-8ef5800739df",
"customDetails": null,
"description": "'This query detects when newly created Global admin removes multiple existing global admins which can be an attempt by adversaries to lock down organization and retain sole access. \n Investigate reasoning and intention of multiple membership removal by new Global admins and take necessary actions accordingly.'\n",
"displayName": "Threat Essentials - Multiple admin membership removals from newly created admin.",
"enabled": true,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "Name",
"identifier": "Name"
},
{
"columnName": "UPNSuffix",
"identifier": "UPNSuffix"
}
]
}
],
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/SecurityThreatEssentialSolution/Analytic%20Rules/Threat_Essentials_MultipleAdmin_membership_removals_from_NewAdmin.yaml",
"query": "let lookback = 7d; \nlet timeframe = 1h; \nlet GlobalAdminsRemoved = AuditLogs \n| where TimeGenerated > ago(timeframe) \n| where Category =~ \"RoleManagement\" \n| where AADOperationType in~ (\"Unassign\", \"RemoveEligibleRole\") \n| where ActivityDisplayName has_any (\"Remove member from role\", \"Remove eligible member from role\") \n| mv-expand TargetResources \n| mv-expand TargetResources.modifiedProperties \n| extend displayName_ = tostring(TargetResources_modifiedProperties.displayName) \n| where displayName_ =~ \"Role.DisplayName\" \n| extend RoleName = tostring(parse_json(tostring(TargetResources_modifiedProperties.oldValue))) \n| where RoleName =~ \"Global Administrator\" // Add other Privileged role if applicable \n| extend InitiatingApp = tostring(parse_json(tostring(InitiatedBy.app)).displayName) \n| extend Initiator = iif(isnotempty(InitiatingApp), InitiatingApp, tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)) \n| where Initiator != \"MS-PIM\" and Initiator != \"MS-PIM-Fairfax\" // Filtering PIM events \n| extend Target = tostring(TargetResources.userPrincipalName) \n| summarize RemovedGlobalAdminTime = max(TimeGenerated), TargetAdmins = make_set(Target) by OperationName, RoleName, Initiator, Result; \nlet GlobalAdminsAdded = AuditLogs \n| where TimeGenerated > ago(lookback) \n| where Category =~ \"RoleManagement\" \n| where AADOperationType in~ (\"Assign\", \"AssignEligibleRole\") \n| where ActivityDisplayName has_any (\"Add eligible member to role\", \"Add member to role\") and Result =~ \"success\" \n| mv-expand TargetResources \n| mv-expand TargetResources.modifiedProperties \n| extend displayName_ = tostring(TargetResources_modifiedProperties.displayName) \n| where displayName_ =~ \"Role.DisplayName\" \n| extend RoleName = tostring(parse_json(tostring(TargetResources_modifiedProperties.newValue))) \n| where RoleName =~ \"Global Administrator\" // Add other Privileged role if applicable \n| extend InitiatingApp = tostring(parse_json(tostring(InitiatedBy.app)).displayName) \n| extend Initiator = iif(isnotempty(InitiatingApp), InitiatingApp, tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)) \n| where Initiator != \"MS-PIM\" and Initiator != \"MS-PIM-Fairfax\" // Filtering PIM events \n| extend Target = tostring(TargetResources.userPrincipalName) \n| summarize AddedGlobalAdminTime = max(TimeGenerated) by OperationName, RoleName, Target, Initiator, Result; \nGlobalAdminsAdded \n| join kind= inner GlobalAdminsRemoved on $left.Target == $right.Initiator \n| where AddedGlobalAdminTime < RemovedGlobalAdminTime \n| extend NoofAdminsRemoved = array_length(TargetAdmins) \n| where NoofAdminsRemoved > 1\n| project AddedGlobalAdminTime, Initiator, Target, RemovedGlobalAdminTime, TargetAdmins, NoofAdminsRemoved\n| extend Name=split(Target, \"@\")[0], UPNSuffix=split(Target, \"@\")[1]\n",
"queryFrequency": "PT1H",
"queryPeriod": "P7D",
"severity": "Medium",
"status": "Available",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"Impact"
],
"tags": [
"DEV-0537"
],
"techniques": [
"T1531"
],
"templateVersion": "1.0.2",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}