Detect Password Spray Attempts

Original Source: [splunk source]
Name:Detect Password Spray Attempts
id:086ab581-8877-42b3-9aee-4a7ecb0923af
version:4
date:2024-10-17
author:Dean Luxton
status:production
type:TTP
Description:This analytic employs the 3-sigma approach to detect an unusual volume of failed authentication attempts from a single source. A password spray attack is a type of brute force attack where an attacker tries a few common passwords across many different accounts to avoid detection and account lockouts. 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:
  • -Windows Event Log Security 4625
search:| tstats `security_content_summariesonly` values(Authentication.user) AS unique_user_names dc(Authentication.user) AS unique_accounts values(Authentication.app) as app count(Authentication.user) as total_failures from datamodel=Authentication.Authentication where Authentication.action="failure" NOT Authentication.src IN ("-","unknown") by Authentication.src, Authentication.action, Authentication.signature_id, sourcetype, _time span=5m
| `drop_dm_object_name("Authentication")`
```fill out time buckets for 0-count events during entire search length```
| appendpipe [| timechart limit=0 span=5m count
| table _time]
| fillnull value=0 unique_accounts
``` Create aggregation field & apply to all null events```
| eval counter=src+"__"+sourcetype+"__"+signature_id
| eventstats values(counter) as fnscounter
| eval counter=coalesce(counter,fnscounter)
``` stats version of mvexpand ```
| stats values(app) as app values(unique_user_names) as unique_user_names values(total_failures) as total_failures values(src) as src values(signature_id) as signature_id values(sourcetype) as sourcetype count by counter unique_accounts _time
``` remove duplicate time buckets for each unique source```
| sort - _time unique_accounts
| dedup _time counter
```Find the outliers```
| eventstats avg(unique_accounts) as comp_avg , stdev(unique_accounts) as comp_std by counter
| eval upperBound=(comp_avg+comp_std*3)
| eval isOutlier=if(unique_accounts > 30 and unique_accounts >= upperBound, 1, 0)
| replace "::ffff:*" with * in src
| where isOutlier=1
| foreach *
[ eval <<FIELD>> = if(<<FIELD>>="null",null(),<<FIELD>>)]
| table _time, src, action, app, unique_accounts, unique_user_names, total_failures, sourcetype, signature_id, counter
| `detect_password_spray_attempts_filter`


how_to_implement:Ensure in-scope authentication data is CIM mapped and the src field is populated with the source device. Also ensure fill_nullvalue is set within the macro security_content_summariesonly. This search operates best on a 5 minute schedule, looking back over the past 70 minutes. Configure 70 minute throttling on the two fields _time and counter.
known_false_positives:Unknown
References:
  -https://attack.mitre.org/techniques/T1110/003/
drilldown_searches:
name:'View the detection results for - "$sourcetype$"'
search:'%original_detection_search% | search sourcetype = "$sourcetype$"'
earliest_offset:'$info_min_time$'
latest_offset:'$info_max_time$'
name:'View risk events for the last 7 days for - "$sourcetype$"'
search:'| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$sourcetype$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`'
earliest_offset:'$info_min_time$'
latest_offset:'$info_max_time$'
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:Potential Password Spraying attack from $src$ targeting $unique_accounts$ unique accounts.
  mitre_attack_id:
    - 'T1110.003'
    - 'T1110'
  observable:
    name:'unique_user_names'
    type:'User'
    - role:
      - 'Victim'
    name:'src'
    type:'Endpoint'
    - role:
      - 'Attacker'
  product:
    - 'Splunk Enterprise'
    - 'Splunk Enterprise Security'
    - 'Splunk Cloud'
  risk_score:70
  required_fields:
    - 'Authentication.action'
    - 'Authentication.user'
    - 'Authentication.src'
  security_domain:access

tests:
name:'True Positive Test'
 attack_data:
  data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1110.003/purplesharp_invalid_users_kerberos_xml/windows-security.log
  source: XmlWinEventLog:Security
  sourcetype: XmlWinEventLog
manual_test:None