Query Details
let query_frequency = 1h;
let query_period = 2h;
let failures_threshold = 5;
let _InfoInvalidUser =
Syslog
| where TimeGenerated > ago(query_period)
| where SyslogMessage has_any ("invalid user") and not(SyslogMessage has "[preauth]") and Facility in ("auth", "authpriv")
| parse SyslogMessage with * "user " User:string " from " RemoteIPAddress:string " port " RemotePort:int *
| summarize hint.strategy=shuffle arg_min(TimeGenerated, *) by HostName, HostIP, ProcessID, RemoteIPAddress, RemotePort
;
let _UserUnknown =
Syslog
| where TimeGenerated > ago(query_period)
| where SyslogMessage has_any ("user unknown") and Facility in ("auth", "authpriv")
| join kind=leftanti _InfoInvalidUser on HostName, ProcessID
;
union _InfoInvalidUser, _UserUnknown
| as _Events
| join kind=leftsemi (
_Events
| evaluate activity_counts_metrics(Type, TimeGenerated, ago(query_period), now(), query_frequency, HostName, HostIP, ProcessName)
| summarize
arg_min(PreviousTimeGenerated = TimeGenerated, PreviousCount = ["count"]),
arg_max(CurrentTimeGenerated = TimeGenerated, CurrentCount = ["count"])
by HostName, HostIP, ProcessName
| where CurrentTimeGenerated > ago(query_period)
| extend PreviousCount = iff(PreviousTimeGenerated == CurrentTimeGenerated, 0, PreviousCount)
| where (not(PreviousCount > failures_threshold) and CurrentCount > failures_threshold)
or ((CurrentCount - PreviousCount) > failures_threshold)
) on HostName, HostIP, ProcessName
| summarize
StartTime = min(TimeGenerated),
EndTime = max(TimeGenerated),
Count = count(),
Facilities = array_sort_asc(make_set(Facility)),
SeverityLevels = array_sort_asc(make_set(SeverityLevel)),
SyslogMessages = make_list(SyslogMessage, 100),
take_any(_ResourceId)
by HostName, HostIP, ProcessName
| project
StartTime,
EndTime,
HostName,
HostIP,
Facilities,
SeverityLevels,
ProcessName,
Count,
SyslogMessages,
_ResourceId
This query is designed to monitor system logs (Syslog) for authentication failures over a period of two hours. It specifically looks for messages indicating an "invalid user" or "user unknown" from the "auth" or "authpriv" facilities.
The query first identifies all instances of these failures, parsing out additional information such as the user, remote IP address, and port from the log message. It then checks for any "user unknown" messages that do not match the "invalid user" messages.
The query then compares the current count of these failures to the previous count, looking for any significant increases (greater than a defined threshold of 5).
Finally, the query summarizes this information, providing the start and end time of the period, the host name and IP, the facilities involved, severity levels, the process name, the total count of failures, and a list of up to 100 of the Syslog messages. It also includes the resource ID.
In simple terms, this query helps to identify and analyze any significant increases in authentication failures in a system over a two-hour period.

Jose Sebastián Canós
Released: March 21, 2023
Tables
Keywords
Operators