Suspicious Login from deleted guest account
| Id | defe4855-0d33-4362-9557-009237623976 |
| Rulename | Suspicious Login from deleted guest account |
| Description | This query will detect logins from guest account which was recently deleted. For any successful logins from deleted identities should be investigated further if any existing user accounts have been altered or linked to such identity prior deletion |
| Severity | Medium |
| Tactics | PrivilegeEscalation |
| Techniques | T1078.004 |
| Required data connectors | AzureActiveDirectory |
| Kind | Scheduled |
| Query frequency | 1h |
| Query period | 1d |
| Trigger threshold | 0 |
| Trigger operator | gt |
| Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Detections/MultipleDataSources/SuspiciousLoginfromDeletedExternalIdentities.yaml |
| Version | 1.0.5 |
| Arm template | defe4855-0d33-4362-9557-009237623976.json |
let query_frequency = 1h;
let query_period = 1d;
AuditLogs
| where TimeGenerated > ago(query_frequency)
| where Category =~ "UserManagement" and OperationName =~ "Delete user"
| mv-expand TargetResource = TargetResources
| where TargetResource["type"] == "User" and TargetResource["userPrincipalName"] has "#EXT#"
| extend ParsedDeletedUserPrincipalName = extract(@"^[0-9a-f]{32}([^\#]+)\#EXT\#", 1, tostring(TargetResource["userPrincipalName"]))
| extend
Initiator = iif(isnotempty(InitiatedBy["app"]), tostring(InitiatedBy["app"]["displayName"]), tostring(InitiatedBy["user"]["userPrincipalName"])),
InitiatorId = iif(isnotempty(InitiatedBy["app"]), tostring(InitiatedBy["app"]["servicePrincipalId"]), tostring(InitiatedBy["user"]["id"])),
Delete_IPAddress = tostring(InitiatedBy[tostring(bag_keys(InitiatedBy)[0])]["ipAddress"])
| project Delete_TimeGenerated = TimeGenerated, Category, Identity, Initiator, Delete_IPAddress, OperationName, Result, ParsedDeletedUserPrincipalName, InitiatedBy, AdditionalDetails, TargetResources, InitiatorId, CorrelationId
| join kind=inner (
SigninLogs
| where TimeGenerated > ago(query_period)
| where ResultType == 0
| summarize take_any(*) by UserPrincipalName
| extend ParsedUserPrincipalName = translate("@", "_", UserPrincipalName)
| project SigninLogs_TimeGenerated = TimeGenerated, UserPrincipalName, UserDisplayName, ResultType, ResultDescription, IPAddress, LocationDetails, AppDisplayName, ResourceDisplayName, ClientAppUsed, UserAgent, DeviceDetail, UserId, UserType, OriginalRequestId, ParsedUserPrincipalName
) on $left.ParsedDeletedUserPrincipalName == $right.ParsedUserPrincipalName
| where SigninLogs_TimeGenerated > Delete_TimeGenerated
| project-away ParsedDeletedUserPrincipalName, ParsedUserPrincipalName
| extend
AccountName = tostring(split(UserPrincipalName, "@")[0]),
AccountUPNSuffix = tostring(split(UserPrincipalName, "@")[1])
description: |
' This query will detect logins from guest account which was recently deleted.
For any successful logins from deleted identities should be investigated further if any existing user accounts have been altered or linked to such identity prior deletion'
queryPeriod: 1d
severity: Medium
tags:
- GuestorExternalIdentities
triggerThreshold: 0
queryFrequency: 1h
tactics:
- PrivilegeEscalation
version: 1.0.5
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/MultipleDataSources/SuspiciousLoginfromDeletedExternalIdentities.yaml
query: |
let query_frequency = 1h;
let query_period = 1d;
AuditLogs
| where TimeGenerated > ago(query_frequency)
| where Category =~ "UserManagement" and OperationName =~ "Delete user"
| mv-expand TargetResource = TargetResources
| where TargetResource["type"] == "User" and TargetResource["userPrincipalName"] has "#EXT#"
| extend ParsedDeletedUserPrincipalName = extract(@"^[0-9a-f]{32}([^\#]+)\#EXT\#", 1, tostring(TargetResource["userPrincipalName"]))
| extend
Initiator = iif(isnotempty(InitiatedBy["app"]), tostring(InitiatedBy["app"]["displayName"]), tostring(InitiatedBy["user"]["userPrincipalName"])),
InitiatorId = iif(isnotempty(InitiatedBy["app"]), tostring(InitiatedBy["app"]["servicePrincipalId"]), tostring(InitiatedBy["user"]["id"])),
Delete_IPAddress = tostring(InitiatedBy[tostring(bag_keys(InitiatedBy)[0])]["ipAddress"])
| project Delete_TimeGenerated = TimeGenerated, Category, Identity, Initiator, Delete_IPAddress, OperationName, Result, ParsedDeletedUserPrincipalName, InitiatedBy, AdditionalDetails, TargetResources, InitiatorId, CorrelationId
| join kind=inner (
SigninLogs
| where TimeGenerated > ago(query_period)
| where ResultType == 0
| summarize take_any(*) by UserPrincipalName
| extend ParsedUserPrincipalName = translate("@", "_", UserPrincipalName)
| project SigninLogs_TimeGenerated = TimeGenerated, UserPrincipalName, UserDisplayName, ResultType, ResultDescription, IPAddress, LocationDetails, AppDisplayName, ResourceDisplayName, ClientAppUsed, UserAgent, DeviceDetail, UserId, UserType, OriginalRequestId, ParsedUserPrincipalName
) on $left.ParsedDeletedUserPrincipalName == $right.ParsedUserPrincipalName
| where SigninLogs_TimeGenerated > Delete_TimeGenerated
| project-away ParsedDeletedUserPrincipalName, ParsedUserPrincipalName
| extend
AccountName = tostring(split(UserPrincipalName, "@")[0]),
AccountUPNSuffix = tostring(split(UserPrincipalName, "@")[1])
metadata:
categories:
domains:
- Security - Others
- Identity
author:
name: Microsoft Security Research
source:
kind: Community
support:
tier: Community
triggerOperator: gt
name: Suspicious Login from deleted guest account
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- AuditLogs
- connectorId: AzureActiveDirectory
dataTypes:
- SigninLogs
relevantTechniques:
- T1078.004
kind: Scheduled
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: UserPrincipalName
- identifier: Name
columnName: AccountName
- identifier: UPNSuffix
columnName: AccountUPNSuffix
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPAddress
id: defe4855-0d33-4362-9557-009237623976