Query Details

Identity Device Code Phishing

Query

//Detect potential device code phishing by finding sign ins with both a error 50199 (additional approval required) and error code 0 (success)

//Depending on the size of your tenant - or if you have developers or devices using these flows you may get false positives. 
//The second query looks for new UserPrincipalNames triggering this sign on flow not previously seen in the last 30 days
//The third query searches for a new combination of both UserPrincipalName AND IPAddress not seen in the last 30 days

//Data connector required for this query - Azure Active Directory - Signin Logs

let suspiciousids=
SigninLogs
| where TimeGenerated > ago (1d)
| where ResultType in (0,50199)
| summarize Results=make_set(ResultType) by CorrelationId
| where Results has_all (0, 50199)
| distinct CorrelationId;
SigninLogs
| where CorrelationId in (suspiciousids)
| project TimeGenerated, UserPrincipalName, Location, IPAddress, UserAgent, ResultType


let knownusers=
SigninLogs
| where TimeGenerated > ago (30d) and TimeGenerated < ago(1d)
| where ResultType in (0,50199)
| summarize Results=make_set(ResultType) by CorrelationId, UserPrincipalName
| where Results has_all (0, 50199)
| distinct UserPrincipalName;
let suspiciousids=
SigninLogs
| where TimeGenerated > ago (1d)
| where ResultType in (0,50199)
| summarize Results=make_set(ResultType) by CorrelationId, UserPrincipalName
| where Results has_all (0, 50199)
| where UserPrincipalName !in (knownusers)
| distinct CorrelationId;
SigninLogs
| where CorrelationId in (suspiciousids)
| project TimeGenerated, UserPrincipalName, Location, IPAddress, UserAgent, ResultType


let suspiciousids=
SigninLogs
| where TimeGenerated > ago (30d) and TimeGenerated < ago(1d)
| where ResultType in (0, 50199)
| summarize Results=make_set(ResultType) by CorrelationId, UserPrincipalName, IPAddress
| where Results has_all (0, 50199)
| distinct UserPrincipalName, IPAddress
| join kind=rightanti (
    SigninLogs
    | where TimeGenerated > ago (1d)
    | where ResultType in (0, 50199)
    | summarize Results=make_set(ResultType) by CorrelationId, UserPrincipalName, IPAddress
    | where Results has_all (0, 50199)
    ) 
    on UserPrincipalName, IPAddress
    | distinct CorrelationId;
SigninLogs
| where CorrelationId in (suspiciousids)
| project TimeGenerated, UserPrincipalName, Location, IPAddress, UserAgent, ResultType

Explanation

The query is looking for potential device code phishing by finding sign-ins with both error code 50199 (additional approval required) and error code 0 (success). It also checks for new UserPrincipalNames triggering this sign-on flow that have not been seen in the last 30 days. Additionally, it searches for a new combination of both UserPrincipalName and IPAddress not seen in the last 30 days. The query uses the Azure Active Directory - Signin Logs data connector. The results include the time generated, user principal name, location, IP address, user agent, and result type for the suspicious sign-ins.

Details

Matt Zorich profile picture

Matt Zorich

Released: December 16, 2022

Tables

SigninLogs

Keywords

Keywords:SigninLogs,TimeGenerated,UserPrincipalName,Location,IPAddress,UserAgent,ResultType,ago,make_set,CorrelationId,has_all,distinct,knownusers,join,rightanti

Operators

whereagoinmake_setbyhas_alldistinctprojectjoinkindon

Actions