Multiple Sensitive Account Authentication In Ad Fs From Unexpected Device
KQL detection rule by ep3p · MIT
No description provided
let query_frequency = 1h;
let query_period = 14d;
let _ExpectedDomain = toscalar(
_GetWatchlist("Activity-ExpectedSignificantActivity")
| where Activity == "DomainJoinedLDAP"
| summarize make_list(Auxiliar)
);
let _ExpectedAuthentications = toscalar(
_GetWatchlist("Activity-ExpectedSignificantActivity")
| where Activity == "SensitiveAccountUnexpectedDeviceADFSAuth"
| summarize RegEx = make_set(strcat(regex_quote(ActorPrincipalName), SourceResource))
| extend RegEx = strcat(@"^(", strcat_array(RegEx, "|"), @")$")
);
let _Identities =
IdentityInfo
| where TimeGenerated > ago(query_period)
| summarize arg_max(TimeGenerated, *) by AccountUPN
| extend AccountUPN = tolower(AccountUPN)
;
IdentityLogonEvents
| where TimeGenerated > ago(query_frequency)
| where ActionType == "LogonSuccess" and Protocol in ("Adfs", "Ntlm") and isnotempty(DeviceName) and not(DeviceName has_any (_ExpectedDomain))
| mv-expand BinTimeGenerated = range(bin(TimeGenerated, 1s) - 1s, bin(TimeGenerated, 1s) + 1s, 1s) to typeof(datetime)
| summarize hint.shufflekey=BinTimeGenerated
TimeGenerated = min(TimeGenerated),
Protocols = array_sort_asc(make_set(Protocol)),
DeviceNames = array_sort_asc(make_set(DeviceName)),
DeviceNamesSample = array_sort_asc(make_set_if(DeviceName, not(DeviceName matches regex @"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"))),
LogonTypes = array_sort_asc(make_list(LogonType)),
AccountSid = make_set_if(AccountSid, isnotempty(AccountSid))
by AccountUpn, BinTimeGenerated
| where Protocols has_all ("Adfs", "Ntlm") and LogonTypes has_all ("Logon with ADFS authentication", "Resource access")
| summarize take_any(*) by AccountUpn, TimeGenerated
| extend AccountUpn = tolower(AccountUpn)
| lookup kind=leftouter (_Identities | where isnotempty(AccountUPN)) on $left.AccountUpn == $right.AccountUPN
| where SourceSystem has "ActiveDirectory"
or UserAccountControl has "PasswordNeverExpires"
or (isempty(SourceSystem) and isempty(UserAccountControl))
| extend DeviceName = iff(array_length(DeviceNamesSample) == 1, tostring(DeviceNamesSample[0]), "")
| where not(strcat(AccountUpn, DeviceName) matches regex _ExpectedAuthentications)
| project
TimeGenerated,
AccountUpn,
DeviceNames,
DeviceName,
LogonTypes,
Protocols,
UserAccountControl,
AccountDisplayName,
JobTitle,
Manager,
Department,
OnPremisesDistinguishedName,
Tags,
GroupMembership,
AssignedRoles,
SourceSystem,
AccountSid,
AccountSID,
AccountObjectId