Query Details

Function User Investigation

Query

//Single function to investigate potential suspicious activity across several data sources. The function will find the following information.
//Azure AD Sign in Logs - legacy auth attempts, conditional access failures, new user agents or locations found in the last day
//Azure AD Audit Logs - add service principals, consent to permissions, add credentials to service principals, any MFA configuration changes
//Azure AD risk events - any non automatically dismissed risk events
//Defender for Cloud Apps - mailbox rule changes
//Security Alert - any alerts from the various products such as Azure AD Identity Protection, Defender for Office 365 etc
//Save as a function in your workspace then invoke via its name, ie UserInvestigation("[email protected]"). Your function requires a parameter as per https://github.com/reprise99/Sentinel-Queries/tree/main/Functions
let legacyauth=
SigninLogs
| where TimeGenerated > ago (30d)
| where UserPrincipalName =~ user
| where ClientAppUsed !in ("Mobile Apps and Desktop clients", "Browser") and isnotempty( ClientAppUsed)
| extend Indicator = "Legacy auth attempts detected"
| extend ['Event Source'] = "Azure AD Signin Logs"
| project TimeGenerated, UserPrincipalName, AppDisplayName, ClientAppUsed, IPAddress, Location, UserAgent, ResultType, ResultDescription, Indicator, ['Event Source'], TableName=Type, CorrelationId;
let cafailures=
SigninLogs
| where TimeGenerated > ago (30d)
| where UserPrincipalName =~ user
| where ResultType == "53003"
| extend Indicator = "Conditional Access failures detected"
| extend ['Event Source'] = "Azure AD Signin Logs"
| project TimeGenerated, UserPrincipalName, AppDisplayName, ClientAppUsed, IPAddress, tostring(Location), UserAgent, ResultType, ResultDescription, Indicator, ['Event Source'], TableName=Type, CorrelationId;
let newuseragents=
SigninLogs
| where TimeGenerated > ago(30d) and TimeGenerated < ago(1d)
| where UserPrincipalName =~ user
| distinct UserAgent
| join kind=rightanti (
SigninLogs
| where TimeGenerated > ago (1d)
| where UserPrincipalName =~ user
) on UserAgent
| extend Indicator = "New user agent detected in last day"
| extend ['Event Source'] = "Azure AD Signin Logs"
| project TimeGenerated, UserPrincipalName, AppDisplayName, ClientAppUsed, IPAddress, tostring(Location), UserAgent, ResultType, ResultDescription, Indicator, ['Event Source'], TableName=Type, CorrelationId;
let newlocations=
SigninLogs
| where TimeGenerated > ago(30d) and TimeGenerated < ago(1d)
| where UserPrincipalName =~ user
| where TimeGenerated > ago(30d) and TimeGenerated < ago(1d)
| distinct Location
| join kind=rightanti (
SigninLogs
| where TimeGenerated > ago (1d)
| where UserPrincipalName =~ user
) on Location
| extend Indicator = "New location detected in last day"
| extend ['Event Source'] = "Azure AD Signin Logs"
| project TimeGenerated, UserPrincipalName, AppDisplayName, ClientAppUsed, IPAddress, tostring(Location), UserAgent, ResultType, ResultDescription, Indicator, ['Event Source'], TableName=Type, CorrelationId;
let riskevents=
AADUserRiskEvents
| where TimeGenerated > ago (30d)
| where UserPrincipalName =~ (user)
| where RiskDetail <> "aiConfirmedSigninSafe"
| extend Indicator = "Azure AD risk event detected"
| extend ['Event Source'] = "Azure AD Risky Signin Logs"
| project TimeGenerated, UserPrincipalName, IPAddress=IpAddress, tostring(Location), RiskState, RiskLevel, RiskEventType, RiskDetail, Indicator, ['Event Source'], TableName=Type, CorrelationId;
let audit=
AuditLogs
| where TimeGenerated > ago (30d)
| where OperationName in~ ("Add service principal","Consent to application","Update application – Certificates and secrets management ","User registered security info", "User changed default security info", "User deleted security info")
| extend UserPrincipalName = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)
| where UserPrincipalName =~ user
| extend Indicator = case (
    OperationName == "Add service principal", strcat("Azure AD service principal added"),
    OperationName == "Consent to application", strcat("Azure AD service principal permissions consented to"),
    OperationName == "Update application – Certificates and secrets management ", strcat("Azure AD service principal credentials added"),
    OperationName == "User registered security info", strcat("MFA method registered"),
    OperationName == "User changed default security info", strcat("MFA default method changed"),
    OperationName == "User deleted security info", strcat("MFA method deleted"),
    "unknown"
    )
| extend ['Event Source'] = "Azure AD Audit Logs"
| extend IPAddress = tostring(parse_json(tostring(InitiatedBy.user)).ipAddress)
| project TimeGenerated, IPAddress, Indicator, ['Event Source'], TableName=Type, CorrelationId;
let cloudapp=
CloudAppEvents
| where TimeGenerated > ago (30d)
| where ActionType in ("New-InboxRule","Remove-InboxRule","Set-InboxRule")
| extend UserPrincipalName = tostring(RawEventData.UserId)
| where UserPrincipalName =~ user
| extend CorrelationId = tostring(RawEventData.Id)
| extend ['Event Source'] = "Defender for Cloud Apps Logs"
| extend Indicator = case (
    ActionType == "New-InboxRule", strcat("Exchange Online inbox rule created"),
    ActionType == "Remove-InboxRule", strcat("Exchange Online inbox rule deleted"),
    ActionType == "Set-InboxRule", strcat("Exchange Online inbox rule changed"),
    "unknown"
    )
| project TimeGenerated, UserPrincipalName, IPAddress, Indicator, TableName=Type, ['Event Source'];
let alerts=
SecurityAlert
| where TimeGenerated > ago (30d)
| where CompromisedEntity =~ user
| project TimeGenerated, UserPrincipalName=CompromisedEntity, Indicator=AlertName, TableName=Type, ['Event Source']=ProductName;
union legacyauth, cafailures, newuseragents, newlocations, riskevents, audit, cloudapp, alerts
| project-reorder TimeGenerated, UserPrincipalName, Indicator, ['Event Source'], TableName, IPAddress
| sort by Indicator asc, TimeGenerated desc

Explanation

The query investigates potential suspicious activity across multiple data sources. It looks for various types of activity in Azure AD Sign in Logs, Azure AD Audit Logs, Azure AD risk events, Defender for Cloud Apps, and Security Alerts. The query filters the logs based on specific criteria such as legacy authentication attempts, conditional access failures, new user agents or locations found in the last day, service principal changes, consent to permissions, MFA configuration changes, mailbox rule changes, and alerts from various products. The results are then combined and sorted by the type of activity and the time it occurred.

Details

Matt Zorich profile picture

Matt Zorich

Released: May 31, 2022

Tables

SigninLogsAADUserRiskEventsAuditLogsCloudAppEventsSecurityAlert

Keywords

AzureADSigninLogs,AzureADAuditLogs,AzureADriskevents,DefenderforCloudApps,SecurityAlert

Operators

whereago=~!inisnotemptyextendprojectjoindistincttostringoncasestrcatparse_jsonin~unionproject-reordersort by

Actions