Detection rules › Kusto

Conditional Access - A Conditional Access policy was updated

Severity
informational
Time window
5m
Source
github.com/Azure/Azure-Sentinel

A Conditional Access policy was updated in Entra ID.

MITRE ATT&CK coverage

TacticTechniques
Defense Impairment

Telemetry coverage

PlatformRecord / event type
AzureUpdate conditional access policy

Rules detecting the same action

These rules filter on the same operation.

Rule body

id: ccca6b88-a7b6-41c9-9be2-fc3daeb65b26
name: Conditional Access - A Conditional Access policy was updated
version: 1.0.1
kind: Scheduled
description: A Conditional Access policy was updated in Entra ID.
severity: Informational
requiredDataConnectors:
  - connectorId: AzureActiveDirectory
    dataTypes:
      - AuditLogs
queryFrequency: 5m
queryPeriod: 5m
triggerOperator: gt
triggerThreshold: 0
tactics:
- DefenseEvasion
relevantTechniques:
- T1562
query: |+
  // A Conditional Access policy was updated.
  AuditLogs
  | where OperationName == "Update conditional access policy"
  | extend
      policy = tostring(TargetResources[0].displayName),
      modifiedBy = tostring(InitiatedBy.user.userPrincipalName),
      oldPolicy = tostring(TargetResources[0].modifiedProperties[0].oldValue),
      newPolicy = tostring(TargetResources[0].modifiedProperties[0].newValue)
  | extend
      accountName = tostring(split(modifiedBy, "@")[0]),
      upnSuffix = tostring(split(modifiedBy, "@")[1])
  | project
      TimeGenerated,
      OperationName,
      policy,
      modifiedBy,
      accountName,
      upnSuffix,
      oldPolicy,
      newPolicy,
      Result
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: Name
    columnName: accountName
  - identifier: UPNSuffix
    columnName: upnSuffix
suppressionEnabled: false
suppressionDuration: 5h
eventGroupingSettings:
  aggregationKind: AlertPerResult
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: false
    reopenClosedIncident: false
    lookbackDuration: PT1H
    matchingMethod: AllEntities
    groupByEntities: []
    groupByAlertDetails: []
    groupByCustomDetails: []

Stages and Predicates

Stage 1: source

AuditLogs

Stage 2: where

| where OperationName == "Update conditional access policy"

Stage 3: extend

| extend
    policy = tostring(TargetResources[0].displayName),
    modifiedBy = tostring(InitiatedBy.user.userPrincipalName),
    oldPolicy = tostring(TargetResources[0].modifiedProperties[0].oldValue),
    newPolicy = tostring(TargetResources[0].modifiedProperties[0].newValue)

Stage 4: extend

| extend
    accountName = tostring(split(modifiedBy, "@")[0]),
    upnSuffix = tostring(split(modifiedBy, "@")[1])

Stage 5: project

| project
    TimeGenerated,
    OperationName,
    policy,
    modifiedBy,
    accountName,
    upnSuffix,
    oldPolicy,
    newPolicy,
    Result

Indicators

These rows show field, operator, and value matches.

Output fields

These fields are emitted when the rule matches.

FieldSource
OperationNameproject
Resultproject
TimeGeneratedproject
accountNameproject
modifiedByproject
newPolicyproject
oldPolicyproject
policyproject
upnSuffixproject