Detect Distributed Password Spray Attempts

Original Source: [splunk source]
Name:Detect Distributed Password Spray Attempts
id:b1a82fc8-8a9f-4344-9ec2-bde5c5331b57
version:2
date:2024-10-17
author:Dean Luxton
status:production
type:Hunting
Description:This analytic employs the 3-sigma approach to identify distributed password spray attacks. A distributed password spray attack is a type of brute force attack where the attacker attempts a few common passwords against many different accounts, connecting from multiple IP addresses to avoid detection. By utilizing the Authentication Data Model, this detection is effective for all CIM-mapped authentication events, providing comprehensive coverage and enhancing security against these attacks.
Data_source:
  • -Azure Active Directory Sign-in activity
search:| tstats `security_content_summariesonly` dc(Authentication.user) AS unique_accounts dc(Authentication.src) as unique_src values(Authentication.app) as app values(Authentication.src) as src count(Authentication.user) as total_failures from datamodel=Authentication.Authentication where Authentication.action="failure" NOT Authentication.src IN ("-","unknown") Authentication.user_agent="*" by Authentication.signature_id, Authentication.user_agent, sourcetype, _time span=10m
| `drop_dm_object_name("Authentication")` ```fill out time buckets for 0-count events during entire search length```
| appendpipe [| timechart limit=0 span=10m count
| table _time]
| fillnull value=0 unique_accounts, unique_src ``` Create aggregation field & apply to all null events```
| eval counter=sourcetype+"__"+signature_id
| eventstats values(counter) as fnscounter
| eval counter=coalesce(counter,fnscounter)
| stats values(total_failures) as total_failures values(signature_id) as signature_id values(src) as src values(sourcetype) as sourcetype values(app) as app count by counter unique_accounts unique_src user_agent _time
``` remove 0 count rows where counter has data```
| sort - _time unique_accounts
| dedup _time counter ``` 3-sigma detection logic ```
| eventstats avg(unique_accounts) as comp_avg_user , stdev(unique_accounts) as comp_std_user avg(unique_src) as comp_avg_src , stdev(unique_src) as comp_std_src by counter user_agent
| eval upperBoundUser=(comp_avg_user+comp_std_user*3), upperBoundsrc=(comp_avg_src+comp_std_src*3)
| eval isOutlier=if((unique_accounts > 30 and unique_accounts >= upperBoundUser) and (unique_src > 30 and unique_src >= upperBoundsrc), 1, 0)
| replace "::ffff:*" with * in src
| where isOutlier=1
| foreach *
[ eval <<FIELD>> = if(<<FIELD>>="null",null(),<<FIELD>>)]
| mvexpand src
| iplocation src
| table _time, unique_src, unique_accounts, total_failures, sourcetype, signature_id, user_agent, src, Country
| eval date_wday=strftime(_time,"%a"), date_hour=strftime(_time,"%H")
| `detect_distributed_password_spray_attempts_filter`


how_to_implement:Ensure that all relevant authentication data is mapped to the Common Information Model (CIM) and that the src field is populated with the source device information. Additionally, ensure that fill_nullvalue is set within the security_content_summariesonly macro to include authentication events from log sources that do not feature the signature_id field in the results.
known_false_positives:It is common to see a spike of legitimate failed authentication events on monday mornings.
References:
  -https://attack.mitre.org/techniques/T1110/003/
drilldown_searches:
  :
tags:
  analytic_story:
    - 'Compromised User Account'
    - 'Active Directory Password Spraying'
  asset_type:Endpoint
  atomic_guid:
    - '90bc2e54-6c84-47a5-9439-0a2a92b4b175'
  confidence:70
  impact:70
  message:Distributed Password Spray Attempt Detected from $src$
  mitre_attack_id:
    - 'T1110.003'
    - 'T1110'
  observable:
    name:'src'
    type:'IP Address'
    - role:
      - 'Attacker'
    name:'user_agent'
    type:'Other'
    - role:
      - 'Attacker'
  product:
    - 'Splunk Enterprise'
    - 'Splunk Enterprise Security'
    - 'Splunk Cloud'
  risk_score:49
  required_fields:
    - 'Authentication.user'
    - 'Authentication.src'
  security_domain:access
  manual_test:The dataset & hardcoded timerange doesn't meet the criteria for this detection.

tests:
name:'True Positive Test'
 attack_data:
  data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1110.003/azure_ad_distributed_spray/azure_ad_distributed_spray.log
  source: azure:monitor:aad
  sourcetype: azure:monitor:aad
manual_test:None