Query Details

Identity Risk Eventfollowedby MF Achanges

Query

// Detects when a user flags an Azure AD risk event followed by changes to their MFA profile - potentially detecting a bad actor changing MFA details

//Data connector required for this query - Azure Active Directory - AAD User Risk Events
//Data connector required for this query - Azure Active Directory - Audit Logs

// Timeframe = the minutes between flagging a risk event and MFA details being changed
let timeframe = 120;
//Search for real time risk events only and retrieve Correlation Id
AADUserRiskEvents
| where TimeGenerated > ago (1d)
| where DetectionTimingType == "realtime"
| where RiskDetail <> "aiConfirmedSigninSafe"
| project CorrelationId
//Join Correlation Id back to sign in data to retrieve the initial sign in time that was flagged for risk
| join kind=inner(
SigninLogs
| where TimeGenerated > ago (1d))
on CorrelationId
| summarize ['Risky Signin Time']=min(TimeGenerated) by CorrelationId, UserPrincipalName
//Join risky sign in UserPrincipalName to audit log for MFA events
| join kind=inner (
    AuditLogs
    | where TimeGenerated > ago (1d)
    | where OperationName in ("User registered security info", "User deleted security info","User registered all required security info")
    | where Result == "success"
    | extend UserPrincipalName = tostring(TargetResources[0].userPrincipalName)
//Find the latest event in the MFA registration process
    | summarize arg_max(TimeGenerated, *) by UserPrincipalName
    | project
        ['MFA Change Time']=TimeGenerated,
        OperationName,
        UserPrincipalName)
    on UserPrincipalName
//Calculate the time between the initial sign in event and the MFA change time
| extend ['Minutes Between Events']=datetime_diff("minute",['MFA Change Time'], ['Risky Signin Time'])
| project-away UserPrincipalName1
| project-reorder ['Risky Signin Time'], ['MFA Change Time'], ['Minutes Between Events'], UserPrincipalName, OperationName, CorrelationId
//Find events where the time between the two events was less than 120 minutes
| where ['Minutes Between Events'] < timeframe

Explanation

This query detects when a user flags an Azure AD risk event and then changes their MFA (Multi-Factor Authentication) profile. It aims to identify potential bad actors who may be trying to manipulate their MFA details.

The query uses two data connectors: Azure Active Directory - AAD User Risk Events and Azure Active Directory - Audit Logs.

The timeframe for detecting these events is set to 120 minutes.

The query first searches for real-time risk events in the past 24 hours and retrieves the Correlation Id. It then joins the Correlation Id with sign-in data to find the initial sign-in time that was flagged as risky.

Next, it joins the risky sign-in UserPrincipalName with the audit log for MFA events. It looks for MFA-related operations such as registering or deleting security info and selects the latest event in the MFA registration process.

The query calculates the time between the initial sign-in event and the MFA change event. It then filters for events where the time between the two events is less than 120 minutes.

The final result includes the risky sign-in time, MFA change time, minutes between events, UserPrincipalName, OperationName, and CorrelationId.

Details

Matt Zorich profile picture

Matt Zorich

Released: June 17, 2022

Tables

AADUserRiskEventsSigninLogsAuditLogs

Keywords

User,AzureAD,MFA,RiskEvent,CorrelationId,SigninLogs,AuditLogs,OperationName,Result,TargetResources,TimeGenerated,MinutesBetweenEvents

Operators

| where| let| project| join| summarize| where| extend| datetime_diff| project-away| project-reorder

Actions