Detection rules › Splunk

Splunk rules: 0a

Application Discovery - Windows (Sysmon)

#
Group by
_time, host
Source
github.com/anvilogic-forge/armory

Adversaries may attempt to get a listing of software and software versions that are installed on a system or in a cloud environment. Adversaries may use the information from Software Discovery during automated discovery to shape follow-on behaviors, including whether or not the adversary fully infects the target and/or attempts specific actions. Adversaries may attempt to enumerate software for a variety of reasons, such as figuring out what security measures are present or if the compromised system has a version of software that is vulnerable to Exploitation for Privilege Escalation. This use case detects commands enumerating applications installed on a Windows system

MITRE ATT&CK Coverage

TacticTechniques
Discovery

References

Telemetry Coverage

ProviderRecord / event type
SysmonEvent ID 1: Process creation

Rule Body

id: '17427.29296'
title: Application Discovery - Windows
description: 'Adversaries may attempt to get a listing of software and software versions
  that are installed on a system or in a cloud environment. Adversaries may use the
  information from Software Discovery during automated discovery to shape follow-on
  behaviors, including whether or not the adversary fully infects the target and/or
  attempts specific actions. Adversaries may attempt to enumerate software for a variety
  of reasons, such as figuring out what security measures are present or if the compromised
  system has a version of software that is vulnerable to Exploitation for Privilege
  Escalation. This use case detects commands enumerating applications installed on
  a Windows system. Atomics T1518 Test #2'
logic_format: Splunk
logic: '`get_endpoint_data` `get_endpoint_data_sysmon` (TERM(EventCode=1) OR "<EventID>1<")
  (TERM(query) OR (TERM(Get-ItemProperty) OR TERM(gp)) "Software" "Uninstall") OR
  ("wmic" TERM(product)) | regex process="(?i)((\s+query\s+|Get-ItemProperty|gp\s).*\x5cUninstall\x5c\*)|wmic\s+product\s+get\s+"
  | table _time, host, user, process, process_*, parent_process_name | bin span=1s
  | stats values(*) as * by _time, host '
techniques:
- discovery:software discovery
technique_id: 
- T1518
data_category:
- Windows Sysmon
- Process command-line parameters
references:
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1518/T1518.md#atomic-test-2---applications-installed

Stages and Predicates

Stage 1: search

`get_endpoint_data` `get_endpoint_data_sysmon` (TERM(EventCode=1) OR "<EventID>1<") (TERM(query) OR (TERM(Get-ItemProperty) OR TERM(gp)) "Software" "Uninstall") OR ("wmic" TERM(product))

Stage 2: regex

| regex
    process="(?i)((\s+query\s+|Get-ItemProperty|gp\s).*\x5cUninstall\x5c\*)|wmic\s+product\s+get\s+"

Stage 3: table

| table _time, host, user, process, process_*, parent_process_name

Stage 4: bucket

| bin span=1s

Stage 5: stats

| stats values(*) as * by _time, host

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventCodeeq
  • 1 corpus 226 (splunk 226)
field:"EventID" kind:eq value:"1"
processregex_match
    • (?i)((\s+query\s+|Get-ItemProperty|gp\s).*\x5cUninstall\x5c*)
    • wmic\s+product\s+get\s+
    corpus 2 (splunk 2)
field:"CommandLine" kind:regex_match

Search Terms

These SPL tokens match against raw event text.

StageTerm
1"<EventID>1<"
1query
1"Get-ItemProperty"
1gp
1"Software"
1"Uninstall"
1"wmic"
1product

Azure AD Concurrent Sessions From Different Ips

#
Status
production
Severity
medium
Group by
_time, aws::recipientAccountId, category, user, vendor_product
Author
Mauricio Velazco, Bhavin Patel, Splunk
Source
github.com/splunk/security_content

The following analytic detects an Azure AD account with concurrent sessions originating from multiple unique IP addresses within a 5-minute window. It leverages Azure Active Directory NonInteractiveUserSignInLogs to identify this behavior by analyzing successful authentication events and counting distinct source IPs. This activity is significant as it may indicate session hijacking, where an attacker uses stolen session cookies to access corporate resources from a different location. If confirmed malicious, this could lead to unauthorized access to sensitive information and potential data breaches.

Known False Positives

  • A user with concurrent sessions from different Ips may also represent the legitimate use of more than one device. Filter as needed and/or customize the threshold to fit your environment. Also consider the geographic location of the IP addresses and filter out IP space that belong to your organization.

MITRE ATT&CK Coverage

TacticTechniques
Collection

Telemetry Coverage

PlatformRecord / event type
AzureSuccess: Successful sign-in

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

name: Azure AD Concurrent Sessions From Different Ips
id: a9126f73-9a9b-493d-96ec-0dd06695490d
version: 15
creation_date: '2023-01-24'
modification_date: '2026-05-13'
author: Mauricio Velazco, Bhavin Patel, Splunk
status: production
type: TTP
description: The following analytic detects an Azure AD account with concurrent sessions originating from multiple unique IP addresses within a 5-minute window. It leverages Azure Active Directory NonInteractiveUserSignInLogs to identify this behavior by analyzing successful authentication events and counting distinct source IPs. This activity is significant as it may indicate session hijacking, where an attacker uses stolen session cookies to access corporate resources from a different location. If confirmed malicious, this could lead to unauthorized access to sensitive information and potential data breaches.
data_source:
    - Azure Active Directory
search: |-
    `azure_monitor_aad` properties.authenticationDetails{}.succeeded=true category=NonInteractiveUserSignInLogs action=success
      | rename properties.* as *
      | bucket span=5m _time
      | rename userAgent as user_agent
      | fillnull
      | stats count min(_time) as firstTime max(_time) as lastTime dc(src) as unique_ips values(dest) as dest values(src) as src values(user_agent) as user_agent
        BY user _time vendor_account
           vendor_product category
      | where unique_ips > 1
      | `security_content_ctime(firstTime)`
      | `security_content_ctime(lastTime)`
      | `azure_ad_concurrent_sessions_from_different_ips_filter`
