From 2ba7c716265148dac1975cd1789557f2e51267f0 Mon Sep 17 00:00:00 2001 From: zake1god Date: Mon, 14 Oct 2024 22:39:00 +0700 Subject: [PATCH 1/8] Add Inactive User Have Activity Detected --- .../inactive_user_have_activity_detected.yml | 80 +++++++++++++++++++ ...have_activity_detected.yml:Zone.Identifier | 0 2 files changed, 80 insertions(+) create mode 100644 detections/network/inactive_user_have_activity_detected.yml create mode 100644 detections/network/inactive_user_have_activity_detected.yml:Zone.Identifier diff --git a/detections/network/inactive_user_have_activity_detected.yml b/detections/network/inactive_user_have_activity_detected.yml new file mode 100644 index 0000000000..c9ea3be7ba --- /dev/null +++ b/detections/network/inactive_user_have_activity_detected.yml @@ -0,0 +1,80 @@ +name: Inactive User Have Activity Detected +id: e08aa2f6-7d90-4ab8-af11-da4df38bb7ff +version: 1 +date: '2024-10-14' +author: Zaki Zarkasih Al Mustafa +data_sources: +- Windows Security 4624 +- Windows Security 4625 +type: Correlation +status: production +description: This detection identifies users who have been inactive for more than 30 days and suddenly have activity based on network traffic logs. +search: '| tstats summariesonly=true fillnull_value=null count min(_time) as firstTime + max(_time) as lastTime from + + datamodel=Network_Traffic.All_Traffic by All_Traffic.authserver, All_Traffic.vendor_product, + + All_Traffic.user, All_Traffic.action + + | `drop_dm_object_name("All_Traffic")` + + | eval inactivityPeriodByDay = (now() - lastTime) / 86400 + + | eval lastTimeLogin = relative_time(now(), "-4h") + + | eval status = if(inactivityPeriodByDay > 29, "inactive", "active") + + | eval inactivityPeriodByDay = round(inactivityPeriodByDay, 0) . " Days" + + | search status = "inactive" AND lastTime <= lastTimeLogin + + | rename authserver as "auth server", vendor_product as "vendor product" + + | eval firstTime=strftime(firstTime, "%Y-%m-%d %H:%M:%S"), lastTimeLogin=strftime(lastTimeLogin, + "%Y-%m-%d + + %H:%M:%S") + + | table "auth server", "vendor product", user, firstTime, lastTimeLogin, inactivityPeriodByDay, + status, + + action | `inactive_user_have_activity_detected_filter`' +how_to_implement: Ensure that the Network Traffic data model is properly populated and includes logs from relevant sources (e.g., firewalls, proxies, or other network monitoring tools). Configure the data model acceleration to ensure performance and availability for this detection. Make sure to adjust any environment-specific filter macros for false positive reduction. +known_false_positives: False positives may include legitimate users returning to the network after extended vacations or periods of inactivity. System accounts or service accounts that are seldom used but have routine tasks may also trigger this detection. +references: + - https://attack.mitre.org/techniques/T1078/ + - https://docs.splunk.com/Documentation/Splunk/latest/Knowledge/Useaccelerateddatamodels + - https://www.sans.org/white-papers/monitoring-inactive-accounts/ +tags: + analytic_story: [] + asset_type: Network + confidence: 85 + impact: 70 + message: This detection identifies users who have been inactive for an extended period and suddenly have activity on the network. + mitre_attack_id: + - T1078 + - T1110 + - T1040 + observable: + - name: user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - user + - authserver + - vendor_product + - action + risk_score: "{{ (impact * confidence) / 100 }}" + security_domain: identity + cve: [] +tests: +- name: True Positive Test + attack_data: + - data: https://github.com/splunk/contentctl/wiki + sourcetype: WinEventLog:Security + source: Active Directory diff --git a/detections/network/inactive_user_have_activity_detected.yml:Zone.Identifier b/detections/network/inactive_user_have_activity_detected.yml:Zone.Identifier new file mode 100644 index 0000000000..e69de29bb2 From 2463307697091824bc73fb9282348968311b7f7f Mon Sep 17 00:00:00 2001 From: zake1god Date: Mon, 14 Oct 2024 22:39:23 +0700 Subject: [PATCH 2/8] Add Inactive User Have Activity Detected --- .../inactive_user_have_activity_detected.yml:Zone.Identifier | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 detections/network/inactive_user_have_activity_detected.yml:Zone.Identifier diff --git a/detections/network/inactive_user_have_activity_detected.yml:Zone.Identifier b/detections/network/inactive_user_have_activity_detected.yml:Zone.Identifier deleted file mode 100644 index e69de29bb2..0000000000 From d82503c0f9e549518d654d810cc539413c695d96 Mon Sep 17 00:00:00 2001 From: zake1god Date: Tue, 15 Oct 2024 14:21:02 +0700 Subject: [PATCH 3/8] Change title to make it easy understand --- ...tected.yml => inactive_account_have_activity_detected.yml} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename detections/network/{inactive_user_have_activity_detected.yml => inactive_account_have_activity_detected.yml} (96%) diff --git a/detections/network/inactive_user_have_activity_detected.yml b/detections/network/inactive_account_have_activity_detected.yml similarity index 96% rename from detections/network/inactive_user_have_activity_detected.yml rename to detections/network/inactive_account_have_activity_detected.yml index c9ea3be7ba..9dc4879763 100644 --- a/detections/network/inactive_user_have_activity_detected.yml +++ b/detections/network/inactive_account_have_activity_detected.yml @@ -1,4 +1,4 @@ -name: Inactive User Have Activity Detected +name: Inactive Account Have Activity Detected id: e08aa2f6-7d90-4ab8-af11-da4df38bb7ff version: 1 date: '2024-10-14' @@ -38,7 +38,7 @@ search: '| tstats summariesonly=true fillnull_value=null count min(_time) as fir | table "auth server", "vendor product", user, firstTime, lastTimeLogin, inactivityPeriodByDay, status, - action | `inactive_user_have_activity_detected_filter`' + action | `inactive_account_have_activity_detected_filter`' how_to_implement: Ensure that the Network Traffic data model is properly populated and includes logs from relevant sources (e.g., firewalls, proxies, or other network monitoring tools). Configure the data model acceleration to ensure performance and availability for this detection. Make sure to adjust any environment-specific filter macros for false positive reduction. known_false_positives: False positives may include legitimate users returning to the network after extended vacations or periods of inactivity. System accounts or service accounts that are seldom used but have routine tasks may also trigger this detection. references: From e6b0f4e27a2a236a25b6086e7031c6948427264d Mon Sep 17 00:00:00 2001 From: zake <139054590+zake1god@users.noreply.github.com> Date: Wed, 23 Oct 2024 10:20:11 +0700 Subject: [PATCH 4/8] Update inactive_account_have_activity_detected.yml Fix name, Fix data_sources, Change type, Add drilldown_searches, Add analytic_story --- ...nactive_account_have_activity_detected.yml | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/detections/network/inactive_account_have_activity_detected.yml b/detections/network/inactive_account_have_activity_detected.yml index 9dc4879763..3425f4e2c1 100644 --- a/detections/network/inactive_account_have_activity_detected.yml +++ b/detections/network/inactive_account_have_activity_detected.yml @@ -1,12 +1,12 @@ -name: Inactive Account Have Activity Detected +name: Detect Network Traffic From Inactive Accounts id: e08aa2f6-7d90-4ab8-af11-da4df38bb7ff version: 1 date: '2024-10-14' author: Zaki Zarkasih Al Mustafa data_sources: -- Windows Security 4624 -- Windows Security 4625 -type: Correlation +- Windows Event Log Security 4624 +- Windows Event Log Security 4625 +type: Anomaly status: production description: This detection identifies users who have been inactive for more than 30 days and suddenly have activity based on network traffic logs. search: '| tstats summariesonly=true fillnull_value=null count min(_time) as firstTime @@ -38,15 +38,29 @@ search: '| tstats summariesonly=true fillnull_value=null count min(_time) as fir | table "auth server", "vendor product", user, firstTime, lastTimeLogin, inactivityPeriodByDay, status, - action | `inactive_account_have_activity_detected_filter`' + action | `detect_network_traffic_from_inactive_accounts_filter`' how_to_implement: Ensure that the Network Traffic data model is properly populated and includes logs from relevant sources (e.g., firewalls, proxies, or other network monitoring tools). Configure the data model acceleration to ensure performance and availability for this detection. Make sure to adjust any environment-specific filter macros for false positive reduction. known_false_positives: False positives may include legitimate users returning to the network after extended vacations or periods of inactivity. System accounts or service accounts that are seldom used but have routine tasks may also trigger this detection. references: - https://attack.mitre.org/techniques/T1078/ - https://docs.splunk.com/Documentation/Splunk/latest/Knowledge/Useaccelerateddatamodels - https://www.sans.org/white-papers/monitoring-inactive-accounts/ +drilldown_searches: +- name: View network activity for $user$ + search: '%original_search% | search user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View detailed inactivity and action history for $user$ + search: '| tstats summariesonly=true fillnull_value=null count min(_time) as firstTime max(_time) as lastTime from datamodel=Network_Traffic.All_Traffic by All_Traffic.user, All_Traffic.action | search All_Traffic.user="$user$" | eval inactivityPeriodByDay = (now() - lastTime) / 86400 | eval status = if(inactivityPeriodByDay > 29, "inactive", "active") | eval inactivityPeriodByDay = round(inactivityPeriodByDay, 0) . " Days" | table user, action, firstTime, lastTime, inactivityPeriodByDay, status' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View associated risk events for $user$ + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ($user$) 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: [] + analytic_story: + - Insider Threat asset_type: Network confidence: 85 impact: 70 From 37e56b939e4e88bf7fcde805d4292c168ef70814 Mon Sep 17 00:00:00 2001 From: zake <139054590+zake1god@users.noreply.github.com> Date: Thu, 24 Oct 2024 08:36:29 +0700 Subject: [PATCH 5/8] Rename inactive_account_have_activity_detected.yml to detect_network_traffic_from_inactive_accounts_filter.yml Rename for fix CI --- ...l => detect_network_traffic_from_inactive_accounts_filter.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename detections/network/{inactive_account_have_activity_detected.yml => detect_network_traffic_from_inactive_accounts_filter.yml} (100%) diff --git a/detections/network/inactive_account_have_activity_detected.yml b/detections/network/detect_network_traffic_from_inactive_accounts_filter.yml similarity index 100% rename from detections/network/inactive_account_have_activity_detected.yml rename to detections/network/detect_network_traffic_from_inactive_accounts_filter.yml From 6cf6a7bed9c9f36c269fc32231b8d82d754c4f18 Mon Sep 17 00:00:00 2001 From: zake <139054590+zake1god@users.noreply.github.com> Date: Thu, 24 Oct 2024 13:27:22 +0700 Subject: [PATCH 6/8] Rename detect_network_traffic_from_inactive_accounts_filter.yml to detect_network_traffic_from_inactive_accounts.yml Wrong name, and already fix it --- ...lter.yml => detect_network_traffic_from_inactive_accounts.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename detections/network/{detect_network_traffic_from_inactive_accounts_filter.yml => detect_network_traffic_from_inactive_accounts.yml} (100%) diff --git a/detections/network/detect_network_traffic_from_inactive_accounts_filter.yml b/detections/network/detect_network_traffic_from_inactive_accounts.yml similarity index 100% rename from detections/network/detect_network_traffic_from_inactive_accounts_filter.yml rename to detections/network/detect_network_traffic_from_inactive_accounts.yml From 5cf3b991bddcc5d728497543c0de976820eda89f Mon Sep 17 00:00:00 2001 From: zake <139054590+zake1god@users.noreply.github.com> Date: Thu, 24 Oct 2024 13:31:55 +0700 Subject: [PATCH 7/8] Update detect_network_traffic_from_inactive_accounts.yml --- .../detect_network_traffic_from_inactive_accounts.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/detections/network/detect_network_traffic_from_inactive_accounts.yml b/detections/network/detect_network_traffic_from_inactive_accounts.yml index 3425f4e2c1..37717decce 100644 --- a/detections/network/detect_network_traffic_from_inactive_accounts.yml +++ b/detections/network/detect_network_traffic_from_inactive_accounts.yml @@ -47,15 +47,15 @@ references: - https://www.sans.org/white-papers/monitoring-inactive-accounts/ drilldown_searches: - name: View network activity for $user$ - search: '%original_search% | search user = "$user$"' + search: '%original_detection_search% | search user = "$user$"' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ - name: View detailed inactivity and action history for $user$ - search: '| tstats summariesonly=true fillnull_value=null count min(_time) as firstTime max(_time) as lastTime from datamodel=Network_Traffic.All_Traffic by All_Traffic.user, All_Traffic.action | search All_Traffic.user="$user$" | eval inactivityPeriodByDay = (now() - lastTime) / 86400 | eval status = if(inactivityPeriodByDay > 29, "inactive", "active") | eval inactivityPeriodByDay = round(inactivityPeriodByDay, 0) . " Days" | table user, action, firstTime, lastTime, inactivityPeriodByDay, status' + search: '%original_detection_search% | search All_Traffic.user="$user$" | eval inactivityPeriodByDay = (now() - lastTime) / 86400 | eval status = if(inactivityPeriodByDay > 29, "inactive", "active") | eval inactivityPeriodByDay = round(inactivityPeriodByDay, 0) . " Days" | table user, action, firstTime, lastTime, inactivityPeriodByDay, status' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ - name: View associated risk events for $user$ - search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ($user$) 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)`' + search: '%original_detection_search% | from datamodel Risk.All_Risk | search normalized_risk_object IN ($user$) 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: From 189d8f0a5b232d6c137da124a618f127299aebc6 Mon Sep 17 00:00:00 2001 From: zake <139054590+zake1god@users.noreply.github.com> Date: Tue, 29 Oct 2024 09:46:14 +0700 Subject: [PATCH 8/8] Update detect_network_traffic_from_inactive_accounts.yml Improve detection description, Remove %original_detection_search% and endhoursago=1, Update message from Analytic Story, Update risk_score --- ...tect_network_traffic_from_inactive_accounts.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/detections/network/detect_network_traffic_from_inactive_accounts.yml b/detections/network/detect_network_traffic_from_inactive_accounts.yml index 37717decce..7b454adc27 100644 --- a/detections/network/detect_network_traffic_from_inactive_accounts.yml +++ b/detections/network/detect_network_traffic_from_inactive_accounts.yml @@ -8,7 +8,7 @@ data_sources: - Windows Event Log Security 4625 type: Anomaly status: production -description: This detection identifies users who have been inactive for more than 30 days and suddenly have activity based on network traffic logs. +description: This detection identifies network traffic activity from user accounts that have been inactive for over 30 days. It monitors the network logs for accounts with no recent activity within the past 30 days and flags any sudden activity (such as login or access events) as a potential anomaly. This can help detect cases where inactive accounts may have been compromised and are being used unexpectedly. The detection logic leverages data from network traffic logs and checks for accounts that have not had any recorded activity within the specified inactivity threshold. search: '| tstats summariesonly=true fillnull_value=null count min(_time) as firstTime max(_time) as lastTime from @@ -51,20 +51,20 @@ drilldown_searches: earliest_offset: $info_min_time$ latest_offset: $info_max_time$ - name: View detailed inactivity and action history for $user$ - search: '%original_detection_search% | search All_Traffic.user="$user$" | eval inactivityPeriodByDay = (now() - lastTime) / 86400 | eval status = if(inactivityPeriodByDay > 29, "inactive", "active") | eval inactivityPeriodByDay = round(inactivityPeriodByDay, 0) . " Days" | table user, action, firstTime, lastTime, inactivityPeriodByDay, status' + search: 'search All_Traffic.user="$user$" | eval inactivityPeriodByDay = (now() - lastTime) / 86400 | eval status = if(inactivityPeriodByDay > 29, "inactive", "active") | eval inactivityPeriodByDay = round(inactivityPeriodByDay, 0) . " Days" | table user, action, firstTime, lastTime, inactivityPeriodByDay, status' earliest_offset: $info_min_time$ latest_offset: $info_max_time$ - name: View associated risk events for $user$ - search: '%original_detection_search% | from datamodel Risk.All_Risk | search normalized_risk_object IN ($user$) 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)`' + search: 'from datamodel Risk.All_Risk | search normalized_risk_object IN ($user$) 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: - Insider Threat asset_type: Network - confidence: 85 - impact: 70 - message: This detection identifies users who have been inactive for an extended period and suddenly have activity on the network. + confidence: 80 + impact: 50 + message: Network traffic detected from an inactive user account - $user$ mitre_attack_id: - T1078 - T1110 @@ -83,7 +83,7 @@ tags: - authserver - vendor_product - action - risk_score: "{{ (impact * confidence) / 100 }}" + risk_score: 40 security_domain: identity cve: [] tests: