Possible device code phishing attempts
Description
This query helps hunting for possible device code Phishing attempts
Query · kql
let suspiciousUserClicks = materialize(UrlClickEvents
| where ActionType in ("ClickAllowed", "UrlScanInProgress", "UrlErrorPage") or IsClickedThrough != "0"
| where UrlChain has_any ("microsoft.com/devicelogin", "login.microsoftonline.com/common/oauth2/deviceauth")
| extend AccountUpn = tolower(AccountUpn)
| project ClickTime = Timestamp, ActionType, UrlChain, NetworkMessageId, Url, AccountUpn);
//Check for Risky Sign-In in the short time window
let interestedUsersUpn = suspiciousUserClicks
| where isnotempty(AccountUpn)
| distinct AccountUpn;
let suspiciousSignIns = materialize(EntraIdSignInEvents
| where ErrorCode == 0
| where AccountUpn in~ (interestedUsersUpn)
| where RiskLevelDuringSignIn in (10, 50, 100)
| extend AccountUpn = tolower(AccountUpn)
| join kind=inner suspiciousUserClicks on AccountUpn
| where (Timestamp - ClickTime) between (-2min .. 7min)
| project Timestamp, ReportId, ClickTime, AccountUpn, RiskLevelDuringSignIn, SessionId, IPAddress, Url
);
//Validate errorCode 50199 followed by success in 5 minute time interval for the interested user, which suggests a pause to input the code from the phishing email
let interestedSessionUsers = suspiciousSignIns
| where isnotempty(AccountUpn)
| distinct AccountUpn;
let shortIntervalSignInAttemptUsers = materialize(EntraIdSignInEvents
| where AccountUpn in~ (interestedSessionUsers)
| where ErrorCode in (0, 50199)
| summarize ErrorCodes = make_set(ErrorCode) by AccountUpn, CorrelationId, SessionId
| where ErrorCodes has_all (0, 50199)
| distinct AccountUpn);
suspiciousSignIns
| where AccountUpn in (shortIntervalSignInAttemptUsers)