Query Details

Conditional Access Gaps

Query

id: 7b8c9d10-aaaa-4001-8001-000000000008
name: HUNT - Conditional Access device-compliance gaps
description: |
  Finds successful sign-ins where ConditionalAccessStatus was `notApplied` and the
  device was not marked compliant/managed. Exposes CA policy gaps that an attacker
  with a non-compliant device would exploit.
requiredDataConnectors:
  - connectorId: AzureActiveDirectory
    dataTypes:
      - SigninLogs
tactics:
  - DefenseEvasion
relevantTechniques:
  - T1562
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
version: 1.0.0

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

Actions