Multiple Unexpected AD FS Authentication Flow
Query
let query_frequency = 5m;
let query_period = 2d;
let query_wait = 30m;
let _ExpectedADFSIPAddress = toscalar(
_GetWatchlist("Activity-ExpectedSignificantActivity")
| where Activity == "ADFSAuthenticationAddress"
| summarize make_list(SourceAddress)
);
let _TrustedNamedLocations = toscalar(
_GetWatchlist("Activity-ExpectedSignificantActivity")
| where Activity == "TrustedNamedLocation"
| summarize make_list(SourceResource)
);
ADFSSignInLogs
| where TimeGenerated between (ago(query_frequency + query_wait) .. ago(query_wait))
| where ResultType == 0 and isnotempty(IPAddress)
| mv-apply AuthenticationProcessingDetail = todynamic(AuthenticationProcessingDetails) on (
where AuthenticationProcessingDetail has "IP Addresses Involved in Auth Flow"
| extend IPAddressesInvolved = split(tostring(AuthenticationProcessingDetail["value"]), ",")
)
| project-away AuthenticationProcessingDetail
| where not(array_length(IPAddressesInvolved) == 1) and not(IPAddress in (_ExpectedADFSIPAddress))
| summarize Auxiliar = arg_max(array_length(IPAddressesInvolved), IPAddressesInvolved) by UserId, CorrelationId
| project-away Auxiliar
| join kind = inner (
union SigninLogs, AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(query_period + query_wait)
| where isnotempty(CorrelationId) and isnotempty(SessionId)
) on UserId, CorrelationId
| project-away *1
| summarize arg_min(CreatedDateTime, *) by UserId, HomeTenantId, ResourceTenantId, IPAddress, CorrelationId
| mv-apply NetworkLocationDetail = todynamic(NetworkLocationDetails) on (
summarize
//NetworkTypes = make_set(tostring(NetworkLocationDetail["networkType"])),
NetworkNames = make_set(tostring(NetworkLocationDetail["networkNames"][0]))
)
| where not(NetworkNames has_any (_TrustedNamedLocations))
| project IPAddressesInvolved, UserId, CorrelationId, SessionId
| join kind = inner (
union SigninLogs, AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(query_period + query_wait)
| where isnotempty(SessionId)
) on UserId, SessionId
| project-away *1
| summarize
arg_min(CreatedDateTime, *),
AccesedApps = array_sort_asc(make_set_if(AppDisplayName, ResultType == 0, 50)),
AccessedResources = array_sort_asc(make_set_if(ResourceDisplayName, ResultType == 0, 50)),
SessionIds = make_set(SessionId),
CorrelationIds = make_set(CorrelationId)
by UserId, IPAddress, HomeTenantId, ResourceTenantId
| project
TimeGenerated,
CreatedDateTime,
UserPrincipalName,
UserDisplayName,
SessionIds,
IPAddressesInvolved,
IPAddress,
Location,
NetworkLocationDetails,
AutonomousSystemNumber,
AuthenticationDetails,
ClientAppUsed,
DeviceDetail = coalesce(tostring(DeviceDetail_dynamic), DeviceDetail_string),
UserAgent,
Category,
AccesedApps,
AccessedResources,
HomeTenantId,
ResourceTenantId,
CorrelationIds,
UserIdExplanation
This KQL (Kusto Query Language) query is designed to analyze authentication logs, specifically focusing on ADFS (Active Directory Federation Services) sign-ins and related activities. Here's a simplified breakdown of what the query does:
-
Define Parameters:
query_frequency,query_period, andquery_waitare set to specify time intervals for the analysis._ExpectedADFSIPAddressand_TrustedNamedLocationsare lists of expected IP addresses and trusted locations, respectively, retrieved from a watchlist.
-
Filter ADFS Sign-In Logs:
- The query examines ADFS sign-in logs within a specific time window.
- It filters for successful logins (
ResultType == 0) with non-empty IP addresses. - It extracts and processes details about IP addresses involved in the authentication flow.
-
Identify Anomalies:
- It identifies cases where multiple IP addresses are involved in a single authentication flow and checks if these IPs are not in the expected list.
- It summarizes these cases by user and correlation ID.
-
Join with Other Sign-In Logs:
- The query joins the filtered ADFS logs with other sign-in logs (both interactive and non-interactive) based on user ID and correlation ID.
- It further filters and summarizes these logs by various attributes like user ID, IP address, and tenant IDs.
-
Network Location Analysis:
- It analyzes network location details to identify if the network names are not in the list of trusted locations.
-
Final Output:
- The query compiles a detailed summary of the authentication events, including accessed applications and resources, session and correlation IDs, and other relevant user and network details.
- It projects a final set of columns for output, providing a comprehensive view of the authentication activities and potential anomalies.
Overall, this query is used to detect unusual or potentially suspicious authentication activities by analyzing ADFS sign-in logs and correlating them with other sign-in data, while considering expected IP addresses and trusted locations.