Skip to content

Commit

Permalink
Merge pull request #3140 from splunk/dlux_4
Browse files Browse the repository at this point in the history
DLUX_4 - Updating detections and adding a new one
  • Loading branch information
patel-bhavin authored Nov 7, 2024
2 parents ccd2c9d + 67f8f87 commit ff9a4f3
Show file tree
Hide file tree
Showing 21 changed files with 382 additions and 91 deletions.
1 change: 0 additions & 1 deletion contentctl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -206,5 +206,4 @@ apps:
version: 3.2.1
description: description of app
hardcoded_path: https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/crowdstrike-falcon-event-streams-technical-add-on_321.tgz

githash: d6fac80e6d50ae06b40f91519a98489d4ce3a3fd
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,41 @@ status: production
type: Hunting
data_source:
- Azure Active Directory Sign-in activity
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.
search: '| tstats `security_content_summariesonly` dc(Authentication.user) AS unique_accounts dc(Authentication.src) as unique_src count(Authentication.user) as total_failures from datamodel=Authentication.Authentication where Authentication.action="failure" by Authentication.action, Authentication.signature_id, sourcetype, _time span=2m | `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, unique_src ``` remove duplicate & empty time buckets``` | sort - total_failures | dedup _time ``` Create aggregation field & apply to all null events``` | eval counter=sourcetype+"__"+signature_id | eventstats values(counter) as fnscounter | eval counter=coalesce(counter,fnscounter) ``` 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 | 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_accounts >= upperBoundsrc), 1, 0) | replace "::ffff:*" with * in src | where isOutlier=1 | foreach * [ eval <<FIELD>> = if(<<FIELD>>="null",null(),<<FIELD>>)] | table _time, action, unique_src, unique_accounts, total_failures, sourcetype, signature_id | sort - total_failures | `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.
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.
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/
Expand All @@ -31,17 +63,16 @@ tags:
type: IP Address
role:
- Attacker
- name: unique_accounts
type: User
- name: user_agent
type: Other
role:
- Victim
- Attacker
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
risk_score: 49
required_fields:
- Authentication.action
- Authentication.user
- Authentication.src
security_domain: access
Expand Down
53 changes: 43 additions & 10 deletions detections/application/detect_password_spray_attempts.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,48 @@
name: Detect Password Spray Attempts
id: 086ab581-8877-42b3-9aee-4a7ecb0923af
version: 2
date: '2024-09-30'
version: 3
date: '2024-10-17'
author: Dean Luxton
status: production
type: TTP
data_source:
- Windows Event Log Security 4625
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.
search: '| tstats `security_content_summariesonly` 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" by Authentication.src, Authentication.action, Authentication.signature_id, sourcetype, _time span=2m | `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, unique_src ``` remove duplicate & empty time buckets``` | sort - total_failures | dedup _time ``` Create aggregation field & apply to all null events``` | eval counter=src+"__"+sourcetype+"__"+signature_id | eventstats values(counter) as fnscounter | eval counter=coalesce(counter,fnscounter) | 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, total_failures, sourcetype, signature_id | `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.
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.
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 opporates 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/
Expand All @@ -36,19 +69,19 @@ tags:
- T1110.003
- T1110
observable:
- name: unique_user_names
type: User
role:
- Victim
- name: src
type: Endpoint
role:
- Attacker
- name: sourcetype
type: Other
role:
- Victim
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
risk_score: 49
risk_score: 70
required_fields:
- Authentication.action
- Authentication.user
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
name: AWS Multiple Users Failing To Authenticate From Ip
id: 71e1fb89-dd5f-4691-8523-575420de4630
version: 3
date: '2024-09-30'
date: '2024-10-16'
author: Bhavin Patel
status: production
type: Anomaly
description: The following analytic identifies a single source IP failing to authenticate into the AWS Console with 30 unique valid users within 10 minutes. It leverages CloudTrail logs to detect multiple failed login attempts from the same IP address. This behavior is significant as it may indicate a Password Spraying attack, where an adversary attempts to gain unauthorized access or elevate privileges by trying common passwords across many accounts. If confirmed malicious, this activity could lead to unauthorized access, data breaches, or further exploitation within the AWS environment.
data_source:
- AWS CloudTrail ConsoleLogin
search: '`cloudtrail` eventName=ConsoleLogin action=failure | bucket span=10m _time | stats dc(user_name) AS unique_accounts values(user_name) as tried_accounts by _time, src_ip | `aws_multiple_users_failing_to_authenticate_from_ip_filter`'
how_to_implement: You must install Splunk Add-on for AWS in order to ingest Cloudtrail. We recommend the users to try different combinations of the bucket span time and the tried account threshold to tune this search according to their environment.
known_false_positives: No known false postives for this detection. Please review this alert
search: '`cloudtrail` eventName=ConsoleLogin action=failure | bucket span=10m _time
| stats dc(user_name) AS unique_accounts values(user_name) as tried_accounts by _time, src_ip
| where unique_accounts>30
| `aws_multiple_users_failing_to_authenticate_from_ip_filter`'
how_to_implement: You must install Splunk Add-on for AWS in order to ingest Cloudtrail.
We recommend the users to try different combinations of the bucket span time and
the tried account threshold to tune this search according to their environment.
known_false_positives: No known false postives for this detection. Please review this
alert
references:
- https://attack.mitre.org/techniques/T1110/003/
- https://www.whiteoaksecurity.com/blog/goawsconsolespray-password-spraying-tool/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
name: Kerberoasting spn request with RC4 encryption
id: 5cc67381-44fa-4111-8a37-7a230943f027
version: 7
date: '2024-09-30'
author: Jose Hernandez, Patrick Bareiss, Mauricio Velazco, Splunk
date: '2024-10-16'
author: Jose Hernandez, Patrick Bareiss, Mauricio Velazco, Dean Luxton, Splunk
status: production
type: TTP
description: The following analytic detects potential Kerberoasting attacks by identifying Kerberos service ticket requests with RC4 encryption through Event ID 4769. It leverages specific Ticket_Options values commonly used by Kerberoasting tools. This activity is significant as Kerberoasting allows attackers to request service tickets for domain accounts, typically service accounts, and crack them offline to gain privileged access. If confirmed malicious, this could lead to unauthorized access, privilege escalation, and further compromise of the Active Directory environment.
data_source:
- Windows Event Log Security 4769
search: '`wineventlog_security` EventCode=4769 ServiceName!="*$" (TicketOptions=0x40810000 OR TicketOptions=0x40800000 OR TicketOptions=0x40810010) TicketEncryptionType=0x17 | stats count min(_time) as firstTime max(_time) as lastTime by Computer, service_id, service, TicketEncryptionType, TicketOptions | rename Computer as dest | `security_content_ctime(lastTime)` | `security_content_ctime(firstTime)` | `kerberoasting_spn_request_with_rc4_encryption_filter`'
how_to_implement: To successfully implement this search, you need to be ingesting Domain Controller and Kerberos events. The Advanced Security Audit policy setting `Audit Kerberos Authentication Service` within `Account Logon` needs to be enabled.
known_false_positives: Older systems that support kerberos RC4 by default like NetApp may generate false positives. Filter as needed
search: '`wineventlog_security` EventCode=4769 ServiceName!="*$" (TicketOptions=0x40810000
OR TicketOptions=0x40800000 OR TicketOptions=0x40810010) TicketEncryptionType=0x17
| stats count min(_time) as firstTime max(_time) as lastTime by Computer, user, service_id,
service, TicketEncryptionType, TicketOptions | rename Computer as dest | `security_content_ctime(lastTime)`
| `security_content_ctime(firstTime)` | `kerberoasting_spn_request_with_rc4_encryption_filter`'
how_to_implement: To successfully implement this search, you need to be ingesting
Domain Controller and Kerberos events. The Advanced Security Audit policy setting
`Audit Kerberos Authentication Service` within `Account Logon` needs to be enabled.
Whithin environments where this type of communication is common, consider dropping
the risk score and add throttling based on the user and service_id for 30 days.
This will allow RBA to alert when there is an anomalous spike of these kerberoastable
SPN requests within a short period of time.
known_false_positives: Older systems that support kerberos RC4 by default like NetApp
may generate false positives. Filter as needed
references:
- https://github.com/redcanaryco/atomic-red-team/blob/4e3e9c8096dde00639a6b98845ec349135554ed5/atomics/T1208/T1208.md
- https://www.hub.trimarcsecurity.com/post/trimarc-research-detecting-kerberoasting-activity
Expand All @@ -32,13 +43,13 @@ tags:
asset_type: Endpoint
confidence: 80
impact: 90
message: Potential kerberoasting attack via service principal name requests detected on $dest$
message: User $user$ requested a service ticket for SPN $service_id$ with RC4 encryption
mitre_attack_id:
- T1558
- T1558.003
observable:
- name: dest
type: Endpoint
- name: user
type: User
role:
- Victim
product:
Expand Down
Loading

0 comments on commit ff9a4f3

Please sign in to comment.