Adversaries may leverage expanded conditional access policies in sign-in logs to bypass authentication controls and gain unauthorized access. SOC teams should proactively hunt for this behavior to identify potential abuse of conditional access configurations that could indicate a compromised account or malicious insider activity.
KQL Query
SigninLogs
| extend OS = DeviceDetail.operatingSystem, Browser = DeviceDetail.browser
| extend ConditionalAccessPol0Name = tostring(ConditionalAccessPolicies[0].displayName), ConditionalAccessPol0Result = tostring(ConditionalAccessPolicies[0].result)
| extend ConditionalAccessPol1Name = tostring(ConditionalAccessPolicies[1].displayName), ConditionalAccessPol1Result = tostring(ConditionalAccessPolicies[1].result)
| extend ConditionalAccessPol2Name = tostring(ConditionalAccessPolicies[2].displayName), ConditionalAccessPol2Result = tostring(ConditionalAccessPolicies[2].result)
| extend StatusCode = tostring(Status.errorCode), StatusDetails = tostring(Status.additionalDetails)
| extend State = tostring(LocationDetails.state), City = tostring(LocationDetails.city)
| extend Date = startofday(TimeGenerated), Hour = datetime_part("Hour", TimeGenerated)
| summarize count() by Date, Identity, UserDisplayName, UserPrincipalName, IPAddress, ResultType, ResultDescription, StatusCode, StatusDetails,
ConditionalAccessPol0Name, ConditionalAccessPol0Result, ConditionalAccessPol1Name, ConditionalAccessPol1Result, ConditionalAccessPol2Name, ConditionalAccessPol2Result,
Location, State, City
| extend timestamp = Date, AccountCustomEntity = UserPrincipalName, IPCustomEntity = IPAddress
| sort by Date
id: 4eb6d052-9873-4092-b989-66eae780e203
name: Signin Logs with expanded Conditional Access Policies
description: |
'Example query for SigninLogs showing how to break out packed fields. In this case extending conditional access Policies '
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- SigninLogs
tactics:
- Impact
query: |
SigninLogs
| extend OS = DeviceDetail.operatingSystem, Browser = DeviceDetail.browser
| extend ConditionalAccessPol0Name = tostring(ConditionalAccessPolicies[0].displayName), ConditionalAccessPol0Result = tostring(ConditionalAccessPolicies[0].result)
| extend ConditionalAccessPol1Name = tostring(ConditionalAccessPolicies[1].displayName), ConditionalAccessPol1Result = tostring(ConditionalAccessPolicies[1].result)
| extend ConditionalAccessPol2Name = tostring(ConditionalAccessPolicies[2].displayName), ConditionalAccessPol2Result = tostring(ConditionalAccessPolicies[2].result)
| extend StatusCode = tostring(Status.errorCode), StatusDetails = tostring(Status.additionalDetails)
| extend State = tostring(LocationDetails.state), City = tostring(LocationDetails.city)
| extend Date = startofday(TimeGenerated), Hour = datetime_part("Hour", TimeGenerated)
| summarize count() by Date, Identity, UserDisplayName, UserPrincipalName, IPAddress, ResultType, ResultDescription, StatusCode, StatusDetails,
ConditionalAccessPol0Name, ConditionalAccessPol0Result, ConditionalAccessPol1Name, ConditionalAccessPol1Result, ConditionalAccessPol2Name, ConditionalAccessPol2Result,
Location, State, City
| extend timestamp = Date, AccountCustomEntity = UserPrincipalName, IPCustomEntity = IPAddress
| sort by Date
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: AccountCustomEntity
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPCustomEntity
version: 1.0.0
metadata:
source:
kind: Community
author:
name: Shain
support:
tier: Community
categories:
domains: [ "Security - Other", "Identity" ]
| Sentinel Table | Notes |
|---|---|
SigninLogs | Ensure this data connector is enabled |
Scenario: Scheduled Job for System Maintenance
Description: A system maintenance job runs nightly and authenticates using a service account with multi-factor authentication (MFA) enabled.
Filter/Exclusion: Exclude sign-in logs where userAgent contains "ScheduledJob" or where deviceName is "SystemMaintenanceJob".
Scenario: Admin Task Using Conditional Access Policy
Description: An admin performs a routine task (e.g., user provisioning or role assignment) and triggers a conditional access policy due to the admin’s elevated privileges.
Filter/Exclusion: Exclude sign-in logs where userPrincipalName matches known admin accounts (e.g., [email protected]) or where correlationId is associated with known admin tasks.
Scenario: Conditional Access Policy Triggered by Azure AD Password Reset
Description: A user resets their password via the Azure AD password reset portal, which triggers a conditional access policy due to the authentication method.
Filter/Exclusion: Exclude sign-in logs where signInType is "passwordReset" or where appDisplayName is "Azure AD Password Reset".
Scenario: Conditional Access Policy for Conditional Access Policy Testing
Description: A security team tests a new conditional access policy by simulating a sign-in from a known test account.
Filter/Exclusion: Exclude sign-in logs where userPrincipalName matches test accounts (e.g., [email protected]) or where ipAddress is from a known test IP range.
Scenario: Conditional Access Policy for Conditional Access Policy for Conditional Access Policy
Description: A user signs in from a corporate device that is part of a conditional access policy that enforces MFA, even though the user is already authenticated.
Filter/Exclusion: Exclude sign-in logs where `