Authentication From Suspicious DeviceName
KQL Queries
Using KQL (Kusto Query Language) query to identify suspicious authentication attempts originating from unusual or suspicious workstation names. This query assumes you're working with Azure Monitor, Sentinel, or a similar platform that supports KQL and logs such as SecurityEvent, SigninLogs, or other authentication-related logs.
Using KQL (Kusto Query Language) query to identify suspicious authentication attempts originating from unusual or suspicious workstation names. This query assumes you're working with Azure Monitor, Sentinel, or a similar platform that supports KQL and logs such as SecurityEvent, SigninLogs, or other authentication-related logs.
// Define a list of known suspicious workstation patterns
let SuspiciousWorkstations = dynamic(["UNKNOWN", "TEMP", "WORKSTATION-", "DESKTOP-"]);
// Query authentication logs
SecurityEvent
| where EventID in (4624, 4625) // Filter for logon success (4624) or failure (4625) events
| extend WorkstationName = iff(isnotempty(Workstation), Workstation, Computer) // Extract workstation/computer name
| where WorkstationName has_any (SuspiciousWorkstations)
or WorkstationName matches regex @"^(TEMP|DESKTOP|UNKNOWN|WORKSTATION-).*$" // Match dynamic list or regex patterns
| summarize
LogonAttempts = count(),
UniqueUserCount = dcount(TargetUserName),
FailedAttempts = countif(EventID == 4625)
by WorkstationName, TargetUserName, LogonType, bin(TimeGenerated, 1h)
| extend LogonTypeDescription = case(
LogonType == 2, "Interactive",
LogonType == 3, "Network",
LogonType == 10, "Remote Interactive",
LogonType == 7, "Unlock",
LogonType == 5, "Service",
LogonType == 4, "Batch",
"Unknown"
)
| order by LogonAttempts desc
| project TimeGenerated, WorkstationName, TargetUserName, LogonTypeDescription, LogonAttempts, FailedAttempts, UniqueUserCountKey Details:
Dynamic List of Suspicious Names: Adjust
SuspiciousWorkstationsto include prefixes, patterns, or specific workstation names you consider suspicious.Event IDs: Targets Windows Security Event IDs for logon success (
4624) and failure (4625).Regex Matching: Matches patterns using a regex for flexible detection of workstation naming conventions.
Summarization: Group data by workstation name, user, and logon type for better analysis and filtering.
Logon Type Mapping: Provides a human-readable description of the logon type for better context.
Results:
WorkstationName: The suspicious workstation name.
TargetUserName: User attempting to log in.
LogonTypeDescription: Describes how the logon was attempted (e.g., Interactive, Network, Remote Interactive).
LogonAttempts: Total authentication attempts.
FailedAttempts: Count of failed logon attempts.
You may have to tweak the query to include additional suspicious patterns or integrate it with threat intelligence feeds for enhanced correlation.
To discover authentication events originating from suspicious workstation names using the DeviceLogonEvents table in Microsoft Sentinel or another Log Analytics environment:
// Define a list of suspicious workstation patterns
let SuspiciousWorkstations = dynamic(["UNKNOWN", "TEMP", "WORKSTATION-", "DESKTOP-"]);
// Query DeviceLogonEvents table
DeviceLogonEvents
| extend WorkstationName = iff(isnotempty(DeviceName), DeviceName,
AccountName) // Normalize workstation/computer name
| where WorkstationName has_any (SuspiciousWorkstations)
or WorkstationName matches regex @"^(TEMP|DESKTOP|UNKNOWN|WORKSTATION-).*$" // Match dynamic list or regex patterns
| summarize
LogonAttempts = count(),
FailedAttempts = countif(ActionType == "LogonFailed"),
SuccessfulAttempts = countif(ActionType == "LogonSuccess"),
UniqueUserCount = dcount(AccountName)
by WorkstationName, AccountName, LogonType, bin(Timestamp, 1h)
| extend LogonTypeDescription = case(
LogonType == "Interactive", "Interactive",
LogonType == "Network", "Network",
LogonType == "RemoteInteractive", "Remote Interactive",
LogonType == "Service", "Service",
LogonType == "Batch", "Batch",
LogonType == "Unlock", "Unlock",
"Unknown"
)
| order by LogonAttempts desc
| project Timestamp, WorkstationName, AccountName, LogonTypeDescription, LogonAttempts, SuccessfulAttempts, FailedAttempts, UniqueUserCountExplanation of the Query:
Suspicious Patterns:
SuspiciousWorkstationsdefines known suspicious naming patterns (e.g.,TEMP,UNKNOWN, etc.).Includes
has_anyfor quick matching and regex for flexible pattern detection.
Table and Fields:
The
DeviceLogonEventstable is queried.Extracts workstation or device names using
DeviceNameorAccountName
Filters:
Filters records with workstation names matching the suspicious patterns.
Aggregation:
Groups result by workstation name, account name, and logon type.
Summarises total logon attempts, failed attempts, successful attempts, and unique user count.
Logon Type Mapping:
Maps the
LogonTypeto descriptive text for better interpretation.
Output:
Results are sorted by the number of logon attempts and projected to show:
Timestamp, WorkstationName, AccountName, LogonTypeDescription, TotalAttempts, SuccessfulAttempts, FailedAttempts, and UniqueUserCount.
Customisation:
Additional Filters: Add conditions for specific user accounts, logon times, or suspicious IPs if required.
Time Binning: Adjust
bin(Timestamp, 1h)to a different interval (e.g., 5 minutes or daily).Threat Intelligence Integration: Correlate workstation names with known threat actor tools or tactics.
Using KQL query to discover authentication attempts from suspicious workstation names using the IdentityLogonEvents table in Microsoft Sentinel or Log Analytics:
// Define a list of suspicious workstation patterns
let SuspiciousWorkstations = dynamic(["UNKNOWN", "TEMP", "WORKSTATION-", "DESKTOP-"]);
// Query IdentityLogonEvents table
IdentityLogonEvents
| extend WorkstationName = iff(isnotempty(DeviceName), DeviceName, TargetDeviceName) // Normalize workstation/device field
| where WorkstationName has_any (SuspiciousWorkstations)
or WorkstationName matches regex @"^(TEMP|DESKTOP|UNKNOWN|WORKSTATION-).*$" // Match patterns or dynamic list
| summarize
TotalAttempts = count(),
FailedAttempts = countif(ActionType == "LogonFailed"),
SuccessfulAttempts = countif(ActionType == "LogonSuccess"),
UniqueUsers = dcount(AccountDisplayName)
by WorkstationName, AccountDisplayName, LogonType, bin(Timestamp, 1h)
| extend LogonTypeDescription = case(
LogonType == "Interactive", "Interactive",
LogonType == "RemoteInteractive", "Remote Interactive",
LogonType == "Network", "Network",
LogonType == "Batch", "Batch",
LogonType == "Service", "Service",
"Unknown"
)
| order by TotalAttempts desc
| project Timestamp, WorkstationName, AccountDisplayName, LogonTypeDescription, TotalAttempts, SuccessfulAttempts, FailedAttempts, UniqueUsersKey Features of the Query:
Suspicious Patterns:
SuspiciousWorkstationsincludes known suspicious naming conventions (e.g.,TEMP,WORKSTATION-).Matches using
has_anyandregexfor flexible detection.
Field Normalisation:
Uses
DeviceNameorTargetDeviceNameto extract workstation or device information.
Logon Event Filtering:
Focuses on logon events where the workstation name matches suspicious patterns.
Aggregation:
Summarises:
TotalAttempts: Total logon attempts.FailedAttempts: Count of failed logon attempts.SuccessfulAttempts: Count of successful logon attempts.UniqueUsers: Count of distinct users attempting logons.
Logon Type Mapping:
Converts raw
LogonTypevalues into meaningful descriptions.
Results:
Sorted by total attempts and includes:
Timestamp,WorkstationName,AccountDisplayName,LogonTypeDescription,TotalAttempts,SuccessfulAttempts,FailedAttempts, andUniqueUsers.
Customisation Options:
Time Filtering: Add
| where Timestamp between (startTime .. endTime)to restrict the timeframe.Additional Filters: Add filters for specific user accounts, IP addresses, or logon statuses.
Suspicious Patterns: Update
SuspiciousWorkstationsto include organisation-specific patterns or known attacker conventions.
Using KQL query to discover authentication attempts from suspicious workstation names using the SigninLogs table in Microsoft Sentinel or Azure Log Analytics:
// Define a list of suspicious workstation patterns
let SuspiciousWorkstations = dynamic(["UNKNOWN", "TEMP", "WORKSTATION-", "DESKTOP-"]);
// Query SigninLogs table
SigninLogs
| extend WorkstationName = iff(isnotempty(DeviceDetail.deviceDisplayName), tostring(DeviceDetail.deviceDisplayName), tostring(DeviceDetail.operatingSystem)) // Extract and cast to string
| where WorkstationName has_any (SuspiciousWorkstations)
or WorkstationName matches regex @"^(TEMP|DESKTOP|UNKNOWN|WORKSTATION-).*$" // Match dynamic list or regex patterns
| summarize
TotalAttempts = count(),
FailedAttempts = countif(ResultType != "0"), // Non-zero ResultType indicates failure
SuccessfulAttempts = countif(ResultType == "0"),
UniqueUsers = dcount(UserPrincipalName)
by tostring(WorkstationName), UserPrincipalName, AppDisplayName, bin(TimeGenerated, 1h)
| order by TotalAttempts desc
| project TimeGenerated, WorkstationName, UserPrincipalName, AppDisplayName, TotalAttempts, SuccessfulAttempts, FailedAttempts, UniqueUsersExplanation:
Suspicious Patterns:
SuspiciousWorkstationsDefines workstation name patterns commonly linked to suspicious activity.Uses
has_anyfor a quick match andregexfor flexible pattern matching.
Field Normalisation:
Extracts workstation name from
DeviceDetail.deviceDisplayNameor falls back toDeviceDetail.operatingSystemif empty.
Logon Results:
ResultType == "0"Indicates successful logons.Any other
ResultTypeis treated as a failure.
Aggregation:
Groups by
WorkstationName,UserPrincipalName, andAppDisplayName.Summarizes:
TotalAttempts: Total authentication attempts.FailedAttempts: Count of failed logons.SuccessfulAttempts: Count of successful logons.UniqueUsers: Count of distinct users.
Time Binning:
Bins results into 1-hour intervals using
bin(TimeGenerated, 1h).
Results:
Sorted by
TotalAttemptsand displays:TimeGenerated,WorkstationName,UserPrincipalName,AppDisplayName,TotalAttempts,SuccessfulAttempts,FailedAttempts, andUniqueUsers.
Customisation:
Patterns: Update
SuspiciousWorkstationsto include organisation-specific suspicious workstation naming conventions.Time Range: Add a time filter using
| where TimeGenerated between (datetime(YYYY-MM-DD HH:MM:SS) .. datetime(YYYY-MM-DD HH:MM:SS)).Additional Fields: Extend with other fields from
SigninLogsfor more context, such as IP addresses or location data.
Splunk Query:
Using Splunk query to discover authentication events originating from suspicious workstation names. This query assumes you're using Windows Event Logs (index=wineventlog) or a similar data source for authentication events.
Note: The fields in your Splunk logs may differ slightly; for example, AccountName may be displayed as Account_Name.
index=wineventlog EventCode IN (4624, 4625)
| eval WorkstationName=coalesce(Workstation, ComputerName) // Normalize workstation field names
| search WorkstationName IN ("TEMP*", "DESKTOP-*", "UNKNOWN", "WORKSTATION-*") // Match known suspicious patterns
| eval Suspicious = if(match(WorkstationName, "^(TEMP|DESKTOP|UNKNOWN|WORKSTATION-).*$"), "Yes", "No")
| stats count AS TotalAttempts,
count(eval(EventCode=4625)) AS FailedAttempts,
dc(UserName) AS UniqueUsers
by WorkstationName, UserName, LogonType, Suspicious
| eval LogonTypeDescription=case(
LogonType=="2", "Interactive",
LogonType=="3", "Network",
LogonType=="10", "Remote Interactive",
LogonType=="7", "Unlock",
LogonType=="5", "Service",
LogonType=="4", "Batch",
true(), "Unknown"
)
| where Suspicious="Yes"
| sort - TotalAttempts
| table WorkstationName, UserName, LogonTypeDescription, TotalAttempts, FailedAttempts, UniqueUsersKey Details:
EventCode Filtering:
4624: Logon success.4625: Logon failure.
Normalization:
Uses
coalesce()to handle scenarios where eitherWorkstationorComputerNamemaybe populated.
Suspicious Workstation Patterns:
Matches common suspicious workstation naming conventions like
TEMP*,DESKTOP-*,UNKNOWN, orWORKSTATION-*.Regex patterns used in
match()provide flexibility.
Stats Aggregation:
Aggregates data to summarise:
TotalAttempts: Total authentication attempts.FailedAttempts: Failed login attempts.UniqueUsers: Unique users attempting to log in from suspicious workstations.
Logon Type Description:
Maps
LogonTypevalues to human-readable descriptions for better context.
Filtering and Sorting:
Displays results only for suspicious workstations (
where Suspicious="Yes").Sorts results by the highest number of total attempts.
Output:
Displays key fields like
WorkstationName,UserName,LogonTypeDescription, and summarised stats.
Customisation:
Suspicious Patterns: Adjust the
searchclause ormatch()function to include additional patterns or specific workstation names based on your organisation's threat models.Additional Fields: Extend the query with fields like
SourceIPorDestinationIPfor more in-depth analysis.Enrichment: Integrate with threat intelligence feeds to correlate suspicious workstation names or IPs.
Detecting authentication events from suspicious workstation names, assuming the use of a custom authentication-related index (e.g., index=authlogs) and avoiding wineventlog. This query works with generic authentication data sources.
Note: The fields in your Splunk logs may differ slightly; for example, AccountName may be displayed as Account_Name.
index=authlogs sourcetype=authentication
| eval WorkstationName=coalesce(device_name, host_name, client_hostname) // Normalize workstation name field
| search WorkstationName IN ("TEMP*", "DESKTOP-*", "UNKNOWN*", "WORKSTATION-*") // Match suspicious patterns
| eval Suspicious=if(match(WorkstationName, "^(TEMP|DESKTOP|UNKNOWN|WORKSTATION-).*"), "Yes", "No")
| stats count AS TotalAttempts,
count(eval(status="failure")) AS FailedAttempts,
count(eval(status="success")) AS SuccessfulAttempts,
dc(user) AS UniqueUsers
by WorkstationName, user, logon_type, Suspicious
| eval LogonTypeDescription=case(
logon_type=="interactive", "Interactive",
logon_type=="network", "Network",
logon_type=="remote", "Remote Interactive",
logon_type=="service", "Service",
logon_type=="batch", "Batch",
true(), "Unknown"
)
| where Suspicious="Yes"
| sort - TotalAttempts
| table WorkstationName, user, LogonTypeDescription, TotalAttempts, SuccessfulAttempts, FailedAttempts, UniqueUsersKey Details:
Custom Index and Sourcetype:
Replace
index=authlogsandsourcetype=authenticationwith your specific index and sourcetype for authentication data.
Normalisation:
Uses
coalesce()to extract workstation names from possible fields (device_name,host_name, orclient_hostname).
Suspicious Patterns:
Matches workstation names using both the
INclause for patterns and a regex (match()function).
Stats Aggregation:
Aggregates data to summarise:
TotalAttempts: Total logon attempts.FailedAttempts: Failed logon attempts.SuccessfulAttempts: Successful logon attempts.UniqueUsers: Count of distinct users involved.
Logon Type Mapping:
Converts
logon_typeinto human-readable descriptions.
Filtering and Sorting:
Filters suspicious workstation names with
where Suspicious="Yes".Sorts results by the number of total attempts.
Output:
Presents key fields:
WorkstationName,user,LogonTypeDescription,TotalAttempts,SuccessfulAttempts,FailedAttempts, andUniqueUsers.
Customisation:
Field Names: Update field names to match your specific dataset (e.g.,
device_name,status,user, etc.).Patterns: Adjust workstation name patterns based on your environment or known threat actor behaviour.
Time Filtering: Add
earliestandlatesttime filters for specific date ranges, e.g.,earliest=-24h.
Last updated