diff --git a/contentctl.yml b/contentctl.yml index e6b8be6f0b..669ef4ca8b 100644 --- a/contentctl.yml +++ b/contentctl.yml @@ -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 diff --git a/detections/application/detect_distributed_password_spray_attempts.yml b/detections/application/detect_distributed_password_spray_attempts.yml index f029979e1b..57e3a99e1d 100644 --- a/detections/application/detect_distributed_password_spray_attempts.yml +++ b/detections/application/detect_distributed_password_spray_attempts.yml @@ -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 <> = if(<>="null",null(),<>)] | 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 <> = if(<>="null",null(),<>)] + | 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/ @@ -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 diff --git a/detections/application/detect_password_spray_attempts.yml b/detections/application/detect_password_spray_attempts.yml index e90f4e889d..7f70cd0f7b 100644 --- a/detections/application/detect_password_spray_attempts.yml +++ b/detections/application/detect_password_spray_attempts.yml @@ -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 <> = if(<>="null",null(),<>)] | 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 <> = if(<>="null",null(),<>)] + | 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/ @@ -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 diff --git a/detections/cloud/aws_multiple_users_failing_to_authenticate_from_ip.yml b/detections/cloud/aws_multiple_users_failing_to_authenticate_from_ip.yml index 9ac352c9ef..fe54a04cb1 100644 --- a/detections/cloud/aws_multiple_users_failing_to_authenticate_from_ip.yml +++ b/detections/cloud/aws_multiple_users_failing_to_authenticate_from_ip.yml @@ -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/ diff --git a/detections/endpoint/kerberoasting_spn_request_with_rc4_encryption.yml b/detections/endpoint/kerberoasting_spn_request_with_rc4_encryption.yml index 7d9e0b4abc..95fbfdeba3 100644 --- a/detections/endpoint/kerberoasting_spn_request_with_rc4_encryption.yml +++ b/detections/endpoint/kerberoasting_spn_request_with_rc4_encryption.yml @@ -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 @@ -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: diff --git a/detections/endpoint/unusual_number_of_kerberos_service_tickets_requested.yml b/detections/endpoint/unusual_number_of_kerberos_service_tickets_requested.yml index 56ae60c45a..0d6fa27f5d 100644 --- a/detections/endpoint/unusual_number_of_kerberos_service_tickets_requested.yml +++ b/detections/endpoint/unusual_number_of_kerberos_service_tickets_requested.yml @@ -1,16 +1,29 @@ name: Unusual Number of Kerberos Service Tickets Requested id: eb3e6702-8936-11ec-98fe-acde48001122 version: 5 -date: '2024-09-30' -author: Mauricio Velazco, Splunk +date: '2024-10-17' +author: Mauricio Velazco, Dean Luxton, Splunk status: production type: Anomaly description: The following analytic identifies an unusual number of Kerberos service ticket requests, potentially indicating a kerberoasting attack. It leverages Kerberos Event 4769 and calculates the standard deviation for each host, using the 3-sigma rule to detect anomalies. This activity is significant as kerberoasting allows adversaries to request service tickets and crack them offline, potentially gaining privileged access to the domain. If confirmed malicious, this could lead to unauthorized access to sensitive accounts and escalation of privileges within the Active Directory environment. data_source: - Windows Event Log Security 4769 -search: '`wineventlog_security` EventCode=4769 ServiceName!="*$" TicketEncryptionType=0x17 | bucket span=2m _time | stats dc(ServiceName) AS unique_services values(ServiceName) as requested_services by _time, src | eventstats avg(unique_services) as comp_avg , stdev(unique_services) as comp_std by src | eval upperBound=(comp_avg+comp_std*3) | eval isOutlier=if(unique_services > 2 and unique_services >= upperBound, 1, 0) | search isOutlier=1 | `unusual_number_of_kerberos_service_tickets_requested_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: An single endpoint requesting a large number of kerberos service tickets is not common behavior. Possible false positive scenarios include but are not limited to vulnerability scanners, administration systems and missconfigured systems. +search: >- + `wineventlog_security` EventCode=4769 ServiceName!="*$" TicketEncryptionType=0x17 + | bucket span=2m _time + | stats dc(ServiceName) AS unique_services values(ServiceName) as requested_services values(user_category) as user_category values(src_category) as src_category by _time, user, src + | eventstats avg(unique_services) as comp_avg , stdev(unique_services) as comp_std by user, src + | eval upperBound=(comp_avg+comp_std*3) + | eval isOutlier=if(unique_services > 2 and unique_services >= upperBound, 1, 0) + | search isOutlier=1 + | `unusual_number_of_kerberos_service_tickets_requested_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: An single endpoint requesting a large number of kerberos service + tickets is not common behavior. Possible false positive scenarios include but are + not limited to vulnerability scanners, administration systems and missconfigured + systems. references: - https://attack.mitre.org/techniques/T1558/003/ - https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/t1208-kerberoasting @@ -27,9 +40,9 @@ tags: analytic_story: - Active Directory Kerberos Attacks asset_type: Endpoint - confidence: 60 - impact: 60 - message: tbd + confidence: 80 + impact: 80 + message: User $user$ requested a service ticket for $unique_services$ services indicating a potential kerberoasting attack mitre_attack_id: - T1558 - T1558.003 @@ -38,6 +51,10 @@ tags: type: Endpoint role: - Victim + - name: user + type: User + role: + - Victim product: - Splunk Enterprise - Splunk Enterprise Security @@ -47,11 +64,12 @@ tags: - EventCode - Ticket_Options - Ticket_Encryption_Type - - dest + - user + - src - Service_Name - service_id - Client_Address - risk_score: 36 + risk_score: 64 security_domain: endpoint tests: - name: True Positive Test diff --git a/detections/endpoint/windows_ad_serviceprincipalname_added_to_domain_account.yml b/detections/endpoint/windows_ad_serviceprincipalname_added_to_domain_account.yml index 05f3e86acc..33fcf5b2f0 100644 --- a/detections/endpoint/windows_ad_serviceprincipalname_added_to_domain_account.yml +++ b/detections/endpoint/windows_ad_serviceprincipalname_added_to_domain_account.yml @@ -1,16 +1,32 @@ name: Windows AD ServicePrincipalName Added To Domain Account id: 8a1259cb-0ea7-409c-8bfe-74bad89259f9 version: 5 -date: '2024-09-30' +date: '2024-10-16' author: Mauricio Velazco, Splunk type: TTP status: production data_source: - Windows Event Log Security 5136 -description: The following analytic detects the addition of a Service Principal Name (SPN) to a domain account. It leverages Windows Event Code 5136 and monitors changes to the servicePrincipalName attribute. This activity is significant because it may indicate an attempt to perform Kerberoasting, a technique where attackers extract and crack service account passwords offline. If confirmed malicious, this could allow an attacker to obtain cleartext passwords, leading to unauthorized access and potential lateral movement within the domain environment. -search: '`wineventlog_security` EventCode=5136 AttributeLDAPDisplayName=servicePrincipalName OperationType="%%14674" | stats values(ObjectDN) as ObjectDN by _time, Computer, SubjectUserName, AttributeValue | rename Computer as dest SubjectUserName as user | `windows_ad_serviceprincipalname_added_to_domain_account_filter`' -how_to_implement: To successfully implement this search, you ned to be ingesting eventcode `5136`. The Advanced Security Audit policy setting `Audit Directory Services Changes` within `DS Access` needs to be enabled. Additionally, a SACL needs to be created for AD objects in order to ingest attribute modifications. -known_false_positives: A Service Principal Name should only be added to an account when an application requires it. While infrequent, this detection may trigger on legitimate actions. Filter as needed. +description: The following analytic detects the addition of a Service Principal Name + (SPN) to a domain account. It leverages Windows Event Code 5136 and monitors changes + to the servicePrincipalName attribute. This activity is significant because it may + indicate an attempt to perform Kerberoasting, a technique where attackers extract + and crack service account passwords offline. If confirmed malicious, this could + allow an attacker to obtain cleartext passwords, leading to unauthorized access + and potential lateral movement within the domain environment. +search: >- + `wineventlog_security` EventCode=5136 AttributeLDAPDisplayName=servicePrincipalName OperationType="%%14674" ObjectClass=user + | stats values(ObjectDN) as ObjectDN by _time, Computer, SubjectUserName, AttributeValue + | rex field=ObjectDN "^CN=(?P[a-zA-Z0-9!#$%&'@^_{}~.-]+)," + | rename Computer as dest, SubjectUserName as src_user + | `windows_ad_serviceprincipalname_added_to_domain_account_filter` +how_to_implement: To successfully implement this search, you ned to be ingesting eventcode + `5136`. The Advanced Security Audit policy setting `Audit Directory Services Changes` + within `DS Access` needs to be enabled. Additionally, a SACL needs to be created + for AD objects in order to ingest attribute modifications. +known_false_positives: A Service Principal Name should only be added to an account + when an application requires it. While infrequent, this detection may trigger on + legitimate actions. Filter as needed. references: - https://adsecurity.org/?p=3466 - https://www.thehacker.recipes/ad/movement/dacl/targeted-kerberoasting @@ -35,11 +51,11 @@ tags: mitre_attack_id: - T1098 observable: - - name: user + - name: src_user type: User role: - Attacker - - name: ObjectDN + - name: user type: User role: - Victim diff --git a/detections/endpoint/windows_driver_load_non_standard_path.yml b/detections/endpoint/windows_driver_load_non_standard_path.yml index 93264b892e..f4c48b9e35 100644 --- a/detections/endpoint/windows_driver_load_non_standard_path.yml +++ b/detections/endpoint/windows_driver_load_non_standard_path.yml @@ -1,16 +1,26 @@ name: Windows Driver Load Non-Standard Path id: 9216ef3d-066a-4958-8f27-c84589465e62 version: 4 -date: '2024-09-30' +date: "2024-10-17" author: Michael Haag, Splunk status: production type: TTP description: The following analytic detects the loading of new Kernel Mode Drivers from non-standard paths using Windows EventCode 7045. It identifies drivers not located in typical directories like Windows, Program Files, or SystemRoot. This activity is significant because adversaries may use these non-standard paths to load malicious or vulnerable drivers, potentially bypassing security controls. If confirmed malicious, this could allow attackers to execute code at the kernel level, escalate privileges, or maintain persistence within the environment, posing a severe threat to system integrity and security. data_source: - Windows Event Log System 7045 -search: '`wineventlog_system` EventCode=7045 ServiceType="kernel mode driver" NOT (ImagePath IN ("*\\Windows\\*", "*\\Program File*", "*\\systemroot\\*","%SystemRoot%*", "system32\*")) | stats count min(_time) as firstTime max(_time) as lastTime by Computer EventCode ImagePath ServiceName ServiceType | rename Computer as dest | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `windows_driver_load_non_standard_path_filter`' -how_to_implement: To implement this analytic, the Windows EventCode 7045 will need to be logged. The Windows TA for Splunk is also recommended. -known_false_positives: False positives may be present based on legitimate third party applications needing to install drivers. Filter, or allow list known good drivers consistently being installed in these paths. +search: >- + `wineventlog_system` EventCode=7045 ServiceType="kernel mode driver" + | regex ImagePath!="(?i)^(\w:\\\\Windows\\\\|\w:\\\\Program\sFile|\\\\systemroot\\\\|%SystemRoot%|system32\\\\)" + | stats count min(_time) as firstTime max(_time) as lastTime by Computer EventCode ImagePath ServiceName ServiceType + | rename Computer as dest + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + | `windows_driver_load_non_standard_path_filter` +how_to_implement: To implement this analytic, the Windows EventCode 7045 will need + to be logged. The Windows TA for Splunk is also recommended. +known_false_positives: False positives may be present based on legitimate third party + applications needing to install drivers. Filter, or allow list known good drivers + consistently being installed in these paths. references: - https://redcanary.com/blog/tracking-driver-inventory-to-expose-rootkits/ - https://attack.mitre.org/techniques/T1014/ diff --git a/detections/endpoint/winevent_windows_task_scheduler_event_action_started.yml b/detections/endpoint/winevent_windows_task_scheduler_event_action_started.yml index 72dea37014..a9312e619e 100644 --- a/detections/endpoint/winevent_windows_task_scheduler_event_action_started.yml +++ b/detections/endpoint/winevent_windows_task_scheduler_event_action_started.yml @@ -1,7 +1,7 @@ name: WinEvent Windows Task Scheduler Event Action Started id: b3632472-310b-11ec-9aab-acde48001122 version: 5 -date: '2024-10-17' +date: '2024-10-24' author: Michael Haag, Splunk status: production type: Hunting @@ -9,9 +9,15 @@ description: The following analytic detects the execution of tasks registered in data_source: - Windows Event Log TaskScheduler 200 - Windows Event Log TaskScheduler 201 -search: '`wineventlog_task_scheduler` EventCode IN ("200","201") | stats count min(_time) as firstTime max(_time) as lastTime by TaskName dest EventCode | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `winevent_windows_task_scheduler_event_action_started_filter`' -how_to_implement: Task Scheduler logs are required to be collected. Enable logging with inputs.conf by adding a stanza for [WinEventLog://Microsoft-Windows-TaskScheduler/Operational] and renderXml=false. Note, not translating it in XML may require a proper extraction of specific items in the Message. -known_false_positives: False positives will be present. Filter based on ActionName paths or specify keywords of interest. +search: '`wineventlog_task_scheduler` EventCode IN ("200","201") | stats count min(_time) + as firstTime max(_time) as lastTime by TaskName dvc EventCode | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` | `winevent_windows_task_scheduler_event_action_started_filter`' +how_to_implement: Task Scheduler logs are required to be collected. Enable logging + with inputs.conf by adding a stanza for [WinEventLog://Microsoft-Windows-TaskScheduler/Operational] + and renderXml=false. Note, not translating it in XML may require a proper extraction + of specific items in the Message. +known_false_positives: False positives will be present. Filter based on ActionName + paths or specify keywords of interest. references: - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1053.005/T1053.005.md - https://thedfirreport.com/2021/10/18/icedid-to-xinglocker-ransomware-in-24-hours/ @@ -37,11 +43,11 @@ tags: asset_type: Endpoint confidence: 100 impact: 80 - message: A Scheduled Task was scheduled and ran on $dest$. + message: A Scheduled Task was scheduled and ran on $dvc$. mitre_attack_id: - T1053.005 observable: - - name: dest + - name: dvc type: Hostname role: - Victim @@ -54,7 +60,7 @@ tags: - TaskName - ActionName - EventID - - dest + - dvc - ProcessID risk_score: 80 security_domain: endpoint @@ -62,5 +68,5 @@ tests: - name: True Positive Test attack_data: - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1053.005/winevent_windows_task_scheduler_event_action_started/windows-xml.log - source: XmlWinEventLog:Security + source: XmlWinEventLog:Microsoft-Windows-TaskScheduler/Operational sourcetype: XmlWinEventLog diff --git a/detections/network/detect_large_outbound_icmp_packets.yml b/detections/network/detect_large_outbound_icmp_packets.yml index fca5de51be..99ee9f52b5 100644 --- a/detections/network/detect_large_outbound_icmp_packets.yml +++ b/detections/network/detect_large_outbound_icmp_packets.yml @@ -1,27 +1,63 @@ name: Detect Large Outbound ICMP Packets id: e9c102de-4d43-42a7-b1c8-8062ea297419 -version: 4 -date: '2024-10-17' -author: Rico Valdez, Splunk -status: experimental +version: 6 +date: '2024-11-06' +author: Rico Valdez, Dean Luxton, Splunk +status: production type: TTP description: The following analytic identifies outbound ICMP packets with a size larger than 1,000 bytes. It leverages the Network_Traffic data model to detect unusually large ICMP packets that are not blocked and are destined for external IP addresses. This activity is significant because threat actors often use ICMP for command and control communication, and large ICMP packets can indicate data exfiltration or other malicious activities. If confirmed malicious, this could allow attackers to maintain covert communication channels, exfiltrate sensitive data, or further compromise the network. -data_source: [] -search: '| tstats `security_content_summariesonly` count earliest(_time) as firstTime latest(_time) as lastTime values(All_Traffic.action) values(All_Traffic.bytes) from datamodel=Network_Traffic where All_Traffic.action !=blocked All_Traffic.dest_category !=internal (All_Traffic.protocol=icmp OR All_Traffic.transport=icmp) All_Traffic.bytes > 1000 by All_Traffic.src_ip All_Traffic.dest_ip | `drop_dm_object_name("All_Traffic")` | search ( dest_ip!=10.0.0.0/8 AND dest_ip!=172.16.0.0/12 AND dest_ip!=192.168.0.0/16) | `security_content_ctime(firstTime)`|`security_content_ctime(lastTime)` | `detect_large_outbound_icmp_packets_filter`' -how_to_implement: 'In order to run this search effectively, we highly recommend that you leverage the Assets and Identity framework. It is important that you have a good understanding of how your network segments are designed and that you are able to distinguish internal from external address space. Add a category named `internal` to the CIDRs that host the company''s assets in the `assets_by_cidr.csv` lookup file, which is located in `$SPLUNK_HOME/etc/apps/SA-IdentityManagement/lookups/`. More information on updating this lookup can be found here: https://docs.splunk.com/Documentation/ES/5.0.0/Admin/Addassetandidentitydata. This search also requires you to be ingesting your network traffic and populating the Network_Traffic data model' -known_false_positives: ICMP packets are used in a variety of ways to help troubleshoot networking issues and ensure the proper flow of traffic. As such, it is possible that a large ICMP packet could be perfectly legitimate. If large ICMP packets are associated with Command And Control traffic, there will typically be a large number of these packets observed over time. If the search is providing a large number of false positives, you can modify the macro `detect_large_outbound_icmp_packets_filter` to adjust the byte threshold or add specific IP addresses to an allow list. +data_source: +- Palo Alto Network Traffic +search: >- + | tstats `security_content_summariesonly` count earliest(_time) as firstTime + latest(_time) as lastTime values(All_Traffic.action) as action values(All_Traffic.bytes) as bytes from + datamodel=Network_Traffic where All_Traffic.action !=blocked (All_Traffic.protocol=icmp OR All_Traffic.transport=icmp) All_Traffic.bytes + > 1000 AND NOT All_Traffic.dest_ip IN ("10.0.0.0/8","172.16.0.0/12","192.168.0.0/16") by All_Traffic.src_ip All_Traffic.dest_category All_Traffic.dest_ip All_Traffic.protocol + | `drop_dm_object_name("All_Traffic")` + | iplocation dest_ip + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` | `detect_large_outbound_icmp_packets_filter` +how_to_implement: 'In order to run this search effectively, we highly recommend that + you leverage the Assets and Identity framework. It is important that you have a + good understanding of how your network segments are designed and that you are able + to distinguish internal from external address space. Add a category named `internal` + to the CIDRs that host the company''s assets in the `assets_by_cidr.csv` lookup + file, which is located in `$SPLUNK_HOME/etc/apps/SA-IdentityManagement/lookups/`. + More information on updating this lookup can be found here: https://docs.splunk.com/Documentation/ES/5.0.0/Admin/Addassetandidentitydata. + This search also requires you to be ingesting your network traffic and populating + the Network_Traffic data model' +known_false_positives: ICMP packets are used in a variety of ways to help troubleshoot + networking issues and ensure the proper flow of traffic. As such, it is possible + that a large ICMP packet could be perfectly legitimate. If large ICMP packets are + associated with Command And Control traffic, there will typically be a large number + of these packets observed over time. If the search is providing a large number of + false positives, you can modify the macro `detect_large_outbound_icmp_packets_filter` + to adjust the byte threshold or add specific IP addresses to an allow list. references: [] +drilldown_searches: +- name: View the detection results for - "$src_ip$" and "$dest_ip$" + search: '%original_detection_search% | search src = "$src_ip$" dest = "$dest_ip$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$src_ip$" and "$dest_ip$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$src_ip$", "$dest_ip$") 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: - Command And Control asset_type: Endpoint confidence: 50 impact: 50 - message: tbd + message: Detect Large Outbound ICMP Packets Detected from $src_ip$ to $dest_ip$ mitre_attack_id: - T1095 observable: - - name: dest + - name: dest_ip + type: Hostname + role: + - Victim + - name: src_ip type: Hostname role: - Victim @@ -40,3 +76,9 @@ tags: - All_Traffic.dest_ip risk_score: 25 security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1095/palologs/large_icmp.log + sourcetype: pan:traffic + source: pan:traffic diff --git a/detections/network/detect_outbound_smb_traffic.yml b/detections/network/detect_outbound_smb_traffic.yml index b3c71b4b08..8917f723bc 100644 --- a/detections/network/detect_outbound_smb_traffic.yml +++ b/detections/network/detect_outbound_smb_traffic.yml @@ -1,15 +1,28 @@ name: Detect Outbound SMB Traffic id: 1bed7774-304a-4e8f-9d72-d80e45ff492b version: 6 -date: '2024-10-17' +date: '2024-10-16' author: Bhavin Patel, Stuart Hopkins, Patrick Bareiss status: experimental type: TTP description: The following analytic detects outbound SMB (Server Message Block) connections from internal hosts to external servers. It identifies this activity by monitoring network traffic for SMB requests directed towards the Internet, which are unusual for standard operations. This detection is significant for a SOC as it can indicate an attacker's attempt to retrieve credential hashes through compromised servers, a key step in lateral movement and privilege escalation. If confirmed malicious, this activity could lead to unauthorized access to sensitive data and potential full system compromise. data_source: [] -search: '| tstats `security_content_summariesonly` earliest(_time) as start_time latest(_time) as end_time values(All_Traffic.action) as action values(All_Traffic.app) as app values(All_Traffic.dest_ip) as dest_ip values(All_Traffic.dest_port) as dest_port values(sourcetype) as sourcetype count from datamodel=Network_Traffic where (All_Traffic.action=allowed All_Traffic.direction=outbound All_Traffic.dest_port=139 OR All_Traffic.dest_port=445 OR All_Traffic.app="smb") by All_Traffic.src_ip | `drop_dm_object_name("All_Traffic")` | eval match=case( cidrmatch("10.0.0.0/8" ,dest_ip) ,"1", cidrmatch("172.16.0.0/12" ,dest_ip) ,"1", cidrmatch("192.168.0.0/16" ,dest_ip) ,"1", cidrmatch("100.64.0.0/10" ,dest_ip) ,"1", 1=1,"0") | search match=0 | fields - match | `security_content_ctime(start_time)` | `security_content_ctime(end_time)` | `detect_outbound_smb_traffic_filter`' -how_to_implement: This search also requires you to be ingesting your network traffic and populating the Network_Traffic data model -known_false_positives: It is likely that the outbound Server Message Block (SMB) traffic is legitimate, if the company's internal networks are not well-defined in the Assets and Identity Framework. Categorize the internal CIDR blocks as `internal` in the lookup file to avoid creating notable events for traffic destined to those CIDR blocks. Any other network connection that is going out to the Internet should be investigated and blocked. Best practices suggest preventing external communications of all SMB versions and related protocols at the network boundary. +search: >- + | tstats `security_content_summariesonly` earliest(_time) as start_time latest(_time) as end_time values(All_Traffic.action) as action values(All_Traffic.app) as app values(sourcetype) as sourcetype count from datamodel=Network_Traffic where (All_Traffic.action=allowed All_Traffic.dest_port=139 OR All_Traffic.dest_port=445 OR All_Traffic.app="smb") AND All_Traffic.src_ip IN ("10.0.0.0/8","172.16.0.0/12","192.168.0.0/16") AND NOT All_Traffic.dest_ip IN ("10.0.0.0/8","172.16.0.0/12","192.168.0.0/16","100.64.0.0/10") by All_Traffic.src_ip All_Traffic.dest_ip All_Traffic.dest_port + | `drop_dm_object_name("All_Traffic")` + | `security_content_ctime(start_time)` + | `security_content_ctime(end_time)` + | iplocation dest_ip + | `detect_outbound_smb_traffic_filter` +how_to_implement: 'This search also requires you to be ingesting your network traffic + and populating the Network_Traffic data model' +known_false_positives: It is likely that the outbound Server Message Block (SMB) traffic + is legitimate, if the company's internal networks are not well-defined in the Assets + and Identity Framework. Categorize the internal CIDR blocks as `internal` in the + lookup file to avoid creating notable events for traffic destined to those CIDR + blocks. Any other network connection that is going out to the Internet should be + investigated and blocked. Best practices suggest preventing external communications + of all SMB versions and related protocols at the network boundary. references: [] tags: analytic_story: diff --git a/detections/network/internal_horizontal_port_scan_nmap_top_20.yml b/detections/network/internal_horizontal_port_scan_nmap_top_20.yml new file mode 100644 index 0000000000..816b6d3af9 --- /dev/null +++ b/detections/network/internal_horizontal_port_scan_nmap_top_20.yml @@ -0,0 +1,73 @@ +name: Internal Horizontal Port Scan NMAP Top 20 +id: 3141a041-4f57-4277-9faa-9305ca1f8e5b +version: 1 +date: '2024-09-25' +author: Dean Luxton +status: production +type: TTP +data_source: +- AWS CloudWatchLogs VPCflow +description: This analytic identifies instances where an internal host has attempted to communicate + with 250 or more destination IP addresses using on of the NMAP top 20 ports. Horizontal + port scans from internal hosts can indicate reconnaissance or scanning activities, + potentially signaling malicious intent or misconfiguration. By monitoring network + traffic logs, this detection helps detect and respond to such behavior promptly, + enhancing network security and preventing potential threats. +search: >- + | tstats `security_content_summariesonly` values(All_Traffic.action) as action values(All_Traffic.src_category) as src_category values(All_Traffic.dest_zone) as dest_zone values(All_Traffic.src_zone) as src_zone count from datamodel=Network_Traffic where All_Traffic.src_ip IN ("10.0.0.0/8","172.16.0.0/12","192.168.0.0/16") AND All_Traffic.dest_port IN (21, 22, 23, 25, 53, 80, 110, 111, 135, 139, 143, 443, 445, 993, 995, 1723, 3306, 3389, 5900, 8080) by All_Traffic.src_ip All_Traffic.dest_port All_Traffic.dest_ip span=1s _time All_Traffic.transport + | `drop_dm_object_name("All_Traffic")` + | eval gtime=_time + | bin span=1h gtime + | stats min(_time) as _time values(action) as action dc(dest_ip) as totalDestIPCount values(src_category) as src_category values(dest_zone) as dest_zone values(src_zone) as src_zone by src_ip dest_port gtime transport + | where totalDestIPCount>=250 + | eval dest_port=transport + "/" + dest_port + | stats min(_time) as _time values(action) as action sum(totalDestIPCount) as totalDestIPCount values(src_category) as src_category values(dest_port) as dest_ports values(dest_zone) as dest_zone values(src_zone) as src_zone by src_ip gtime + | fields - gtime + | `internal_horizontal_port_scan_nmap_top_20_filter` +how_to_implement: To properly run this search, Splunk needs to ingest data from networking telemetry sources such as + firewalls, NetFlow, or host-based networking events. Ensure that the Network_Traffic data model is populated to + 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 + asset_type: Endpoint + confidence: 80 + impact: 90 + message: $src_ip$ has scanned for ports $dest_ports$ across $totalDestIPCount$ destination IPs + mitre_attack_id: + - T1046 + observable: + - name: src_ip + type: Hostname + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + risk_score: 72 + required_fields: + - _time + - All_Traffic.action + - All_Traffic.src_ip + - All_Traffic.dest_ip + - All_Traffic.dest_port + security_domain: network +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1046/nmap/horizontal.log + source: aws:cloudwatchlogs:vpcflow + sourcetype: aws:cloudwatchlogs:vpcflow + update_timestamp: true \ No newline at end of file diff --git a/detections/network/remote_desktop_network_bruteforce.yml b/detections/network/remote_desktop_network_bruteforce.yml index 563c8530ed..2634f6b9cf 100644 --- a/detections/network/remote_desktop_network_bruteforce.yml +++ b/detections/network/remote_desktop_network_bruteforce.yml @@ -1,15 +1,23 @@ name: Remote Desktop Network Bruteforce id: a98727cc-286b-4ff2-b898-41df64695923 -version: 4 -date: '2024-10-17' +version: 5 +date: '2024-10-16' author: Jose Hernandez, Splunk status: experimental type: TTP description: The following analytic identifies potential Remote Desktop Protocol (RDP) brute force attacks by monitoring network traffic for RDP application activity. It detects anomalies by filtering source and destination pairs that generate traffic exceeding twice the standard deviation of the average traffic. This method leverages the Network_Traffic data model to identify unusual patterns indicative of brute force attempts. This activity is significant as it may indicate an attacker attempting to gain unauthorized access to systems via RDP. If confirmed malicious, this could lead to unauthorized access, data exfiltration, or further network compromise. data_source: [] -search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel=Network_Traffic where All_Traffic.app=rdp by All_Traffic.src All_Traffic.dest All_Traffic.dest_port | eventstats stdev(count) AS stdev avg(count) AS avg p50(count) AS p50 | where count>(avg + stdev*2) | rename All_Traffic.src AS src All_Traffic.dest AS dest | table firstTime lastTime src dest count avg p50 stdev | `remote_desktop_network_bruteforce_filter`' -how_to_implement: You must ensure that your network traffic data is populating the Network_Traffic data model. -known_false_positives: RDP gateways may have unusually high amounts of traffic from all other hosts' RDP applications in the network. +search: >- + | tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel=Network_Traffic where (All_Traffic.app=rdp OR All_Traffic.dest_port=3389) AND All_Traffic.action=allowed by All_Traffic.src All_Traffic.dest All_Traffic.dest_port + | eventstats stdev(count) AS stdev avg(count) AS avg p50(count) AS p50 + | where count>(avg + stdev*2) + | rename All_Traffic.src AS src All_Traffic.dest AS dest + | table firstTime lastTime src dest count avg p50 stdev + | `remote_desktop_network_bruteforce_filter` +how_to_implement: You must ensure that your network traffic data is populating the + Network_Traffic data model. +known_false_positives: RDP gateways may have unusually high amounts of traffic from + all other hosts' RDP applications in the network. references: [] tags: analytic_story: @@ -27,6 +35,10 @@ tags: type: Hostname role: - Victim + - name: src + type: Hostname + role: + - Victim product: - Splunk Enterprise - Splunk Enterprise Security diff --git a/detections/network/remote_desktop_network_traffic.yml b/detections/network/remote_desktop_network_traffic.yml index f33797c6f0..0fdb8716b0 100644 --- a/detections/network/remote_desktop_network_traffic.yml +++ b/detections/network/remote_desktop_network_traffic.yml @@ -1,7 +1,7 @@ name: Remote Desktop Network Traffic id: 272b8407-842d-4b3d-bead-a704584003d3 -version: 6 -date: '2024-09-30' +version: 7 +date: '2024-10-16' author: David Dorsey, Splunk status: production type: Anomaly @@ -29,7 +29,7 @@ tags: asset_type: Endpoint confidence: 50 impact: 50 - message: tbd + message: Remote Desktop Network Traffic Anomaly Detected from $src$ to $dest$ mitre_attack_id: - T1021.001 - T1021 diff --git a/detections/network/smb_traffic_spike.yml b/detections/network/smb_traffic_spike.yml index 37df31cad3..6240cd584a 100644 --- a/detections/network/smb_traffic_spike.yml +++ b/detections/network/smb_traffic_spike.yml @@ -20,12 +20,12 @@ tags: asset_type: Endpoint confidence: 50 impact: 50 - message: tbd + message: Anomalous splike of SMB traffic sent from $src$ mitre_attack_id: - T1021.002 - T1021 observable: - - name: dest + - name: src type: Hostname role: - Victim diff --git a/detections/network/high_volume_of_bytes_out_to_url.yml b/detections/web/high_volume_of_bytes_out_to_url.yml similarity index 100% rename from detections/network/high_volume_of_bytes_out_to_url.yml rename to detections/web/high_volume_of_bytes_out_to_url.yml diff --git a/detections/endpoint/java_class_file_download_by_java_user_agent.yml b/detections/web/java_class_file_download_by_java_user_agent.yml similarity index 81% rename from detections/endpoint/java_class_file_download_by_java_user_agent.yml rename to detections/web/java_class_file_download_by_java_user_agent.yml index b1d9185b03..1c3ba6d4c6 100644 --- a/detections/endpoint/java_class_file_download_by_java_user_agent.yml +++ b/detections/web/java_class_file_download_by_java_user_agent.yml @@ -1,15 +1,21 @@ name: Java Class File download by Java User Agent id: 8281ce42-5c50-11ec-82d2-acde48001122 version: 4 -date: '2024-09-30' +date: '2024-10-16' author: Michael Haag, Splunk status: production type: TTP description: The following analytic identifies a Java user agent performing a GET request for a .class file from a remote site. It leverages web or proxy logs within the Web Datamodel to detect this activity. This behavior is significant as it may indicate exploitation attempts, such as those related to CVE-2021-44228 (Log4Shell). If confirmed malicious, an attacker could exploit vulnerabilities in the Java application, potentially leading to remote code execution and further compromise of the affected system. data_source: - Splunk Stream HTTP -search: '| tstats count from datamodel=Web where Web.http_user_agent="*Java*" Web.http_method="GET" Web.url="*.class*" by Web.http_user_agent Web.http_method, Web.url,Web.url_length Web.src, Web.dest | `drop_dm_object_name("Web")` | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `java_class_file_download_by_java_user_agent_filter`' -how_to_implement: To successfully implement this search, you need to be ingesting web or proxy logs, or ensure it is being filled by a proxy like device, into the Web Datamodel. For additional filtering, allow list private IP space or restrict by known good. +search: '| tstats `security_content_summariesonly` count from datamodel=Web where Web.http_user_agent="*Java*" Web.http_method="GET" + Web.url="*.class*" by Web.http_user_agent Web.http_method, Web.url,Web.url_length + Web.src, Web.dest | `drop_dm_object_name("Web")` | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` | `java_class_file_download_by_java_user_agent_filter`' +how_to_implement: To successfully implement this search, you need to be ingesting + web or proxy logs, or ensure it is being filled by a proxy like device, into the + Web Datamodel. For additional filtering, allow list private IP space or restrict + by known good. known_false_positives: Filtering may be required in some instances, filter as needed. references: - https://arstechnica.com/information-technology/2021/12/as-log4shell-wreaks-havoc-payroll-service-reports-ransomware-attack/ diff --git a/detections/network/multiple_archive_files_http_post_traffic.yml b/detections/web/multiple_archive_files_http_post_traffic.yml similarity index 100% rename from detections/network/multiple_archive_files_http_post_traffic.yml rename to detections/web/multiple_archive_files_http_post_traffic.yml diff --git a/detections/network/plain_http_post_exfiltrated_data.yml b/detections/web/plain_http_post_exfiltrated_data.yml similarity index 100% rename from detections/network/plain_http_post_exfiltrated_data.yml rename to detections/web/plain_http_post_exfiltrated_data.yml diff --git a/detections/network/unusually_long_content_type_length.yml b/detections/web/unusually_long_content_type_length.yml similarity index 58% rename from detections/network/unusually_long_content_type_length.yml rename to detections/web/unusually_long_content_type_length.yml index 0e2abef8e8..3126377481 100644 --- a/detections/network/unusually_long_content_type_length.yml +++ b/detections/web/unusually_long_content_type_length.yml @@ -7,9 +7,20 @@ status: experimental type: Anomaly description: The following analytic identifies unusually long strings in the Content-Type HTTP header sent by the client to the server. It uses data from the Stream:HTTP source, specifically evaluating the length of the `cs_content_type` field. This activity is significant because excessively long Content-Type headers can indicate attempts to exploit vulnerabilities or evade detection mechanisms. If confirmed malicious, this behavior could allow attackers to execute code, manipulate data, or bypass security controls, potentially leading to unauthorized access or data breaches. data_source: [] -search: '`stream_http` | eval cs_content_type_length = len(cs_content_type) | where cs_content_type_length > 100 | table endtime src_ip dest_ip cs_content_type_length cs_content_type url | `unusually_long_content_type_length_filter`' -how_to_implement: This particular search leverages data extracted from Stream:HTTP. You must configure the http stream using the Splunk Stream App on your Splunk Stream deployment server to extract the cs_content_type field. -known_false_positives: Very few legitimate Content-Type fields will have a length greater than 100 characters. +search: >- + | tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel=Web by Web.src Web.dest Web.url Web.http_user_agent Web.http_content_type + | `drop_dm_object_name("Web")` + | eval http_content_type_length = len(http_content_type) + | where http_content_type_length > 100 + | table firstTime lastTime src dest http_content_type_length http_content_type url http_user_agent + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + | `unusually_long_content_type_length_filter` +how_to_implement: This particular search leverages data extracted from Stream:HTTP. + You must configure the http stream using the Splunk Stream App on your Splunk Stream + deployment server to extract the cs_content_type field. +known_false_positives: Very few legitimate Content-Type fields will have a length + greater than 100 characters. references: [] tags: analytic_story: @@ -17,12 +28,16 @@ tags: asset_type: Web Server confidence: 50 impact: 50 - message: tbd + message: Unusually Long Content-Type Length ($http_content_type_length$ characters) In Web Request from $src$ observable: - name: dest type: Hostname role: - Victim + - name: src + type: Hostname + role: + - Victim product: - Splunk Enterprise - Splunk Enterprise Security diff --git a/macros/wineventlog_task_scheduler.yml b/macros/wineventlog_task_scheduler.yml index 49af84013c..d548b6f987 100644 --- a/macros/wineventlog_task_scheduler.yml +++ b/macros/wineventlog_task_scheduler.yml @@ -1,4 +1,4 @@ -definition: source="XmlWinEventLog:Security" +definition: (source="XmlWinEventLog:Microsoft-Windows-TaskScheduler/Operational" OR source="WinEventLog:Microsoft-Windows-TaskScheduler/Operational") description: customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent. name: wineventlog_task_scheduler \ No newline at end of file