how_to_implement: You must install the latest version of Splunk Add-on for Microsoft Cloud Services from Splunkbase (https://splunkbase.splunk.com/app/3110/#/details). You must be ingesting Azure Active Directory events into your Splunk environment through an EventHub. This analytic was written to be used with the azure:monitor:aad sourcetype leveraging the SignInLogs log category.
known_false_positives: A user with concurrent sessions from different Ips may also represent the legitimate use of more than one device. Filter as needed and/or customize the threshold to fit your environment. Also consider the geographic location of the IP addresses and filter out IP space that belong to your organization.
references:
    - https://attack.mitre.org/techniques/T1185/
    - https://breakdev.org/evilginx-2-next-generation-of-phishing-2fa-tokens/
    - https://github.com/kgretzky/evilginx2
finding:
    title: User $user$ has concurrent sessions from more than one unique IP address in the span of 5 minutes.
    entity:
        field: user
        type: user
        score: 50
threat_objects:
    - field: src
      type: ip_address
analytic_story:
    - Compromised User Account
    - Azure Active Directory Account Takeover
    - Scattered Lapsus$ Hunters
asset_type: Azure Tenant
mitre_attack_id:
    - T1185
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: cloud
security_domain: threat

Stages and Predicates

Stage 1: search

`azure_monitor_aad` properties.authenticationDetails{}.succeeded=true
    category=NonInteractiveUserSignInLogs action=success

Stage 2: rename

| rename properties.* as *

Stage 3: bucket

| bucket span=5m _time

Stage 4: rename

| rename userAgent as user_agent

Stage 5: fillnull

| fillnull

Stage 6: stats

| stats
    count
    min(_time) as firstTime
    max(_time) as lastTime
    dc(src) as unique_ips
    values(dest) as dest
    values(src) as src
    values(user_agent) as user_agent
  BY user _time vendor_account
       vendor_product category

Stage 7: where

| where unique_ips > 1

Stage 8: search

| `security_content_ctime(firstTime)`

Stage 9: search

| `security_content_ctime(lastTime)`

Stage 10: search

| `azure_ad_concurrent_sessions_from_different_ips_filter`

Indicators

These rows show field, operator, and value matches.

Azure AD User Enabled And Password Reset

#
Status
production
Severity
medium
Group by
aws::recipientAccountId, dest, initiatedBy, signature, src, user, vendor_product
Author
Mauricio Velazco, Gowthamaraj Rajendran, Splunk
Source
github.com/splunk/security_content

The following analytic detects an Azure AD user enabling a previously disabled account and resetting its password within 2 minutes. It uses Azure Active Directory events to identify this sequence of actions. This activity is significant because it may indicate an adversary with administrative access attempting to establish a backdoor identity within the Azure AD tenant. If confirmed malicious, this could allow the attacker to maintain persistent access, escalate privileges, and potentially exfiltrate sensitive information from the environment.

Known False Positives

  • While not common, Administrators may enable accounts and reset their passwords for legitimate reasons. Filter as needed.

MITRE ATT&CK Coverage

TacticTechniques
Persistence
Privilege Escalation

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

name: Azure AD User Enabled And Password Reset
id: 1347b9e8-2daa-4a6f-be73-b421d3d9e268
version: 14
creation_date: '2022-08-30'
modification_date: '2026-05-13'
author: Mauricio Velazco, Gowthamaraj Rajendran, Splunk
status: production
type: TTP
description: The following analytic detects an Azure AD user enabling a previously disabled account and resetting its password within 2 minutes. It uses Azure Active Directory events to identify this sequence of actions. This activity is significant because it may indicate an adversary with administrative access attempting to establish a backdoor identity within the Azure AD tenant. If confirmed malicious, this could allow the attacker to maintain persistent access, escalate privileges, and potentially exfiltrate sensitive information from the environment.
data_source:
    - Azure Active Directory Enable account
    - Azure Active Directory Reset password (by admin)
    - Azure Active Directory Update user
search: |-
    `azure_monitor_aad` (operationName="Enable account" OR operationName="Reset password (by admin)" OR operationName="Update user")
      | transaction user startsWith=(operationName="Enable account") endsWith=(operationName="Reset password (by admin)") maxspan=2m
      | rename properties.* as *
      | rename initiatedBy.user.userPrincipalName as initiatedBy
      | fillnull
      | stats count min(_time) as firstTime max(_time) as lastTime
        BY dest user src
           vendor_account vendor_product initiatedBy
           signature
      | `security_content_ctime(firstTime)`
      | `security_content_ctime(lastTime)`
      | `azure_ad_user_enabled_and_password_reset_filter`
how_to_implement: You must install the latest version of Splunk Add-on for Microsoft Cloud Services from Splunkbase(https://splunkbase.splunk.com/app/3110/#/details). You must be ingesting Azure Active Directory events into your Splunk environment. This analytic was written to be used with the azure:monitor:aad sourcetype leveraging the AuditLog log category.
known_false_positives: While not common, Administrators may enable accounts and reset their passwords for legitimate reasons. Filter as needed.
references:
    - https://attack.mitre.org/techniques/T1098/
finding:
    title: A user account, $user$, was enabled and its password reset within 2 minutes by $initiatedBy$
    entity:
        field: initiatedBy
        type: user
        score: 50
intermediate_findings:
    entities:
        - field: user
          type: user
          score: 50
          message: A user account, $user$, was enabled and its password reset within 2 minutes by $initiatedBy$
analytic_story:
    - Azure Active Directory Persistence
    - Scattered Lapsus$ Hunters
asset_type: Azure Active Directory
mitre_attack_id:
    - T1098
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: cloud
security_domain: identity

Stages and Predicates

Stage 1: search

`azure_monitor_aad` (
    operationName="Enable account"
    OR operationName="Reset password (by admin)"
    OR operationName="Update user"
)

Stage 2: transaction

| transaction user startsWith=(operationName="Enable account")
    endsWith=(operationName="Reset password (by admin)") maxspan=2m

Stage 3: rename

| rename properties.* as *

Stage 4: rename

| rename initiatedBy.user.userPrincipalName as initiatedBy

Stage 5: fillnull

| fillnull

Stage 6: stats

| stats count min(_time) as firstTime max(_time) as lastTime
    BY dest user src
       vendor_account vendor_product initiatedBy
       signature

Stage 7: search

| `security_content_ctime(firstTime)`

Stage 8: search

| `security_content_ctime(lastTime)`

Stage 9: search

| `azure_ad_user_enabled_and_password_reset_filter`

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
operationNameeq
  • Enable account
  • Reset password (by admin)
  • Update user corpus 3 (splunk 3)
field:"operationName" kind:eq
sourcetypeeq
  • azure:monitor:aad corpus 47 (splunk 47)
field:"sourcetype" kind:eq value:"azure:monitor:aad"

Esentutl.exe Collecting Browser Data (Sysmon)

#
Group by
_time, host
Source
github.com/anvilogic-forge/armory

Esentutl.exe is a Windows command line utility that provides database utilities for the Extensible Storage Engine (ESE). While esentutl.exe is a legitimate and useful tool within Windows environments, its abuse has been observed in malware infections including Qakbot, where it has been used to collect data from Internet Explorer and Microsoft Edge. This use case detects command line arguments used with esentutl.exe to collect data from web browsers

MITRE ATT&CK Coverage

TacticTechniques
Collection

References

Telemetry Coverage

ProviderRecord / event type
SysmonEvent ID 1: Process creation

Rule Body

id: '24860.46041'
title: Esentutl.exe Collecting Browser Data
description: 'Esentutl.exe is a Windows command line utility that provides database
  utilities for the Extensible Storage Engine (ESE). While esentutl.exe is a legitimate
  and useful tool within Windows environments, its abuse has been observed in malware
  infections including Qakbot, where it has been used to collect data from Internet
  Explorer and Microsoft Edge. This use case detects command line arguments used with
  esentutl.exe to collect data from web browsers. -- Software Association: Akira --
  Living Off the Land Binary and Scripts (LOLBAS) (LOLBIN)'
logic_format: Splunk
logic: '`get_endpoint_data` `get_endpoint_data_sysmon` (TERM(EventCode=1) OR "<EventID>1<")
  "esentutl.exe" OR ("/r " "\\Windows\\WebCache") | where match(process, "(?i)\s/r\s.*\x5cWindows\x5cWebCache")
  | table _time, host, user, signature_id, process, process_*, parent_* | bin span=1s
  | stats values(*) as * by _time, host '
techniques:
- collection:data from local system
technique_id: 
- T1005
data_category:
- Windows Sysmon
references:
- https://thedfirreport.com/2022/02/07/qbot-likes-to-move-it-move-it/
- https://www.cybereason.com/blog/threat-alert-aggressive-qakbot-campaign-and-the-black-basta-ransomware-group-targeting-u.s.-companies

Stages and Predicates

Stage 1: search

`get_endpoint_data` `get_endpoint_data_sysmon` (TERM(EventCode=1) OR "<EventID>1<") "esentutl.exe" OR ("/r " "\\Windows\\WebCache")

Stage 2: where

| where match(process, "(?i)\s/r\s.*\x5cWindows\x5cWebCache")

Stage 3: table

| table _time, host, user, signature_id, process, process_*, parent_*

Stage 4: bucket

| bin span=1s

Stage 5: stats

| stats values(*) as * by _time, host

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventCodeeq
  • 1 corpus 226 (splunk 226)
field:"EventID" kind:eq value:"1"
processregex_match
  • (?i)\s/r\s.*\x5cWindows\x5cWebCache
field:"CommandLine" kind:regex_match value:"(?i)\s/r\s.*\x5cWindows\x5cWebCache"

Search Terms

These SPL tokens match against raw event text.

StageTerm
1"<EventID>1<"
1"esentutl.exe"
1"/r "
1"\\Windows\\WebCache"

FScan.exe Network Scan (Windows Event Log)

#
Group by
_time, host
Source
github.com/anvilogic-forge/armory

Threat actors may use fscan, an open-source security scanning tool, to perform network reconnaissance, identify open ports, and detect vulnerabilities within a target environment. When executed, fscan often leverages rapid ICMP pings to scan private IP ranges for live hosts. This use case detects internal network scans by identifying hosts that generate over 100 rapid ICMP ping requests to private IP addresses matching fscan's automated command style within a grouped event window (default 30s), which may indicate unauthorized network scanning activity from fscan or similar utilities.

MITRE ATT&CK Coverage

References

Telemetry Coverage

Rule Body

id: '44122.86349'
title: FScan.exe Network Scan
description: Threat actors may use fscan, an open-source security scanning tool, to
  perform network reconnaissance, identify open ports, and detect vulnerabilities
  within a target environment. When executed, fscan often leverages rapid ICMP pings
  to scan private IP ranges for live hosts. This use case detects internal network
  scans by identifying hosts that generate over 100 rapid ICMP ping requests to private
  IP addresses matching fscan's automated command style within a grouped event window
  (default 30s), which may indicate unauthorized network scanning activity from fscan
  or similar utilities.
logic_format: Splunk
logic: ' `get_endpoint_data` `get_endpoint_data_winevent` (TERM(EventCode=4688) OR
  "<EventID>4688<" OR Type=Process) TERM(ping) "-n" "-w" | where match(process, "(?i)ping\s+-n\s1\s-w\s1\s(10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}|172\.(1[6-9]|2[0-9]|3[0-1])\.[0-9]{1,3}\.[0-9]{1,3}|192\.168\.[0-9]{1,3}\.[0-9]{1,3})")
  | table _time, host, user, host, process*, parent* | bin span=30s | stats values(*)
  as * by _time, host | where event_count > 100 '
techniques:
- discovery:remote system discovery
- discovery:network service discovery
technique_id: 
- T1018
- T1046
data_category:
- Process command-line parameters
- Windows event logs
references:
- https://github.com/shadow1ng/fscan
- https://blog.talosintelligence.com/new-persistent-attacks-japan/

Stages and Predicates

Stage 1: search

`get_endpoint_data` `get_endpoint_data_winevent` (TERM(EventCode=4688) OR "<EventID>4688<" OR Type=Process) TERM(ping) "-n" "-w"

Stage 2: where

| where
    match(
        process,
        "(?i)ping\s+-n\s1\s-w\s1\s(10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}|172\.(1[6-9]|2[0-9]|3[0-1])\.[0-9]{1,3}\.[0-9]{1,3}|192\.168\.[0-9]{1,3}\.[0-9]{1,3})"
    )

Stage 3: table

| table _time, host, user, host, process*, parent*

Stage 4: bucket

| bin span=30s

Stage 5: stats

| stats values(*) as * by _time, host

Stage 6: where

| where event_count > 100

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventCodeeq
  • 4688 corpus 284 (splunk 283, elastic 1)
field:"EventID" kind:eq value:"4688"
event_countgt
  • 100 corpus 2 (splunk 2)
field:"event_count" kind:gt value:"100"
processregex_match
  • (?i)ping\s+-n\s1\s-w\s1\s(10.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}|172.(1[6-9]|2[0-9]|3[0-1]).[0-9]{1,3}.[0-9]{1,3}|192.168.[0-9]{1,3}.[0-9]{1,3}) corpus 2 (splunk 2)
field:"CommandLine" kind:regex_match value:"(?i)ping\s+-n\s1\s-w\s1\s(10.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}|172.(1[6-9]|2[0-9]|3[0-1]).[0-9]{1,3}.[0-9]{1,3}|192.168.[0-9]{1,3}.[0-9]{1,3})"

Search Terms

These SPL tokens match against raw event text.

StageTerm
1"<EventID>4688<"
1ping
1"-n"
1"-w"

Go Run Execution (PowerShell)

#
Group by
_time, host
Source
github.com/anvilogic-forge/armory

Malicious actors are beginning to turn to Golang as a malware language since it is not typically picked up by antivirus software. Although the language is about 10 years old, and is used by many legitimate programmers, there has not been as much activity with Golang malware. This use case looks for run executions by go.

MITRE ATT&CK Coverage

References

Telemetry Coverage

Rule Body

id: '6091.6542'
title: Go Run Execution
description: Malicious actors are beginning to turn to Golang as a malware language
  since it is not typically picked up by antivirus software. Although the language
  is about 10 years old, and is used by many legitimate programmers, there has not
  been as much activity with Golang malware. This use case looks for run executions
  by go.
logic_format: Splunk
logic: '`get_endpoint_data` `get_endpoint_data_powershell` (TERM(EventCode=4104) OR
  TERM(<EventID>4104<)) (TERM(GO) OR "go.exe") TERM(RUN) | rex field=process (?<ioc>"(?i)\S+\.go")
  | table _time, host, user, signature_id, process, process_*, ioc | bin span=1s |
  stats values(*) as * by _time, host '
techniques:
- execution:command and scripting interpreter
technique_id: 
- T1059
data_category:
- PowerShell logs
- Process command-line parameters
references:
- https://www.f5.com/labs/articles/threat-intelligence/new-golang-malware-is-spreading-via-multiple-exploits-to-mine-mo

Stages and Predicates

Stage 1: search

`get_endpoint_data` `get_endpoint_data_powershell` (TERM(EventCode=4104) OR TERM(<EventID>4104<)) (TERM(GO) OR "go.exe") TERM(RUN)

Stage 2: rex

| rex field=process (?<ioc>"(?i)\S+\.go")

Stage 3: table

| table _time, host, user, signature_id, process, process_*, ioc

Stage 4: bucket

| bin span=1s

Stage 5: stats

| stats values(*) as * by _time, host

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventCodeeq
  • 4104 corpus 269 (splunk 269)
field:"EventID" kind:eq value:"4104"

Search Terms

These SPL tokens match against raw event text.

StageTerm
1"<EventID>4104<"
1GO
1"go.exe"
1RUN

Linux Auditd Possible Access Or Modification Of Sshd Config File

#
Status
production
Severity
low
Group by
audit_id, current_working_directory, dest, host, match_count, reconstructed_path
Author
Teoderick Contreras, Nasreddine Bencherchali, Splunk
Source
github.com/splunk/security_content

The following analytic detects access, deletion or modification of the ssh_config file on Linux systems. It leverages data from Linux Auditd, focusing on events of type PATH with a nametype of ("NORMAL", "CREATE", "DELETE"). This activity could be significant because unauthorized changes to ssh_config can allow threat actors to redirect port connections or use unauthorized keys, potentially compromising the system. Correlate this with related EXECVE or PROCTITLE events to identify the process or user responsible for the access or modification. If confirmed malicious, this could lead to unauthorized access, privilege escalation, or persistent backdoor access, posing a severe security risk.

Known False Positives

  • Administrator or network operator can use this commandline for automation purposes. Please update the filter macros to remove false positives.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

name: Linux Auditd Possible Access Or Modification Of Sshd Config File
id: acb3ea33-70f7-47aa-b335-643b3aebcb2f
version: 11
creation_date: '2022-01-12'
modification_date: '2026-05-13'
author: Teoderick Contreras, Nasreddine Bencherchali, Splunk
status: production
type: Anomaly
description: |
    The following analytic detects access, deletion or modification of the ssh_config file on Linux systems.
    It leverages data from Linux Auditd, focusing on events of type PATH with a nametype of ("NORMAL", "CREATE", "DELETE").
    This activity could be significant because unauthorized changes to ssh_config can allow threat actors to redirect port connections or use unauthorized keys, potentially compromising the system.
    Correlate this with related EXECVE or PROCTITLE events to identify the process or user responsible for the access or modification.
    If confirmed malicious, this could lead to unauthorized access, privilege escalation, or persistent backdoor access, posing a severe security risk.
data_source:
    - Linux Auditd Path
    - Linux Auditd Cwd
search: |
    `linux_auditd`
    (
      (type=PATH nametype IN ("NORMAL", "CREATE", "DELETE"))
      OR
      type=CWD
    )
    | rex "msg=audit\([^)]*:(?<audit_id>\d+)\)"

    | stats
      values(type) as types
      values(name) as names
      values(nametype) as nametype
      values(cwd) as cwd_list
      values(_time) as event_times
      by audit_id, host

    | eval current_working_directory = coalesce(mvindex(cwd_list, 0), "N/A")
    | eval candidate_paths = mvmap(names, if(match(names, "^/"), names, current_working_directory + "/" + names))
    | eval matched_paths = mvfilter(match(candidate_paths, "/etc/ssh/ssh_config.*"))
    | eval match_count = mvcount(matched_paths)
    | eval reconstructed_path = mvindex(matched_paths, 0)
    | eval e_time = mvindex(event_times, 0)
    | where match_count > 0
    | rename host as dest

    | stats count min(e_time) as firstTime max(e_time) as lastTime
      values(nametype) as nametype
      by current_working_directory
         reconstructed_path
         match_count
         dest
         audit_id

    | `security_content_ctime(firstTime)`
    | `security_content_ctime(lastTime)`
    |  `linux_auditd_possible_access_or_modification_of_sshd_config_file_filter`
