Signinlogs Legacy Protocols Used In Entra Id Authentication
KQL detection rule by ep3p · MIT
No description provided
let legacy_auth_protocols = dynamic(["Authenticated SMTP", "AutoDiscover", "Exchange ActiveSync", "Exchange Online PowerShell", "Exchange Web Services", "IMAP4", "MAPI Over HTTP", "Outlook Anywhere (RPC over HTTP)", "Outlook Service", "POP3", "Reporting Web Services", "Other clients"]);
let legacy_user_agents = dynamic(["BAV2ROPC", "CBAinPROD", "CBAinTAR", "MSRPC"]);
let _ExpectedResultTypes = toscalar(
_GetWatchlist("ResultType-SignInLogsErrorCodes")
| where Notes has "[Failure]" and not(Notes has "[Expired]") and isnotempty(ResultDescription)
| summarize make_list(ResultType)
);
let _ExpectedLocations = toscalar(
_GetWatchlist("Activity-ExpectedSignificantActivity")
| where Activity == "CorporateGeolocation"
| summarize make_list(Auxiliar)
);
let _ExpectedUsers = toscalar(
_GetWatchlist("Activity-ExpectedSignificantActivity")
| where Activity == "LegacyProtocolAuthentication"
| summarize make_list(ActorId)
);
SigninLogs
| where ClientAppUsed in (legacy_auth_protocols) or UserAgent in (legacy_user_agents)
| where not(AuthenticationDetails has "Incorrect password" or RiskState == "remediated")
| where not(ResultType in (_ExpectedResultTypes) and not(ResultDescription has "Sign-in was blocked by built-in protections due to high confidence of risk" or Status has "Sign-in was blocked by built-in protections due to high confidence of risk"))
| where not(UserId in (_ExpectedUsers))
| summarize
StartTime = min(TimeGenerated),
EndTime = max(TimeGenerated),
ResultTypes = make_set(ResultType),
Resources = make_set(ResourceDisplayName),
RiskStates = make_set_if(RiskState, not(RiskState == "none")),
RiskLevelsAggregated = make_set_if(RiskLevelAggregated, not(RiskLevelAggregated == "none")),
RiskEventTypes = make_set(todynamic(RiskEventTypes)),
CorrelationIds = make_set(CorrelationId),
arg_max(TimeGenerated, UserPrincipalName, UserDisplayName, Location, NetworkLocationDetails, ConditionalAccessStatus, ConditionalAccessPolicies)
by UserId, IPAddress, AppDisplayName, AppId, UserAgent, ClientAppUsed
| extend AlertSeverity = case(
Location in (_ExpectedLocations), "Low",
"High"
)
| project
StartTime,
EndTime,
UserPrincipalName,
UserDisplayName,
IPAddress,
Location,
NetworkLocationDetails,
ResultTypes,
AppDisplayName,
Resources,
ClientAppUsed,
UserAgent,
ConditionalAccessStatus,
ConditionalAccessPolicies,
RiskStates,
RiskLevelsAggregated,
RiskEventTypes,
CorrelationIds,
AppId,
UserId,
AlertSeverity