Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 25 additions & 17 deletions Detections/ASimAuthentication/imAuthBruteForce.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
id: a6c435a2-b1a0-466d-b730-9f8af69262e8
name: Brute force attack against user credentials (Uses Authentication Normalization)
description: |
'Identifies evidence of brute force activity against a user highlighting multiple authentication failures
and by a successful authentication within a given time window.
(The query does not enforce any sequence - eg requiring the successful authentication to occur last.)
Default Failure count is 10, Default Success count is 1 and default Time Window is 20 minutes.
'Identifies evidence of brute force activity against a user based on multiple authentication failures
and at least one successful authentication within a given time window. Note that the query does not enforce any sequence,
and does not require the successful authentication to occur last.
The default failure threshold is 10, success threshold is 1, and the default time window is 20 minutes.
To use this analytics rule, make sure you have deployed the [ASIM normalization parsers](https://aka.ms/ASimAuthentication)'
severity: Medium
requiredDataConnectors: []
queryFrequency: 1h
queryPeriod: 1h
queryFrequency: 20m
queryPeriod: 20m
triggerOperator: gt
triggerThreshold: 0
tactics:
Expand All @@ -24,23 +24,31 @@ tags:
query: |
let failureCountThreshold = 10;
let successCountThreshold = 1;
let authenticationWindow = 20m;
// let authenticationWindow = 20m; // Implicit in the analytic rule query period
imAuthentication
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), IPAddress = make_set(SrcDvcIpAddr)
, FailureCount = countif(EventResult=='Failure')
, SuccessCount = countif(EventResult=='Success')
// might be improved by counting FailReason:Outdated as Success.
by bin(TimeGenerated, authenticationWindow), TargetUserId, TargetUsername, TargetUserType
| summarize
StartTime = min(TimeGenerated),
EndTime = max(TimeGenerated),
IpAddresses = make_set (SrcDvcIpAddr, 100),
ReportedBy = make_set (strcat (EventVendor, "/", EventProduct), 100),
FailureCount = countif(EventResult=='Failure'),
SuccessCount = countif(EventResult=='Success')
by
TargetUserId, TargetUsername, TargetUserType
| where FailureCount >= failureCountThreshold and SuccessCount >= successCountThreshold
| extend
IpAddresses = strcat_array(IpAddresses, ", "),
ReportedBy = strcat_array(ReportedBy, ", ")

entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: TargetUsername
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SrcDvcIpAddr
version: 1.1.2

customDetails:
IpAddresses: IpAddresses
ReportedBy: ReportedBy

version: 1.2.0
kind: Scheduled