// Microsoft Entra ID Backdoors: Identity Federation
//Ref: https://www.inversecos.com/2021/11/how-to-detect-azure-active-directory.html
AuditLogs
| where OperationName == "Add unverified domain"
| where Result == "success"
| extend InitiatedBy = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)
| extend DomainName = tostring(TargetResources[0].displayName)
| summarize DomainAddedTime = min(TimeGenerated), ModifiedProperties = make_set(parse_json(TargetResources[0].modifiedProperties),1048576) by InitiatedBy, DomainName
| join kind=inner (
SigninLogs
| where ResultType == "0"
| extend UserDomain = tostring(parse_json(split(UserPrincipalName,"@",1)[0]))
| summarize SignInTime = min(TimeGenerated) by UserPrincipalName, IPAddress, tostring(LocationDetails),AppDisplayName,ResourceDisplayName,UserDomain
) on $left.DomainName == $right.UserDomain
// Getting UserName and Domain
| extend Name = split(UserPrincipalName,"@",0), Domain = split(UserPrincipalName,"@",1)
| mv-expand Name,Domain
requiredDataConnectors:
- dataTypes:
- SigninLogs
- AuditLogs
connectorId: AzureActiveDirectory
description: |
'Identifies when a user adds an unverified domain as an authentication method, followed by a sign-in from a user the newly added domain. Threat actors may add custom domains to create a backdoor to your tenant. It's important to monitor whenever custom domains are added to the tenant.'
relevantTechniques:
- T1098
tactics:
- Persistence
triggerThreshold: 0
triggerOperator: gt
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Entra ID/Analytic Rules/PossibleSignInfromAzureBackdoor.yaml
version: 1.0.0
queryPeriod: 1h
customDetails:
DomainAddedTime: DomainAddedTime
AppDisplayName: AppDisplayName
InitiatedBy: InitiatedBy
ModifiedProperties: ModifiedProperties
ResourceDisplayName: ResourceDisplayName
DomainAdded: DomainName
SignInTime: SignInTime
id: fa00014c-c5f4-4715-8f5b-ba567e19e41e
severity: Medium
kind: Scheduled
entityMappings:
- entityType: Account
fieldMappings:
- columnName: UserDomain
identifier: NTDomain
- columnName: UserPrincipalName
identifier: FullName
- entityType: IP
fieldMappings:
- columnName: IPAddress
identifier: Address
name: Possible SignIn from Azure Backdoor
queryFrequency: 1h
query: |
// Microsoft Entra ID Backdoors: Identity Federation
//Ref: https://www.inversecos.com/2021/11/how-to-detect-azure-active-directory.html
AuditLogs
| where OperationName == "Add unverified domain"
| where Result == "success"
| extend InitiatedBy = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)
| extend DomainName = tostring(TargetResources[0].displayName)
| summarize DomainAddedTime = min(TimeGenerated), ModifiedProperties = make_set(parse_json(TargetResources[0].modifiedProperties),1048576) by InitiatedBy, DomainName
| join kind=inner (
SigninLogs
| where ResultType == "0"
| extend UserDomain = tostring(parse_json(split(UserPrincipalName,"@",1)[0]))
| summarize SignInTime = min(TimeGenerated) by UserPrincipalName, IPAddress, tostring(LocationDetails),AppDisplayName,ResourceDisplayName,UserDomain
) on $left.DomainName == $right.UserDomain
// Getting UserName and Domain
| extend Name = split(UserPrincipalName,"@",0), Domain = split(UserPrincipalName,"@",1)
| mv-expand Name,Domain