Detection rules › Kusto
Microsoft Entra ID Hybrid Health AD FS Suspicious Application
This detection uses AzureActivity logs (Administrative category) to identify a suspicious application adding a server instance to an Microsoft Entra ID Hybrid Health AD FS service or deleting the AD FS service instance. Usually the Microsoft Entra ID Connect Health Agent application with ID cf6d7e68-f018-4e0a-a7b3-126e053fb88d and ID cb1056e2-e479-49de-ae31-7812af012ed8 is used to perform those operations.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Credential Access | |
| Lateral Movement |
Telemetry coverage
Rules detecting the same action
These rules filter on the same operation.
- Azure Active Directory Hybrid Health AD FS New Server (Sigma)
- Azure Active Directory Hybrid Health AD FS Service Delete (Sigma)
- Azure Subscription Permission Elevation Via AuditLogs (Sigma)
- Detect Custom Script or Run Command deployment by risky user (Kusto)
- Microsoft Entra ID Hybrid Health AD FS New Server (Kusto)
- Microsoft Entra ID Hybrid Health AD FS Service Delete (Kusto)
- NRT Microsoft Entra ID Hybrid Health AD FS New Server (Kusto)
Rule body
id: d9938c3b-16f9-444d-bc22-ea9a9110e0fd
name: Microsoft Entra ID Hybrid Health AD FS Suspicious Application
description: |
'This detection uses AzureActivity logs (Administrative category) to identify a suspicious application adding a server instance to an Microsoft Entra ID Hybrid Health AD FS service or deleting the AD FS service instance.
Usually the Microsoft Entra ID Connect Health Agent application with ID cf6d7e68-f018-4e0a-a7b3-126e053fb88d and ID cb1056e2-e479-49de-ae31-7812af012ed8 is used to perform those operations.'
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: AzureActivity
dataTypes:
- AzureActivity
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- CredentialAccess
- DefenseEvasion
relevantTechniques:
- T1528
- T1550
tags:
- SimuLand
query: |
// Microsoft Entra ID Connect Health Agent - cf6d7e68-f018-4e0a-a7b3-126e053fb88d
// Microsoft Entra ID Connect - cb1056e2-e479-49de-ae31-7812af012ed8
let appList = dynamic(['cf6d7e68-f018-4e0a-a7b3-126e053fb88d','cb1056e2-e479-49de-ae31-7812af012ed8']);
let operationNamesList = dynamic(['Microsoft.ADHybridHealthService/services/servicemembers/action','Microsoft.ADHybridHealthService/services/delete']);
AzureActivity
| where CategoryValue =~ 'Administrative'
| where ResourceProviderValue =~ 'Microsoft.ADHybridHealthService'
| where _ResourceId has 'AdFederationService'
| where OperationNameValue in~ (operationNamesList)
| extend claimsJson = parse_json(Claims)
| extend AppId = tostring(claimsJson.appid), AccountName = tostring(claimsJson.name), Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])
| where AppId !in (appList)
| project-away claimsJson
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: Caller
- identifier: Name
columnName: Name
- identifier: UPNSuffix
columnName: UPNSuffix
- entityType: IP
fieldMappings:
- identifier: Address
columnName: CallerIpAddress
version: 2.0.3
kind: Scheduled
Stages and Predicates
Parameters
let appList = dynamic(['cf6d7e68-f018-4e0a-a7b3-126e053fb88d','cb1056e2-e479-49de-ae31-7812af012ed8']);
let operationNamesList = dynamic(['Microsoft.ADHybridHealthService/services/servicemembers/action','Microsoft.ADHybridHealthService/services/delete']);
Stage 1: source
AzureActivity
Stage 2: where
| where CategoryValue =~ 'Administrative'
Stage 3: where
| where ResourceProviderValue =~ 'Microsoft.ADHybridHealthService'
Stage 4: where
| where _ResourceId has 'AdFederationService'
Stage 5: where
| where OperationNameValue in~ (operationNamesList)
Stage 6: extend
| extend claimsJson = parse_json(Claims)
Stage 7: extend
| extend AppId = tostring(claimsJson.appid), AccountName = tostring(claimsJson.name), Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])
Stage 8: where
| where AppId !in (appList)
Stage 9: project-away
| project-away claimsJson
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
AppId | in | cb1056e2-e479-49de-ae31-7812af012ed8, cf6d7e68-f018-4e0a-a7b3-126e053fb88d | excludes:AppId field:"AppId" value:"cb1056e2-e479-49de-ae31-7812af012ed8" field:"AppId" value:"cf6d7e68-f018-4e0a-a7b3-126e053fb88d" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
CategoryValue | eq |
| field:"CategoryValue" kind:eq value:"Administrative" |
OperationNameValue | in |
| field:"azure_ad::operation_name_value" kind:in |
ResourceProviderValue | eq |
| field:"ResourceProviderValue" kind:eq value:"Microsoft.ADHybridHealthService" |
_ResourceId | match |
| field:"_ResourceId" kind:match value:"AdFederationService" |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
AccountName | extend |
AppId | extend |
Name | extend |
UPNSuffix | extend |