Query Details

HUNT - Conditional Access device-compliance gaps

Conditional Access Gaps

Query

let NetworkAllowlist = _GetWatchlist('NetworkAllowlist') | project IPRange = tostring(SearchKey);
let AllowedRanges = toscalar(NetworkAllowlist | summarize make_list(IPRange));
SigninLogs
| where TimeGenerated > ago(7d) and ResultType == 0
| where not(ipv4_is_in_any_range(tostring(IPAddress), AllowedRanges))
| extend IsCompliant = tobool(tostring(DeviceDetail.isCompliant)),
         IsManaged   = tobool(tostring(DeviceDetail.isManaged)),
         TrustType   = tostring(DeviceDetail.trustType),
         CAStatus    = tostring(ConditionalAccessStatus)
| where CAStatus =~ "notApplied" and (IsCompliant != true or IsManaged != true)
| summarize SignIns = count(),
            Apps  = make_set(AppDisplayName, 20),
            IPs   = make_set(IPAddress, 20),
            Users = make_set(UserPrincipalName, 50)
          by TrustType
| order by SignIns desc

Explanation

This query is designed to identify security gaps in Conditional Access (CA) policies by analyzing sign-in logs from Azure Active Directory. It specifically looks for successful sign-ins where the Conditional Access Status was "notApplied" and the device used was either not compliant or not managed. This scenario could be exploited by an attacker using a non-compliant device.

Here's a breakdown of the query:

  1. Network Allowlist: It retrieves a list of allowed IP ranges from a watchlist named 'NetworkAllowlist'.

  2. SigninLogs Filtering: It filters sign-in logs from the past 7 days where the sign-in was successful (ResultType == 0) and the IP address is not in the allowed ranges.

  3. Device Compliance Check: It checks if the device is compliant or managed. It also retrieves the trust type of the device and the status of Conditional Access.

  4. Conditional Access Status: It focuses on entries where the Conditional Access Status was "notApplied" and the device was either not compliant or not managed.

  5. Data Summarization: It summarizes the data by counting the number of sign-ins and listing the applications, IP addresses, and user principal names involved, grouped by the device's trust type.

  6. Ordering: The results are ordered by the number of sign-ins in descending order.

This query helps identify potential security risks by highlighting instances where Conditional Access policies were not applied, potentially allowing unauthorized access through non-compliant devices.

Details

David Alonso profile picture

David Alonso

Released: April 22, 2026

Tables

SigninLogs

Keywords

AzureActiveDirectorySigninLogsDeviceConditionalAccessStatusDeviceDetailIPAddressUserPrincipalNameAppDisplayNameNetworkAllowlist

Operators

letprojecttoscalarsummarizemake_listwhereagoandnotipv4_is_in_any_rangetostringextendtobool=~!=orcountmake_setbyorder bydesc

Tactics

DefenseEvasion

MITRE Techniques

Actions

GitHub