diff --git a/detections/application/detect_distributed_password_spray_attempts.yml b/detections/application/detect_distributed_password_spray_attempts.yml index 54a5b3900a..9b813996df 100644 --- a/detections/application/detect_distributed_password_spray_attempts.yml +++ b/detections/application/detect_distributed_password_spray_attempts.yml @@ -64,7 +64,7 @@ tags: role: - Attacker - name: user_agent - type: user_agent + type: Other role: - Attacker product: diff --git a/detections/application/detect_password_spray_attempts.yml b/detections/application/detect_password_spray_attempts.yml index 2dbdce0d62..5a609a0a79 100644 --- a/detections/application/detect_password_spray_attempts.yml +++ b/detections/application/detect_password_spray_attempts.yml @@ -13,7 +13,7 @@ description: This analytic employs the 3-sigma approach to detect an unusual vol 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" NOT Authentication.src IN ("-","unknown") by Authentication.src, Authentication.action, Authentication.signature_id, sourcetype, _time span=5m + | 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] @@ -22,7 +22,7 @@ search: >- | eval counter=src+"__"+sourcetype+"__"+signature_id | eventstats values(counter) as fnscounter | eval counter=coalesce(counter,fnscounter) - | stats values(app) as app 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 + | 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 @@ -34,7 +34,7 @@ search: >- | where isOutlier=1 | foreach * [ eval <> = if(<>="null",null(),<>)] - | table _time, src, action, app, unique_accounts, total_failures, sourcetype, signature_id, counter + | 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. @@ -68,6 +68,10 @@ tags: - T1110.003 - T1110 observable: + - name: unique_user_names + type: User + role: + - Victim - name: src type: Endpoint role: diff --git a/detections/network/internal_horizontal_port_scan_nmap_top_20.yml b/detections/network/internal_horizontal_port_scan_nmap_top_20.yml index aa5d7ea3e9..816b6d3af9 100644 --- a/detections/network/internal_horizontal_port_scan_nmap_top_20.yml +++ b/detections/network/internal_horizontal_port_scan_nmap_top_20.yml @@ -29,6 +29,15 @@ how_to_implement: To properly run this search, Splunk needs to ingest data from enable this search effectively. known_false_positives: Unknown references: [] +drilldown_searches: +- name: View the detection results for $src_ip$ + search: '%original_detection_search% | search src_ip = $src_ip$' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for $src_ip$ + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ($src_ip$) starthoursago=168 endhoursago=1 | 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: - Network Discovery