how_to_implement: |
    To implement this detection, the process begins by ingesting auditd
    data, that consist SYSCALL, TYPE, EXECVE and PROCTITLE events, which captures command-line
    executions and process details on Unix/Linux systems. These logs should be ingested
    and processed using Splunk Add-on for Unix and Linux (https://splunkbase.splunk.com/app/833),
    which is essential for correctly parsing and categorizing the data. The next step
    involves normalizing the field names  to match the field names set by the Splunk
    Common Information Model (CIM) to ensure consistency across different data sources
    and enhance the efficiency of data modeling and make sure the type=CWD record type is activate in your auditd configuration.
    This approach enables effective monitoring and detection of linux endpoints where auditd is deployed.
known_false_positives: |
    Administrator or network operator can use this commandline for automation purposes.
    Please update the filter macros to remove false positives.
references:
    - https://www.hackingarticles.in/ssh-penetration-testing-port-22/
    - https://attack.mitre.org/techniques/T1098/004/
intermediate_findings:
    entities:
        - field: dest
          type: system
          score: 20
          message: $reconstructed_path$ has been accessed with type $nametype$ on host - [$dest$]
analytic_story:
    - Linux Living Off The Land
    - Linux Privilege Escalation
    - Linux Persistence Techniques
    - Compromised Linux Host
asset_type: Endpoint
mitre_attack_id:
    - T1098.004
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: endpoint
security_domain: endpoint

Stages and Predicates

Stage 1: search

`linux_auditd`
(
  (type=PATH nametype IN ("NORMAL", "CREATE", "DELETE"))
  OR
  type=CWD
)

Stage 2: rex

| rex "msg=audit\([^)]*:(?<audit_id>\d+)\)"

Stage 3: stats

| stats
  values(type) as types
  values(name) as names
  values(nametype) as nametype
  values(cwd) as cwd_list
  values(_time) as event_times
  by audit_id, host

Stage 4: eval

| eval current_working_directory = coalesce(mvindex(cwd_list, 0), "N/A")

Stage 5: eval

| eval
    candidate_paths = mvmap(
        names,
        if(match(names, "^/"), names, current_working_directory + "/" + names)
    )

Stage 6: eval

| eval matched_paths = mvfilter(match(candidate_paths, "/etc/ssh/ssh_config.*"))

Stage 7: eval

| eval match_count = mvcount(matched_paths)

Stage 8: eval

| eval reconstructed_path = mvindex(matched_paths, 0)

Stage 9: eval

| eval e_time = mvindex(event_times, 0)

Stage 10: where

| where match_count > 0

Stage 11: rename

| rename host as dest

Stage 12: stats

| stats count min(e_time) as firstTime max(e_time) as lastTime
  values(nametype) as nametype
  by current_working_directory
     reconstructed_path
     match_count
     dest
     audit_id

Stage 13: search

| `security_content_ctime(firstTime)`

Stage 14: search

| `security_content_ctime(lastTime)`

Stage 15: search

| `linux_auditd_possible_access_or_modification_of_sshd_config_file_filter`

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
match_countgt
  • 0 corpus 7 (splunk 7)
field:"match_count" kind:gt value:"0"
nametypein
  • CREATE
  • DELETE
  • NORMAL
field:"nametype" kind:in
sourcetypeeq
  • auditd corpus 58 (splunk 58)
field:"sourcetype" kind:eq value:"auditd"
typeeq
  • CWD corpus 7 (splunk 7)
  • PATH corpus 19 (sigma 12, splunk 7)
field:"type" kind:eq

Linux File Creation In Init Boot Directory

#
Status
production
Severity
low
Group by
CreationUtcTime, computer_name, event_action, file_access_time, file_acl, file_hash, file_modify_time, file_name, file_size, process_guid, process_id, target_filename, user, vendor_product
Author
Teoderick Contreras, Splunk
Source
github.com/splunk/security_content

The following analytic detects the creation of files in Linux init boot directories, which are used for automatic execution upon system startup. It leverages file system logs to identify new files in directories such as /etc/init.d/ and /etc/rc.d/. This activity is significant as it is a common persistence technique used by adversaries, malware authors, and red teamers. If confirmed malicious, this could allow an attacker to maintain persistence on the compromised host, potentially leading to further exploitation and unauthorized control over the system.

Known False Positives

  • Administrator or network operator can create file in this folders for automation purposes. Please update the filter macros to remove false positives.

MITRE ATT&CK Coverage

Telemetry Coverage

PlatformRecord / event type
LinuxEvent ID 11: File created

Rule Body

name: Linux File Creation In Init Boot Directory
id: 97d9cfb2-61ad-11ec-bb2d-acde48001122
version: 14
creation_date: '2021-12-23'
modification_date: '2026-05-13'
author: Teoderick Contreras, Splunk
status: production
type: Anomaly
description: |-
    The following analytic detects the creation of files in Linux init boot directories, which are used for automatic execution upon system startup.
    It leverages file system logs to identify new files in directories such as /etc/init.d/ and /etc/rc.d/. This activity is significant as it is a common persistence technique used by adversaries, malware authors, and red teamers.
    If confirmed malicious, this could allow an attacker to maintain persistence on the compromised host, potentially leading to further exploitation and unauthorized control over the system.
data_source:
    - Sysmon for Linux EventID 11
search: |-
    | tstats `security_content_summariesonly`
      count min(_time) as firstTime
            max(_time) as lastTime

    FROM datamodel=Endpoint.Filesystem WHERE

    Filesystem.action = "created"
    Filesystem.file_path IN (
        "*/etc/init.d/*",
        "*/etc/rc.d/*",
        "*/etc/rc.local*",
        "*/sbin/init.d/*"
    )
    BY Filesystem.action Filesystem.dest Filesystem.file_access_time
       Filesystem.file_create_time Filesystem.file_hash Filesystem.file_modify_time
       Filesystem.file_name Filesystem.file_path Filesystem.file_acl
       Filesystem.file_size Filesystem.process_guid Filesystem.process_id
       Filesystem.user Filesystem.vendor_product

    | `drop_dm_object_name(Filesystem)`
    | `security_content_ctime(lastTime)`
    | `security_content_ctime(firstTime)`
    | `linux_file_creation_in_init_boot_directory_filter`
how_to_implement: |-
    To successfully implement this search, you need to be ingesting logs with the file name, file path, and process_guid executions from your endpoints. If you are using Sysmon, you can use the Add-on for Linux Sysmon from Splunkbase
known_false_positives: |-
    Administrator or network operator can create file in this folders for automation purposes. Please update the filter macros to remove false positives.
references:
    - https://www.intezer.com/blog/research/kaiji-new-chinese-linux-malware-turning-to-golang/
intermediate_findings:
    entities:
        - field: dest
          type: system
          score: 20
          message: A file $file_name$ is created in $file_path$ on $dest$
analytic_story:
    - China-Nexus Threat Activity
    - Backdoor Pingpong
    - Linux Persistence Techniques
    - XorDDos
    - Linux Privilege Escalation
asset_type: Endpoint
mitre_attack_id:
    - T1037.004
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: endpoint
security_domain: endpoint

Stages and Predicates

Stage 1: tstats

| tstats `security_content_summariesonly`
  count min(_time) as firstTime
        max(_time) as lastTime

FROM datamodel=Endpoint.Filesystem WHERE

Filesystem.action = "created"
Filesystem.file_path IN (
    "*/etc/init.d/*",
    "*/etc/rc.d/*",
    "*/etc/rc.local*",
    "*/sbin/init.d/*"
)
BY Filesystem.action Filesystem.dest Filesystem.file_access_time
   Filesystem.file_create_time Filesystem.file_hash Filesystem.file_modify_time
   Filesystem.file_name Filesystem.file_path Filesystem.file_acl
   Filesystem.file_size Filesystem.process_guid Filesystem.process_id
   Filesystem.user Filesystem.vendor_product

Stage 2: search

| `drop_dm_object_name(Filesystem)`

Stage 3: search

| `security_content_ctime(lastTime)`

Stage 4: search

| `security_content_ctime(firstTime)`

Stage 5: search

| `linux_file_creation_in_init_boot_directory_filter`

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
Filesystem.actioneq
  • created corpus 11 (splunk 11)
field:"event_action" kind:eq value:"created"
Filesystem.file_pathin
  • */etc/init.d/*
  • */etc/rc.d/*
  • */etc/rc.local*
  • */sbin/init.d/*
field:"TargetFilename" kind:in

O365 Excessive Authentication Failures Alert

#
Status
production
Severity
low
Group by
aws::recipientAccountId, dest, user, vendor_product
Author
Rod Soto, Splunk
Source
github.com/splunk/security_content

The following analytic identifies an excessive number of authentication failures, including failed attempts against MFA prompt codes. It uses data from the o365_management_activity dataset, focusing on events where the authentication status is marked as failure. This behavior is significant as it may indicate a brute force attack or an attempt to compromise user accounts. If confirmed malicious, this activity could lead to unauthorized access, data breaches, or further exploitation within the environment.

Known False Positives

  • The threshold for alert is above 10 attempts and this should reduce the number of false positives.

MITRE ATT&CK Coverage

TacticTechniques
Credential Access

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

name: O365 Excessive Authentication Failures Alert
id: d441364c-349c-453b-b55f-12eccab67cf9
version: 11
creation_date: '2020-12-16'
modification_date: '2026-05-13'
author: Rod Soto, Splunk
status: production
type: Anomaly
description: The following analytic identifies an excessive number of authentication failures, including failed attempts against MFA prompt codes. It uses data from the `o365_management_activity` dataset, focusing on events where the authentication status is marked as failure. This behavior is significant as it may indicate a brute force attack or an attempt to compromise user accounts. If confirmed malicious, this activity could lead to unauthorized access, data breaches, or further exploitation within the environment.
data_source: []
search: |-
    `o365_management_activity` Workload=AzureActiveDirectory UserAuthenticationMethod=* status=failure
      | stats count earliest(_time) AS firstTime latest(_time) AS lastTime values(UserAuthenticationMethod) AS UserAuthenticationMethod values(UserAgent) AS user_agent values(status) AS status values(src_ip) AS src values(signature) as signature
        BY user vendor_account vendor_product
           dest
      | where count > 10
      | `security_content_ctime(firstTime)`
      | `security_content_ctime(lastTime)`
      | `o365_excessive_authentication_failures_alert_filter`
how_to_implement: You must install splunk Microsoft Office 365 add-on. This search works with o365:management:activity
known_false_positives: The threshold for alert is above 10 attempts and this should reduce the number of false positives.
references:
    - https://attack.mitre.org/techniques/T1110/
intermediate_findings:
    entities:
        - field: user
          type: user
          score: 20
          message: User $user$ has caused excessive number of authentication failures from $src$ using UserAgent $user_agent$.
threat_objects:
    - field: src
      type: ip_address
analytic_story:
    - Office 365 Account Takeover
asset_type: O365 Tenant
mitre_attack_id:
    - T1110
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: cloud
security_domain: threat

Stages and Predicates

Stage 1: search

`o365_management_activity` Workload=AzureActiveDirectory UserAuthenticationMethod=* status=failure

Stage 2: stats

| stats
    count
    earliest(_time) AS firstTime
    latest(_time) AS lastTime
    values(UserAuthenticationMethod) AS UserAuthenticationMethod
    values(UserAgent) AS user_agent
    values(status) AS status
    values(src_ip) AS src
    values(signature) as signature
  BY user vendor_account vendor_product
       dest

Stage 3: where

| where count > 10

Stage 4: search

| `security_content_ctime(firstTime)`

Stage 5: search

| `security_content_ctime(lastTime)`

Stage 6: search

| `o365_excessive_authentication_failures_alert_filter`

Indicators

These rows show field, operator, and value matches.

RDP File Written by Outlook (Sysmon)

#
Group by
_time, host
Source
github.com/anvilogic-forge/armory

Remote desktop is a common feature in operating systems. It allows a user to log into an interactive session with a system desktop graphical user interface on a remote system. Targeted spear-phishing campaigns attributed to Russia’s APT29 have been observed distributing .rdp files to victims to initiate a remote connection. This use case detects the creation of .rdp files in the temporary directory that Outlook uses when opening attachments.

MITRE ATT&CK Coverage

References

Telemetry Coverage

ProviderRecord / event type
SysmonEvent ID 11: FileCreate

Rule Body

id: '39085.70282'
title: RDP File Written by Outlook
description: Remote desktop is a common feature in operating systems. It allows a
  user to log into an interactive session with a system desktop graphical user interface
  on a remote system. Targeted spear-phishing campaigns attributed to Russia’s APT29
  have been observed distributing .rdp files to victims to initiate a remote connection.
  This use case detects the creation of .rdp files in the temporary directory that
  Outlook uses when opening attachments.
logic_format: Splunk
logic: '`get_endpoint_data` `get_endpoint_data_sysmon` (TERM(EventCode=11) OR "<EventID>11<")
  ".rdp" ("\\AppData\\Local\\Packages\\Microsoft.Outlook_" OR ("\\AppData\\Local\\Microsoft\\Windows\\"
  "\\Content.Outlook\\"))| where match(file_name, "(?i)\.rdp$") and match(file_path,
  "(?i)(\x5cAppData\x5cLocal\x5cMicrosoft\x5cWindows\x5c.*\x5cContent\.Outlook\x5c)|(\x5cAppData\x5cLocal\x5cPackages\x5cMicrosoft\.Outlook_)")
  | table _time, host, user, process_*, process, parent_*, file_* | bin span=1s |
  stats values(*) as * by _time, host '
techniques:
- lateral-movement:remote services:remote desktop protocol
- initial-access:phishing:spearphishing attachment
technique_id:
- T1021.001
- T1566.001
data_category:
- Windows Sysmon
references:
- https://x.com/cyb3rops/status/1851880158640099675?s=46
- https://www.microsoft.com/en-us/security/blog/2024/10/29/midnight-blizzard-conducts-large-scale-spear-phishing-campaign-using-rdp-files/
- https://cert.gov.ua/article/6281076
- https://aws.amazon.com/blogs/security/amazon-identified-internet-domains-abused-by-apt29/
- https://github.com/SigmaHQ/sigma/pull/5063/files

Stages and Predicates

Stage 1: search

`get_endpoint_data` `get_endpoint_data_sysmon` (TERM(EventCode=11) OR "<EventID>11<") ".rdp" ("\\AppData\\Local\\Packages\\Microsoft.Outlook_" OR ("\\AppData\\Local\\Microsoft\\Windows\\" "\\Content.Outlook\\"))

Stage 2: where

| where match(file_name, "(?i)\.rdp$")
    and match(
        file_path,
        "(?i)(\x5cAppData\x5cLocal\x5cMicrosoft\x5cWindows\x5c.*\x5cContent\.Outlook\x5c)|(\x5cAppData\x5cLocal\x5cPackages\x5cMicrosoft\.Outlook_)"
    )

Stage 3: table

| table _time, host, user, process_*, process, parent_*, file_*

Stage 4: bucket

| bin span=1s

Stage 5: stats

| stats values(*) as * by _time, host

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventCodeeq
  • 11 corpus 25 (splunk 25)
field:"EventID" kind:eq value:"11"
file_nameregex_match
  • (?i).rdp$
field:"file_name" kind:regex_match value:"(?i).rdp$"
file_pathregex_match
    • (?i)(\x5cAppData\x5cLocal\x5cMicrosoft\x5cWindows\x5c.*\x5cContent.Outlook\x5c)
    • (\x5cAppData\x5cLocal\x5cPackages\x5cMicrosoft.Outlook_)
field:"TargetFilename" kind:regex_match

Search Terms

These SPL tokens match against raw event text.

StageTerm
1"<EventID>11<"
1".rdp"
1"\\AppData\\Local\\Packages\\Microsoft.Outlook_"
1"\\AppData\\Local\\Microsoft\\Windows\\"
1"\\Content.Outlook\\"

Remote .msi Installation (Sysmon)

#
Group by
_time, host
Source
github.com/anvilogic-forge/armory

Adversaries may abuse msiexec.exe to proxy execution of malicious payloads. Msiexec.exe is the command-line utility for the Windows Installer and is thus commonly associated with executing installation packages (.msi). The Msiexec.exe binary may also be digitally signed by Microsoft. This use case detects attempts to install .msi from remote locations

MITRE ATT&CK Coverage

References

Telemetry Coverage

ProviderRecord / event type
SysmonEvent ID 1: Process creation

Rule Body

id: '18093.30599'
title: Remote .msi Installation
description: 'Adversaries may abuse msiexec.exe to proxy execution of malicious payloads.
  Msiexec.exe is the command-line utility for the Windows Installer and is thus commonly
  associated with executing installation packages (.msi). The Msiexec.exe binary may
  also be digitally signed by Microsoft. This use case detects attempts to install
  .msi from remote locations. -- Threat Actor Association: APT-K-47/Mysterious Elephant
  -- Atomics T1218.007 Test #11'
logic_format: Splunk
logic: '`get_endpoint_data` `get_endpoint_data_sysmon` (TERM(EventCode=1) OR "<EventID>1<")
  (TERM(/i) OR TERM(install)) ".msi" | where match(process, "(?i)\w+tps?://\S+\.msi")
  | table _time, host, user process, process_*, parent_* | bin span=1s | stats values(*)
  as * by _time, host '
techniques:
- defense-evasion:system binary proxy execution:msiexec
technique_id:
- T1218.007
data_category:
- Windows Sysmon
references:
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1218.007/T1218.007.md#atomic-test-11---msiexecexe---execute-remote-msi-file

Stages and Predicates

Stage 1: search

`get_endpoint_data` `get_endpoint_data_sysmon` (TERM(EventCode=1) OR "<EventID>1<") (TERM(/i) OR TERM(install)) ".msi"

Stage 2: where

| where match(process, "(?i)\w+tps?://\S+\.msi")

Stage 3: table

| table _time, host, user process, process_*, parent_*

Stage 4: bucket

| bin span=1s

Stage 5: stats

| stats values(*) as * by _time, host

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventCodeeq
  • 1 corpus 226 (splunk 226)
field:"EventID" kind:eq value:"1"
processregex_match
  • (?i)\w+tps?://\S+.msi corpus 6 (splunk 6)
field:"CommandLine" kind:regex_match value:"(?i)\w+tps?://\S+.msi"

Search Terms

These SPL tokens match against raw event text.

StageTerm
1"<EventID>1<"
1"/i"
1install
1".msi"

Remote Admin Tools (Windows Event Log)

#
Group by
_time, command_line, host
Source
github.com/anvilogic-forge/armory

PsExec, RemCom, PaExec, and CsExec are administrative command-line utilities that allow remote command execution

MITRE ATT&CK Coverage

References

Telemetry Coverage

Rule Body

id: '5343.5439'
title: 'Remote Admin Tools  '
description: 'PsExec, RemCom, PaExec, and CsExec are administrative command-line utilities
  that allow remote command execution Threat Actor Association: Antlion, DarkSide,
  BlackMatter, APT29/Nobelium, APT31, Carbanak, FIN6, FIN7, FIN8, FIN12, Fox Kitten,
  GoldenJackal, Hello Kitty / Five Hands, MalKamak, Muddled Libra, OilRig, Traveling
  Spider, UNC2596, Vice Society, Wizard Spider - Software Association: ALPHV/BlackCat,
  AvosLocker, BianLian, Blackbyte, Blacksuit, Black Basta, Conti, Cuba, GhostShell,
  Lockbit, Play, Prometheus/Spook, Prestige, PYSA/Mespinoza, Quantum, Rhysida, Royal,
  Vice Society - Atomics T1021.002 Test#3'
logic_format: Splunk
logic: '`get_endpoint_data` `get_endpoint_data_winevent` (TERM(EventCode=4688) OR
  "<EventID>4688<" OR Type=Process) ".exe" "\\\\"| regex process="(?i)((\.exe(\")?(\s+|\s+\/c)\s+)|(psexec.{1,}))|(\"{1,})?\x5c\x5c.{2,}"
  | table _time, host, user process, process_*, parent_process, parent_process_*,
  src_user | bin span=1s | stats values(*) as * by _time, host, process `hec_collect`'
techniques:
- execution:system services:service execution
- lateral-movement:remote services
- execution:command and scripting interpreter:windows command shell
- lateral-movement:lateral tool transfer
technique_id:
- T1569.002
- T1021
- T1059.003
- T1570
data_category:
- Process command-line parameters
- Windows event logs
references:
- https://redcanary.com/blog/threat-hunting-psexec-lateral-movement/

Stages and Predicates

Stage 1: search

`get_endpoint_data` `get_endpoint_data_winevent` (TERM(EventCode=4688) OR "<EventID>4688<" OR Type=Process) ".exe" "\\\\"

Stage 2: regex

| regex process="(?i)((\.exe(\")?(\s+|\s+\/c)\s+)|(psexec.{1,}))|(\"{1,})?\x5c\x5c.{2,}"

Stage 3: table

| table _time, host, user process, process_*, parent_process, parent_process_*, src_user

Stage 4: bucket

| bin span=1s

Stage 5: stats

| stats values(*) as * by _time, host, process `hec_collect`

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventCodeeq
  • 4688 corpus 284 (splunk 283, elastic 1)
field:"EventID" kind:eq value:"4688"
processregex_match
    • (?i)((.exe(")?(\s+|\s+\/c)\s+)|(psexec.{1,}))
    • ("{1,})?\x5c\x5c.{2,}
    corpus 2 (splunk 2)
field:"CommandLine" kind:regex_match

Search Terms

These SPL tokens match against raw event text.

StageTerm
1"<EventID>4688<"
1".exe"
1"\\\\"

SMB Write Access on Administrative Share (Windows Event Log)

#
Group by
_time, host
Source
github.com/anvilogic-forge/armory

SMB is a Windows file and printer sharing protocol. Threat actors may use SMB to connect to shared drives when moving laterally. An administrative share is a network share created by default on Windows systems for administrative purposes, allowing privileged users remote access to system resources, typically hidden from regular network users (denoted by $). Domain controllers may have administrative shares NETLOGON or SYSVOL. This use case detects SMB access attempts targeting Administrative shares with write access masks (0x2) from non-system accounts.

MITRE ATT&CK Coverage

References

Telemetry Coverage

Rule Body

id: '24475.45119'
title: SMB Write Access on Administrative Share
description: SMB is a Windows file and printer sharing protocol. Threat actors may
  use SMB to connect to shared drives when moving laterally. An administrative share
  is a network share created by default on Windows systems for administrative purposes,
  allowing privileged users remote access to system resources, typically hidden from
  regular network users (denoted by $). Domain controllers may have administrative
  shares NETLOGON or SYSVOL. This use case detects SMB access attempts targeting Administrative
  shares with write access masks (0x2) from non-system accounts.
logic_format: Splunk
logic: '`get_endpoint_data` `get_endpoint_data_winevent` (TERM(EventCode=5145) OR
  "<EventID>5145<" OR TERM(EventCode=5140) OR "<EventID>5140<") "0x2" ("$" OR "SYSVOL"
  OR "NETLOGON") | rex "<Data Name=''ShareName''>(?<share_name>[^<]+)</Data>"| rex
  "<Data Name=''AccessMask''>(?<access_mask>[^<]+)"| where match(share_name, "(?i)(.*\$$)|NETLOGON|SYSVOL")
  and match(access_mask, "(?i)0x2") and not match(user, ".*\$$") | table _time, host,
  user process, process_*, parent_process_name, parent_process_path, share_name |
  bin span=1s | stats values(*) as * by _time, host '
techniques:
- lateral-movement:remote services:smb/windows admin shares
technique_id:
- T1021.002
data_category:
- Windows event logs
references:
- https://securitydatasets.com/notebooks/atomic/windows/lateral_movement/SDWIN-200806015757.html?highlight=create%20file

Stages and Predicates

Stage 1: search

`get_endpoint_data` `get_endpoint_data_winevent` (TERM(EventCode=5145) OR "<EventID>5145<" OR TERM(EventCode=5140) OR "<EventID>5140<") "0x2" ("$" OR "SYSVOL" OR "NETLOGON")

Stage 2: rex

| rex "<Data Name='ShareName'>(?<share_name>[^<]+)</Data>"

Stage 3: rex

| rex "<Data Name='AccessMask'>(?<access_mask>[^<]+)"

Stage 4: where

| where match(share_name, "(?i)(.*\$$)|NETLOGON|SYSVOL") and match(access_mask, "(?i)0x2")
    and not match(user, ".*\$$")

Stage 5: table

| table _time, host, user process, process_*, parent_process_name, parent_process_path, share_name

Stage 6: bucket

| bin span=1s

Stage 7: stats

| stats values(*) as * by _time, host

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventCodeeq
  • 5140 corpus 8 (splunk 8)
  • 5145 corpus 19 (splunk 17, elastic 2)
field:"EventID" kind:eq
access_maskregex_match
  • (?i)0x2
field:"access_mask" kind:regex_match value:"(?i)0x2"
share_nameregex_match
    • (?i)(.*$$)
    • NETLOGON
    • SYSVOL
field:"share_name" kind:regex_match

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
userregex_match.*$$excludes:user field:"user" value:".*$$"

Search Terms

These SPL tokens match against raw event text.

StageTerm
1"<EventID>5145<"
1"<EventID>5140<"
1"0x2"
1"$"
1"SYSVOL"
1"NETLOGON"

Unusual Number of Remote Endpoint Authentication Events

#
Status
experimental
Group by
Source_Account, Source_Network_Address, _time
Author
Mauricio Velazco, Splunk
Source
github.com/splunk/security_content

The following analytic identifies an unusual number of remote authentication attempts from a single source by leveraging Windows Event ID 4624, which logs successful account logons. It uses statistical analysis, specifically the 3-sigma rule, to detect deviations from normal behavior. This activity is significant for a SOC as it may indicate lateral movement, malware staging, or reconnaissance. If confirmed malicious, this behavior could allow an attacker to move laterally within the network, escalate privileges, or gather information for further attacks.

Known False Positives

  • An single endpoint authenticating to a large number of hosts is not common behavior. Possible false positive scenarios include but are not limited to vulnerability scanners, jump servers and missconfigured systems.

MITRE ATT&CK Coverage

TacticTechniques
Initial Access
Persistence
Privilege Escalation
Stealth

Telemetry Coverage

Rule Body

name: Unusual Number of Remote Endpoint Authentication Events
id: acb5dc74-5324-11ec-a36d-acde48001122
version: 8
creation_date: '2021-12-03'
modification_date: '2026-05-13'
author: Mauricio Velazco, Splunk
status: experimental
type: Hunting
description: The following analytic identifies an unusual number of remote authentication attempts from a single source by leveraging Windows Event ID 4624, which logs successful account logons. It uses statistical analysis, specifically the 3-sigma rule, to detect deviations from normal behavior. This activity is significant for a SOC as it may indicate lateral movement, malware staging, or reconnaissance. If confirmed malicious, this behavior could allow an attacker to move laterally within the network, escalate privileges, or gather information for further attacks.
data_source:
    - Windows Event Log Security 4624
search: |-
    `wineventlog_security` EventCode=4624 Logon_Type=3 Account_Name!="*$"
      | eval Source_Account = mvindex(Account_Name, 1)
      | bucket span=2m _time
      | stats dc(ComputerName) AS unique_targets values(ComputerName) as target_hosts
        BY _time, Source_Network_Address, Source_Account
      | eventstats avg(unique_targets) as comp_avg , stdev(unique_targets) as comp_std
        BY Source_Network_Address, Source_Account
      | eval upperBound=(comp_avg+comp_std*3)
      | eval isOutlier=if(unique_targets >10 and unique_targets >= upperBound, 1, 0)
      | `unusual_number_of_remote_endpoint_authentication_events_filter`
how_to_implement: To successfully implement this search, you need to be ingesting Windows Event Logs from domain controllers as well as member servers and workstations. The Advanced Security Audit policy setting `Audit Logon` within `Logon/Logoff` needs to be enabled.
known_false_positives: An single endpoint authenticating to a large number of hosts is not common behavior. Possible false positive scenarios include but are not limited to vulnerability scanners, jump servers and missconfigured systems.
references:
    - https://attack.mitre.org/techniques/T1078/
analytic_story:
    - Active Directory Lateral Movement
    - Active Directory Privilege Escalation
asset_type: Endpoint
mitre_attack_id:
    - T1078
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: endpoint
security_domain: endpoint

Stages and Predicates

Stage 1: search

`wineventlog_security` EventCode=4624 Logon_Type=3 Account_Name!="*$"

Stage 2: eval

| eval Source_Account = mvindex(Account_Name, 1)

Stage 3: bucket

| bucket span=2m _time

Stage 4: stats

| stats dc(ComputerName) AS unique_targets values(ComputerName) as target_hosts
    BY _time, Source_Network_Address, Source_Account

Stage 5: eventstats

| eventstats avg(unique_targets) as comp_avg , stdev(unique_targets) as comp_std
    BY Source_Network_Address, Source_Account

Stage 6: eval

| eval upperBound=(comp_avg+comp_std*3)

Stage 7: eval

| eval isOutlier=if(unique_targets >10 and unique_targets >= upperBound, 1, 0)
isOutlier =
ifunique_targets > 10 AND unique_targets >= upperBound1
else0

Stage 8: search

| `unusual_number_of_remote_endpoint_authentication_events_filter`

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
Account_Namene
  • *$ corpus 3 (splunk 3)
field:"user" kind:ne value:"*$"
EventCodeeq
  • 4624 corpus 13 (splunk 13)
field:"EventID" kind:eq value:"4624"
Logon_Typeeq
  • 3 corpus 30 (splunk 13, sigma 12, elastic 5)
field:"LogonType" kind:eq value:"3"

Windows AD Domain Root ACL Deletion

#
Status
production
Severity
medium
Group by
LogonId, ObjectClass, ObjectDN, OpCorrelationID, _time, user
Author
Dean Luxton
Source
github.com/splunk/security_content

ACL deletion performed on the domain root object, significant AD change with high impact. Following MS guidance all changes at this level should be reviewed. Drill into the logonID within EventCode 4624 for information on the source device during triage.

Known False Positives

  • No false positives have been identified at this time.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

name: Windows AD Domain Root ACL Deletion
id: 3cb56e57-5642-4638-907f-8dfde9afb889
version: 10
creation_date: '2024-07-01'
modification_date: '2026-05-13'
author: Dean Luxton
status: production
type: TTP
description: ACL deletion performed on the domain root object, significant AD change with high impact. Following MS guidance all changes at this level should be reviewed. Drill into the logonID within EventCode 4624 for information on the source device during triage.
data_source:
    - Windows Event Log Security 5136
search: '`wineventlog_security` EventCode=5136 ObjectClass=domainDNS  | stats min(_time) as _time values(eval(if(OperationType=="%%14675",AttributeValue,null))) as old_value values(eval(if(OperationType=="%%14674",AttributeValue,null))) as new_value values(OperationType) as OperationType values(dest) as dest by ObjectClass ObjectDN OpCorrelationID src_user SubjectLogonId  | rex field=old_value max_match=10000 "\((?P<old_values>.*?)\)"  | rex field=new_value max_match=10000 "\((?P<new_values>.*?)\)"  | mvexpand old_values  | where NOT old_values IN (new_values)  | rex field=old_values "(?P<aceType>.*?);(?P<aceFlags>.*?);(?P<aceAccessRights>.*?);(?P<aceObjectGuid>.*?);;(?P<aceSid>.*?)$"  | rex max_match=100 field=aceAccessRights "(?P<AccessRights>[A-Z]{2})"  | rex max_match=100 field=aceFlags "(?P<aceFlags>[A-Z]{2})"  | lookup msad_guid_lookup guid as aceObjectGuid OUTPUT displayName as ControlAccessRights  | lookup ace_access_rights_lookup access_rights_string as AccessRights OUTPUT access_rights_value  | lookup ace_type_lookup ace_type_string as aceType OUTPUT ace_type_value  | lookup ace_flag_lookup flag_string as aceFlags OUTPUT flag_value as ace_flag_value ``` Optional SID resolution lookups | lookup identity_lookup_expanded objectSid as aceSid OUTPUT downLevelDomainName as user  | lookup admon_groups_def objectSid as aceSid OUTPUT cn as group ``` | lookup builtin_groups_lookup builtin_group_string  as aceSid OUTPUT builtin_group_name as builtin_group | eval aceType=coalesce(ace_type_value,aceType), aceFlags=coalesce(ace_flag_value,"This object only"), aceAccessRights=if(aceAccessRights="CCDCLCSWRPWPDTLOCRSDRCWDWO","Full control",coalesce(access_rights_value,AccessRights)), aceControlAccessRights=coalesce(ControlAccessRights,aceObjectGuid), user=coalesce(user, group, builtin_group, aceSid) | stats values(aceType) as aceType values(aceFlags) as aceFlags(inheritance) values(aceControlAccessRights) as aceControlAccessRights values(aceAccessRights) as aceAccessRights values(old_values) as old_values by _time ObjectClass ObjectDN src_user SubjectLogonId user OpCorrelationID | eval aceControlAccessRights=if(mvcount(aceControlAccessRights)=1 AND aceControlAccessRights="","All rights",''aceControlAccessRights'') | `windows_ad_domain_root_acl_deletion_filter`'
how_to_implement: Ensure you are ingesting Active Directory audit logs - specifically event 5136. See lantern article in references for further on how to onboard AD audit data. Ensure the wineventlog_security macro is configured with the correct indexes and include lookups for SID resolution if evt_resolve_ad_obj is set to 0.
known_false_positives: No false positives have been identified at this time.
references:
    - https://learn.microsoft.com/en-us/windows/win32/secauthz/ace-strings
    - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/1522b774-6464-41a3-87a5-1e5633c3fbbb
    - https://trustedsec.com/blog/a-hitchhackers-guide-to-dacl-based-detections-part-1-a
    - https://lantern.splunk.com/Security/Product_Tips/Enterprise_Security/Enabling_an_audit_trail_from_Active_Directory
finding:
    title: $src_user$ has removed $user$ $aceAccessRights$ ACL rights to domain root $ObjectDN$
    entity:
        field: src_user
        type: user
        score: 50
intermediate_findings:
    entities:
        - field: user
          type: user
          score: 50
          message: $src_user$ has removed $user$ $aceAccessRights$ ACL rights to domain root $ObjectDN$
analytic_story:
    - Sneaky Active Directory Persistence Tricks
asset_type: Endpoint
mitre_attack_id:
    - T1222.001
    - T1484
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: endpoint
security_domain: endpoint

Stages and Predicates

Stage 1: search

`wineventlog_security` EventCode=5136 ObjectClass=domainDNS

Stage 2: stats

| stats
    min(_time) as _time
    values(eval(if(OperationType=="%%14675",AttributeValue,null))) as old_value
    values(eval(if(OperationType=="%%14674",AttributeValue,null))) as new_value
    values(OperationType) as OperationType
    values(dest) as dest
  by ObjectClass ObjectDN OpCorrelationID src_user SubjectLogonId

Stage 3: rex

| rex field=old_value max_match=10000 "\((?P<old_values>.*?)\)"

Stage 4: rex

| rex field=new_value max_match=10000 "\((?P<new_values>.*?)\)"

Stage 5: mvexpand

| mvexpand old_values

Stage 6: where

| where NOT old_values IN (new_values)

Stage 7: rex

| rex field=old_values
    "(?P<aceType>.*?);(?P<aceFlags>.*?);(?P<aceAccessRights>.*?);(?P<aceObjectGuid>.*?);;(?P<aceSid>.*?)$"

Stage 8: rex

| rex max_match=100 field=aceAccessRights "(?P<AccessRights>[A-Z]{2})"

Stage 9: rex

| rex max_match=100 field=aceFlags "(?P<aceFlags>[A-Z]{2})"

Stage 10: lookup

| lookup msad_guid_lookup guid as aceObjectGuid OUTPUT displayName as ControlAccessRights
Lookup table
msad_guid_lookup
Key field
guid as aceObjectGuid
Output columns
['displayName', 'ControlAccessRights']

Stage 11: lookup

| lookup ace_access_rights_lookup access_rights_string as AccessRights OUTPUT access_rights_value
Lookup table
ace_access_rights_lookup
Key field
access_rights_string as AccessRights
Output columns
['access_rights_value', 'access_rights_value']

Stage 12: lookup

| lookup ace_type_lookup ace_type_string as aceType OUTPUT ace_type_value
Lookup table
ace_type_lookup
Key field
ace_type_string as aceType
Output columns
['ace_type_value', 'ace_type_value']

Stage 13: lookup

| lookup ace_flag_lookup flag_string as aceFlags OUTPUT flag_value as ace_flag_value
Lookup table
ace_flag_lookup
Key field
flag_string as aceFlags
Output columns
['flag_value', 'ace_flag_value']

Stage 14: lookup

| lookup builtin_groups_lookup builtin_group_string  as aceSid OUTPUT
    builtin_group_name as builtin_group
Lookup table
builtin_groups_lookup
Key field
builtin_group_string as aceSid
Output columns
['builtin_group_name', 'builtin_group']

Stage 15: eval

| eval aceType=coalesce(ace_type_value,aceType),
    aceFlags=coalesce(ace_flag_value,"This object only"),
    aceAccessRights=if(
        aceAccessRights="CCDCLCSWRPWPDTLOCRSDRCWDWO",
        "Full control",
        coalesce(access_rights_value,AccessRights)
    ),
    aceControlAccessRights=coalesce(ControlAccessRights,aceObjectGuid),
    user=coalesce(user, group, builtin_group, aceSid)

Stage 16: stats

| stats
    values(aceType) as aceType
    values(aceFlags) as aceFlags(inheritance)
    values(aceControlAccessRights) as aceControlAccessRights
    values(aceAccessRights) as aceAccessRights
    values(old_values) as old_values
  by _time ObjectClass ObjectDN src_user SubjectLogonId user OpCorrelationID

Stage 17: eval

| eval
    aceControlAccessRights=if(
        mvcount(aceControlAccessRights)=1 AND aceControlAccessRights="",
        "All rights",
        'aceControlAccessRights'
    )
aceControlAccessRights =
ifmvcount(aceControlAccessRights) = 1 AND aceControlAccessRights = """All rights"
else'aceControlAccessRights'

Stage 18: search

| `windows_ad_domain_root_acl_deletion_filter`

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventCodeeq
  • 5136 corpus 25 (splunk 24, elastic 1)
field:"EventID" kind:eq value:"5136"
ObjectClasseq
  • domainDNS corpus 4 (splunk 4)
field:"ObjectClass" kind:eq value:"domainDNS"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
old_valueseqnew_valuesexcludes:old_values field:"old_values" value:"new_values"

Windows AD Self DACL Assignment

#
Status
production
Severity
medium
Group by
LogonId, ObjectClass, ObjectDN, OpCorrelationID, _time, dest, user
Author
Dean Luxton
Source
github.com/splunk/security_content

Detect when a user creates a new DACL in AD for their own AD object.

Known False Positives

  • No false positives have been identified at this time.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

name: Windows AD Self DACL Assignment
id: 16132445-da9f-4d03-ad44-56d717dcd67d
version: 12
creation_date: '2024-07-01'
modification_date: '2026-05-13'
author: Dean Luxton
status: production
type: TTP
description: Detect when a user creates a new DACL in AD for their own AD object.
data_source:
    - Windows Event Log Security 5136
search: |
    `wineventlog_security`
    EventCode=5136
    | stats min(_time) as _time
            values(
              eval(
                if(OperationType=="%%14675",AttributeValue,null)
                )
            ) as old_value

            values(
              eval(
                if(OperationType=="%%14674" ,AttributeValue,null)
              )
            ) as new_value

            values(OperationType) as OperationType
    by ObjectClass ObjectDN OpCorrelationID src_user SubjectLogonId dest

    | rex field=old_value max_match=10000 "\((?P<old_values>.*?)\)"
    | rex field=new_value max_match=10000 "\((?P<new_ace>.*?)\)"
    | mvexpand new_ace
    | where NOT new_ace IN (old_values)
    | rex field=new_ace "(?P<aceType>.*?);(?P<aceFlags>.*?);(?P<aceAccessRights>.*?);(?P<aceObjectGuid>.*?);(?P<aceInheritedTypeGuid>.*?);(?P<aceSid>.*?)$"
    | rex max_match=100 field=aceAccessRights "(?P<AccessRights>[A-Z]{2})"
    | rex max_match=100 field=aceFlags "(?P<aceFlags>[A-Z]{2})"

    | lookup ace_type_lookup ace_type_string as aceType OUTPUT ace_type_value as aceType
    | lookup ace_flag_lookup flag_string as aceFlags OUTPUT flag_value as ace_flag_value
    | lookup ace_access_rights_lookup access_rights_string as AccessRights OUTPUT access_rights_value
    | lookup msad_guid_lookup guid as aceObjectGuid OUTPUT displayName as ControlAccessRights

    ``` Optional SID resolution lookups
    | lookup identity_lookup_expanded objectSid as aceSid OUTPUT downLevelDomainName as user
    | lookup admon_groups_def objectSid as aceSid OUTPUT cn as group
    ```

    | lookup builtin_groups_lookup builtin_group_string as aceSid OUTPUT builtin_group_name as builtin_group

    | eval aceType = coalesce(ace_type_value, aceType),
           aceInheritance = coalesce(ace_flag_value, "This object only"),
           aceAccessRights = if(
                                aceAccessRights = "CCDCLCSWRPWPDTLOCRSDRCWDWO", "Full control", coalesce(access_rights_value,AccessRights)
                              ),
           aceControlAccessRights = if(
                                  (
                                    ControlAccessRights = "Write member"
                                    OR
                                    aceObjectGuid = "bf9679c0-0de6-11d0-a285-00aa003049e2"
                                  ) AND
                                  (
                                    aceAccessRights = "All validated writes"
                                    OR
                                    AccessRights = "SW"
                                  ),
                                  "Add/remove self as member",
                                  coalesce(ControlAccessRights,aceObjectGuid)
                                ),
           user=coalesce(user, group, builtin_group, aceSid)

    | stats values(aceType) as aceType
            values(aceInheritance) as aceInheritance
            values(aceControlAccessRights) as aceControlAccessRights
            values(aceAccessRights) as aceAccessRights
            values(new_ace) as new_ace
            values(aceInheritedTypeGuid) as aceInheritedTypeGuid

    by _time ObjectClass ObjectDN src_user SubjectLogonId user OpCorrelationID dest

    | eval aceControlAccessRights = if(
                                      mvcount(aceControlAccessRights) = 1
                                      AND
                                      aceControlAccessRights = "", "All rights", "aceControlAccessRights"
                                    )
    | rex field=user "\\\\(?P<nt_user>.*?)$"
    | where lower(src_user)=lower(nt_user)
    | `windows_ad_self_dacl_assignment_filter`
how_to_implement: Ensure you are ingesting Active Directory audit logs - specifically event 5136. See lantern article in references for further on how to onboard AD audit data. Ensure the wineventlog_security macro is configured with the correct indexes and include lookups for SID resolution if evt_resolve_ad_obj is set to 0.
known_false_positives: No false positives have been identified at this time.
references:
    - https://lantern.splunk.com/Security/Product_Tips/Enterprise_Security/Enabling_an_audit_trail_from_Active_Directory
finding:
    title: $user$ has created a DACL on $ObjectDN$ to grant themselves $aceControlAccessRights$ across $aceAccessRights$
    entity:
        field: user
        type: user
        score: 50
analytic_story:
    - Sneaky Active Directory Persistence Tricks
asset_type: Endpoint
mitre_attack_id:
    - T1484
    - T1098
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: endpoint
security_domain: endpoint

Stages and Predicates

Stage 1: search

`wineventlog_security`
EventCode=5136

Stage 2: stats

| stats min(_time) as _time
        values(
          eval(
            if(OperationType=="%%14675",AttributeValue,null)
            )
        ) as old_value

        values(
          eval(
            if(OperationType=="%%14674" ,AttributeValue,null)
          )
        ) as new_value

        values(OperationType) as OperationType
by ObjectClass ObjectDN OpCorrelationID src_user SubjectLogonId dest

Stage 3: rex

| rex field=old_value max_match=10000 "\((?P<old_values>.*?)\)"

Stage 4: rex

| rex field=new_value max_match=10000 "\((?P<new_ace>.*?)\)"

Stage 5: mvexpand

| mvexpand new_ace

Stage 6: where

| where NOT new_ace IN (old_values)

Stage 7: rex

| rex field=new_ace
    "(?P<aceType>.*?);(?P<aceFlags>.*?);(?P<aceAccessRights>.*?);(?P<aceObjectGuid>.*?);(?P<aceInheritedTypeGuid>.*?);(?P<aceSid>.*?)$"

Stage 8: rex

| rex max_match=100 field=aceAccessRights "(?P<AccessRights>[A-Z]{2})"

Stage 9: rex

| rex max_match=100 field=aceFlags "(?P<aceFlags>[A-Z]{2})"

Stage 10: lookup

| lookup ace_type_lookup ace_type_string as aceType OUTPUT ace_type_value as aceType
Lookup table
ace_type_lookup
Key field
ace_type_string as aceType
Output columns
['ace_type_value', 'aceType']

Stage 11: lookup

| lookup ace_flag_lookup flag_string as aceFlags OUTPUT flag_value as ace_flag_value
Lookup table
ace_flag_lookup
Key field
flag_string as aceFlags
Output columns
['flag_value', 'ace_flag_value']

Stage 12: lookup

| lookup ace_access_rights_lookup access_rights_string as AccessRights OUTPUT access_rights_value
Lookup table
ace_access_rights_lookup
Key field
access_rights_string as AccessRights
Output columns
['access_rights_value', 'access_rights_value']

Stage 13: lookup

| lookup msad_guid_lookup guid as aceObjectGuid OUTPUT displayName as ControlAccessRights
Lookup table
msad_guid_lookup
Key field
guid as aceObjectGuid
Output columns
['displayName', 'ControlAccessRights']

Stage 14: lookup

| lookup builtin_groups_lookup builtin_group_string as aceSid OUTPUT
    builtin_group_name as builtin_group
Lookup table
builtin_groups_lookup
Key field
builtin_group_string as aceSid
Output columns
['builtin_group_name', 'builtin_group']

Stage 15: eval

| eval aceType = coalesce(ace_type_value, aceType),
       aceInheritance = coalesce(ace_flag_value, "This object only"),
       aceAccessRights = if(
           aceAccessRights = "CCDCLCSWRPWPDTLOCRSDRCWDWO",
           "Full control",
           coalesce(access_rights_value,AccessRights)
       ),
       aceControlAccessRights = if(
           (
                                ControlAccessRights = "Write member"
                                OR
                                aceObjectGuid = "bf9679c0-0de6-11d0-a285-00aa003049e2"
                              ) AND
                              (
                                aceAccessRights = "All validated writes"
                                OR
                                AccessRights = "SW"
                              ),
           "Add/remove self as member",
           coalesce(ControlAccessRights,aceObjectGuid)
       ),
       user=coalesce(user, group, builtin_group, aceSid)

Stage 16: stats

| stats values(aceType) as aceType
        values(aceInheritance) as aceInheritance
        values(aceControlAccessRights) as aceControlAccessRights
        values(aceAccessRights) as aceAccessRights
        values(new_ace) as new_ace
        values(aceInheritedTypeGuid) as aceInheritedTypeGuid

by _time ObjectClass ObjectDN src_user SubjectLogonId user OpCorrelationID dest

Stage 17: eval

| eval aceControlAccessRights = if(
    mvcount(aceControlAccessRights) = 1
                                  AND
                                  aceControlAccessRights = "",
    "All rights",
    "aceControlAccessRights"
)
aceControlAccessRights =
ifmvcount(aceControlAccessRights) = 1 AND aceControlAccessRights = """All rights"
else"aceControlAccessRights"

Stage 18: rex

| rex field=user "\\\\(?P<nt_user>.*?)$"

Stage 19: where

| where lower(src_user)=lower(nt_user)

Stage 20: search

| `windows_ad_self_dacl_assignment_filter`

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventCodeeq
  • 5136 corpus 25 (splunk 24, elastic 1)
field:"EventID" kind:eq value:"5136"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
new_aceeqold_valuesexcludes:new_ace field:"new_ace" value:"old_values"

Windows Modify Registry Configure BitLocker

#
Status
production
Severity
medium
Group by
TargetObject, computer_name, details, event_type, process_guid, process_id, registry_hive, registry_path, registry_status, registry_value_name, registry_value_type, user, vendor_product
Author
Teoderick Contreras, Splunk
Source
github.com/splunk/security_content

This analytic is developed to detect suspicious registry modifications targeting BitLocker settings. The malware ShrinkLocker alters various registry keys to change how BitLocker handles encryption, potentially bypassing TPM requirements, enabling BitLocker without TPM, and enforcing specific startup key and PIN configurations. Such modifications can weaken system security, making it easier for unauthorized access and data breaches. Detecting these changes is crucial for maintaining robust encryption and data protection.

Known False Positives

  • administrators may enable or disable this feature that may cause some false positive.

MITRE ATT&CK Coverage

TacticTechniques
Persistence
Defense Impairment

Telemetry Coverage

Rule Body

name: Windows Modify Registry Configure BitLocker
id: bd1c770f-1b55-411e-b49e-20d07bcac5f8
version: 9
creation_date: '2024-07-25'
modification_date: '2026-05-13'
author: Teoderick Contreras, Splunk
status: production
type: TTP
description: This analytic is developed to detect suspicious registry modifications targeting BitLocker settings. The malware ShrinkLocker alters various registry keys to change how BitLocker handles encryption, potentially bypassing TPM requirements, enabling BitLocker without TPM, and enforcing specific startup key and PIN configurations. Such modifications can weaken system security, making it easier for unauthorized access and data breaches. Detecting these changes is crucial for maintaining robust encryption and data protection.
data_source:
    - Sysmon EventID 13
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime FROM datamodel=Endpoint.Registry where (Registry.registry_path= "*\\Policies\\Microsoft\\FVE\\*" Registry.registry_value_name IN("EnableBDEWithNoTPM", "EnableNonTPM", "UseAdvancedStartup") Registry.registry_value_data = 0x00000001) OR (Registry.registry_path= "*\\Policies\\Microsoft\\FVE\\*" Registry.registry_value_name IN("UsePIN", "UsePartialEncryptionKey", "UseTPM", "UseTPMKey", "UseTPMKeyPIN", "UseTPMPIN") Registry.registry_value_data = 0x00000002) by Registry.action Registry.dest Registry.process_guid Registry.process_id Registry.registry_hive Registry.registry_path Registry.registry_key_name Registry.registry_value_data Registry.registry_value_name Registry.registry_value_type Registry.status Registry.user Registry.vendor_product | `drop_dm_object_name(Registry)` | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `windows_modify_registry_configure_bitlocker_filter`'
how_to_implement: To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint` datamodel in the `Processes` node. In addition, confirm the latest CIM App 4.20 or higher is installed and the latest TA for the endpoint product.
known_false_positives: administrators may enable or disable this feature that may cause some false positive.
references:
    - https://www.bleepingcomputer.com/news/security/new-shrinklocker-ransomware-uses-bitlocker-to-encrypt-your-files/
finding:
    title: A registry modification in Windows bitlocker registry settings on $dest$
    entity:
        field: dest
        type: system
        score: 50
analytic_story:
    - ShrinkLocker
asset_type: Endpoint
mitre_attack_id:
    - T1112
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: endpoint
security_domain: endpoint

Stages and Predicates

Stage 1: tstats

| tstats `security_content_summariesonly`
    count
    min(_time) as firstTime
    max(_time) as lastTime
  FROM datamodel=Endpoint.Registry
  where (
      Registry.registry_path= "*\\Policies\\Microsoft\\FVE\\*"
      Registry.registry_value_name IN("EnableBDEWithNoTPM", "EnableNonTPM", "UseAdvancedStartup")
      Registry.registry_value_data = 0x00000001
  ) OR (
      Registry.registry_path= "*\\Policies\\Microsoft\\FVE\\*"
      Registry.registry_value_name IN(
          "UsePIN",
          "UsePartialEncryptionKey",
          "UseTPM",
          "UseTPMKey",
          "UseTPMKeyPIN",
          "UseTPMPIN"
      )
      Registry.registry_value_data = 0x00000002
  )
  by
    Registry.action
    Registry.dest
    Registry.process_guid
    Registry.process_id
    Registry.registry_hive
    Registry.registry_path
    Registry.registry_key_name
    Registry.registry_value_data
    Registry.registry_value_name
    Registry.registry_value_type
    Registry.status
    Registry.user
    Registry.vendor_product

Stage 2: search

| `drop_dm_object_name(Registry)`

Stage 3: search

| `security_content_ctime(firstTime)`

Stage 4: search

| `security_content_ctime(lastTime)`

Stage 5: search

| `windows_modify_registry_configure_bitlocker_filter`

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
Registry.registry_patheq
  • *\Policies\Microsoft\FVE\*
field:"registry_path" kind:eq value:"*\Policies\Microsoft\FVE\*"
Registry.registry_value_dataeq
  • 0x00000001 corpus 61 (splunk 52, elastic 9)
  • 0x00000002 corpus 4 (elastic 2, splunk 2)
field:"Details" kind:eq
Registry.registry_value_namein
  • EnableBDEWithNoTPM
  • EnableNonTPM
  • UseAdvancedStartup
  • UsePIN
  • UsePartialEncryptionKey
  • UseTPM
  • UseTPMKey
  • UseTPMKeyPIN
  • UseTPMPIN
field:"registry_value_name" kind:in

Windows Modify Registry Delete Firewall Rules

#
Status
production
Severity
medium
Group by
TargetObject, action, dest, process_guid, process_id, registry_hive, registry_path, status, user, vendor_product
Author
Teoderick Contreras, Splunk
Source
github.com/splunk/security_content

The following analytic detects a potential deletion of firewall rules, indicating a possible security breach or unauthorized access attempt. It identifies actions where firewall rules are removed using commands like netsh advfirewall firewall delete rule, which can expose the network to external threats by disabling critical security measures. Monitoring these activities helps maintain network integrity and prevent malicious attacks.

Known False Positives

  • network admin may add/remove/modify public inbound firewall rule that may cause this rule to be triggered.

MITRE ATT&CK Coverage

TacticTechniques
Persistence
Defense Impairment

Telemetry Coverage

Rule Body

name: Windows Modify Registry Delete Firewall Rules
id: 41c61539-98ca-4750-b3ec-7c29a2f06343
version: 11
creation_date: '2024-07-25'
modification_date: '2026-05-13'
author: Teoderick Contreras, Splunk
status: production
type: TTP
description: The following analytic detects a potential deletion of firewall rules, indicating a possible security breach or unauthorized access attempt. It identifies actions where firewall rules are removed using commands like netsh advfirewall firewall delete rule, which can expose the network to external threats by disabling critical security measures. Monitoring these activities helps maintain network integrity and prevent malicious attacks.
data_source:
    - Sysmon EventID 12
search: '`sysmon` EventCode=12 TargetObject = "*\\System\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\FirewallRules\\*" EventType=DeleteValue |  stats count min(_time) as firstTime max(_time) as lastTime by action dest process_guid process_id registry_hive registry_path registry_key_name status user vendor_product | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `windows_modify_registry_delete_firewall_rules_filter`'
how_to_implement: To successfully implement this search, you need to be ingesting logs with the registry value name, registry path, and registry value data from your endpoints. If you are using Sysmon, you must have at least version 2.0 of the official Sysmon TA. https://splunkbase.splunk.com/app/5709
known_false_positives: network admin may add/remove/modify public inbound firewall rule that may cause this rule to be triggered.
references:
    - https://www.bleepingcomputer.com/news/security/new-shrinklocker-ransomware-uses-bitlocker-to-encrypt-your-files/
finding:
    title: firewall deletion found in registry on $dest$
    entity:
        field: user
        type: user
        score: 50
intermediate_findings:
    entities:
        - field: dest
          type: system
          score: 50
          message: firewall deletion found in registry on $dest$
analytic_story:
    - ShrinkLocker
    - CISA AA24-241A
    - NetSupport RMM Tool Abuse
asset_type: Endpoint
mitre_attack_id:
    - T1112
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: endpoint
security_domain: endpoint

Stages and Predicates

Stage 1: search

`sysmon` EventCode=12
    TargetObject = "*\\System\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\FirewallRules\\*"
    EventType=DeleteValue

Stage 2: stats

| stats
    count
    min(_time) as firstTime
    max(_time) as lastTime
  by
    action
    dest
    process_guid
    process_id
    registry_hive
    registry_path
    registry_key_name
    status
    user
    vendor_product

Stage 3: search

| `security_content_ctime(firstTime)`

Stage 4: search

| `security_content_ctime(lastTime)`

Stage 5: search

| `windows_modify_registry_delete_firewall_rules_filter`

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventCodeeq
  • 12 corpus 9 (splunk 9)
field:"EventID" kind:eq value:"12"
EventTypeeq
  • DeleteValue corpus 5 (sigma 4, splunk 1)
field:"EventType" kind:eq value:"DeleteValue"
TargetObjecteq
  • *\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules\*
field:"TargetObject" kind:eq value:"*\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules\*"

Windows MSIX Package Interaction

#
Status
production
Group by
host, signature_id
Author
Michael Haag, Splunk
Source
github.com/splunk/security_content

This hunting query detects user interactions with MSIX packages by monitoring EventCode 171 in the Microsoft-Windows-AppXPackaging/Operational logs. These events are generated when a user clicks on or attempts to interact with an MSIX package, even if the package is not fully installed. This information can be valuable for security teams to identify what MSIX packages users are attempting to open in their environment, which may help detect malicious MSIX packages before they're fully installed. Monitoring these interactions can provide early warning of potential MSIX package abuse, which has been leveraged by threat actors such as FIN7, Zloader (Storm-0569), and FakeBat (Storm-1113).

Known False Positives

  • This hunting query will detect legitimate MSIX package interactions from normal users. It is not designed to specifically identify malicious activity but rather to provide visibility into all MSIX package interactions. Security teams should review the results and look for unusual patterns, unexpected packages, or suspicious file paths.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

name: Windows MSIX Package Interaction
id: 1a06689d-814e-4db2-b2c7-5a174f8c2d6d
version: 3
creation_date: '2025-08-18'
modification_date: '2026-05-13'
author: Michael Haag, Splunk
status: production
type: Hunting
description: This hunting query detects user interactions with MSIX packages by monitoring EventCode 171 in the Microsoft-Windows-AppXPackaging/Operational logs. These events are generated when a user clicks on or attempts to interact with an MSIX package, even if the package is not fully installed. This information can be valuable for security teams to identify what MSIX packages users are attempting to open in their environment, which may help detect malicious MSIX packages before they're fully installed. Monitoring these interactions can provide early warning of potential MSIX package abuse, which has been leveraged by threat actors such as FIN7, Zloader (Storm-0569), and FakeBat (Storm-1113).
data_source:
    - Windows Event Log AppXPackaging 171
search: |-
    `wineventlog_appxpackaging` EventCode=171
      | stats count min(_time) as firstTime max(_time) as lastTime values(packageFullName) as packageFullName values(user_id) as user_id
        BY host EventCode
      | `security_content_ctime(firstTime)`
      | `security_content_ctime(lastTime)`
      | `windows_msix_package_interaction_filter`
how_to_implement: To implement this detection, you need to be collecting Windows Event logs from the Microsoft-Windows-AppXPackaging/Operational channel. In Splunk, this typically requires the Windows TA and configuration to collect from this specific channel. Ensure your Windows event collection is properly configured to capture EventCode 171 from the Microsoft-Windows-AppXPackaging/Operational log. This query is designed as a hunting query to help identify MSIX package interactions across your environment.
known_false_positives: This hunting query will detect legitimate MSIX package interactions from normal users. It is not designed to specifically identify malicious activity but rather to provide visibility into all MSIX package interactions. Security teams should review the results and look for unusual patterns, unexpected packages, or suspicious file paths.
references:
    - https://www.appdeploynews.com/packaging-types/msix/troubleshooting-an-msix-package/
    - https://learn.microsoft.com/en-us/windows/win32/appxpkg/troubleshooting
    - https://www.advancedinstaller.com/msix-installation-or-launching-errors-and-fixes.html
    - https://redcanary.com/blog/msix-installers/
analytic_story:
    - MSIX Package Abuse
asset_type: Endpoint
mitre_attack_id:
    - T1204.002
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: endpoint
security_domain: endpoint

Stages and Predicates

Stage 1: search

`wineventlog_appxpackaging` EventCode=171

Stage 2: stats

| stats
    count
    min(_time) as firstTime
    max(_time) as lastTime
    values(packageFullName) as packageFullName
    values(user_id) as user_id
  BY host EventCode

Stage 3: search

| `security_content_ctime(firstTime)`

Stage 4: search

| `security_content_ctime(lastTime)`

Stage 5: search

| `windows_msix_package_interaction_filter`

Indicators

These rows show field, operator, and value matches.

Windows Steal or Forge Kerberos Tickets Klist

#
Status
production
Group by
IntegrityLevel, command_line, computer_name, event_action, original_file_name, parent_command_line, parent_process_basename, parent_process_guid, parent_process_id, parent_process_name, process_basename, process_guid, process_hash, process_id, process_name, user, user_id, vendor_product
Author
Teoderick Contreras, Splunk
Source
github.com/splunk/security_content

The following analytic identifies the execution of the Windows OS tool klist.exe, often used by post-exploitation tools like winpeas. This detection leverages data from Endpoint Detection and Response (EDR) agents, focusing on process and parent process details. Monitoring klist.exe is significant as it can indicate attempts to list or gather cached Kerberos tickets, which are crucial for lateral movement or privilege escalation. If confirmed malicious, this activity could enable attackers to move laterally within the network or escalate privileges, posing a severe security risk.

Known False Positives

  • No false positives have been identified at this time.

MITRE ATT&CK Coverage

TacticTechniques
Credential Access

Telemetry Coverage

Rule Body

name: Windows Steal or Forge Kerberos Tickets Klist
id: 09d88404-1e29-46cb-806c-1eedbc85ad5d
version: 9
creation_date: '2022-12-06'
modification_date: '2026-05-13'
author: Teoderick Contreras, Splunk
status: production
type: Hunting
description: The following analytic identifies the execution of the Windows OS tool klist.exe, often used by post-exploitation tools like winpeas. This detection leverages data from Endpoint Detection and Response (EDR) agents, focusing on process and parent process details. Monitoring klist.exe is significant as it can indicate attempts to list or gather cached Kerberos tickets, which are crucial for lateral movement or privilege escalation. If confirmed malicious, this activity could enable attackers to move laterally within the network or escalate privileges, posing a severe security risk.
data_source:
    - Sysmon EventID 1
    - Windows Event Log Security 4688
    - CrowdStrike ProcessRollup2
search: |-
    | tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime FROM datamodel=Endpoint.Processes
      WHERE Processes.process_name="klist.exe"
        OR
        Processes.original_file_name = "klist.exe" Processes.parent_process_name IN ("cmd.exe", "powershell*")
      BY Processes.action Processes.dest Processes.original_file_name
         Processes.parent_process Processes.parent_process_exec Processes.parent_process_guid
         Processes.parent_process_id Processes.parent_process_name Processes.parent_process_path
         Processes.process Processes.process_exec Processes.process_guid
         Processes.process_hash Processes.process_id Processes.process_integrity_level
         Processes.process_name Processes.process_path Processes.user
         Processes.user_id Processes.vendor_product
    | `drop_dm_object_name(Processes)`
    | `security_content_ctime(firstTime)`
    | `security_content_ctime(lastTime)`
    | `windows_steal_or_forge_kerberos_tickets_klist_filter`
how_to_implement: The detection is based on data that originates from Endpoint Detection and Response (EDR) agents. These agents are designed to provide security-related telemetry from the endpoints where the agent is installed. To implement this search, you must ingest logs that contain the process GUID, process name, and parent process. Additionally, you must ingest complete command-line executions. These logs must be processed using the appropriate Splunk Technology Add-ons that are specific to the EDR product. The logs must also be mapped to the `Processes` node of the `Endpoint` data model. Use the Splunk Common Information Model (CIM) to normalize the field names and speed up the data modeling process.
known_false_positives: No false positives have been identified at this time.
references:
    - https://github.com/carlospolop/PEASS-ng/tree/master/winPEAS
    - https://www.microsoft.com/en-us/security/blog/2022/10/14/new-prestige-ransomware-impacts-organizations-in-ukraine-and-poland/
analytic_story:
    - Windows Post-Exploitation
    - Prestige Ransomware
asset_type: Endpoint
mitre_attack_id:
    - T1558
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: endpoint
security_domain: endpoint

Stages and Predicates

Stage 1: tstats

| tstats `security_content_summariesonly`
    count
    min(_time) as firstTime
    max(_time) as lastTime
  FROM datamodel=Endpoint.Processes
  WHERE Processes.process_name="klist.exe"
    OR
    Processes.original_file_name = "klist.exe" Processes.parent_process_name IN (
        "cmd.exe",
        "powershell*"
    )
  BY
    Processes.action
    Processes.dest
    Processes.original_file_name
    Processes.parent_process
    Processes.parent_process_exec
    Processes.parent_process_guid
    Processes.parent_process_id
    Processes.parent_process_name
    Processes.parent_process_path
    Processes.process
    Processes.process_exec
    Processes.process_guid
    Processes.process_hash
    Processes.process_id
    Processes.process_integrity_level
    Processes.process_name
    Processes.process_path
    Processes.user
    Processes.user_id
    Processes.vendor_product

Stage 2: search

| `drop_dm_object_name(Processes)`

Stage 3: search

| `security_content_ctime(firstTime)`

Stage 4: search

| `security_content_ctime(lastTime)`

Stage 5: search

| `windows_steal_or_forge_kerberos_tickets_klist_filter`

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
Processes.original_file_nameeq
  • klist.exe
field:"OriginalFileName" kind:eq value:"klist.exe"
Processes.parent_process_namein
  • cmd.exe corpus 9 (splunk 7, elastic 1, kusto 1)
  • powershell* corpus 2 (splunk 2)
field:"parent_process_basename" kind:in
Processes.process_nameeq
  • klist.exe corpus 2 (elastic 1, splunk 1)
field:"process_basename" kind:eq value:"klist.exe"

Windows Unusual Count Of Users Remotely Failed To Auth From Host

#
Status
production
Severity
low
Group by
_time, action, app, authentication_method, computer_name, signature, signature_id, src_ip
Author
Mauricio Velazco, Splunk
Source
github.com/splunk/security_content

The following analytic identifies a source host failing to authenticate against a remote host with multiple users, potentially indicating a Password Spraying attack. It leverages Windows Event 4625 (failed logon attempts) and Logon Type 3 (remote authentication) to detect this behavior. This activity is significant as it may represent an adversary attempting to gain initial access or elevate privileges within an Active Directory environment. If confirmed malicious, this could lead to unauthorized access, privilege escalation, and further compromise of the network.

Known False Positives

  • A host failing to authenticate with multiple valid users against a remote host is not a common behavior for legitimate systems. Possible false positive scenarios include but are not limited to vulnerability scanners, remote administration tools, missconfigyred systems, etc.

MITRE ATT&CK Coverage

TacticTechniques
Credential Access

Telemetry Coverage

Rule Body

name: Windows Unusual Count Of Users Remotely Failed To Auth From Host
id: cf06a0ee-ffa9-4ed3-be77-0670ed9bab52
version: 12
creation_date: '2021-04-14'
modification_date: '2026-05-13'
author: Mauricio Velazco, Splunk
status: production
type: Anomaly
description: The following analytic identifies a source host failing to authenticate against a remote host with multiple users, potentially indicating a Password Spraying attack. It leverages Windows Event 4625 (failed logon attempts) and Logon Type 3 (remote authentication) to detect this behavior. This activity is significant as it may represent an adversary attempting to gain initial access or elevate privileges within an Active Directory environment. If confirmed malicious, this could lead to unauthorized access, privilege escalation, and further compromise of the network.
data_source:
    - Windows Event Log Security 4625
search: |-
    `wineventlog_security`  EventCode=4625 Logon_Type=3 IpAddress!="-"
      | bucket span=2m _time
      | stats dc(TargetUserName) AS unique_accounts values(TargetUserName) as tried_accounts values(dest) as dest values(src) as src values(user) as user
        BY _time, IpAddress, Computer,
           action, app, authentication_method,
           signature, signature_id
      | eventstats avg(unique_accounts) as comp_avg , stdev(unique_accounts) as comp_std
        BY IpAddress, Computer
      | eval upperBound=(comp_avg+comp_std*3)
      | eval isOutlier=if(unique_accounts > 10 and unique_accounts >= upperBound, 1, 0)
      | search isOutlier=1
      | `windows_unusual_count_of_users_remotely_failed_to_auth_from_host_filter`
how_to_implement: To successfully implement this search, you need to be ingesting Windows Event Logs from domain controllers as as well as member servers and workstations. The Advanced Security Audit policy setting `Audit Logon` within `Logon/Logoff` needs to be enabled.
known_false_positives: A host failing to authenticate with multiple valid users against a remote host is not a common behavior for legitimate systems. Possible false positive scenarios include but are not limited to vulnerability scanners, remote administration tools, missconfigyred systems, etc.
references:
    - https://attack.mitre.org/techniques/T1110/003/
    - https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4625
    - https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventID=4625
    - https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/basic-audit-logon-events
intermediate_findings:
    entities:
        - field: Computer
          type: system
          score: 20
          message: Potential password spraying attack on $Computer$
analytic_story:
    - Active Directory Password Spraying
    - Volt Typhoon
asset_type: Endpoint
mitre_attack_id:
    - T1110.003
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: endpoint
security_domain: endpoint

Stages and Predicates

Stage 1: search

`wineventlog_security`  EventCode=4625 Logon_Type=3 IpAddress!="-"

Stage 2: bucket

| bucket span=2m _time

Stage 3: stats

| stats
    dc(TargetUserName) AS unique_accounts
    values(TargetUserName) as tried_accounts
    values(dest) as dest
    values(src) as src
    values(user) as user
  BY _time, IpAddress, Computer,
       action, app, authentication_method,
       signature, signature_id

Stage 4: eventstats

| eventstats avg(unique_accounts) as comp_avg , stdev(unique_accounts) as comp_std
    BY IpAddress, Computer

Stage 5: eval

| eval upperBound=(comp_avg+comp_std*3)

Stage 6: eval

| eval isOutlier=if(unique_accounts > 10 and unique_accounts >= upperBound, 1, 0)
isOutlier =
ifunique_accounts > 10 AND unique_accounts >= upperBound1
else0

Stage 7: search

| search isOutlier=1

Stage 8: search

| `windows_unusual_count_of_users_remotely_failed_to_auth_from_host_filter`

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventCodeeq
  • 4625 corpus 11 (splunk 11)
field:"EventID" kind:eq value:"4625"
IpAddressne
  • - corpus 2 (splunk 2)
field:"src_ip" kind:ne value:"-"
Logon_Typeeq
  • 3 corpus 30 (splunk 13, sigma 12, elastic 5)
field:"LogonType" kind:eq value:"3"
isOutliereq
  • 1 corpus 33 (splunk 33)
field:"isOutlier" kind:eq value:"1"

Zoom Rare Audio Devices

#
Status
experimental
Author
Marissa Bower, Raven Tait
Source
github.com/splunk/security_content

Detects rare audio devices from Zoom logs. Actors performing Remote Employment Fraud (REF) typically use unusual device information compared to a majority of employees. Detecting this activity requires careful analysis, regular review, and a thorough understanding of the audio and video devices commonly used within your environment.

Known False Positives

  • This is a hunting query meant to identify rare audio devices.

MITRE ATT&CK Coverage

TacticTechniques
Collection

Rule Body

name: Zoom Rare Audio Devices
id: 9fdbf709-4c46-4819-9fb6-98b2d72059ed
version: 3
creation_date: '2025-06-12'
modification_date: '2026-05-13'
author: Marissa Bower, Raven Tait
status: experimental
type: Hunting
description: Detects rare audio devices from Zoom logs. Actors performing Remote Employment Fraud (REF) typically use unusual device information compared to a majority of employees. Detecting this activity requires careful analysis, regular review, and a thorough understanding of the audio and video devices commonly used within your environment.
data_source: []
search: |-
    `zoom_index` speaker=* NOT (camera=*iPhone* OR camera="*FaceTime*" OR speaker="*AirPods*" OR camera="*MacBook*" OR microphone="*MacBook Pro Microphone*")
      | rare speaker limit=50
      | `zoom_rare_audio_devices_filter`
how_to_implement: The analytic leverages Zoom logs to be ingested using Splunk Connect for Zoom (https://splunkbase.splunk.com/app/4961)
known_false_positives: This is a hunting query meant to identify rare audio devices.
analytic_story:
    - Remote Employment Fraud
asset_type: Identity
mitre_attack_id:
    - T1123
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: application
security_domain: identity

Stages and Predicates

Stage 1: search

`zoom_index` speaker=* NOT (
    camera=*iPhone*
    OR camera="*FaceTime*"
    OR speaker="*AirPods*"
    OR camera="*MacBook*"
    OR microphone="*MacBook Pro Microphone*"
)

Stage 2: rare

| rare speaker limit=50

Stage 3: search

| `zoom_rare_audio_devices_filter`

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

Back to all Splunk rules