Detection rules › Elastic
Elastic rules: 0p
Attempted Private Key Access
#Attackers may try to access private keys, e.g. ssh, in order to gain further authenticated access to the environment.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access | |
| Collection |
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 1: Process creation |
| Security-Auditing | Event ID 4688: A new process has been created. |
Rule Body
[metadata]
creation_date = "2023/08/21"
integration = ["endpoint", "windows", "system"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
building_block_type = "default"
description = "Attackers may try to access private keys, e.g. ssh, in order to gain further authenticated access to the environment.\n"
from = "now-119m"
index = [
"endgame-*",
"logs-endpoint.events.process-*",
"logs-system.security*",
"logs-windows.sysmon_operational-*",
"winlogbeat-*",
]
interval = "60m"
language = "eql"
license = "Elastic License v2"
name = "Attempted Private Key Access"
risk_score = 21
rule_id = "c55badd3-3e61-4292-836f-56209dc8a601"
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Credential Access",
"Data Source: Elastic Defend",
"Rule Type: BBR",
"Data Source: Sysmon",
"Data Source: Elastic Endgame",
"Data Source: Windows Security Event Logs",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "windows" and event.type == "start" and
process.command_line : ("*.pem *", "*.pem", "*.id_rsa*") and
not process.args : (
"--rootcert",
"--cert",
"--crlfile"
) and
not process.command_line : (
"*--cacert*",
"*--ssl-cert*",
"*--tls-cert*",
"*--tls_server_certs*"
) and
not process.executable : (
"?:\\ProgramData\\Logishrd\\LogiOptions\\Software\\*\\LogiLuUpdater.exe",
"?:\\Program Files\\Elastic\\Agent\\data\\*\\osqueryd.exe",
"?:\\Program Files\\Git\\cmd\\git.exe",
"?:\\Program Files\\Git\\mingw64\\bin\\git.exe",
"?:\\Program Files\\Guardicore\\gc-controller.exe",
"?:\\Program Files\\Guardicore\\gc-deception-agent.exe",
"?:\\Program Files\\Guardicore\\gc-detection-agent.exe",
"?:\\Program Files\\Guardicore\\gc-enforcement-agent.exe",
"?:\\Program Files\\Guardicore\\gc-guest-agent.exe",
"?:\\Program Files\\Logi\\LogiBolt\\LogiBoltUpdater.exe",
"?:\\Program Files (x86)\\Schneider Electric EcoStruxure\\Building Operation 5.0\\Device Administrator\\Python\\python.exe",
"?:\\Program Files\\Splunk\\bin\\openssl.exe",
"?:\\Program Files\\SplunkUniversalForwarder\\bin\\openssl.exe",
"?:\\Users\\*\\AppData\\Local\\Logi\\LogiBolt\\LogiBoltUpdater.exe",
"?:\\Windows\\system32\\icacls.exe",
"?:\\Windows\\System32\\OpenSSH\\*"
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1552"
name = "Unsecured Credentials"
reference = "https://attack.mitre.org/techniques/T1552/"
[[rule.threat.technique.subtechnique]]
id = "T1552.004"
name = "Private Keys"
reference = "https://attack.mitre.org/techniques/T1552/004/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1005"
name = "Data from Local System"
reference = "https://attack.mitre.org/techniques/T1005/"
[rule.threat.tactic]
id = "TA0009"
name = "Collection"
reference = "https://attack.mitre.org/tactics/TA0009/"
Stages and Predicates
Stage 1: process
process where host.os.type == "windows" and event.type == "start" and
process.command_line : ("*.pem *", "*.pem", "*.id_rsa*") and
not process.args : (
"--rootcert",
"--cert",
"--crlfile"
) and
not process.command_line : (
"*--cacert*",
"*--ssl-cert*",
"*--tls-cert*",
"*--tls_server_certs*"
) and
not process.executable : (
"?:\\ProgramData\\Logishrd\\LogiOptions\\Software\\*\\LogiLuUpdater.exe",
"?:\\Program Files\\Elastic\\Agent\\data\\*\\osqueryd.exe",
"?:\\Program Files\\Git\\cmd\\git.exe",
"?:\\Program Files\\Git\\mingw64\\bin\\git.exe",
"?:\\Program Files\\Guardicore\\gc-controller.exe",
"?:\\Program Files\\Guardicore\\gc-deception-agent.exe",
"?:\\Program Files\\Guardicore\\gc-detection-agent.exe",
"?:\\Program Files\\Guardicore\\gc-enforcement-agent.exe",
"?:\\Program Files\\Guardicore\\gc-guest-agent.exe",
"?:\\Program Files\\Logi\\LogiBolt\\LogiBoltUpdater.exe",
"?:\\Program Files (x86)\\Schneider Electric EcoStruxure\\Building Operation 5.0\\Device Administrator\\Python\\python.exe",
"?:\\Program Files\\Splunk\\bin\\openssl.exe",
"?:\\Program Files\\SplunkUniversalForwarder\\bin\\openssl.exe",
"?:\\Users\\*\\AppData\\Local\\Logi\\LogiBolt\\LogiBoltUpdater.exe",
"?:\\Windows\\system32\\icacls.exe",
"?:\\Windows\\System32\\OpenSSH\\*"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | eq | --rootcert, --cert, --crlfile | excludes:process.args field:"process.args" value:"--rootcert" field:"process.args" value:"--cert" field:"process.args" value:"--crlfile" |
process.command_line | match | --cacert, --ssl-cert, --tls-cert, --tls_server_certs | excludes:process.command_line |
process.executable | wildcard | ?:\ProgramData\Logishrd\LogiOptions\Software\*\LogiLuUpdater.exe, ?:\Program Files\Elastic\Agent\data\*\osqueryd.exe, ?:\Program Files\Git\cmd\git.exe, ?:\Program Files\Git\mingw64\bin\git.exe, ?:\Program Files\Guardicore\gc-controller.exe, ?:\Program Files\Guardicore\gc-deception-agent.exe, ?:\Program Files\Guardicore\gc-detection-agent.exe, ?:\Program Files\Guardicore\gc-enforcement-agent.exe, ?:\Program Files\Guardicore\gc-guest-agent.exe, ?:\Program Files\Logi\LogiBolt\LogiBoltUpdater.exe, ?:\Program Files (x86)\Schneider Electric EcoStruxure\Building Operation 5.0\Device Administrator\Python\python.exe, ?:\Program Files\Splunk\bin\openssl.exe, ?:\Program Files\SplunkUniversalForwarder\bin\openssl.exe, ?:\Users\*\AppData\Local\Logi\LogiBolt\LogiBoltUpdater.exe, ?:\Windows\system32\icacls.exe, ?:\Windows\System32\OpenSSH\* | excludes:process.executable |
Authentication via Unusual PAM Grantor
#This rule detects successful authentications via PAM grantors that are not commonly used. This could indicate an attacker is attempting to escalate privileges or maintain persistence on the system by modifying the default PAM configuration.
MITRE ATT&CK Coverage
Rule Body
[metadata]
creation_date = "2024/03/06"
integration = ["auditd_manager"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
This rule detects successful authentications via PAM grantors that are not commonly used. This could indicate an
attacker is attempting to escalate privileges or maintain persistence on the system by modifying the default PAM
configuration.
"""
from = "now-9m"
index = ["auditbeat-*", "logs-auditd_manager.auditd-*"]
language = "kuery"
license = "Elastic License v2"
name = "Authentication via Unusual PAM Grantor"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Authentication via Unusual PAM Grantor
Pluggable Authentication Modules (PAM) are integral to Linux systems, managing authentication tasks. Adversaries may exploit uncommon PAM grantors to escalate privileges or maintain persistence by altering default configurations. The detection rule identifies successful authentications using atypical PAM grantors, signaling potential unauthorized access or configuration tampering.
### Possible investigation steps
- Review the specific PAM grantor involved in the authentication event to determine if it is known or expected in your environment.
- Check the user account associated with the authentication event for any signs of compromise or unusual activity, such as recent changes in permissions or unexpected login times.
- Investigate the source IP address and hostname of the authentication event to verify if it is a recognized and authorized system within your network.
- Examine recent changes to the PAM configuration files on the affected host to identify any unauthorized modifications or additions.
- Correlate this event with other security alerts or logs from the same host or user to identify potential patterns of malicious activity.
- Consult with system administrators or relevant personnel to confirm if the use of the unusual PAM grantor was part of a legitimate change or update.
### False positive analysis
- Custom PAM modules: Organizations may use custom PAM modules for specific applications or security policies. Review these modules to ensure they are legitimate and add them to an exception list if they are frequently triggering alerts.
- Administrative scripts: Some administrative scripts might use non-standard PAM grantors for automation purposes. Verify the scripts' legitimacy and consider excluding them from the rule if they are part of routine operations.
- Third-party software: Certain third-party software may install or use uncommon PAM grantors as part of their authentication process. Validate the software's authenticity and add its grantors to an exception list if they are known to be safe.
- Development environments: In development or testing environments, developers might experiment with different PAM configurations. Ensure these environments are properly isolated and consider excluding them from the rule to avoid unnecessary alerts.
### Response and remediation
- Immediately isolate the affected system from the network to prevent further unauthorized access or lateral movement by the adversary.
- Review the PAM configuration files on the affected system to identify and revert any unauthorized changes to the grantors. Ensure only legitimate PAM modules are in use.
- Terminate any suspicious or unauthorized processes that may have been initiated by the attacker to maintain persistence or escalate privileges.
- Conduct a thorough review of user accounts and privileges on the affected system to identify any unauthorized changes or newly created accounts. Revoke any unauthorized access.
- Restore the affected system from a known good backup if unauthorized changes cannot be easily reverted or if the system's integrity is in question.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems are affected.
- Implement enhanced monitoring and logging for PAM-related activities across the network to detect similar threats in the future, ensuring that alerts are promptly reviewed and acted upon."""
risk_score = 47
rule_id = "a8aaa49d-9834-462d-bf8f-b1255cebc004"
setup = """## Setup
This rule requires the use of the `auditd_manager` integration. `Auditd_manager` is a tool designed to simplify and enhance the management of the audit subsystem in Linux systems. It provides a user-friendly interface and automation capabilities for configuring and monitoring system auditing through the auditd daemon. With `auditd_manager`, administrators can easily define audit rules, track system events, and generate comprehensive audit reports, improving overall security and compliance in the system. The following steps should be executed in order to install and deploy `auditd_manager` on a Linux system.
```
Kibana -->
Management -->
Integrations -->
Auditd Manager -->
Add Auditd Manager
```
`Auditd_manager` subscribes to the kernel and receives events as they occur without any additional configuration. However, if more advanced configuration is required to detect specific behavior, audit rules can be added to the integration in either the "audit rules" configuration box or the "auditd rule files" box by specifying a file to read the audit rules from.
For this detection rule to trigger, no additional configuration is required.
"""
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Credential Access",
"Tactic: Persistence",
"Data Source: Auditd Manager",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
event.category:authentication and host.os.type:linux and event.action:authenticated and event.outcome:success and
auditd.data.grantors:(* and not (pam_rootok or *pam_cap* or *pam_permit*))
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[[rule.threat.technique]]
id = "T1556"
name = "Modify Authentication Process"
reference = "https://attack.mitre.org/techniques/T1556/"
[[rule.threat.technique.subtechnique]]
id = "T1556.003"
name = "Pluggable Authentication Modules"
reference = "https://attack.mitre.org/techniques/T1556/003/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1556"
name = "Modify Authentication Process"
reference = "https://attack.mitre.org/techniques/T1556/"
[[rule.threat.technique.subtechnique]]
id = "T1556.003"
name = "Pluggable Authentication Modules"
reference = "https://attack.mitre.org/techniques/T1556/003/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[rule.new_terms]
field = "new_terms_fields"
value = ["auditd.data.grantors"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-5d"
Stages and Predicates
Stage 1: new_terms
event.category:authentication and host.os.type:linux and event.action:authenticated and event.outcome:success and
auditd.data.grantors:(* and not (pam_rootok or *pam_cap* or *pam_permit*))
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
auditd.data.grantors | is_not_null | field:"auditd.data.grantors" kind:is_not_null | |
event.action | eq |
| field:"EventType" kind:eq value:"authenticated" |
event.category | eq |
| field:"event.category" kind:eq value:"authentication" |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"success" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
auditd.data.grantors | eq | pam_rootok | excludes:auditd.data.grantors field:"auditd.data.grantors" value:"pam_rootok" |
auditd.data.grantors | match | pam_cap | excludes:auditd.data.grantors field:"auditd.data.grantors" value:"pam_cap" |
auditd.data.grantors | match | pam_permit | excludes:auditd.data.grantors field:"auditd.data.grantors" value:"pam_permit" |
Chattr Execution with Unusual Target File
#This rule detects the execution of the "chattr" command with an unusual target file. The "chattr" command is used to change file attributes, and is often used by attackers to hide files or directories or mark them as immutable and/or undeletable.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Rule Body
[rule]
description = """
This rule detects the execution of the "chattr" command with an unusual target file. The "chattr" command is used to
change file attributes, and is often used by attackers to hide files or directories or mark them as immutable and/or
undeletable.
"""
id = "831513aa-8320-484f-9275-5b46c57760f0"
license = "Elastic License v2"
name = "Chattr Execution with Unusual Target File"
os_list = ["linux"]
reference = [
"https://www.trendmicro.com/en_nl/research/22/i/how-malicious-actors-abuse-native-linux-tools-in-their-attacks.html",
]
version = "1.0.15"
query = '''
process where event.type == "start" and event.action == "exec" and process.name == "chattr" and
process.executable like ("/bin/chattr", "/usr/bin/chattr", "/usr/local/bin/chattr") and
process.args like (
"/root/.ssh/*", "/home/*/.ssh/*", "/etc/ld.so.preload", "/dev/shm*", "/tmp*", "/var/spool/cron*", "/etc/cron*",
"/etc/init.d/*", "/etc/rc.local", "/etc/passwd", "/etc/shadow", "/etc/group", "/etc/sudoers", "/etc/sudoers.d/*",
"/etc/ssh/*", "/var/tmp*", "/usr/bin/*", "/bin/*", "/usr/local/bin/*", "/sbin/*", "/usr/sbin/*", "/usr/local/sbin/*",
"/usr/lib/*", "/usr/local/lib/*", "/lib/*", "/lib64/*", "/usr/lib64/*", "/usr/local/lib64/*"
) and
not (
process.args : (
"/*chattr", // excluding entries where absolute path is added to chattr command
"/etc/resolv.conf", "/etc/resolv-secure.conf", // commonly used to ensure resolv.conf is not modified by the system
"/etc/pki/entitlement"
) or
process.parent.executable in (
"/opt/rudder/bin/cf-agent", "/usr/local/bin/ldap2sshkeys", "./ldap2sshkeys", "/var/lib/dpkg/info/cblauncher.postinst",
"/run/lxd_agent/lxd-agent"
) or
process.parent.executable like "/etc/platform/*/crons/pause" or
process.parent.args : ("/var/lib/waagent/*", "/opt/tableau/tableau_server/*", "/var/tmp/rpm-tmp.*") or
process.parent.command_line in ("/bin/bash /usr/sbin/libpam", "sh clean") or
process.parent.command_line like "*.ansible*" or
process.command_line in (
"chattr +i /etc/pam.d/common-auth", "chattr -i /etc/pam.d/common-auth", "chattr -i /etc/fstab",
"chattr +i /etc/pam.d/password-auth", "chattr -i /etc/pam.d/password-auth"
) or
(
process.parent.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "sudo") and process.args in (
"/var/spool/cron/root", "/var/spool/cron", "/etc/crontab", "/etc/ld.so.preload", "/etc/hosts", "/etc/fstab",
"/etc/ssh/sshd_config", "/etc/sssd/sssd.conf", "/etc/vxagent/involflt"
)
) or
(process.working_directory == "/mdm_shared/postgresql/15/main" and process.command_line == "chattr -iua /tmp") or
(process.parent.args == "/opt/forticlientems/bin/setup_cli.sh" and process.command_line == "chattr +i /usr/local/bin/ems_vm_shell.sh") or
(
process.command_line in (
"chattr +i /usr/lib64/security/.pam_cache/.pam_ldap_helper2",
"chattr -i /usr/lib64/security/.pam_cache/.pam_ldap_helper2"
) and
process.parent.command_line == "/bin/bash /usr/lib64/security/.pam_cache/.data2/.sys-monitor"
)
)
'''
min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1222"
name = "File and Directory Permissions Modification"
reference = "https://attack.mitre.org/techniques/T1222/"
[[threat.technique.subtechnique]]
id = "T1222.002"
name = "Linux and Mac File and Directory Permissions Modification"
reference = "https://attack.mitre.org/techniques/T1222/002/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.type == "start" and event.action == "exec" and process.name == "chattr" and
process.executable like ("/bin/chattr", "/usr/bin/chattr", "/usr/local/bin/chattr") and
process.args like (
"/root/.ssh/*", "/home/*/.ssh/*", "/etc/ld.so.preload", "/dev/shm*", "/tmp*", "/var/spool/cron*", "/etc/cron*",
"/etc/init.d/*", "/etc/rc.local", "/etc/passwd", "/etc/shadow", "/etc/group", "/etc/sudoers", "/etc/sudoers.d/*",
"/etc/ssh/*", "/var/tmp*", "/usr/bin/*", "/bin/*", "/usr/local/bin/*", "/sbin/*", "/usr/sbin/*", "/usr/local/sbin/*",
"/usr/lib/*", "/usr/local/lib/*", "/lib/*", "/lib64/*", "/usr/lib64/*", "/usr/local/lib64/*"
) and
not (
process.args : (
"/*chattr",
"/etc/resolv.conf", "/etc/resolv-secure.conf",
"/etc/pki/entitlement"
) or
process.parent.executable in (
"/opt/rudder/bin/cf-agent", "/usr/local/bin/ldap2sshkeys", "./ldap2sshkeys", "/var/lib/dpkg/info/cblauncher.postinst",
"/run/lxd_agent/lxd-agent"
) or
process.parent.executable like "/etc/platform/*/crons/pause" or
process.parent.args : ("/var/lib/waagent/*", "/opt/tableau/tableau_server/*", "/var/tmp/rpm-tmp.*") or
process.parent.command_line in ("/bin/bash /usr/sbin/libpam", "sh clean") or
process.parent.command_line like "*.ansible*" or
process.command_line in (
"chattr +i /etc/pam.d/common-auth", "chattr -i /etc/pam.d/common-auth", "chattr -i /etc/fstab",
"chattr +i /etc/pam.d/password-auth", "chattr -i /etc/pam.d/password-auth"
) or
(
process.parent.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "sudo") and process.args in (
"/var/spool/cron/root", "/var/spool/cron", "/etc/crontab", "/etc/ld.so.preload", "/etc/hosts", "/etc/fstab",
"/etc/ssh/sshd_config", "/etc/sssd/sssd.conf", "/etc/vxagent/involflt"
)
) or
(process.working_directory == "/mdm_shared/postgresql/15/main" and process.command_line == "chattr -iua /tmp") or
(process.parent.args == "/opt/forticlientems/bin/setup_cli.sh" and process.command_line == "chattr +i /usr/local/bin/ems_vm_shell.sh") or
(
process.command_line in (
"chattr +i /usr/lib64/security/.pam_cache/.pam_ldap_helper2",
"chattr -i /usr/lib64/security/.pam_cache/.pam_ldap_helper2"
) and
process.parent.command_line == "/bin/bash /usr/lib64/security/.pam_cache/.data2/.sys-monitor"
)
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.name | eq |
| field:"process_basename" kind:eq value:"chattr" |
Exclusions
The rule actively suppresses these predicates.
Command Execution via ForFiles
#Detects attempts to execute a command via the forfiles Windows utility. Adversaries may use this utility to proxy execution via a trusted parent process.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 1: Process creation |
| Security-Auditing | Event ID 4688: A new process has been created. |
Rule Body
[metadata]
creation_date = "2025/02/03"
integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/05/04"
[rule]
author = ["Elastic"]
description = """
Detects attempts to execute a command via the forfiles Windows utility. Adversaries may use this utility to proxy
execution via a trusted parent process.
"""
from = "now-9m"
index = [
"endgame-*",
"logs-crowdstrike.fdr*",
"logs-endpoint.events.process-*",
"logs-m365_defender.event-*",
"logs-sentinel_one_cloud_funnel.*",
"logs-system.security*",
"logs-windows.forwarded*",
"logs-windows.sysmon_operational-*",
"winlogbeat-*",
]
language = "eql"
license = "Elastic License v2"
name = "Command Execution via ForFiles"
note = """## Triage and analysis
### Investigating Command Execution via ForFiles
### Possible investigation steps
- Identify the user account that performed the action and whether it should perform this kind of action.
- Contact the account owner and confirm whether they are aware of this activity.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Validate the activity is not related to planned patches, updates, network administrator activity, or legitimate software installations.
- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.
### False positive analysis
- This is a dual-use tool, meaning its usage is not inherently malicious. Analysts can dismiss the alert if the administrator is aware of the activity, no other suspicious activity was identified.
### Response and Remediation
- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
setup = """## Setup
This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
Setup instructions: https://ela.st/install-elastic-defend
### Additional data sources
This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
- [CrowdStrike](https://ela.st/crowdstrike-integration)
- [Microsoft Defender XDR](https://ela.st/m365-defender)
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
- [Windows Process Creation Logs](https://ela.st/audit-process-creation)
"""
references = ["https://lolbas-project.github.io/lolbas/Binaries/Forfiles/"]
risk_score = 47
rule_id = "3f7bd5ac-9711-44b4-82c1-fa246d829f15"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Data Source: Windows Security Event Logs",
"Data Source: Microsoft Defender XDR",
"Data Source: Sysmon",
"Data Source: SentinelOne",
"Data Source: Crowdstrike",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "windows" and event.type == "start" and user.id != "S-1-5-18" and
(process.name : "forfiles.exe" or ?process.pe.original_file_name == "forfiles.exe") and process.args : ("/c", "-c") and
not process.args : ("-d", "/d", "cmd /c copy @file*", "cmd /c DEL /Q /F @*", "cmd /c del @*", "D:\\*")
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1202"
name = "Indirect Command Execution"
reference = "https://attack.mitre.org/techniques/T1202/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: process
process where host.os.type == "windows" and event.type == "start" and user.id != "S-1-5-18" and
(process.name : "forfiles.exe" or ?process.pe.original_file_name == "forfiles.exe") and process.args : ("/c", "-c") and
not process.args : ("-d", "/d", "cmd /c copy @file*", "cmd /c DEL /Q /F @*", "cmd /c del @*", "D:\\*")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"forfiles.exe" |
process.pe.original_file_name | eq |
| field:"OriginalFileName" kind:eq value:"forfiles.exe" |
user.id | ne |
| field:"user.id" kind:ne value:"S-1-5-18" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | wildcard | -d, /d, cmd /c copy @file*, cmd /c DEL /Q /F @*, cmd /c del @*, D:\* | excludes:process.args |
Curl HTTP Fetch Piped to Cmd or Node via Command Shell
#Identifies cmd.exe with a command line consistent with downloading content over HTTP(S) using curl and piping the output into another interpreter (cmd.exe or node.exe). This pattern is used to fetch and execute remote commands or script without staging a file.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Command & Control |
Rule Body
[rule]
description = """
Identifies cmd.exe with a command line consistent with downloading content over HTTP(S) using curl and piping the output
into another interpreter (cmd.exe or node.exe). This pattern is used to fetch and execute remote commands or script
without staging a file.
"""
id = "a8d3e441-2b0c-4e91-bf22-1d9c8f7a6e5d"
license = "Elastic License v2"
name = "Curl HTTP Fetch Piped to Cmd or Node via Command Shell"
os_list = ["windows"]
reference = [
"https://curl.se/docs/manpage.html",
"https://attack.mitre.org/techniques/T1105/",
"https://attack.mitre.org/techniques/T1059/",
]
version = "1.0.1"
query = '''
process where event.action == "start" and
process.name : "cmd.exe" and
process.command_line : (
"*curl*http*| cmd*",
"*curl*http*| node*",
"*curl*http*|cmd",
"*curl*http*|node*"
)
'''
min_endpoint_version = "8.10.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
tree = true
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.003"
name = "Windows Command Shell"
reference = "https://attack.mitre.org/techniques/T1059/003/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"
[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[internal]
min_endpoint_version = "8.10.0"
Stages and Predicates
Stage 1: process
process where event.action == "start" and
process.name : "cmd.exe" and
process.command_line : (
"*curl*http*| cmd*",
"*curl*http*| node*",
"*curl*http*|cmd",
"*curl*http*|node*"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"cmd.exe" |
Disown Execution via Shell Command from Volume Mount
#Detects when disown is executed by a shell command with the responsible process having been executed from a volume mount. The use of the disown binary on macOS is in itself an anomaly and something that almost never occurs but when paired with being executed via a shell command from a volume mounted binary indicates malicious activity. Disown originates from unix and allows one to remove any and all jobs from the current shell. A threat actor may do this in order to ensure there are no current jobs executing or that may execute that could prevent their actions from completing or cause them to be noticed.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution |
Telemetry Coverage
Rule Body
[rule]
description = """
Detects when disown is executed by a shell command with the responsible process having been executed from a volume
mount. The use of the disown binary on macOS is in itself an anomaly and something that almost never occurs but when
paired with being executed via a shell command from a volume mounted binary indicates malicious activity. Disown
originates from unix and allows one to remove any and all jobs from the current shell. A threat actor may do this in
order to ensure there are no current jobs executing or that may execute that could prevent their actions from completing
or cause them to be noticed.
"""
id = "511bd55d-f845-45da-8b35-7dd9a40fa7b2"
license = "Elastic License v2"
name = "Disown Execution via Shell Command from Volume Mount"
os_list = ["macos"]
version = "1.0.3"
query = '''
process where event.type == "start" and event.action == "exec" and process.args in ("bash", "sh", "zsh") and
process.args == "-c" and process.args like~ "*disown*" and process.parent.executable like "/Volumes/*"
'''
min_endpoint_version = "8.11.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[internal]
min_endpoint_version = "8.11.0"
Stages and Predicates
Stage 1: process
process where event.type == "start" and event.action == "exec" and process.args in ("bash", "sh", "zsh") and
process.args == "-c" and process.args like~ "*disown*" and process.parent.executable like "/Volumes/*"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | eq |
| field:"process.args" kind:eq value:"-c" |
process.args | in |
| field:"process.args" kind:in |
process.args | wildcard |
| field:"process.args" kind:wildcard value:"*disown*" |
process.parent.executable | wildcard |
| field:"ParentImage" kind:wildcard value:"/Volumes/*" |
Egress Connection by a DNF Package Manager Descendant
#Detects suspicious network events executed by the DNF package manager, potentially indicating persistence through a DNF backdoor. In Linux, DNF (Dandified YUM) is a command-line utility used for handling packages on Fedora-based systems, providing functions for installing, updating, upgrading, and removing software along with managing package repositories. Attackers can backdoor DNF to gain persistence by injecting malicious code into plugins that DNF runs, thereby ensuring continued unauthorized access or control each time DNF is used for package management.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Stealth |
Rule Body
[rule]
description = """
Detects suspicious network events executed by the DNF package manager, potentially indicating persistence through a DNF
backdoor. In Linux, DNF (Dandified YUM) is a command-line utility used for handling packages on Fedora-based systems,
providing functions for installing, updating, upgrading, and removing software along with managing package repositories.
Attackers can backdoor DNF to gain persistence by injecting malicious code into plugins that DNF runs, thereby ensuring
continued unauthorized access or control each time DNF is used for package management.
"""
id = "3e79f8fc-26a4-4646-9a58-9f11b9c11e28"
license = "Elastic License v2"
name = "Egress Connection by a DNF Package Manager Descendant"
os_list = ["linux"]
reference = [
"https://pwnshift.github.io/2020/10/01/persistence.html",
"https://www.elastic.co/security-labs/sequel-on-persistence-mechanisms",
]
version = "1.0.11"
query = '''
sequence by process.entity_id with maxspan=5s
[process where event.type == "start" and event.action == "exec" and (
process.name : (
"bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "python*", "php*",
"perl", "ruby", "lua*", "openssl", "nc", "ncat", "netcat", "netcat.openbsd",
"netcat.traditional", "nc.openbsd", "nc.traditional", "telnet", "awk"
) or
process.executable : (
"./*", "/boot/*", "/dev/shm/*", "/etc/cron.*/*", "/etc/init.d/*", "/etc/update-motd.d/*", "/run/*", "/srv/*",
"/tmp/*", "/var/tmp/*", "/var/log/*"
)
) and descendant of [process where event.action == "exec" and process.name == "dnf"] and not (
process.working_directory == "/tmp/newroot" or
process.command_line like "*petalinux.xilinx.com*" or
process.executable like ("/var/lib/docker/overlay2/*", "/tmp/newroot/*", "/builds/*", "/workspaces/*") or
process.parent.executable == "/usr/lib/opt/kolide-k2/bin/launcher" or
process.args like "/home/ansible/.ansible/*" or
(process.name like "python*" and process.args == "azure.cli")
)
]
[network where event.action == "connection_attempted" and event.type == "start" and not (
destination.ip == null or
destination.ip == "0.0.0.0" or
cidrmatch(
destination.ip, "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24", "192.0.0.0/29",
"192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24",
"192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4", "100.64.0.0/10",
"192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1", "FE80::/10",
"FF00::/8", "172.31.0.0/16"
) or
process.executable like (
"/tmp/newroot/usr/lib64/google-cloud-sdk/platform/bundledpythonunix/bin/python*", "/usr/bin/node"
)
)
]
'''
min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[[threat.technique]]
id = "T1546"
name = "Event Triggered Execution"
reference = "https://attack.mitre.org/techniques/T1546/"
[[threat.technique.subtechnique]]
id = "T1546.016"
name = "Installer Packages"
reference = "https://attack.mitre.org/techniques/T1546/016/"
[[threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"
[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[threat]]
framework = "MITRE ATT&CK"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[threat]]
framework = "MITRE ATT&CK"
[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 5s, correlated by process.entity_id.
Stage 1: process
[process where event.type == "start" and event.action == "exec" and (
process.name : (
"bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "python*", "php*",
"perl", "ruby", "lua*", "openssl", "nc", "ncat", "netcat", "netcat.openbsd",
"netcat.traditional", "nc.openbsd", "nc.traditional", "telnet", "awk"
) or
process.executable : (
"./*", "/boot/*", "/dev/shm/*", "/etc/cron.*/*", "/etc/init.d/*", "/etc/update-motd.d/*", "/run/*", "/srv/*",
"/tmp/*", "/var/tmp/*", "/var/log/*"
)
) and descendant of [process where event.action == "exec" and process.name == "dnf"] and not (
process.working_directory == "/tmp/newroot" or
process.command_line like "*petalinux.xilinx.com*" or
process.executable like ("/var/lib/docker/overlay2/*", "/tmp/newroot/*", "/builds/*", "/workspaces/*") or
process.parent.executable == "/usr/lib/opt/kolide-k2/bin/launcher" or
process.args like "/home/ansible/.ansible/*" or
(process.name like "python*" and process.args == "azure.cli")
)
]
Stage 2: network
[network where event.action == "connection_attempted" and event.type == "start" and not (
destination.ip == null or
destination.ip == "0.0.0.0" or
cidrmatch(
destination.ip, "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24", "192.0.0.0/29",
"192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24",
"192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4", "100.64.0.0/10",
"192.175.48.0/24","198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "240.0.0.0/4", "::1", "FE80::/10",
"FF00::/8", "172.31.0.0/16"
) or
process.executable like (
"/tmp/newroot/usr/lib64/google-cloud-sdk/platform/bundledpythonunix/bin/python*", "/usr/bin/node"
)
)
]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | eq | azure.cli | excludes:process.args field:"process.args" value:"azure.cli" |
process.name | starts_with | python | excludes:process.name field:"process.name" value:"python" |
process.args | starts_with | /home/ansible/.ansible/ | excludes:process.args field:"process.args" value:"/home/ansible/.ansible/" |
process.command_line | match | petalinux.xilinx.com | excludes:process.command_line field:"process.command_line" value:"petalinux.xilinx.com" |
process.executable | starts_with | /var/lib/docker/overlay2/, /tmp/newroot/, /builds/, /workspaces/ | excludes:process.executable |
process.parent.executable | eq | /usr/lib/opt/kolide-k2/bin/launcher | excludes:process.parent.executable field:"process.parent.executable" value:"/usr/lib/opt/kolide-k2/bin/launcher" |
process.working_directory | eq | /tmp/newroot | excludes:process.working_directory field:"process.working_directory" value:"/tmp/newroot" |
destination.ip | cidr_match | 10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.0.0.0/24, 192.0.0.0/29, 192.0.0.8/32, 192.0.0.9/32, 192.0.0.10/32, 192.0.0.170/32, 192.0.0.171/32, 192.0.2.0/24, 192.31.196.0/24, 192.52.193.0/24, 192.168.0.0/16, 192.88.99.0/24, 224.0.0.0/4, 100.64.0.0/10, 192.175.48.0/24, 198.18.0.0/15, 198.51.100.0/24, 203.0.113.0/24, 240.0.0.0/4, ::1, FE80::/10, FF00::/8, 172.31.0.0/16 | excludes:destination.ip |
destination.ip | eq | 0.0.0.0 | excludes:destination.ip field:"destination.ip" value:"0.0.0.0" |
destination.ip | is_null | excludes:destination.ip | |
process.executable | wildcard | /tmp/newroot/usr/lib64/google-cloud-sdk/platform/bundledpythonunix/bin/python*, /usr/bin/node | excludes:process.executable field:"process.executable" value:"/tmp/newroot/usr/lib64/google-cloud-sdk/platform/bundledpythonunix/bin/python*" field:"process.executable" value:"/usr/bin/node" |
Evasion via LdrpKernel32 Overwrite
#Identifies attempts to load a malicious DLL early via hijacking the normal NTDLL bootstrap process. Instead of loading kernel32 it will load a malicious one that may execute malicious code and resume the rest of the loading process steps.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[rule]
description = """
Identifies attempts to load a malicious DLL early via hijacking the normal NTDLL bootstrap process. Instead of loading
kernel32 it will load a malicious one that may execute malicious code and resume the rest of the loading process steps.
"""
id = "6a01a5d9-1fb0-4ad9-a813-d541012996b8"
license = "Elastic License v2"
name = "Evasion via LdrpKernel32 Overwrite"
os_list = ["windows"]
reference = ["https://github.com/rbmm/LdrpKernel32DllName"]
version = "1.0.13"
query = '''
library where (dll.code_signature.trusted == false or dll.code_signature.exists == false) and process.uptime == 0 and
_arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : "*!BaseThreadInitThunk*") and
process.executable : ("?:\\*", "\\Device\\Mup\\*") and
not _arraysearch(process.thread.Ext.call_stack, $entry,
$entry.symbol_info : ("?:\\Windows\\System32\\kernel32.dll!BaseThreadInitThunk*",
"?:\\Windows\\SysWOW64\\kernel32.dll!BaseThreadInitThunk*",
"?:\\Windows\\WinSxS\\*\\kernel32.dll!BaseThreadInitThunk*",
"?:\\Windows\\WinSxS\\Temp\\PendingDeletes\\*!BaseThreadInitThunk*",
"\\Device\\*\\Windows\\*\\kernel32.dll!BaseThreadInitThunk*")) and
not dll.path : ("?:\\Windows\\assembly\\NativeImages_*\\System.Numerics.ni.dll", "C:\\Program Files\\Fortinet\\FortiClient\\utilsdll.dll")
'''
min_endpoint_version = "8.8.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"
[[threat.technique.subtechnique]]
id = "T1574.001"
name = "DLL"
reference = "https://attack.mitre.org/techniques/T1574/001/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "8.8.0"
Stages and Predicates
Stage 1: library
library where (dll.code_signature.trusted == false or dll.code_signature.exists == false) and process.uptime == 0 and
_arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : "*!BaseThreadInitThunk*") and
process.executable : ("?:\\*", "\\Device\\Mup\\*") and
not _arraysearch(process.thread.Ext.call_stack, $entry,
$entry.symbol_info : ("?:\\Windows\\System32\\kernel32.dll!BaseThreadInitThunk*",
"?:\\Windows\\SysWOW64\\kernel32.dll!BaseThreadInitThunk*",
"?:\\Windows\\WinSxS\\*\\kernel32.dll!BaseThreadInitThunk*",
"?:\\Windows\\WinSxS\\Temp\\PendingDeletes\\*!BaseThreadInitThunk*",
"\\Device\\*\\Windows\\*\\kernel32.dll!BaseThreadInitThunk*")) and
not dll.path : ("?:\\Windows\\assembly\\NativeImages_*\\System.Numerics.ni.dll", "C:\\Program Files\\Fortinet\\FortiClient\\utilsdll.dll")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
dll.code_signature.exists | eq |
| field:"dll.code_signature.exists" kind:eq value:"false" |
dll.code_signature.trusted | eq |
| field:"dll.code_signature.trusted" kind:eq value:"false" |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.uptime | eq |
| field:"process.uptime" kind:eq value:"0" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.thread.Ext.call_stack | array_any | excludes:process.thread.Ext.call_stack | |
dll.path | wildcard | ?:\Windows\assembly\NativeImages_*\System.Numerics.ni.dll, C:\Program Files\Fortinet\FortiClient\utilsdll.dll | excludes:dll.path field:"dll.path" value:"?:\Windows\assembly\NativeImages_*\System.Numerics.ni.dll" field:"dll.path" value:"C:\Program Files\Fortinet\FortiClient\utilsdll.dll" |
Execution via WMI CommandLine Event Consumer
#Identifies the creation or execution via the Windows Management Instrumentation CommandLine Event Consumer class. The CommandLineEventConsumer class starts an arbitrary process in the local system when an event is delivered to it.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution |
Rule Body
[rule]
description = """
Identifies the creation or execution via the Windows Management Instrumentation CommandLine Event Consumer class. The
CommandLineEventConsumer class starts an arbitrary process in the local system when an event is delivered to it.
"""
id = "fd597bc7-8cf6-4dec-8bc0-bda7696bbbdb"
license = "Elastic License v2"
name = "Execution via WMI CommandLine Event Consumer"
os_list = ["windows"]
reference = [
"https://in.security/2019/04/03/an-intro-into-abusing-and-identifying-wmi-event-subscriptions-for-persistence/",
"https://learn.microsoft.com/en-us/windows/win32/wmisdk/commandlineeventconsumer",
]
version = "1.0.10"
query = '''
process where event.action == "start" and
(
(process.parent.executable : "?:\\Windows\\Sys*\\wbem\\WmiPrvSE.exe" and
/* wbemcons.dll - WMI Standard Event Consumers */
process.parent.thread.Ext.call_stack_summary : "*wbemcons.dll*") or
(process.pe.original_file_name : "wmic.exe" and process.command_line : "*create*" and process.command_line : "*CommandLineEventConsumer*")
) and
not (process.executable : ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe") and
process.code_signature.trusted == true and not process.code_signature.subject_name : "Microsoft*") and
not process.executable : "?:\\Windows\\System32\\chkntfs.exe" and
not process.hash.sha256 : "c4ecbd9e75fbe2d8ab5f4d94d663207d2b73ec924ba9e27b5df9560818ff1105"
'''
min_endpoint_version = "8.7.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1047"
name = "Windows Management Instrumentation"
reference = "https://attack.mitre.org/techniques/T1047/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[internal]
min_endpoint_version = "8.7.0"
Stages and Predicates
Stage 1: process
process where event.action == "start" and
(
(process.parent.executable : "?:\\Windows\\Sys*\\wbem\\WmiPrvSE.exe" and
process.parent.thread.Ext.call_stack_summary : "*wbemcons.dll*") or
(process.pe.original_file_name : "wmic.exe" and process.command_line : "*create*" and process.command_line : "*CommandLineEventConsumer*")
) and
not (process.executable : ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe") and
process.code_signature.trusted == true and not process.code_signature.subject_name : "Microsoft*") and
not process.executable : "?:\\Windows\\System32\\chkntfs.exe" and
not process.hash.sha256 : "c4ecbd9e75fbe2d8ab5f4d94d663207d2b73ec924ba9e27b5df9560818ff1105"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.code_signature.subject_name | wildcard |
| field:"Signature" kind:wildcard value:"Microsoft*" |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.parent.executable | wildcard |
| field:"ParentImage" kind:wildcard value:"?:\Windows\Sys*\wbem\WmiPrvSE.exe" |
process.parent.thread.Ext.call_stack_summary | wildcard |
| field:"process.parent.thread.Ext.call_stack_summary" kind:wildcard value:"*wbemcons.dll*" |
process.pe.original_file_name | wildcard |
| field:"OriginalFileName" kind:wildcard value:"wmic.exe" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.code_signature.subject_name | starts_with | Microsoft | excludes:process.code_signature.subject_name field:"process.code_signature.subject_name" value:"Microsoft" |
process.code_signature.trusted | eq | true | excludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true" |
process.executable | wildcard | ?:\Program Files\*.exe, ?:\Program Files (x86)\*.exe | excludes:process.executable field:"process.executable" value:"?:\Program Files\*.exe" field:"process.executable" value:"?:\Program Files (x86)\*.exe" |
process.executable | eq | ?:\Windows\System32\chkntfs.exe | excludes:process.executable field:"process.executable" value:"?:\Windows\System32\chkntfs.exe" |
process.hash.sha256 | eq | c4ecbd9e75fbe2d8ab5f4d94d663207d2b73ec924ba9e27b5df9560818ff1105 | excludes:process.hash.sha256 field:"process.hash.sha256" value:"c4ecbd9e75fbe2d8ab5f4d94d663207d2b73ec924ba9e27b5df9560818ff1105" |
File and Directory Permissions Modification
#Identifies the change of permissions/ownership of files/folders through built-in Windows utilities. Threat actors may require permission modification of files/folders to change, modify or delete them.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 1: Process creation |
| Security-Auditing | Event ID 4688: A new process has been created. |
Rule Body
[metadata]
creation_date = "2023/07/12"
integration = ["endpoint"]
maturity = "production"
updated_date = "2024/05/21"
[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Identifies the change of permissions/ownership of files/folders through built-in Windows utilities. Threat actors may
require permission modification of files/folders to change, modify or delete them.
"""
from = "now-119m"
index = ["logs-endpoint.events.process-*"]
interval = "60m"
language = "eql"
license = "Elastic License v2"
name = "File and Directory Permissions Modification"
risk_score = 21
rule_id = "bc9e4f5a-e263-4213-a2ac-1edf9b417ada"
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Rule Type: BBR",
"Data Source: Elastic Defend",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where event.type == "start" and host.os.type == "windows" and
(
((process.name: "icacls.exe" or process.pe.original_file_name == "iCACLS.EXE") and process.args: ("*:F", "/reset", "/setowner", "*grant*")) or
((process.name: "cacls.exe" or process.pe.original_file_name == "CACLS.EXE") and process.args: ("/g", "*:f")) or
((process.name: "takeown.exe" or process.pe.original_file_name == "takeown.exe") and process.args: ("/F")) or
((process.name: "attrib.exe" or process.pe.original_file_name== "ATTRIB.EXE") and process.args: "-r")
) and not user.id : "S-1-5-18" and
not (
process.args : ("C:\\ProgramData\\Lenovo\\*", "C:\\ProgramData\\Adobe\\*", "C:\\ProgramData\\ASUS\\ASUS*")
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1222"
name = "File and Directory Permissions Modification"
reference = "https://attack.mitre.org/techniques/T1222/"
[[rule.threat.technique.subtechnique]]
id = "T1222.001"
name = "Windows File and Directory Permissions Modification"
reference = "https://attack.mitre.org/techniques/T1222/001/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: process
process where event.type == "start" and host.os.type == "windows" and
(
((process.name: "icacls.exe" or process.pe.original_file_name == "iCACLS.EXE") and process.args: ("*:F", "/reset", "/setowner", "*grant*")) or
((process.name: "cacls.exe" or process.pe.original_file_name == "CACLS.EXE") and process.args: ("/g", "*:f")) or
((process.name: "takeown.exe" or process.pe.original_file_name == "takeown.exe") and process.args: ("/F")) or
((process.name: "attrib.exe" or process.pe.original_file_name== "ATTRIB.EXE") and process.args: "-r")
) and not user.id : "S-1-5-18" and
not (
process.args : ("C:\\ProgramData\\Lenovo\\*", "C:\\ProgramData\\Adobe\\*", "C:\\ProgramData\\ASUS\\ASUS*")
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.pe.original_file_name | eq |
| field:"OriginalFileName" kind:eq |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | starts_with | C:\ProgramData\Lenovo\, C:\ProgramData\Adobe\, C:\ProgramData\ASUS\ASUS | excludes:process.args field:"process.args" value:"C:\ProgramData\Lenovo\" field:"process.args" value:"C:\ProgramData\Adobe\" field:"process.args" value:"C:\ProgramData\ASUS\ASUS" |
user.id | eq | S-1-5-18 | excludes:user.id field:"user.id" value:"S-1-5-18" |
Kernel Module Load via Built-in Utility
#Detects the use of the insmod binary to load a Linux kernel object file. Threat actors can use this binary, given they have root privileges, to load a rootkit on a system providing them with complete control and the ability to hide from security products. Manually loading a kernel module in this manner should not be at all common and can indicate suspicious or malicious behavior.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Stealth |
Rule Body
[metadata]
creation_date = "2022/07/11"
integration = ["endpoint"]
maturity = "production"
min_stack_version = "9.3.0"
min_stack_comments = "Module loading detection for Linux was introduced in 9.3.0"
updated_date = "2026/07/16"
[transform]
[[transform.osquery]]
label = "Osquery - Retrieve all Kernel Modules"
query = "SELECT * FROM kernel_modules"
[[transform.osquery]]
label = "Osquery - Retrieve Running Processes by User"
query = "SELECT pid, username, name FROM processes p JOIN users u ON u.uid = p.uid ORDER BY username"
[[transform.osquery]]
label = "Osquery - Retrieve Listening Ports"
query = "SELECT pid, address, port, socket, protocol, path FROM listening_ports"
[[transform.osquery]]
label = "Osquery - Retrieve Open Sockets"
query = "SELECT pid, family, remote_address, remote_port, socket, state FROM process_open_sockets"
[[transform.osquery]]
label = "Osquery - Retrieve Information for a Specific User"
query = "SELECT * FROM users WHERE username = {{user.name}}"
[[transform.osquery]]
label = "Osquery - Investigate the Account Authentication Status"
query = "SELECT * FROM logged_in_users WHERE user = {{user.name}}"
[rule]
author = ["Elastic"]
description = """
Detects the use of the insmod binary to load a Linux kernel object file. Threat actors can use this binary, given they
have root privileges, to load a rootkit on a system providing them with complete control and the ability to hide from
security products. Manually loading a kernel module in this manner should not be at all common and can indicate
suspicious or malicious behavior.
"""
from = "now-9m"
index = ["logs-endpoint.events.process*"]
language = "eql"
license = "Elastic License v2"
name = "Kernel Module Load via Built-in Utility"
note = """## Triage and analysis
### Investigating Kernel Module Load via Built-in Utility
Threat actors with root privileges may abuse pre-installed binaries to load loadable kernel modules (LKMs), which are object files that extend the functionality of the kernel.
Threat actors can abuse this utility to load rootkits, granting them full control over the system and the ability to evade security products.
The detection rule 'Kernel Module Load via Built-in Utility' is designed to identify instances where these binaries are used to load a kernel object file (with a .ko extension) on a Linux system. This activity is uncommon and may indicate suspicious or malicious behavior.
> **Note**:
> This investigation guide uses the [Osquery Markdown Plugin](https://www.elastic.co/guide/en/security/current/invest-guide-run-osquery.html) introduced in Elastic Stack version 8.5.0. Older Elastic Stack versions will display unrendered Markdown in this guide.
> This investigation guide uses [placeholder fields](https://www.elastic.co/guide/en/security/current/osquery-placeholder-fields.html) to dynamically pass alert data into Osquery queries. Placeholder fields were introduced in Elastic Stack version 8.7.0. If you're using Elastic Stack version 8.6.0 or earlier, you'll need to manually adjust this investigation guide's queries to ensure they properly run.
### Possible investigation steps
- Investigate the kernel object file that was loaded.
- $osquery_1
- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence and whether they are located in expected locations.
- $osquery_2
- Investigate the kernel ring buffer for any warnings or messages, such as tainted or out-of-tree kernel module loads through `dmesg`.
- Investigate syslog for any unusual segfaults or other messages. Rootkits may be installed on targets with different architecture as expected, and could potentially cause segmentation faults.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Validate the activity is not related to planned patches, updates, network administrator activity, or legitimate software installations.
- Investigate whether the altered scripts call other malicious scripts elsewhere on the file system.
- If scripts or executables were dropped, retrieve the files and determine if they are malicious:
- Use a private sandboxed malware analysis system to perform analysis.
- Observe and collect information about the following activities:
- Attempts to contact external domains and addresses.
- Check if the domain is newly registered or unexpected.
- Check the reputation of the domain or IP address.
- File access, modification, and creation activities.
- Investigate abnormal behaviors by the subject process/user such as network connections, file modifications, and any other spawned child processes.
- Investigate listening ports and open sockets to look for potential command and control traffic or data exfiltration.
- $osquery_3
- $osquery_4
- Identify the user account that performed the action, analyze it, and check whether it should perform this kind of action.
- $osquery_5
- Investigate whether the user is currently logged in and active.
- $osquery_6
### False positive analysis
- If this activity is related to new benign software installation activity, consider adding exceptions — preferably with a combination of user and command line conditions.
- If this activity is related to a system administrator who uses cron jobs for administrative purposes, consider adding exceptions for this specific administrator user account.
- Try to understand the context of the execution by thinking about the user, machine, or business purpose. A small number of endpoints, such as servers with unique software, might appear unusual but satisfy a specific business need.
### Related Rules
- Kernel Driver Load - 3e12a439-d002-4944-bc42-171c0dcb9b96
- Tainted Out-Of-Tree Kernel Module Load - 51a09737-80f7-4551-a3be-dac8ef5d181a
- Tainted Kernel Module Load - 05cad2fb-200c-407f-b472-02ea8c9e5e4a
- Attempt to Clear Kernel Ring Buffer - 2724808c-ba5d-48b2-86d2-0002103df753
- Enumeration of Kernel Modules via Proc - 80084fa9-8677-4453-8680-b891d3c0c778
- Suspicious Modprobe File Event - 40ddbcc8-6561-44d9-afc8-eefdbfe0cccd
- Kernel Module Removal - cd66a5af-e34b-4bb0-8931-57d0a043f2ef
- Enumeration of Kernel Modules - 2d8043ed-5bda-4caf-801c-c1feb7410504
### Response and Remediation
- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
- Implement temporary network rules, procedures, and segmentation to contain the malware.
- Stop suspicious processes.
- Immediately block the identified indicators of compromise (IoCs).
- Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Leverage the incident response data and logging to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
references = [
"https://decoded.avast.io/davidalvarez/linux-threat-hunting-syslogk-a-kernel-rootkit-found-under-development-in-the-wild/",
]
risk_score = 47
rule_id = "2339f03c-f53f-40fa-834b-40c5983fc41f"
setup = """## Setup
This rule requires data coming in from Elastic Defend.
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Tactic: Defense Evasion",
"Threat: Rootkit",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "linux" and event.type == "start" and event.action == "load_module" and
(
(process.name == "kmod" and process.args == "insmod" and process.args like~ "*.ko*") or
(process.name == "kmod" and process.args == "modprobe" and not process.args in ("-r", "--remove")) or
(process.name == "insmod" and process.args like~ "*.ko*") or
(process.name == "modprobe" and not process.args in ("-r", "--remove"))
) and
not (
process.parent.executable like ("/opt/ds_agent/*", "/opt/TrendMicro/vls_agent/*", "/opt/intel/oneapi/*") or
process.working_directory in ("/opt/vinchin/agent", "/var/opt/ds_agent/am", "/opt/ds_agent", "/var/opt/TrendMicro/vls_agent/am") or
process.parent.executable in (
"/usr/lib/uptrack/ksplice-apply", "/opt/commvault/commvault/Base/linux_drv", "/opt/cisco/amp/bin/cisco-amp-helper",
"/usr/bin/kcarectl", "/usr/share/ksplice/ksplice-apply", "/opt/commvault/Base/linux_drv", "/usr/sbin/veeamsnap-loader",
"/bin/falcoctl", "/usr/sbin/veeamworker"
) or
process.parent.executable like (
"/sbin/iptables-multi*", "/var/ossec/bin/wazuh-modulesd", "/usr/sbin/mkinitramfs",
"/usr/share/initramfs-tools/hooks/lvm2", "/usr/lpp/mmfs/bin/*", "/opt/forticlient/*",
"/opt/traps/bin/*", "/snap/lxd/*/sbin/lxd", "/usr/sbin/xtables*"
) or
(process.parent.name like ("python*", "platform-python*") and process.parent.args in ("--smart-update", "--auto-update")) or
process.args in ("--showconfig", "--dump-modversions") or
(
process.name == "modprobe" and process.args == "-q" and process.args == "--" and
(process.args in ("net-pf-10", "binfmt-464c") or process.args like ("netdev-*", "block-major-*"))
) or
(
process.name == "modprobe" and process.args == "-n" and process.args == "-v" and
process.args in ("usb-storage", "dccp", "squashfs", "udf", "sctp", "cramfs", "hfsplus", "rds", "hfs", "jffs2", "freevxfs", "vfat", "overlay")
) or
process.parent.args like "/usr/share/initramfs-tools/hooks/*"
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1547"
name = "Boot or Logon Autostart Execution"
reference = "https://attack.mitre.org/techniques/T1547/"
[[rule.threat.technique.subtechnique]]
id = "T1547.006"
name = "Kernel Modules and Extensions"
reference = "https://attack.mitre.org/techniques/T1547/006/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1014"
name = "Rootkit"
reference = "https://attack.mitre.org/techniques/T1014/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
Stages and Predicates
Stage 1: process
process where host.os.type == "linux" and event.type == "start" and event.action == "load_module" and
(
(process.name == "kmod" and process.args == "insmod" and process.args like~ "*.ko*") or
(process.name == "kmod" and process.args == "modprobe" and not process.args in ("-r", "--remove")) or
(process.name == "insmod" and process.args like~ "*.ko*") or
(process.name == "modprobe" and not process.args in ("-r", "--remove"))
) and
not (
process.parent.executable like ("/opt/ds_agent/*", "/opt/TrendMicro/vls_agent/*", "/opt/intel/oneapi/*") or
process.working_directory in ("/opt/vinchin/agent", "/var/opt/ds_agent/am", "/opt/ds_agent", "/var/opt/TrendMicro/vls_agent/am") or
process.parent.executable in (
"/usr/lib/uptrack/ksplice-apply", "/opt/commvault/commvault/Base/linux_drv", "/opt/cisco/amp/bin/cisco-amp-helper",
"/usr/bin/kcarectl", "/usr/share/ksplice/ksplice-apply", "/opt/commvault/Base/linux_drv", "/usr/sbin/veeamsnap-loader",
"/bin/falcoctl", "/usr/sbin/veeamworker"
) or
process.parent.executable like (
"/sbin/iptables-multi*", "/var/ossec/bin/wazuh-modulesd", "/usr/sbin/mkinitramfs",
"/usr/share/initramfs-tools/hooks/lvm2", "/usr/lpp/mmfs/bin/*", "/opt/forticlient/*",
"/opt/traps/bin/*", "/snap/lxd/*/sbin/lxd", "/usr/sbin/xtables*"
) or
(process.parent.name like ("python*", "platform-python*") and process.parent.args in ("--smart-update", "--auto-update")) or
process.args in ("--showconfig", "--dump-modversions") or
(
process.name == "modprobe" and process.args == "-q" and process.args == "--" and
(process.args in ("net-pf-10", "binfmt-464c") or process.args like ("netdev-*", "block-major-*"))
) or
(
process.name == "modprobe" and process.args == "-n" and process.args == "-v" and
process.args in ("usb-storage", "dccp", "squashfs", "udf", "sctp", "cramfs", "hfsplus", "rds", "hfs", "jffs2", "freevxfs", "vfat", "overlay")
) or
process.parent.args like "/usr/share/initramfs-tools/hooks/*"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"load_module" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | eq |
| field:"process.args" kind:eq |
process.args | wildcard |
| field:"process.args" kind:wildcard value:"*.ko*" |
process.name | eq |
| field:"process_basename" kind:eq |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | in | binfmt-464c, net-pf-10 | excludes:process.args field:"process.args" value:"binfmt-464c" field:"process.args" value:"net-pf-10" |
process.args | starts_with | netdev-, block-major- | excludes:process.args field:"process.args" value:"netdev-" field:"process.args" value:"block-major-" |
process.args | eq | -- | excludes:process.args field:"process.args" value:"--" |
process.args | eq | -q | excludes:process.args field:"process.args" value:"-q" |
process.name | eq | modprobe | excludes:process.name field:"process.name" value:"modprobe" |
process.args | eq | -n | excludes:process.args field:"process.args" value:"-n" |
process.args | eq | -v | excludes:process.args field:"process.args" value:"-v" |
process.args | in | cramfs, dccp, freevxfs, hfs, hfsplus, jffs2, overlay, rds, sctp, squashfs, udf, usb-storage, vfat | excludes:process.args |
process.parent.args | in | --auto-update, --smart-update | excludes:process.parent.args field:"process.parent.args" value:"--auto-update" field:"process.parent.args" value:"--smart-update" |
process.parent.name | starts_with | python, platform-python | excludes:process.parent.name field:"process.parent.name" value:"python" field:"process.parent.name" value:"platform-python" |
process.args | in | --dump-modversions, --showconfig | excludes:process.args field:"process.args" value:"--dump-modversions" field:"process.args" value:"--showconfig" |
process.parent.args | starts_with | /usr/share/initramfs-tools/hooks/ | excludes:process.parent.args field:"process.parent.args" value:"/usr/share/initramfs-tools/hooks/" |
process.parent.executable | in | /bin/falcoctl, /opt/cisco/amp/bin/cisco-amp-helper, /opt/commvault/Base/linux_drv, /opt/commvault/commvault/Base/linux_drv, /usr/bin/kcarectl, /usr/lib/uptrack/ksplice-apply, /usr/sbin/veeamsnap-loader, /usr/sbin/veeamworker, /usr/share/ksplice/ksplice-apply | excludes:process.parent.executable |
process.parent.executable | starts_with | /opt/ds_agent/, /opt/TrendMicro/vls_agent/, /opt/intel/oneapi/ | excludes:process.parent.executable field:"process.parent.executable" value:"/opt/ds_agent/" field:"process.parent.executable" value:"/opt/TrendMicro/vls_agent/" field:"process.parent.executable" value:"/opt/intel/oneapi/" |
process.parent.executable | wildcard | /sbin/iptables-multi*, /var/ossec/bin/wazuh-modulesd, /usr/sbin/mkinitramfs, /usr/share/initramfs-tools/hooks/lvm2, /usr/lpp/mmfs/bin/*, /opt/forticlient/*, /opt/traps/bin/*, /snap/lxd/*/sbin/lxd, /usr/sbin/xtables* | excludes:process.parent.executable |
process.working_directory | in | /opt/ds_agent, /opt/vinchin/agent, /var/opt/TrendMicro/vls_agent/am, /var/opt/ds_agent/am | excludes:process.working_directory |
Keystrokes Input Capture via PowerShell
#Identifies attempts to capture input via SetWindowsHookEx using PowerShell. Adversaries may log user keystrokes to intercept credentials or other information from the user as the user types them.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Collection |
Rule Body
[rule]
description = """
Identifies attempts to capture input via SetWindowsHookEx using PowerShell. Adversaries may log user keystrokes to
intercept credentials or other information from the user as the user types them.
"""
id = "a8311681-6a92-4daa-973a-58f509156907"
license = "Elastic License v2"
name = "Keystrokes Input Capture via PowerShell"
os_list = ["windows"]
reference = [
"https://attack.mitre.org/techniques/T1056/001/",
"https://www.elastic.co/security-labs/protecting-your-devices-from-information-theft-keylogger-protection",
]
version = "1.0.3"
query = '''
api where
process.Ext.api.name == "SetWindowsHookEx" and process.Ext.api.parameters.hook_type == "WH_KEYBOARD_LL" and
process.Ext.api.parameters.hook_module == "null" and process.name : ("powershell.exe", "pwsh.exe", "Sqlps.exe")
'''
min_endpoint_version = "8.12.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1056"
name = "Input Capture"
reference = "https://attack.mitre.org/techniques/T1056/"
[[threat.technique.subtechnique]]
id = "T1056.001"
name = "Keylogging"
reference = "https://attack.mitre.org/techniques/T1056/001/"
[threat.tactic]
id = "TA0009"
name = "Collection"
reference = "https://attack.mitre.org/tactics/TA0009/"
[internal]
min_endpoint_version = "8.12.0"
Stages and Predicates
Stage 1: api
api where
process.Ext.api.name == "SetWindowsHookEx" and process.Ext.api.parameters.hook_type == "WH_KEYBOARD_LL" and
process.Ext.api.parameters.hook_module == "null" and process.name : ("powershell.exe", "pwsh.exe", "Sqlps.exe")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
process.Ext.api.name | eq |
| field:"process.Ext.api.name" kind:eq value:"SetWindowsHookEx" |
process.Ext.api.parameters.hook_module | eq |
| field:"process.Ext.api.parameters.hook_module" kind:eq value:"null" |
process.Ext.api.parameters.hook_type | eq |
| field:"process.Ext.api.parameters.hook_type" kind:eq value:"WH_KEYBOARD_LL" |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
Linux Powershell Suspicious Child Process
#Detects when Powershell (pwsh) spawns a highly abnormal or suspicious child process. Powershell usage on Linux is rare, and leveraging Powershell to launch any of this list of suspicious utilities may indicate malicious behavior.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution |
Rule Body
[rule]
description = """
Detects when Powershell (pwsh) spawns a highly abnormal or suspicious child process. Powershell usage on Linux is rare,
and leveraging Powershell to launch any of this list of suspicious utilities may indicate malicious behavior.
"""
id = "e9731cea-c3fc-4183-a76c-9a798ae0a2b0"
license = "Elastic License v2"
name = "Linux Powershell Suspicious Child Process"
os_list = ["linux"]
version = "1.0.12"
query = '''
process where event.type == "start" and event.action == "exec" and process.parent.name == "pwsh" and
process.name like (
"nc", "ncat", "netcat", "netcat.openbsd", "netcat.traditional", "nc.openbsd", "nc.traditional", "socat", "ngrok", "ping",
"python*", "php*", "perl*", "ruby*", "lua*", "openssl", "telnet"
) and
not (
(process.name like "python*" and process.args == "azure.cli") or
process.parent.executable like~ (
"/opt/ansible*/Evaluate-STIG/powershell/pwsh", "/evaluate/Evaluate-STIG/powershell/pwsh",
"/opt/Evaluate-STIG/powershell/pwsh"
) or
process.working_directory like "/opt/azurevstsagent/agent*" or
process.args like "/home/*/.local/bin/az" or
(process.parent.args == "./vmware_ap_vcenter.global.ps1" and process.name == "ping")
)
'''
min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.type == "start" and event.action == "exec" and process.parent.name == "pwsh" and
process.name like (
"nc", "ncat", "netcat", "netcat.openbsd", "netcat.traditional", "nc.openbsd", "nc.traditional", "socat", "ngrok", "ping",
"python*", "php*", "perl*", "ruby*", "lua*", "openssl", "telnet"
) and
not (
(process.name like "python*" and process.args == "azure.cli") or
process.parent.executable like~ (
"/opt/ansible*/Evaluate-STIG/powershell/pwsh", "/evaluate/Evaluate-STIG/powershell/pwsh",
"/opt/Evaluate-STIG/powershell/pwsh"
) or
process.working_directory like "/opt/azurevstsagent/agent*" or
process.args like "/home/*/.local/bin/az" or
(process.parent.args == "./vmware_ap_vcenter.global.ps1" and process.name == "ping")
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.parent.name | eq |
| field:"parent_process_basename" kind:eq value:"pwsh" |
Exclusions
The rule actively suppresses these predicates.
M365 or Entra ID Identity Sign-in from a Suspicious Source
#This rule correlate Entra-ID or Microsoft 365 mail successful sign-in events with network security alerts by source address. Adversaries may trigger some network security alerts such as reputation or other anomalies before accessing cloud resources.
Known False Positives
- Custom network security rules that triggers on a proxy or gateway used by users to access Azure or O365.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2025/04/29"
integration = ["azure", "o365"]
maturity = "production"
updated_date = "2026/05/22"
[rule]
author = ["Elastic"]
description = """
This rule correlate Entra-ID or Microsoft 365 mail successful sign-in events with network security alerts by source address.
Adversaries may trigger some network security alerts such as reputation or other anomalies before accessing cloud
resources.
"""
false_positives = [
"""
Custom network security rules that triggers on a proxy or gateway used by users to access Azure or O365.
""",
]
from = "now-8h"
interval="1h"
language = "esql"
license = "Elastic License v2"
name = "M365 or Entra ID Identity Sign-in from a Suspicious Source"
note = """## Triage and analysis
### Investigating M365 or Entra ID Identity Sign-in from a Suspicious Source
#### Possible investigation steps
- Investiguate all the alerts associated with the source.ip.
- Verify the network security alert details associated with this source.ip.
- Verify all sign-in events associated with this source.ip.
- Consider the source IP address and geolocation for the involved user account.
- Consider the device used to sign in. Is it registered and compliant?
- Investigate other alerts associated with the user account during the past 48 hours.
- Contact the account owner and confirm whether they are aware of this activity.
- Check if this operation was approved and performed according to the organization's change management policy.
- If you suspect the account has been compromised, scope potentially compromised assets by tracking servers, services, and data accessed by the account in the last 24 hours.
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- Disable or limit the account during the investigation and response.
- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context:
- Identify the account role in the cloud environment.
- Assess the criticality of affected services and servers.
- Work with your IT team to identify and minimize the impact on users.
- Identify if the attacker is moving laterally and compromising other accounts, servers, or services.
- Identify any regulatory or legal ramifications related to this activity.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords or delete API keys as needed to revoke the attacker's access to the environment. Work with your IT teams to minimize the impact on business operations during these actions.
- Check if unauthorized new users were created, remove unauthorized new accounts, and request password resets for other IAM users.
- Consider enabling multi-factor authentication for users.
- Follow security best practices [outlined](https://docs.microsoft.com/en-us/azure/security/fundamentals/identity-management-best-practices) by Microsoft.
- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
## Setup
The Azure Fleet integration, Office 365 Logs Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
risk_score = 73
rule_id = "f0cc239b-67fa-46fc-89d4-f861753a40f5"
severity = "high"
tags = [
"Domain: Cloud",
"Domain: SaaS",
"Data Source: Azure",
"Data Source: Entra ID",
"Data Source: Entra ID Sign-in Logs",
"Data Source: Microsoft 365",
"Data Source: Microsoft 365 Audit Logs",
"Use Case: Identity and Access Audit",
"Use Case: Threat Detection",
"Tactic: Initial Access",
"Resources: Investigation Guide",
"Rule Type: Higher-Order Rule",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-o365.audit-*, logs-azure.signinlogs-*, .alerts-security.*
// filter for azure or m365 sign-in and external alerts with source.ip not null
| where to_ip(source.ip) is not null
and (data_stream.dataset in ("o365.audit", "azure.signinlogs") or kibana.alert.rule.rule_id == "eb079c62-4481-4d6e-9643-3ca499df7aaa")
and not cidr_match(
to_ip(source.ip),
"10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24", "192.0.0.0/29",
"192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24",
"192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4",
"100.64.0.0/10", "192.175.48.0/24", "198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24",
"240.0.0.0/4", "::1", "FE80::/10", "FF00::/8"
)
// capture relevant raw fields
| keep source.ip, event.action, event.outcome, data_stream.dataset, kibana.alert.rule.rule_id, event.category
// classify each source ip based on alert type
| eval
Esql.source_ip_mail_access_case = case(data_stream.dataset == "o365.audit" and event.action == "MailItemsAccessed" and event.outcome == "success", to_ip(source.ip)),
Esql.source_ip_azure_signin_case = case(data_stream.dataset == "azure.signinlogs" and event.outcome == "success", to_ip(source.ip)),
Esql.source_ip_network_alert_case = case(kibana.alert.rule.rule_id == "eb079c62-4481-4d6e-9643-3ca499df7aaa" and not data_stream.dataset in ("o365.audit", "azure.signinlogs"), to_ip(source.ip))
// aggregate by source ip
| stats
Esql.event_count = count(*),
Esql.source_ip_mail_access_case_count_distinct = count_distinct(Esql.source_ip_mail_access_case),
Esql.source_ip_azure_signin_case_count_distinct = count_distinct(Esql.source_ip_azure_signin_case),
Esql.source_ip_network_alert_case_count_distinct = count_distinct(Esql.source_ip_network_alert_case),
Esql.data_stream_dataset_count_distinct = count_distinct(data_stream.dataset),
Esql.data_stream_dataset_values = values(data_stream.dataset),
Esql.kibana_alert_rule_id_values = values(kibana.alert.rule.rule_id),
Esql.event_category_values = values(event.category)
by Esql.source_ip = to_ip(source.ip)
// correlation condition
| where
Esql.source_ip_network_alert_case_count_distinct > 0
and Esql.data_stream_dataset_count_distinct >= 2
and (Esql.source_ip_mail_access_case_count_distinct > 0 or Esql.source_ip_azure_signin_case_count_distinct > 0)
and Esql.event_count <= 100
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"
[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
Stages and Predicates
Stage 1: from
from logs-o365.audit-*, logs-azure.signinlogs-*, .alerts-security.*
Stage 2: where
| where to_ip(source.ip) is not null
and (data_stream.dataset in ("o365.audit", "azure.signinlogs") or kibana.alert.rule.rule_id == "eb079c62-4481-4d6e-9643-3ca499df7aaa")
and not cidr_match(
to_ip(source.ip),
"10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24", "192.0.0.0/29",
"192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24",
"192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4",
"100.64.0.0/10", "192.175.48.0/24", "198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24",
"240.0.0.0/4", "::1", "FE80::/10", "FF00::/8"
)
Stage 3: keep
| keep source.ip, event.action, event.outcome, data_stream.dataset, kibana.alert.rule.rule_id, event.category
Stage 4: eval
| eval
Esql.source_ip_mail_access_case = case(data_stream.dataset == "o365.audit" and event.action == "MailItemsAccessed" and event.outcome == "success", to_ip(source.ip)),
Esql.source_ip_azure_signin_case = case(data_stream.dataset == "azure.signinlogs" and event.outcome == "success", to_ip(source.ip)),
Esql.source_ip_network_alert_case = case(kibana.alert.rule.rule_id == "eb079c62-4481-4d6e-9643-3ca499df7aaa" and not data_stream.dataset in ("o365.audit", "azure.signinlogs"), to_ip(source.ip))
Esql.source_ip_azure_signin_case =to_ip(source.ip)Esql.source_ip_mail_access_case =to_ip(source.ip)Esql.source_ip_network_alert_case =to_ip(source.ip)Stage 5: stats
| stats
Esql.event_count = count(*),
Esql.source_ip_mail_access_case_count_distinct = count_distinct(Esql.source_ip_mail_access_case),
Esql.source_ip_azure_signin_case_count_distinct = count_distinct(Esql.source_ip_azure_signin_case),
Esql.source_ip_network_alert_case_count_distinct = count_distinct(Esql.source_ip_network_alert_case),
Esql.data_stream_dataset_count_distinct = count_distinct(data_stream.dataset),
Esql.data_stream_dataset_values = values(data_stream.dataset),
Esql.kibana_alert_rule_id_values = values(kibana.alert.rule.rule_id),
Esql.event_category_values = values(event.category)
by Esql.source_ip = to_ip(source.ip)
Stage 6: where
| where
Esql.source_ip_network_alert_case_count_distinct > 0
and Esql.data_stream_dataset_count_distinct >= 2
and (Esql.source_ip_mail_access_case_count_distinct > 0 or Esql.source_ip_azure_signin_case_count_distinct > 0)
and Esql.event_count <= 100
Indicators
These rows show field, operator, and value matches.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
to_ip(source.ip) | cidr_match | 10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.0.0.0/24, 192.0.0.0/29, 192.0.0.8/32, 192.0.0.9/32, 192.0.0.10/32, 192.0.0.170/32, 192.0.0.171/32, 192.0.2.0/24, 192.31.196.0/24, 192.52.193.0/24, 192.168.0.0/16, 192.88.99.0/24, 224.0.0.0/4, 100.64.0.0/10, 192.175.48.0/24, 198.18.0.0/15, 198.51.100.0/24, 203.0.113.0/24, 240.0.0.0/4, ::1, FE80::/10, FF00::/8 | excludes:to_ip(source.ip) |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Esql.event_count | STATS Esql.event_count = count(*) |
Esql.source_ip_mail_access_case_count_distinct | STATS Esql.source_ip_mail_access_case_count_distinct = count_distinct(Esql.source_ip_mail_access_case) |
Esql.source_ip_azure_signin_case_count_distinct | STATS Esql.source_ip_azure_signin_case_count_distinct = count_distinct(Esql.source_ip_azure_signin_case) |
Esql.source_ip_network_alert_case_count_distinct | STATS Esql.source_ip_network_alert_case_count_distinct = count_distinct(Esql.source_ip_network_alert_case) |
Esql.data_stream_dataset_count_distinct | STATS Esql.data_stream_dataset_count_distinct = count_distinct(data_stream.dataset) |
Esql.data_stream_dataset_values | STATS Esql.data_stream_dataset_values = values(data_stream.dataset) |
Esql.kibana_alert_rule_id_values | STATS Esql.kibana_alert_rule_id_values = values(kibana.alert.rule.rule_id) |
Esql.event_category_values | STATS Esql.event_category_values = values(event.category) |
Esql.source_ip = to_ip(source.ip) | STATS BY |
M365 Threat Intelligence Signal
#Identifies Microsoft 365 audit logs generated for Threat Intelligence signals by Microsoft Defender for Office 365. This includes phishing and malware events, campaign-related threat detections, file-based threats in SharePoint, OneDrive, and Teams, as well as Microsoft Threat Intelligence Center (MSTIC) signals. These events provide early indicators of compromise attempts and can be correlated with other signals for threat hunting and detection.
Known False Positives
- Signals are generated by Microsoft Defender for Office 365. False-positives may occur if legitimate user activity is misclassified as a threat.
MITRE ATT&CK Coverage
Telemetry Coverage
Rule Body
[metadata]
bypass_bbr_timing = true
creation_date = "2025/08/19"
integration = ["o365"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Identifies Microsoft 365 audit logs generated for Threat Intelligence signals by Microsoft Defender for Office 365.
This includes phishing and malware events, campaign-related threat detections, file-based threats in SharePoint, OneDrive,
and Teams, as well as Microsoft Threat Intelligence Center (MSTIC) signals. These events provide early indicators of
compromise attempts and can be correlated with other signals for threat hunting and detection.
"""
false_positives = [
"""
Signals are generated by Microsoft Defender for Office 365. False-positives may occur if legitimate user activity is
misclassified as a threat.
""",
]
from = "now-9m"
index = ["filebeat-*", "logs-o365.audit-*"]
language = "kuery"
license = "Elastic License v2"
name = "M365 Threat Intelligence Signal"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating M365 Threat Intelligence Signal
Microsoft 365 Threat Intelligence leverages audit logs to monitor activities across services like Exchange Online and SharePoint. Adversaries may exploit these platforms for phishing, gaining initial access. The detection rule identifies signals from Microsoft Defender, focusing on audit logs tagged with "ThreatIntelligence," to pinpoint potential abuse, assigning a medium risk score to such events.
### Possible investigation steps
- Review the audit logs filtered by event.dataset: "o365.audit" and the relevant event.code (ThreatIntelligence, ThreatFinder, ThreatIntelligenceAtpContent, or MSTIC) to identify the specific activities flagged by the rule.
- Examine the user accounts associated with the flagged activities to determine if they have been compromised or are behaving anomalously.
- Investigate the source IP addresses and locations associated with the flagged events to identify any unusual or suspicious access patterns.
- Check for any related alerts or signals in Microsoft Defender for Office 365 that might provide additional context or corroborate the threat.
- Assess the potential impact on Exchange Online, SharePoint Online, and OneDrive for Business by reviewing any changes or access attempts to sensitive data or configurations.
- Determine if the flagged activities align with known phishing techniques (MITRE ATT&CK T1566) and assess the likelihood of initial access attempts.
### False positive analysis
- Routine administrative activities in Exchange Online or SharePoint Online may trigger audit logs tagged with "ThreatIntelligence" without indicating malicious intent. Review these logs to identify patterns of legitimate administrative actions and consider excluding them from the detection rule.
- Automated processes or third-party integrations with Microsoft 365 services can generate audit logs similar to those flagged by the rule. Identify these processes and create exceptions for known benign activities to reduce false positives.
- Frequent file sharing or collaboration activities in OneDrive for Business might be misinterpreted as potential threats. Analyze the context of these activities and exclude regular business operations from the rule to prevent unnecessary alerts.
- Regular updates or maintenance tasks performed by IT staff can appear as suspicious activities. Establish a baseline of expected behavior during these periods and adjust the detection rule to accommodate these known activities.
- User training sessions or onboarding processes may involve actions that mimic initial access tactics. Monitor these events and exclude them from the rule when they align with scheduled training or onboarding activities.
### Response and remediation
- Immediately isolate any affected accounts or systems identified in the audit logs to prevent further unauthorized access or data exfiltration.
- Conduct a thorough review of the audit logs to identify any additional suspicious activities or compromised accounts related to the Threat Intelligence signals.
- Reset passwords for compromised accounts and enforce multi-factor authentication to enhance security and prevent further unauthorized access.
- Notify relevant stakeholders, including IT security teams and management, about the incident and potential impact, ensuring alignment on response actions.
- Escalate the incident to Microsoft support if necessary, providing detailed information from the audit logs to assist in further investigation and resolution.
- Implement additional monitoring and alerting for similar threat indicators to enhance detection capabilities and prevent recurrence.
- Review and update security policies and configurations for Exchange Online, SharePoint Online, and OneDrive for Business to mitigate vulnerabilities exploited by adversaries.
"""
references = [
"https://learn.microsoft.com/en-us/purview/audit-supported-services",
"https://www.octiga.io/en-gb/insights/nist-csf-for-office-365",
"https://learn.microsoft.com/en-us/office/office-365-management-api/office-365-management-activity-api-schema",
]
risk_score = 21
rule_id = "60c814fc-7d06-11f0-b326-f661ea17fbcd"
setup = """### Additional notes
For information on troubleshooting the maximum alerts warning please refer to this [guide](https://www.elastic.co/guide/en/security/current/alerts-ui-monitor.html#troubleshoot-max-alerts).
"""
severity = "low"
tags = [
"Domain: Cloud",
"Domain: SaaS",
"Data Source: Microsoft 365",
"Data Source: Microsoft 365 Audit Logs",
"Data Source: Microsoft Defender",
"Data Source: Microsoft Defender for Office 365",
"Data Source: Microsoft Threat Intelligence",
"Use Case: Threat Detection",
"Tactic: Initial Access",
"Tactic: Execution",
"Resources: Investigation Guide",
"Rule Type: BBR",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
event.dataset: "o365.audit" and
event.code:(ThreatIntelligence or ThreatFinder or ThreatIntelligenceAtpContent or ThreatIntelligenceUrl or MSTIC or Campaign)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[rule.threat.technique.subtechnique]]
id = "T1566.001"
name = "Spearphishing Attachment"
reference = "https://attack.mitre.org/techniques/T1566/001/"
[[rule.threat.technique.subtechnique]]
id = "T1566.002"
name = "Spearphishing Link"
reference = "https://attack.mitre.org/techniques/T1566/002/"
[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1204"
name = "User Execution"
reference = "https://attack.mitre.org/techniques/T1204/"
[[rule.threat.technique.subtechnique]]
id = "T1204.001"
name = "Malicious Link"
reference = "https://attack.mitre.org/techniques/T1204/001/"
[[rule.threat.technique.subtechnique]]
id = "T1204.002"
name = "Malicious File"
reference = "https://attack.mitre.org/techniques/T1204/002/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
Stages and Predicates
Stage 1: query
event.dataset: "o365.audit" and
event.code:(ThreatIntelligence or ThreatFinder or ThreatIntelligenceAtpContent or ThreatIntelligenceUrl or MSTIC or Campaign)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.code | in |
| field:"EventID" kind:in |
event.dataset | eq |
| field:"event.dataset" kind:eq value:"o365.audit" |
Okta User Sessions Started from Different Geolocations
#Detects when a specific Okta actor has multiple sessions started from different geolocations. Adversaries may attempt to launch an attack by using a list of known usernames and passwords to gain unauthorized access to user accounts from different locations.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
- Failed Logins from Unknown or Invalid User (Kusto)
- First Occurrence of Okta User Session Started via Proxy (Elastic)
- High-Risk Admin Activity (Kusto)
- Multiple Okta Sessions Detected for a Single User (Elastic)
- Multiple Okta User Authentication Events with Same Device Token Hash (Elastic)
- New Device/Location sign-in along with critical operation (Kusto)
- Okta AiTM Session Cookie Replay (Elastic)
- Okta Login From CrowdStrike Unmanaged Device (Panther)
Rule Body
[metadata]
creation_date = "2023/11/18"
integration = ["okta"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
Detects when a specific Okta actor has multiple sessions started from different geolocations. Adversaries may attempt to
launch an attack by using a list of known usernames and passwords to gain unauthorized access to user accounts from
different locations.
"""
from = "now-30m"
interval = "15m"
language = "esql"
license = "Elastic License v2"
name = "Okta User Sessions Started from Different Geolocations"
note = """## Triage and analysis
### Investigating Okta User Sessions Started from Different Geolocations
This rule detects when a specific Okta actor has multiple sessions started from different geolocations. Adversaries may attempt to launch an attack by using a list of known usernames and passwords to gain unauthorized access to user accounts from different locations.
#### Possible investigation steps:
- Since this is an ESQL rule, the `okta.actor.alternate_id` and `okta.client.id` values can be used to pivot into the raw authentication events related to this alert.
- Identify the users involved in this action by examining the `okta.actor.id`, `okta.actor.type`, `okta.actor.alternate_id`, and `okta.actor.display_name` fields.
- Determine the device client used for these actions by analyzing `okta.client.ip`, `okta.client.user_agent.raw_user_agent`, `okta.client.zone`, `okta.client.device`, and `okta.client.id` fields.
- With Okta end users identified, review the `okta.debug_context.debug_data.dt_hash` field.
- Historical analysis should indicate if this device token hash is commonly associated with the user.
- Review the `okta.event_type` field to determine the type of authentication event that occurred.
- If the event type is `user.authentication.sso`, the user may have legitimately started a session via a proxy for security or privacy reasons.
- If the event type is `user.authentication.password`, the user may be using a proxy to access multiple accounts for password spraying.
- If the event type is `user.session.start`, the source may have attempted to establish a session via the Okta authentication API.
- Review the past activities of the actor(s) involved in this action by checking their previous actions.
- Evaluate the actions that happened just before and after this event in the `okta.event_type` field to help understand the full context of the activity.
- This may help determine the authentication and authorization actions that occurred between the user, Okta and application.
### False positive analysis:
- It is very rare that a legitimate user would have multiple sessions started from different geo-located countries in a short time frame.
### Response and remediation:
- If the user is legitimate and the authentication behavior is not suspicious based on device analysis, no action is required.
- If the user is legitimate but the authentication behavior is suspicious, consider resetting passwords for the users involves and enabling multi-factor authentication (MFA).
- If MFA is already enabled, consider resetting MFA for the users.
- If any of the users are not legitimate, consider deactivating the user's account.
- Conduct a review of Okta policies and ensure they are in accordance with security best practices.
- Check with internal IT teams to determine if the accounts involved recently had MFA reset at the request of the user.
- If so, confirm with the user this was a legitimate request.
- If so and this was not a legitimate request, consider deactivating the user's account temporarily.
- Reset passwords and reset MFA for the user.
- If this is a false positive, consider adding the `okta.debug_context.debug_data.dt_hash` field to the `exceptions` list in the rule.
- This will prevent future occurrences of this event for this device from triggering the rule.
- Alternatively adding `okta.client.ip` or a CIDR range to the `exceptions` list can prevent future occurrences of this event from triggering the rule.
- This should be done with caution as it may prevent legitimate alerts from being generated.
"""
references = [
"https://developer.okta.com/docs/reference/api/system-log/",
"https://developer.okta.com/docs/reference/api/event-types/",
"https://www.elastic.co/security-labs/testing-okta-visibility-and-detection-dorothy",
"https://sec.okta.com/articles/2023/08/cross-tenant-impersonation-prevention-and-detection",
"https://www.rezonate.io/blog/okta-logs-decoded-unveiling-identity-threats-through-threat-hunting/",
"https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security",
"https://www.elastic.co/security-labs/starter-guide-to-understanding-okta",
]
risk_score = 47
rule_id = "2e56e1bc-867a-11ee-b13e-f661ea17fbcd"
setup = "The Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.\n"
severity = "medium"
tags = [
"Use Case: Identity and Access Audit",
"Data Source: Okta",
"Tactic: Initial Access",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-okta*
| where
data_stream.dataset == "okta.system" and
(event.action like "user.authentication.*" or event.action == "user.session.start") and
okta.security_context.is_proxy != true and
okta.actor.id != "unknown" and
event.outcome == "success"
| keep
event.action,
okta.security_context.is_proxy,
okta.actor.id,
okta.actor.alternate_id,
event.outcome,
client.geo.country_name
| stats
Esql.client_geo_country_name_count_distinct = count_distinct(client.geo.country_name)
by okta.actor.id, okta.actor.alternate_id
| where
Esql.client_geo_country_name_count_distinct >= 2
| sort
Esql.client_geo_country_name_count_distinct desc
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"
[[rule.threat.technique.subtechnique]]
id = "T1078.004"
name = "Cloud Accounts"
reference = "https://attack.mitre.org/techniques/T1078/004/"
[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
Stages and Predicates
Stage 1: from
from logs-okta*
Stage 2: where
| where
data_stream.dataset == "okta.system" and
(event.action like "user.authentication.*" or event.action == "user.session.start") and
okta.security_context.is_proxy != true and
okta.actor.id != "unknown" and
event.outcome == "success"
Stage 3: keep
| keep
event.action,
okta.security_context.is_proxy,
okta.actor.id,
okta.actor.alternate_id,
event.outcome,
client.geo.country_name
Stage 4: stats
| stats
Esql.client_geo_country_name_count_distinct = count_distinct(client.geo.country_name)
by okta.actor.id, okta.actor.alternate_id
Stage 5: where
| where
Esql.client_geo_country_name_count_distinct >= 2
Stage 6: sort
| sort
Esql.client_geo_country_name_count_distinct desc
Indicators
These rows show field, operator, and value matches.
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Esql.client_geo_country_name_count_distinct | STATS Esql.client_geo_country_name_count_distinct = count_distinct(client.geo.country_name) |
okta.actor.id | STATS BY |
okta.actor.alternate_id | STATS BY |
PANW and Elastic Defend - Command and Control Correlation
#This detection correlates Palo Alto Networks (PANW) command and control events with Elastic Defend network events to identify the source process performing the network activity.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
Rule Body
[metadata]
creation_date = "2025/11/18"
integration = ["endpoint", "panw"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
This detection correlates Palo Alto Networks (PANW) command and control events with Elastic Defend network events to identify
the source process performing the network activity.
"""
from = "now-9m"
index = ["logs-endpoint.events.network-*", "logs-panw.panos-*"]
language = "eql"
license = "Elastic License v2"
name = "PANW and Elastic Defend - Command and Control Correlation"
references = [
"https://attack.mitre.org/tactics/TA0011/",
"https://www.elastic.co/docs/reference/integrations/panw",
"https://www.elastic.co/docs/reference/integrations/endpoint"
]
risk_score = 47
rule_id = "da4f56b8-9bc5-4003-a46c-d23616fbc691"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Linux",
"OS: Windows",
"OS: macOS",
"Use Case: Threat Detection",
"Tactic: Command and Control",
"Data Source: Elastic Defend",
"Data Source: PAN-OS",
"Resources: Investigation Guide",
]
type = "eql"
query = '''
sequence by source.port, source.ip, destination.ip with maxspan=1m
[network where event.module == "panw" and event.action == "c2_communication"]
[network where event.module == "endpoint" and event.action in ("disconnect_received", "connection_attempted")]
'''
note = """## Triage and analysis
### Investigating PANW and Elastic Defend - Command and Control Correlation
### Possible investigation steps
- Investigate in the Timeline feature the two events matching this correlation (PANW and Elastic Defend).
- Review the process details like command_line, privileges, global relevance and reputation.
- Assess the destination.ip reputation and global relevance.
- Review the parent process execution details like command_line, global relevance and reputation.
- Examine all network connection details performed by the process during last 48h.
- Correlate the alert with other security events or logs to identify any patterns or additional indicators of compromise related to the same process or network activity.
### False positive analysis
- Trusted system or third party processes performing network activity that looks like beaconing.
### Response and remediation
- Immediately isolate the affected system from the network to prevent further unauthorized access or data exfiltration.
- Terminate the suspicious processes and all associated children and parents.
- Implement network-level controls to block traffic to the destination.ip.
- Conduct a thorough review of the system's configuration files to identify unauthorized changes.
- Reset credentials for any accounts associated with the source machine.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if additional systems are affected.
"""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
Stages and Predicates
Ordered sequence: each step below must occur in order within 1m, correlated by destination.ip, source.ip, source.port.
Stage 1: network
[network where event.module == "panw" and event.action == "c2_communication"]
Stage 2: network
[network where event.module == "endpoint" and event.action in ("disconnect_received", "connection_attempted")]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"c2_communication" |
event.action | in |
| field:"EventType" kind:in |
event.module | eq |
| field:"event.module" kind:eq |
Persistence via WMI Standard Registry Provider
#Identifies use of the Windows Management Instrumentation StdRegProv (registry provider) to modify commonly abused registry locations for persistence.
MITRE ATT&CK Coverage
Telemetry Coverage
Rule Body
[metadata]
creation_date = "2021/03/15"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/05/03"
[rule]
author = ["Elastic"]
description = """
Identifies use of the Windows Management Instrumentation StdRegProv (registry provider) to modify commonly abused
registry locations for persistence.
"""
from = "now-9m"
index = ["logs-endpoint.events.registry-*", "endgame-*"]
language = "eql"
license = "Elastic License v2"
name = "Persistence via WMI Standard Registry Provider"
references = [
"https://learn.microsoft.com/en-us/previous-versions/windows/desktop/regprov/stdregprov",
"https://www.elastic.co/security-labs/hunting-for-persistence-using-elastic-security-part-1",
]
risk_score = 73
rule_id = "70d12c9c-0dbd-4a1a-bc44-1467502c9cf6"
severity = "high"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
registry where host.os.type == "windows" and event.type == "change" and
registry.data.strings != null and process.name : "WmiPrvSe.exe" and
registry.path : (
"HKEY_USERS\\*\\SOFTWARE\\Microsoft\\Command Processor\\Autorun",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\*",
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\*",
"HKLM\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run\\*",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run\\*",
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run\\*",
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\*",
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\\*",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\*",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\\*",
"HKLM\\SYSTEM\\*ControlSet*\\Services\\*\\ServiceDLL",
"HKLM\\SYSTEM\\*ControlSet*\\Services\\*\\ImagePath",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Shell\\*",
"HKEY_USERS\\*\\Environment\\UserInitMprLogonScript",
"HKEY_USERS\\*\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows\\Load",
"HKEY_USERS\\*\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Shell",
"HKEY_USERS\\*\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\Shell",
"HKEY_USERS\\*\\SOFTWARE\\Policies\\Microsoft\\Windows\\System\\Scripts\\Logoff\\Script",
"HKEY_USERS\\*\\SOFTWARE\\Policies\\Microsoft\\Windows\\System\\Scripts\\Logon\\Script",
"HKEY_USERS\\*\\SOFTWARE\\Policies\\Microsoft\\Windows\\System\\Scripts\\Shutdown\\Script",
"HKEY_USERS\\*\\SOFTWARE\\Policies\\Microsoft\\Windows\\System\\Scripts\\Startup\\Script",
"HKEY_USERS\\*\\SOFTWARE\\Microsoft\\Ctf\\LangBarAddin\\*\\FilePath",
"HKEY_USERS\\*\\SOFTWARE\\Microsoft\\Internet Explorer\\Extensions\\*\\Exec",
"HKEY_USERS\\*\\SOFTWARE\\Microsoft\\Internet Explorer\\Extensions\\*\\Script",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Microsoft\\Command Processor\\Autorun",
"\\REGISTRY\\USER\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\*",
"\\REGISTRY\\MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\*",
"\\REGISTRY\\MACHINE\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run\\*",
"\\REGISTRY\\USER\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run\\*",
"\\REGISTRY\\MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run\\*",
"\\REGISTRY\\MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\*",
"\\REGISTRY\\MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\\*",
"\\REGISTRY\\USER\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\*",
"\\REGISTRY\\USER\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\\*",
"\\REGISTRY\\MACHINE\\SYSTEM\\*ControlSet*\\Services\\*\\ServiceDLL",
"\\REGISTRY\\MACHINE\\SYSTEM\\*ControlSet*\\Services\\*\\ImagePath",
"\\REGISTRY\\USER\\*\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Shell\\*",
"\\REGISTRY\\USER\\*\\Environment\\UserInitMprLogonScript",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows\\Load",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Shell",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\Shell",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Policies\\Microsoft\\Windows\\System\\Scripts\\Logoff\\Script",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Policies\\Microsoft\\Windows\\System\\Scripts\\Logon\\Script",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Policies\\Microsoft\\Windows\\System\\Scripts\\Shutdown\\Script",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Policies\\Microsoft\\Windows\\System\\Scripts\\Startup\\Script",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Microsoft\\Ctf\\LangBarAddin\\*\\FilePath",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Microsoft\\Internet Explorer\\Extensions\\*\\Exec",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Microsoft\\Internet Explorer\\Extensions\\*\\Script"
)
'''
note = """## Triage and analysis
### Investigating Persistence via WMI Standard Registry Provider
#### Possible investigation steps
- Which StdRegProv-backed persistence value changed, and what will it run?
- Why: StdRegProv can set logon and service ASEPs through "WmiPrvSe.exe" without a child process from the requester; registry value data is the payload clue.
- Focus: `registry.path`, `registry.value`, `registry.data.type`, and `registry.data.strings`.
- Implication: escalate when machine-wide Run/RunOnce, Winlogon shell, policy script, "ServiceDLL", or "ImagePath" values launch user-writable, share-hosted, script-host, shell-replacement, or unusual service content; lower suspicion only when the exact value and data match a recognized WMI-based deployment, configuration, or test workflow.
- Who is the logical requester behind the WMI provider host?
- Why: `process.executable` usually identifies the provider host; effective process fields can identify the StdRegProv requester.
- Focus: `Effective_process.executable`, `Effective_process.name`, `Effective_process.entity_id`, `process.executable`, and `process.entity_id`.
- Hint: do not clear on the Microsoft-signed provider host alone; attacker and admin tooling can both route registry writes through "WmiPrvSe.exe".
- Implication: escalate when the requester is blank with suspicious value data, or is a script host, user-writable binary, Office/browser descendant, or unexpected remote administration tool; lower suspicion when requester path and name match the management or deployment component that owns the value.
- Does the launch and session context fit the expected WMI workflow?
- Focus: `process.command_line`, `process.parent.executable`, `process.parent.command_line`, `process.Ext.session_info.logon_type`, and `user.id`.
- Implication: escalate when WMI registry writes occur under an unexpected user, service, remote, or parent context; lower suspicion when parent chain, session type, and user scope match the same recognized management or validation workflow.
- Did the payload referenced by the modified value execute?
- Focus: same-host process starts after `@timestamp` where `process.command_line` matches the payload from `registry.data.strings`. $investigate_1
- Hint: empty results do not prove non-execution; quoting, environment expansion, or arguments may require manual parsing.
- Implication: escalate when the payload launches after the WMI-backed registry change, especially from user-writable, share-hosted, service, shell, or script paths; keep unresolved when value data cannot be matched directly.
- Did the same requester cluster additional persistence changes on this host?
- Why: clustered ASEP writes separate one managed configuration change from service-plus-logon fallback persistence.
- Focus: same-host registry changes by `Effective_process.entity_id`, or `process.entity_id` when the effective requester is blank, reviewing `registry.path`, `registry.value`, and `registry.data.strings`. $investigate_0
- Implication: escalate when the same requester changes multiple ASEPs, service values, shell values, or policy scripts in one timeline; lower suspicion when activity is limited to one exact value with data matching the recognized workflow.
- If local evidence remains suspicious or unresolved, does the requester or host recur in recent alerts?
- Focus: recent alerts for `Effective_process.executable`. $investigate_2
- Hint: run the host alert view only after the registry target, requester, session, or same-host registry cluster remains suspicious or unresolved. $investigate_3
- Implication: broaden scope when the requester path or host shows repeated WMI abuse, persistence changes, or related execution alerts; keep local when recurrence is absent and local evidence supports a recognized workflow.
- Escalate for unrecognized or blank requester with suspicious value data, unexpected remote/service context, clustered ASEP changes, execution, or alert recurrence; close only when modified ASEP, value data, requester, process/session context, cluster, and recurrence evidence bind one recognized management or test workflow with no contradictory registry data; preserve evidence and escalate if mixed or incomplete.
### False positive analysis
- Configuration managers, endpoint-management agents, installers, and hardening baselines can use StdRegProv to set Run keys, policy scripts, or service values. Confirm `Effective_process.executable`, `Effective_process.name`, parent context, registry path/value/data, and host or user scope converge on the same workflow. Use change records, owner confirmation, or tool inventory when available; otherwise require the same requester path, modified ASEP, and registry data pattern to recur across prior alerts from this rule on the same managed host cohort.
- Authorized security testing or detection validation can write persistence values through StdRegProv. Confirm the expected requester, exact value, value data, parsed payload path, test scope, and engagement records when available. Without records, require recurrence only on known test assets and no appearance on unrelated production hosts. Do not exception on `process.name`, "WmiPrvSe.exe", or a broad ASEP family alone.
### Response and remediation
- If confirmed benign:
- Reverse temporary containment and document the requester identity, exact registry value and data, host or user scope, and the recurrence or records that proved the management or test workflow. Build exceptions from that minimum pattern, not from "WmiPrvSe.exe", `process.name`, or a broad registry key alone.
- If suspicious but unconfirmed:
- Preserve the alert event, exact registry value and data, effective requester identifiers, parsed payload path from the value data, and same-requester registry timeline before changing host state.
- Apply reversible containment tied to the evidence, such as disabling the exact Run, policy, shell, or service value, blocking the requester path, or increasing monitoring on the affected host. Use host isolation only when host criticality allows it and the registry or requester evidence shows active persistence risk.
- If confirmed malicious:
- Isolate the host after preserving the registry evidence, requester identifiers, parsed payload paths, and same-requester registry changes that established malicious activity; contain the affected account only when process or session evidence supports account misuse.
- Terminate the requester process only after recording the relevant entity or PID, then remove the malicious Run key, shell value, policy script, "ServiceDLL", or "ImagePath" change, restore the ASEP to known-good state, and remove only the payloads identified from the investigation.
- Review other hosts for the same requester path or registry pattern before deleting artifacts that may be needed for scoping.
- Post-incident hardening:
- Restrict unnecessary WMI and remote administration access, monitor WMI-hosted writes to high-value ASEPs, keep endpoint process and registry telemetry enabled, and document any visibility gaps surfaced during triage.
"""
setup = """## Setup
This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
Setup instructions: https://ela.st/install-elastic-defend
"""
[rule.investigation_fields]
field_names = [
"@timestamp",
"host.id",
"user.id",
"process.entity_id",
"process.name",
"process.executable",
"process.command_line",
"process.Ext.session_info.logon_type",
"Effective_process.entity_id",
"Effective_process.name",
"Effective_process.executable",
"registry.path",
"registry.value",
"registry.data.type",
"registry.data.strings",
]
[transform]
[[transform.investigate]]
label = "Registry changes by the same effective requester"
description = ""
providers = [
[
{ excluded = false, field = "event.category", queryType = "phrase", value = "registry", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "Effective_process.entity_id", queryType = "phrase", value = "{{Effective_process.entity_id}}", valueType = "string" }
],
[
{ excluded = false, field = "event.category", queryType = "phrase", value = "registry", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" }
]
]
relativeFrom = "now-1h"
relativeTo = "now"
[[transform.investigate]]
label = "Process starts matching the modified registry payload"
description = ""
providers = [
[
{ excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
{ excluded = false, field = "event.type", queryType = "phrase", value = "start", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
{ excluded = false, field = "process.command_line", queryType = "phrase", value = "{{registry.data.strings}}", valueType = "string" }
]
]
relativeFrom = "now"
relativeTo = "now"
[[transform.investigate]]
label = "Alerts involving the same effective requester path"
description = ""
providers = [
[
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
{ excluded = false, field = "Effective_process.executable", queryType = "phrase", value = "{{Effective_process.executable}}", valueType = "string" }
]
]
relativeFrom = "now-48h/h"
relativeTo = "now"
[[transform.investigate]]
label = "Alerts associated with the host"
description = ""
providers = [
[
{ excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
{ excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
]
]
relativeFrom = "now-48h/h"
relativeTo = "now"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[[rule.threat.technique.subtechnique]]
id = "T1543.003"
name = "Windows Service"
reference = "https://attack.mitre.org/techniques/T1543/003/"
[[rule.threat.technique]]
id = "T1547"
name = "Boot or Logon Autostart Execution"
reference = "https://attack.mitre.org/techniques/T1547/"
[[rule.threat.technique.subtechnique]]
id = "T1547.001"
name = "Registry Run Keys / Startup Folder"
reference = "https://attack.mitre.org/techniques/T1547/001/"
[[rule.threat.technique.subtechnique]]
id = "T1547.004"
name = "Winlogon Helper DLL"
reference = "https://attack.mitre.org/techniques/T1547/004/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1047"
name = "Windows Management Instrumentation"
reference = "https://attack.mitre.org/techniques/T1047/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
Stages and Predicates
Stage 1: registry
registry where host.os.type == "windows" and event.type == "change" and
registry.data.strings != null and process.name : "WmiPrvSe.exe" and
registry.path : (
"HKEY_USERS\\*\\SOFTWARE\\Microsoft\\Command Processor\\Autorun",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\*",
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\*",
"HKLM\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run\\*",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run\\*",
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run\\*",
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\*",
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\\*",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\*",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\\*",
"HKLM\\SYSTEM\\*ControlSet*\\Services\\*\\ServiceDLL",
"HKLM\\SYSTEM\\*ControlSet*\\Services\\*\\ImagePath",
"HKEY_USERS\\*\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Shell\\*",
"HKEY_USERS\\*\\Environment\\UserInitMprLogonScript",
"HKEY_USERS\\*\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows\\Load",
"HKEY_USERS\\*\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Shell",
"HKEY_USERS\\*\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\Shell",
"HKEY_USERS\\*\\SOFTWARE\\Policies\\Microsoft\\Windows\\System\\Scripts\\Logoff\\Script",
"HKEY_USERS\\*\\SOFTWARE\\Policies\\Microsoft\\Windows\\System\\Scripts\\Logon\\Script",
"HKEY_USERS\\*\\SOFTWARE\\Policies\\Microsoft\\Windows\\System\\Scripts\\Shutdown\\Script",
"HKEY_USERS\\*\\SOFTWARE\\Policies\\Microsoft\\Windows\\System\\Scripts\\Startup\\Script",
"HKEY_USERS\\*\\SOFTWARE\\Microsoft\\Ctf\\LangBarAddin\\*\\FilePath",
"HKEY_USERS\\*\\SOFTWARE\\Microsoft\\Internet Explorer\\Extensions\\*\\Exec",
"HKEY_USERS\\*\\SOFTWARE\\Microsoft\\Internet Explorer\\Extensions\\*\\Script",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Microsoft\\Command Processor\\Autorun",
"\\REGISTRY\\USER\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\*",
"\\REGISTRY\\MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\*",
"\\REGISTRY\\MACHINE\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run\\*",
"\\REGISTRY\\USER\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run\\*",
"\\REGISTRY\\MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run\\*",
"\\REGISTRY\\MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\*",
"\\REGISTRY\\MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\\*",
"\\REGISTRY\\USER\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\*",
"\\REGISTRY\\USER\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\\*",
"\\REGISTRY\\MACHINE\\SYSTEM\\*ControlSet*\\Services\\*\\ServiceDLL",
"\\REGISTRY\\MACHINE\\SYSTEM\\*ControlSet*\\Services\\*\\ImagePath",
"\\REGISTRY\\USER\\*\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Shell\\*",
"\\REGISTRY\\USER\\*\\Environment\\UserInitMprLogonScript",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows\\Load",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Shell",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\Shell",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Policies\\Microsoft\\Windows\\System\\Scripts\\Logoff\\Script",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Policies\\Microsoft\\Windows\\System\\Scripts\\Logon\\Script",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Policies\\Microsoft\\Windows\\System\\Scripts\\Shutdown\\Script",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Policies\\Microsoft\\Windows\\System\\Scripts\\Startup\\Script",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Microsoft\\Ctf\\LangBarAddin\\*\\FilePath",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Microsoft\\Internet Explorer\\Extensions\\*\\Exec",
"\\REGISTRY\\USER\\*\\SOFTWARE\\Microsoft\\Internet Explorer\\Extensions\\*\\Script"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"change" |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"WmiPrvSe.exe" |
registry.data.strings | is_not_null | field:"Details" kind:is_not_null | |
registry.path | wildcard |
| field:"TargetObject" kind:wildcard |
Potential DNS Tunneling via NsLookup
#This rule identifies a large number (15) of nslookup.exe executions with an explicit query type from the same host. This may indicate command and control activity utilizing the DNS protocol.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 1: Process creation |
| Security-Auditing | Event ID 4688: A new process has been created. |
Rule Body
[metadata]
creation_date = "2020/11/11"
integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/07/03"
[rule]
author = ["Elastic"]
description = """
This rule identifies a large number (15) of nslookup.exe executions with an explicit query type from the same host. This
may indicate command and control activity utilizing the DNS protocol.
"""
from = "now-9m"
index = [
"endgame-*",
"logs-endpoint.events.process-*",
"logs-m365_defender.event-*",
"logs-sentinel_one_cloud_funnel.*",
"logs-system.security*",
"logs-windows.forwarded*",
"logs-windows.sysmon_operational-*",
"logs-crowdstrike.fdr*",
"winlogbeat-*",
]
language = "eql"
license = "Elastic License v2"
name = "Potential DNS Tunneling via NsLookup"
note = """## Triage and analysis
### Investigating Potential DNS Tunneling via NsLookup
Attackers can abuse existing network rules that allow DNS communication with external resources to use the protocol as their command and control and/or exfiltration channel.
DNS queries can be used to infiltrate data such as commands to be run, malicious files, etc., and also for exfiltration, since queries can be used to send data to the attacker-controlled DNS server. This process is commonly known as DNS tunneling.
More information on how tunneling works and how it can be abused can be found on [Palo Alto Unit42 Research](https://unit42.paloaltonetworks.com/dns-tunneling-how-dns-can-be-abused-by-malicious-actors).
#### Possible investigation steps
- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Inspect the DNS query and identify the information sent.
- Extract this communication's indicators of compromise (IoCs) and use traffic logs to search for other potentially compromised hosts.
### False positive analysis
- This mechanism can be used legitimately. If the parent process is trusted and the data sent is not sensitive nor command and control related, this alert can be closed.
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- Immediately block the identified indicators of compromise (IoCs).
- Implement any temporary network rules, procedures, and segmentation required to contain the attack.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Update firewall rules to be more restrictive.
- Reimage the host operating system or restore the compromised files to clean versions.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
setup = """## Setup
This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
Setup instructions: https://ela.st/install-elastic-defend
### Additional data sources
This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
- [Microsoft Defender XDR](https://ela.st/m365-defender)
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
- [Windows Process Creation Logs](https://ela.st/audit-process-creation)
- [CrowdStrike](https://ela.st/crowdstrike-integration)
"""
references = ["https://unit42.paloaltonetworks.com/dns-tunneling-in-the-wild-overview-of-oilrigs-dns-tunneling/"]
risk_score = 47
rule_id = "3a59fc81-99d3-47ea-8cd6-d48d561fca20"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Command and Control",
"Resources: Investigation Guide",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Data Source: Windows Security Event Logs",
"Data Source: Microsoft Defender XDR",
"Data Source: SentinelOne",
"Data Source: Sysmon",
"Data Source: Crowdstrike",
]
type = "eql"
query = '''
sequence by host.id with maxspan=5m
[process where host.os.type == "windows" and event.type == "start" and
process.name : "nslookup.exe" and process.args:("-querytype=*", "-qt=*", "-q=*", "-type=*")] with runs = 10
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[[rule.threat.technique.subtechnique]]
id = "T1071.004"
name = "DNS"
reference = "https://attack.mitre.org/techniques/T1071/004/"
[[rule.threat.technique]]
id = "T1572"
name = "Protocol Tunneling"
reference = "https://attack.mitre.org/techniques/T1572/"
[rule.threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
Stages and Predicates
Stage 1: process ×10
[process where host.os.type == "windows" and event.type == "start" and
process.name : "nslookup.exe" and process.args:("-querytype=*", "-qt=*", "-q=*", "-type=*")] with runs = 10
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"nslookup.exe" |
Potential Execution via LNK Stomping
#Identifies the overwrite of a Windows shortcut (lnk) file by processes that defaults to handle archive extraction. This could be the result of an attempt to bypass bypass Microsoft SmartScreen protection.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Execution |
Rule Body
[rule]
description = """
Identifies the overwrite of a Windows shortcut (lnk) file by processes that defaults to handle archive extraction. This
could be the result of an attempt to bypass bypass Microsoft SmartScreen protection.
"""
id = "27d1b0dc-a50c-4e7b-9ec5-961351fbe819"
license = "Elastic License v2"
name = "Potential Execution via LNK Stomping"
os_list = ["windows"]
reference = ["https://www.elastic.co/security-labs/dismantling-smart-app-control"]
version = "1.0.3"
query = '''
sequence with maxspan=3s
[file where event.action == "overwrite" and file.extension : "lnk" and
process.name : ("explorer.exe", "7zFM.exe", "WinRAR.exe", "Bandizip.exe") and file.Ext.header_bytes : "4c0000000114020000000000c0000000" and
process.thread.Ext.call_stack_summary : "ntdll.dll|*|windows.storage.dll|shell32.dll|*" and
(
file.path : ("?:\\Users\\*\\Downloads\\*.lnk", "?:\\Users\\*\\AppData\\Local\\Temp\\*.lnk") or
file.Ext.windows.zone_identifier == 3
)] by process.entity_id
[process where event.action == "start" and
process.parent.name : ("explorer.exe", "7zFM.exe", "WinRAR.exe", "Bandizip.exe") and
not process.executable : ("C:\\Program Files (x86)\\*.exe", "C:\\Program Files\\*.exe")] by process.parent.entity_id
'''
min_endpoint_version = "8.7.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[threat.technique.subtechnique]]
id = "T1566.001"
name = "Spearphishing Attachment"
reference = "https://attack.mitre.org/techniques/T1566/001/"
[[threat.technique.subtechnique]]
id = "T1566.002"
name = "Spearphishing Link"
reference = "https://attack.mitre.org/techniques/T1566/002/"
[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1204"
name = "User Execution"
reference = "https://attack.mitre.org/techniques/T1204/"
[[threat.technique.subtechnique]]
id = "T1204.001"
name = "Malicious Link"
reference = "https://attack.mitre.org/techniques/T1204/001/"
[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[internal]
min_endpoint_version = "8.7.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 3s, correlated by process.entity_id, process.parent.entity_id.
Stage 1: file
[file where event.action == "overwrite" and file.extension : "lnk" and
process.name : ("explorer.exe", "7zFM.exe", "WinRAR.exe", "Bandizip.exe") and file.Ext.header_bytes : "4c0000000114020000000000c0000000" and
process.thread.Ext.call_stack_summary : "ntdll.dll|*|windows.storage.dll|shell32.dll|*" and
(
file.path : ("?:\\Users\\*\\Downloads\\*.lnk", "?:\\Users\\*\\AppData\\Local\\Temp\\*.lnk") or
file.Ext.windows.zone_identifier == 3
)] by process.entity_id
Stage 2: process
[process where event.action == "start" and
process.parent.name : ("explorer.exe", "7zFM.exe", "WinRAR.exe", "Bandizip.exe") and
not process.executable : ("C:\\Program Files (x86)\\*.exe", "C:\\Program Files\\*.exe")] by process.parent.entity_id
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq |
file.Ext.header_bytes | wildcard |
| field:"file.Ext.header_bytes" kind:wildcard value:"4c0000000114020000000000c0000000" |
file.Ext.windows.zone_identifier | eq |
| field:"file.Ext.windows.zone_identifier" kind:eq value:"3" |
file.extension | wildcard |
| field:"file.extension" kind:wildcard value:"lnk" |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard |
process.thread.Ext.call_stack_summary | wildcard |
| field:"process.thread.Ext.call_stack_summary" kind:wildcard value:"ntdll.dll|*|windows.storage.dll|shell32.dll|*" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.executable | wildcard | C:\Program Files (x86)\*.exe, C:\Program Files\*.exe | excludes:process.executable field:"process.executable" value:"C:\Program Files (x86)\*.exe" field:"process.executable" value:"C:\Program Files\*.exe" |
Potential Network Scan Detected
#This rule identifies a potential port scan from an internal IP address. A port scan is a method utilized by attackers to systematically scan a target system for open ports, allowing them to identify available services and potential vulnerabilities. By mapping out the open ports, attackers can gather critical information to plan and execute targeted attacks, gaining unauthorized access, compromising security, and potentially leading to data breaches, unauthorized control, or further exploitation of the targeted system. This rule defines a threshold-based approach to detect connection attempts from a single internal source to a wide range of destination ports on a single destination.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Reconnaissance | |
| Discovery |
Rule Body
[metadata]
creation_date = "2023/05/17"
integration = ["network_traffic", "panw"]
maturity = "production"
updated_date = "2026/09/03"
[rule]
author = ["Elastic"]
description = """
This rule identifies a potential port scan from an internal IP address. A port scan is a method utilized by attackers to
systematically scan a target system for open ports, allowing them to identify available services and potential
vulnerabilities. By mapping out the open ports, attackers can gather critical information to plan and execute targeted
attacks, gaining unauthorized access, compromising security, and potentially leading to data breaches, unauthorized
control, or further exploitation of the targeted system. This rule defines a threshold-based approach to detect
connection attempts from a single internal source to a wide range of destination ports on a single destination.
"""
from = "now-9m"
language = "esql"
license = "Elastic License v2"
max_signals = 5
name = "Potential Network Scan Detected"
risk_score = 21
rule_id = "0171f283-ade7-4f87-9521-ac346c68cc9b"
severity = "low"
tags = [
"Domain: Network",
"Tactic: Discovery",
"Tactic: Reconnaissance",
"Use Case: Network Security Monitoring",
"Data Source: PAN-OS",
"Resources: Investigation Guide"
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-network_traffic.*, packetbeat-*, logs-panw.panos*
| mv_expand event.action
| where event.action in ("network_flow", "flow_started") and destination.port is not null and source.ip is not null and destination.ip is not null
| eval Esql.time_window = DATE_TRUNC(1min, @timestamp)
| where CIDR_MATCH(source.ip, "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16")
| eval sensitive_port = case(destination.port IN (21, 22, 23, 53, 88, 139, 389, 445, 3389, 5900, 5985, 5986, 9389), true, false)
| stats
Esql.count_distinct_destination_ports = COUNT_DISTINCT(destination.port),
Esql.count_distinct_sensitive_ports = COUNT_DISTINCT(destination.port) where sensitive_port == true,
Esql.values_destination_ports = VALUES(destination.port),
Esql.values_sensitive_ports = VALUES(destination.port) where sensitive_port == true
by Esql.time_window, destination.ip, source.ip
| where (Esql.count_distinct_destination_ports >= 50 or Esql.count_distinct_sensitive_ports >= 5)
| keep source.ip, destination.ip, Esql.*
'''
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Potential Network Scan Detected
Network scanning is a technique used to identify open ports and services on a network, often exploited by attackers to find vulnerabilities. Adversaries may use this method to map out a network's structure and identify weak points for further exploitation. The detection rule identifies suspicious activity by monitoring for multiple connection attempts from a single source to numerous destination ports, indicating a potential scan. This helps in early detection and mitigation of reconnaissance activities.
### Possible investigation steps
- Review the source IP address involved in the alert to determine if it belongs to a known or trusted entity within the organization. Check if the IP falls within the specified ranges: 10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16.
- Analyze the network flow logs to identify the specific destination ports that were targeted by the source IP. Determine if these ports are associated with critical services or known vulnerabilities.
- Correlate the detected activity with any recent changes or updates in the network infrastructure that might explain the scanning behavior, such as new devices or services being deployed.
- Investigate if there are any other alerts or logs indicating similar scanning activities from the same source IP or other IPs within the same subnet, which might suggest a coordinated scanning effort.
- Check for any historical data or past incidents involving the source IP to assess if this behavior is part of a recurring pattern or a new anomaly.
- Consult with network administrators to verify if the detected activity aligns with any scheduled network assessments or security tests that might have been conducted without prior notification.
### False positive analysis
- Internal network scanning tools used for legitimate security assessments can trigger this rule. To manage this, create exceptions for known IP addresses of authorized scanning tools.
- Automated network monitoring systems that check service availability across multiple ports may be flagged. Exclude these systems by identifying their IP addresses and adding them to an exception list.
- Load balancers and network devices that perform health checks on various services might cause false positives. Identify these devices and configure the rule to ignore their IP addresses.
- Development and testing environments where frequent port scanning is part of routine operations can be mistakenly flagged. Implement exceptions for these environments by specifying their IP ranges.
- Regularly scheduled vulnerability assessments conducted by internal security teams can appear as network scans. Document these activities and exclude the associated IPs from triggering the rule.
### Response and remediation
- Isolate the affected host: Immediately disconnect the source IP from the network to prevent further scanning or potential exploitation of identified vulnerabilities.
- Conduct a thorough investigation: Analyze the source IP's activity logs to determine if any unauthorized access or data exfiltration has occurred. This will help assess the extent of the threat.
- Update firewall rules: Implement stricter access controls to limit the number of open ports and restrict unnecessary inbound and outbound traffic from the affected IP range.
- Patch and update systems: Ensure all systems and services identified during the scan are up-to-date with the latest security patches to mitigate known vulnerabilities.
- Monitor for recurrence: Set up enhanced monitoring for the source IP and similar scanning patterns to quickly detect and respond to any future scanning attempts.
- Escalate to security operations: If the scan is part of a larger attack or if sensitive data is at risk, escalate the incident to the security operations team for further analysis and response.
- Review and enhance detection capabilities: Evaluate the effectiveness of current detection mechanisms and consider integrating additional threat intelligence sources to improve early detection of similar threats."""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1046"
name = "Network Service Discovery"
reference = "https://attack.mitre.org/techniques/T1046/"
[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1595"
name = "Active Scanning"
reference = "https://attack.mitre.org/techniques/T1595/"
[[rule.threat.technique.subtechnique]]
id = "T1595.001"
name = "Scanning IP Blocks"
reference = "https://attack.mitre.org/techniques/T1595/001/"
[rule.threat.tactic]
id = "TA0043"
name = "Reconnaissance"
reference = "https://attack.mitre.org/tactics/TA0043/"
[rule.alert_suppression]
group_by = ["source.ip", "destination.ip"]
missing_fields_strategy = "doNotSuppress"
[rule.alert_suppression.duration]
unit = "h"
value = 1
Stages and Predicates
Stage 1: from
from logs-network_traffic.*, packetbeat-*, logs-panw.panos*
Stage 2: mv_expand
| mv_expand event.action
Stage 3: where
| where event.action in ("network_flow", "flow_started") and destination.port is not null and source.ip is not null and destination.ip is not null
Stage 4: eval
| eval Esql.time_window = DATE_TRUNC(1min, @timestamp)
Stage 5: where
| where CIDR_MATCH(source.ip, "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16")
Stage 6: eval
| eval sensitive_port = case(destination.port IN (21, 22, 23, 53, 88, 139, 389, 445, 3389, 5900, 5985, 5986, 9389), true, false)
sensitive_port =destination.port IN (21, 22, 23, 53, 88, 139, 389, 445, 3389, 5900, 5985, 5986, 9389)truefalseStage 7: stats
| stats
Esql.count_distinct_destination_ports = COUNT_DISTINCT(destination.port),
Esql.count_distinct_sensitive_ports = COUNT_DISTINCT(destination.port) where sensitive_port == true,
Esql.values_destination_ports = VALUES(destination.port),
Esql.values_sensitive_ports = VALUES(destination.port) where sensitive_port == true
by Esql.time_window, destination.ip, source.ip
Stage 8: where
| where (Esql.count_distinct_destination_ports >= 50 or Esql.count_distinct_sensitive_ports >= 5)
Stage 9: keep
| keep source.ip, destination.ip, Esql.*
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Esql.count_distinct_destination_ports | ge |
| field:"Esql.count_distinct_destination_ports" kind:ge value:"50" |
Esql.count_distinct_sensitive_ports | ge |
| field:"Esql.count_distinct_sensitive_ports" kind:ge value:"5" |
destination.ip | is_not_null | field:"dest_ip" kind:is_not_null | |
destination.port | is_not_null | field:"DestinationPort" kind:is_not_null | |
event.action | in |
| field:"EventType" kind:in |
source.ip | cidr_match |
| field:"src_ip" kind:cidr_match |
source.ip | is_not_null | field:"src_ip" kind:is_not_null |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
source.ip | KEEP source.ip |
destination.ip | KEEP destination.ip |
Esql.* | KEEP Esql.* |
Potential Network Sweep Detected
#This rule identifies a potential network sweep. A network sweep is a method used by attackers to scan a target network, identifying active hosts, open ports, and available services to gather information on vulnerabilities and weaknesses. This reconnaissance helps them plan subsequent attacks and exploit potential entry points for unauthorized access, data theft, or other malicious activities. This rule defines a threshold-based approach to detect multiple connection attempts from a single host to numerous destination hosts over commonly used network services.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Reconnaissance | |
| Discovery |
Rule Body
[metadata]
creation_date = "2023/05/17"
integration = ["network_traffic", "panw"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
This rule identifies a potential network sweep. A network sweep is a method used by attackers to scan a target network,
identifying active hosts, open ports, and available services to gather information on vulnerabilities and weaknesses.
This reconnaissance helps them plan subsequent attacks and exploit potential entry points for unauthorized access, data
theft, or other malicious activities. This rule defines a threshold-based approach to detect multiple connection
attempts from a single host to numerous destination hosts over commonly used network services.
"""
from = "now-9m"
index = ["packetbeat-*", "filebeat-*", "logs-network_traffic.*", "logs-panw.panos*"]
language = "kuery"
license = "Elastic License v2"
max_signals = 5
name = "Potential Network Sweep Detected"
risk_score = 21
rule_id = "781f8746-2180-4691-890c-4c96d11ca91d"
severity = "low"
tags = [
"Domain: Network",
"Tactic: Discovery",
"Tactic: Reconnaissance",
"Use Case: Network Security Monitoring",
"Data Source: PAN-OS",
"Resources: Investigation Guide"
]
timestamp_override = "event.ingested"
type = "threshold"
query = '''
event.action:(network_flow or flow_started) and destination.port:(21 or 22 or 23 or 25 or 139 or 445 or 3389 or 5985 or 5986) and
source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)
'''
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Potential Network Sweep Detected
Network sweeps are reconnaissance techniques where attackers scan networks to identify active hosts and services, often targeting common ports. This activity helps adversaries map out network vulnerabilities for future exploitation. The detection rule identifies such sweeps by monitoring connection attempts from a single source to multiple destinations on key ports, flagging potential reconnaissance activities for further investigation.
### Possible investigation steps
- Review the source IP address to determine if it belongs to a known or trusted entity within the network, focusing on the private IP ranges specified in the query (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16).
- Analyze the destination IP addresses to identify any patterns or commonalities, such as specific subnets or devices, that could indicate targeted reconnaissance.
- Check historical logs for previous connection attempts from the same source IP to see if there is a pattern of repeated scanning behavior or if this is an isolated incident.
- Investigate the specific ports targeted (21, 22, 23, 25, 139, 445, 3389, 5985, 5986) to determine if they are associated with critical services or known vulnerabilities within the network.
- Correlate the detected activity with any recent changes or incidents in the network environment that might explain the behavior, such as new device deployments or configuration changes.
- Consult threat intelligence sources to determine if the source IP or similar scanning patterns have been associated with known threat actors or campaigns.
### False positive analysis
- Internal network scans by IT teams can trigger the rule. Regularly scheduled scans for security assessments should be documented and their source IPs added to an exception list to prevent false alerts.
- Automated monitoring tools that check network health might cause false positives. Identify these tools and exclude their IP addresses from the rule to avoid unnecessary alerts.
- Load balancers or network devices that perform health checks across multiple hosts can be mistaken for network sweeps. Exclude these devices by adding their IPs to a whitelist.
- Development or testing environments where multiple connections are made for legitimate purposes can trigger the rule. Ensure these environments are recognized and their IP ranges are excluded from monitoring.
- Misconfigured devices that repeatedly attempt to connect to multiple hosts can appear as network sweeps. Investigate and correct the configuration, then exclude these devices if necessary.
### Response and remediation
- Isolate the source IP: Immediately isolate the source IP address identified in the alert from the network to prevent further reconnaissance or potential exploitation of identified vulnerabilities.
- Block suspicious ports: Implement firewall rules to block incoming and outgoing traffic on the commonly targeted ports (21, 22, 23, 25, 139, 445, 3389, 5985, 5986) from the source IP to mitigate further scanning attempts.
- Conduct a network-wide scan: Perform a comprehensive scan of the network to identify any unauthorized access or changes that may have occurred as a result of the network sweep.
- Review and update access controls: Ensure that access controls and permissions are appropriately configured to limit exposure of critical services and sensitive data.
- Monitor for recurrence: Set up enhanced monitoring and alerting for any future connection attempts from the source IP or similar patterns of network sweep activity.
- Escalate to security operations: Notify the security operations team to conduct a deeper investigation into the source of the network sweep and assess any potential threats or breaches.
- Document and report: Record all findings, actions taken, and lessons learned in an incident report to inform future response strategies and improve network defenses."""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1018"
name = "Remote System Discovery"
reference = "https://attack.mitre.org/techniques/T1018/"
[[rule.threat.technique]]
id = "T1046"
name = "Network Service Discovery"
reference = "https://attack.mitre.org/techniques/T1046/"
[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1595"
name = "Active Scanning"
reference = "https://attack.mitre.org/techniques/T1595/"
[[rule.threat.technique.subtechnique]]
id = "T1595.001"
name = "Scanning IP Blocks"
reference = "https://attack.mitre.org/techniques/T1595/001/"
[rule.threat.tactic]
id = "TA0043"
name = "Reconnaissance"
reference = "https://attack.mitre.org/tactics/TA0043/"
[rule.threshold]
field = ["source.ip"]
value = 1
[[rule.threshold.cardinality]]
field = "destination.ip"
value = 100
Stages and Predicates
Stage 1: query
event.action:(network_flow or flow_started) and destination.port:(21 or 22 or 23 or 25 or 139 or 445 or 3389 or 5985 or 5986) and
source.ip:(10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
destination.port | in |
| field:"DestinationPort" kind:in |
event.action | in |
| field:"EventType" kind:in |
source.ip | in |
| field:"src_ip" kind:in |
Potential Password Spraying Attack via SSH
#This rule detects potential password spraying attacks via SSH by identifying multiple failed login attempts from a single source IP address targeting various user accounts within a short time frame. Password spraying is a technique where an attacker attempts to gain unauthorized access by trying a few commonly used passwords against many different accounts, rather than targeting a single account with multiple password attempts.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Rule Body
[metadata]
creation_date = "2025/12/24"
integration = ["system"]
maturity = "production"
updated_date = "2026/04/10"
[rule]
author = ["Elastic"]
description = """
This rule detects potential password spraying attacks via SSH by identifying multiple failed login
attempts from a single source IP address targeting various user accounts within a short time frame.
Password spraying is a technique where an attacker attempts to gain unauthorized access by trying a
few commonly used passwords against many different accounts, rather than targeting a single account
with multiple password attempts.
"""
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Potential Password Spraying Attack via SSH"
note = """ ## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Potential Password Spraying Attack via SSH
This rule flags bursts of failed SSH logins coming from the same network origin against many different Linux accounts within a short window, indicating password spraying that can precede account compromise. It matters because attackers try a small set of common passwords across broad user lists to evade lockouts and find one weak credential. A typical pattern is an external VPS rapidly trying passwords like “Welcome123” or “Spring2024!” against 30+ usernames (e.g., admin, test, ubuntu, devops) over five minutes via SSH on a single server.
### Possible investigation steps
- Check for any successful SSH authentications from the same source IP within a short window around the failures and, if found, pivot to session details such as interactive TTY use, sudo activity, and modifications like authorized_keys updates.
- Enrich the source IP with geolocation, ASN, reputation, and cloud-provider attribution and verify whether it is observed attempting SSH across multiple hosts to confirm a broad spray pattern.
- Compare the attempted usernames against your directory to identify valid and privileged or service accounts and confirm whether lockouts, password resets, or MFA challenges were triggered.
- Determine if the affected host is internet-exposed and which port SSH is reachable on, then review current SSH authentication settings (password vs key-based, PAM/MFA) to assess risk of compromise.
- Correlate the source IP with approved scanners, bastion hosts, or change tickets and maintenance windows to quickly rule out sanctioned testing or misconfigured monitoring.
### False positive analysis
- A misconfigured internal automation or admin script on a management or jump host sequentially attempts SSH to many accounts with an outdated password, producing more than 10 distinct usernames and at least 30 failures from a single source IP within five minutes.
- Legitimate users behind a shared NAT or bastion host concurrently attempt SSH with expired credentials during a password rotation or temporary authentication issue, making failures across many distinct usernames appear to come from one IP.
### Response and remediation
- Immediately block the spraying source IP(s) at host firewalls (iptables/nftables) and edge controls, and temporarily restrict SSH (port 22) to approved bastion/jump host CIDRs only.
- If any login succeeded or an sshd session from the same IP is active, terminate it, remove any newly added ~/.ssh/authorized_keys entries, and force password resets with MFA for the targeted users.
- Before restoring normal access, verify no persistence by checking for changes to /etc/ssh/sshd_config, sudoers, or cron jobs and reviewing /var/log/auth.log and lastlog for anomalies, then re-enable only required accounts.
- Escalate to incident response if privileged or service accounts were targeted, the spray spanned multiple servers, or there is evidence of sudo activity, file changes under /root or /etc, or a successful login, and preserve auth logs, bash histories, and firewall block artifacts.
- Harden SSH by disabling PasswordAuthentication, enforcing key-based auth with PAM MFA, setting conservative MaxAuthTries and LoginGraceTime, enabling fail2ban or equivalent bans, and restricting access via AllowUsers/AllowGroups and security group rules.
"""
risk_score = 21
rule_id = "9e81b1fd-e9fb-49a7-8ebe-0d1a14090142"
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Credential Access",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-system.auth-* metadata _id, _index, _version
// Create 5-minute time buckets
| eval Esql.time_window_date_trunc = date_trunc(5 minutes, @timestamp)
// Ensure event.action values in a list are expanded
| mv_expand event.action
| where
event.category == "authentication" and event.action in ("ssh_login", "user_login") and event.outcome == "failure" and
source.ip is not null
// Keep relevant fields
| keep
@timestamp,
_id,
_index,
_version,
event.category,
event.action,
event.outcome,
source.ip,
process.name,
user.name,
data_stream.dataset,
data_stream.namespace,
agent.id,
user.id,
Esql.time_window_date_trunc
| stats
Esql.event_count = count(*),
Esql.user_name_count_distinct = count_distinct(user.name),
Esql.user_name_values = values(user.name),
Esql.process_name_values = values(process.name),
Esql.data_stream_dataset_values = values(data_stream.dataset),
Esql.data_stream_namespace_values = values(data_stream.namespace)
by Esql.time_window_date_trunc, source.ip
| where Esql.user_name_count_distinct > 10 and Esql.event_count >= 30
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1110"
name = "Brute Force"
reference = "https://attack.mitre.org/techniques/T1110/"
[[rule.threat.technique.subtechnique]]
id = "T1110.001"
name = "Password Guessing"
reference = "https://attack.mitre.org/techniques/T1110/001/"
[[rule.threat.technique.subtechnique]]
id = "T1110.003"
name = "Password Spraying"
reference = "https://attack.mitre.org/techniques/T1110/003/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
Stages and Predicates
Stage 1: from
from logs-system.auth-* metadata _id, _index, _version
Stage 2: eval
| eval Esql.time_window_date_trunc = date_trunc(5 minutes, @timestamp)
Stage 3: mv_expand
| mv_expand event.action
Stage 4: where
| where
event.category == "authentication" and event.action in ("ssh_login", "user_login") and event.outcome == "failure" and
source.ip is not null
Stage 5: keep
| keep
@timestamp,
_id,
_index,
_version,
event.category,
event.action,
event.outcome,
source.ip,
process.name,
user.name,
data_stream.dataset,
data_stream.namespace,
agent.id,
user.id,
Esql.time_window_date_trunc
Stage 6: stats
| stats
Esql.event_count = count(*),
Esql.user_name_count_distinct = count_distinct(user.name),
Esql.user_name_values = values(user.name),
Esql.process_name_values = values(process.name),
Esql.data_stream_dataset_values = values(data_stream.dataset),
Esql.data_stream_namespace_values = values(data_stream.namespace)
by Esql.time_window_date_trunc, source.ip
Stage 7: where
| where Esql.user_name_count_distinct > 10 and Esql.event_count >= 30
Indicators
These rows show field, operator, and value matches.
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Esql.event_count | STATS Esql.event_count = count(*) |
Esql.user_name_count_distinct | STATS Esql.user_name_count_distinct = count_distinct(user.name) |
Esql.user_name_values | STATS Esql.user_name_values = values(user.name) |
Esql.process_name_values | STATS Esql.process_name_values = values(process.name) |
Esql.data_stream_dataset_values | STATS Esql.data_stream_dataset_values = values(data_stream.dataset) |
Esql.data_stream_namespace_values | STATS Esql.data_stream_namespace_values = values(data_stream.namespace) |
Esql.time_window_date_trunc | STATS BY |
source.ip | STATS BY |
Potential Veeam Credential Access Command
#Identifies commands that can access and decrypt Veeam credentials stored in MSSQL databases. Attackers can use Veeam Credentials to target backups as part of destructive operations such as Ransomware attacks.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Credential Access | |
| Collection |
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 1: Process creation |
| Security-Auditing | Event ID 4688: A new process has been created. |
Rule Body
[metadata]
creation_date = "2024/03/14"
integration = ["windows", "endpoint", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/05/04"
[rule]
author = ["Elastic"]
description = """
Identifies commands that can access and decrypt Veeam credentials stored in MSSQL databases. Attackers can use Veeam
Credentials to target backups as part of destructive operations such as Ransomware attacks.
"""
from = "now-9m"
index = [
"endgame-*",
"logs-crowdstrike.fdr*",
"logs-endpoint.events.process-*",
"logs-m365_defender.event-*",
"logs-sentinel_one_cloud_funnel.*",
"logs-system.security*",
"logs-windows.forwarded*",
"logs-windows.sysmon_operational-*",
"winlogbeat-*",
]
language = "eql"
license = "Elastic License v2"
name = "Potential Veeam Credential Access Command"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Potential Veeam Credential Access Command
Veeam credentials stored in MSSQL databases are crucial for managing backup operations. Attackers may exploit tools like `sqlcmd.exe` or PowerShell commands to access and decrypt these credentials, potentially leading to data breaches or ransomware attacks. The detection rule identifies suspicious command executions targeting Veeam credentials, focusing on specific processes and arguments, to alert analysts of potential credential access attempts.
### Possible investigation steps
- Review the process execution details to confirm the presence of sqlcmd.exe or PowerShell commands like Invoke-Sqlcmd, focusing on the process.name and process.args fields.
- Examine the command line arguments for any references to [VeeamBackup].[dbo].[Credentials] to determine if there was an attempt to access or decrypt Veeam credentials.
- Check the user account associated with the process execution to assess if it is a legitimate user or potentially compromised.
- Investigate the source host for any signs of unauthorized access or suspicious activity, such as unusual login times or failed login attempts.
- Correlate the alert with other security events or logs from data sources like Microsoft Defender XDR or Sysmon to identify any related malicious activities or patterns.
- Assess the risk and impact by determining if any Veeam credentials were successfully accessed or exfiltrated, and evaluate the potential for data breaches or ransomware attacks.
### False positive analysis
- Routine database maintenance tasks may trigger the rule if they involve accessing Veeam credentials for legitimate purposes. To manage this, identify and document regular maintenance schedules and exclude these activities from triggering alerts.
- Automated scripts used for backup verification or testing might use similar commands. Review and whitelist these scripts by their process names or specific arguments to prevent unnecessary alerts.
- Internal security audits or compliance checks that involve credential access could be mistaken for malicious activity. Coordinate with audit teams to schedule these activities and create exceptions for known audit processes.
- Development or testing environments where Veeam credentials are accessed for non-production purposes can generate false positives. Implement environment-specific exclusions to differentiate between production and non-production activities.
- Legitimate use of PowerShell commands for database management by authorized personnel may be flagged. Maintain a list of authorized users and their typical command patterns to refine the detection rule and reduce false positives.
### Response and remediation
- Immediately isolate the affected system from the network to prevent further unauthorized access or data exfiltration.
- Terminate any suspicious processes identified by the alert, such as `sqlcmd.exe` or PowerShell commands accessing Veeam credentials.
- Change all Veeam-related credentials stored in the MSSQL database to prevent further unauthorized access using compromised credentials.
- Conduct a thorough review of recent backup operations and logs to identify any unauthorized access or modifications.
- Escalate the incident to the security operations center (SOC) for further investigation and to determine if additional systems are compromised.
- Implement enhanced monitoring on systems storing Veeam credentials to detect similar suspicious activities in the future.
- Review and update access controls and permissions for MSSQL databases to ensure only authorized personnel have access to Veeam credentials."""
references = ["https://thedfirreport.com/2021/12/13/diavol-ransomware/"]
risk_score = 47
rule_id = "b661f86d-1c23-4ce7-a59e-2edbdba28247"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Defense Evasion",
"Tactic: Credential Access",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Data Source: Windows Security Event Logs",
"Data Source: Microsoft Defender XDR",
"Data Source: Sysmon",
"Data Source: SentinelOne",
"Data Source: Crowdstrike",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "windows" and event.type == "start" and
(
(process.name : "sqlcmd.exe" or ?process.pe.original_file_name : "sqlcmd.exe") or
process.args : ("Invoke-Sqlcmd", "Invoke-SqlExecute", "Invoke-DbaQuery", "Invoke-SqlQuery")
) and
process.args : "*[VeeamBackup].[dbo].[Credentials]*"
'''
setup = """## Setup
This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
Setup instructions: https://ela.st/install-elastic-defend
### Additional data sources
This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
- [CrowdStrike](https://ela.st/crowdstrike-integration)
- [Microsoft Defender XDR](https://ela.st/m365-defender)
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
- [Windows Process Creation Logs](https://ela.st/audit-process-creation)
"""
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1003"
name = "OS Credential Dumping"
reference = "https://attack.mitre.org/techniques/T1003/"
[[rule.threat.technique]]
id = "T1555"
name = "Credentials from Password Stores"
reference = "https://attack.mitre.org/techniques/T1555/"
[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1213"
name = "Data from Information Repositories"
reference = "https://attack.mitre.org/techniques/T1213/"
[rule.threat.tactic]
id = "TA0009"
name = "Collection"
reference = "https://attack.mitre.org/tactics/TA0009/"
Stages and Predicates
Stage 1: process
process where host.os.type == "windows" and event.type == "start" and
(
(process.name : "sqlcmd.exe" or ?process.pe.original_file_name : "sqlcmd.exe") or
process.args : ("Invoke-Sqlcmd", "Invoke-SqlExecute", "Invoke-DbaQuery", "Invoke-SqlQuery")
) and
process.args : "*[VeeamBackup].[dbo].[Credentials]*"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"sqlcmd.exe" |
process.pe.original_file_name | wildcard |
| field:"OriginalFileName" kind:wildcard value:"sqlcmd.exe" |
Privilege Escalation via Named Pipe Impersonation
#Identifies a privilege escalation attempt via named pipe impersonation. An adversary may abuse this technique by utilizing a framework like Metasploit's getsystem command.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Privilege Escalation |
Rule Body
[rule]
description = """
Identifies a privilege escalation attempt via named pipe impersonation. An adversary may abuse this technique by
utilizing a framework like Metasploit's getsystem command.
"""
id = "a0265178-779d-4bc5-b3f1-abb3bcddedab"
license = "Elastic License v2"
name = "Privilege Escalation via Named Pipe Impersonation"
os_list = ["windows"]
reference = [
"https://www.ired.team/offensive-security/privilege-escalation/windows-namedpipes-privilege-escalation",
]
version = "1.0.35"
query = '''
process where event.action == "start" and
(process.name in~ ("cmd.exe", "powershell.exe", "sc.exe", "schtasks.exe") or
process.pe.original_file_name in ("Cmd.Exe", "PowerShell.EXE", "sc.exe", "schtasks.exe")) and
process.command_line : "*echo*>*\\\\.\\pipe\\*" and
not process.parent.executable like
("?:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
"?:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
"?:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe")
'''
min_endpoint_version = "7.15.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1134"
name = "Access Token Manipulation"
reference = "https://attack.mitre.org/techniques/T1134/"
[threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Stage 1: process
process where event.action == "start" and
(process.name in~ ("cmd.exe", "powershell.exe", "sc.exe", "schtasks.exe") or
process.pe.original_file_name in ("Cmd.Exe", "PowerShell.EXE", "sc.exe", "schtasks.exe")) and
process.command_line : "*echo*>*\\\\.\\pipe\\*" and
not process.parent.executable like
("?:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
"?:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
"?:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard value:"*echo*>*\\.\pipe\*" |
process.name | in |
| field:"process_basename" kind:in |
process.pe.original_file_name | in |
| field:"OriginalFileName" kind:in |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.parent.executable | eq | ?:\Program Files (x86)\Google\Chrome\Application\chrome.exe, ?:\Program Files\Google\Chrome\Application\chrome.exe, ?:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe | excludes:process.parent.executable field:"process.parent.executable" value:"?:\Program Files (x86)\Google\Chrome\Application\chrome.exe" field:"process.parent.executable" value:"?:\Program Files\Google\Chrome\Application\chrome.exe" field:"process.parent.executable" value:"?:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" |
Process Creation from Backed RWX Memory
#Identifies attempts to create a child process from a memory section with read, write and execute permissions and backed by a file on disk. This may indicate image hollowing or unpacking from suspicious memory sections.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule Body
[rule]
description = """
Identifies attempts to create a child process from a memory section with read, write and execute permissions and backed
by a file on disk. This may indicate image hollowing or unpacking from suspicious memory sections.
"""
id = "13dadee2-f4b8-4877-8b9c-37ce59f82432"
license = "Elastic License v2"
name = "Process Creation from Backed RWX Memory"
os_list = ["windows"]
version = "1.0.13"
query = '''
sequence with maxspan=1m
[process where event.action == "start" and
(
process.name : ("rundll32.exe", "regsvr32.exe") or
(process.Ext.relative_file_creation_time <= 300 and not process.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*") and
process.executable : ("?:\\Users\\*", "?:\\ProgramData\\*")) or
(process.Ext.device.product_id : ("Virtual DVD-ROM", "Virtual Disk","USB *") and not process.executable : "C:\\*") or
process.executable : ("?:\\Users\\Public\\*",
"?:\\Users\\*\\Downloads\\*",
"?:\\Users\\*\\AppData\\Local\\Temp\\7z*\\",
"?:\\Users\\*\\AppData\\Local\\Temp\\Rar$*\\*",
"?:\\Users\\*\\AppData\\Local\\Temp\\Temp?_*\\*",
"?:\\Users\\*\\AppData\\Local\\Temp\\BNZ.*")
) and
process.hash.sha256 != null and
not process.executable :
("?:\\Windows\\Installer\\MSI*.tmp",
"?:\\Program Files\\*.exe",
"?:\\Program Files (x86)\\*.exe",
"?:\\Users\\*\\AppData\\Local\\Temp\\_ir_sf*_temp_*\\irsetup.exe",
"?:\\Users\\*\\AppData\\Local\\Temp\\~nsuA.tmp\\*.exe",
"?:\\Users\\*\\AppData\\Local\\Temp\\INS*.tmp") and
not process.hash.sha256 :
("9ad4c8d68a26f6feb2287e9d9895358a5a560ecc34cb3649edade01b054e1dd5",
"aaa782279126c5e78dda4ab68e1d9f2da2d4b87b183b9ed24546637d25e5d3c6",
"80be4152f9bdb4631ec7f12da1dc8dae1037b340753a1552c3e4cd8dfdd05d2d",
"2cd1b00947abe2df2cba3997d7bdd5a9043ebe598987f0e9cade0aceb73f9edd",
"c15f1490506641b2e93239830d4707074d4690e947138df86a61c82a29cf4230",
"e95b57c5a9decfa6ad11b187172c61a3c480ff26c6520ae8251f97e868e3e9a6",
"805190b03fe6179269e536f3be50a2432466af2716cd931e50ffcfffb910fd9d",
"2eae330562f3eaa5d889b58cac5e7e14757cea683b03c9850cf6ca99abe557f8",
"67b2c31ad5c94d5d3a2e9380a66393551dfb6498889952e968437bca306a1eba",
"f840099459d5780f2a8f637f96b1656f84473a2bb6ddf6600aad8c9b31a797c7") and
not process.parent.thread.Ext.call_stack_summary : "*|python*.dll|*" and
not (process.code_signature.status : ("trusted", "errorExpired") and process.executable : "?:\\Users\\*\\Downloads\\*") and
not process.pe.original_file_name : "python.exe"] by process.entity_id
[process where event.action == "start" and
not process.parent.thread.Ext.call_stack_contains_unbacked == true and
process.parent.thread.Ext.call_stack_summary : "?*" and
not process.executable : "?:\\Program Files\\AutoHotkey\\UX\\AutoHotkeyUX.exe" and
not process.parent.thread.Ext.call_stack_summary : ("*Unbacked*", "*clr.dll*", "*Unknown*") and
(
_arraysearch(process.parent.thread.Ext.call_stack, $entry, $entry.protection : "RWX" and startswith~($entry.symbol_info, process.parent.executable)) or
_arraysearch(process.parent.thread.Ext.call_stack, $entry,
$entry.protection : "RWX" and $entry.symbol_info : "?:\\*" and
not $entry.symbol_info : ("?:\\Program Files*", "?:\\Windows\\*", "?:*\\isrt.dll*", "?:*\\ISSetup.dll*"))
) and
not _arraysearch(process.parent.thread.Ext.call_stack, $entry, $entry.protection : "RWX" and $entry.symbol_info : ("?:\\Windows\\*", "?:\\Program Files*", "*.exe!*", "*.exe+*")) and
not process.parent.thread.Ext.call_stack_summary : ("*|python*.dll|*", "*|isrt.dll*", "|issetup.dll*") and
not _arraysearch(process.parent.thread.Ext.call_stack, $entry, $entry.callsite_trailing_bytes : ("85c00f8?a6000000*", "8d45f253508*", "8b4df464890d*", "6a006890751*"))
] by process.parent.entity_id
'''
min_endpoint_version = "8.8.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"
[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[internal]
min_endpoint_version = "8.8.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 1m, correlated by process.entity_id, process.parent.entity_id.
Stage 1: process
[process where event.action == "start" and
(
process.name : ("rundll32.exe", "regsvr32.exe") or
(process.Ext.relative_file_creation_time <= 300 and not process.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*") and
process.executable : ("?:\\Users\\*", "?:\\ProgramData\\*")) or
(process.Ext.device.product_id : ("Virtual DVD-ROM", "Virtual Disk","USB *") and not process.executable : "C:\\*") or
process.executable : ("?:\\Users\\Public\\*",
"?:\\Users\\*\\Downloads\\*",
"?:\\Users\\*\\AppData\\Local\\Temp\\7z*\\",
"?:\\Users\\*\\AppData\\Local\\Temp\\Rar$*\\*",
"?:\\Users\\*\\AppData\\Local\\Temp\\Temp?_*\\*",
"?:\\Users\\*\\AppData\\Local\\Temp\\BNZ.*")
) and
process.hash.sha256 != null and
not process.executable :
("?:\\Windows\\Installer\\MSI*.tmp",
"?:\\Program Files\\*.exe",
"?:\\Program Files (x86)\\*.exe",
"?:\\Users\\*\\AppData\\Local\\Temp\\_ir_sf*_temp_*\\irsetup.exe",
"?:\\Users\\*\\AppData\\Local\\Temp\\~nsuA.tmp\\*.exe",
"?:\\Users\\*\\AppData\\Local\\Temp\\INS*.tmp") and
not process.hash.sha256 :
("9ad4c8d68a26f6feb2287e9d9895358a5a560ecc34cb3649edade01b054e1dd5",
"aaa782279126c5e78dda4ab68e1d9f2da2d4b87b183b9ed24546637d25e5d3c6",
"80be4152f9bdb4631ec7f12da1dc8dae1037b340753a1552c3e4cd8dfdd05d2d",
"2cd1b00947abe2df2cba3997d7bdd5a9043ebe598987f0e9cade0aceb73f9edd",
"c15f1490506641b2e93239830d4707074d4690e947138df86a61c82a29cf4230",
"e95b57c5a9decfa6ad11b187172c61a3c480ff26c6520ae8251f97e868e3e9a6",
"805190b03fe6179269e536f3be50a2432466af2716cd931e50ffcfffb910fd9d",
"2eae330562f3eaa5d889b58cac5e7e14757cea683b03c9850cf6ca99abe557f8",
"67b2c31ad5c94d5d3a2e9380a66393551dfb6498889952e968437bca306a1eba",
"f840099459d5780f2a8f637f96b1656f84473a2bb6ddf6600aad8c9b31a797c7") and
not process.parent.thread.Ext.call_stack_summary : "*|python*.dll|*" and
not (process.code_signature.status : ("trusted", "errorExpired") and process.executable : "?:\\Users\\*\\Downloads\\*") and
not process.pe.original_file_name : "python.exe"] by process.entity_id
Stage 2: process
[process where event.action == "start" and
not process.parent.thread.Ext.call_stack_contains_unbacked == true and
process.parent.thread.Ext.call_stack_summary : "?*" and
not process.executable : "?:\\Program Files\\AutoHotkey\\UX\\AutoHotkeyUX.exe" and
not process.parent.thread.Ext.call_stack_summary : ("*Unbacked*", "*clr.dll*", "*Unknown*") and
(
_arraysearch(process.parent.thread.Ext.call_stack, $entry, $entry.protection : "RWX" and startswith~($entry.symbol_info, process.parent.executable)) or
_arraysearch(process.parent.thread.Ext.call_stack, $entry,
$entry.protection : "RWX" and $entry.symbol_info : "?:\\*" and
not $entry.symbol_info : ("?:\\Program Files*", "?:\\Windows\\*", "?:*\\isrt.dll*", "?:*\\ISSetup.dll*"))
) and
not _arraysearch(process.parent.thread.Ext.call_stack, $entry, $entry.protection : "RWX" and $entry.symbol_info : ("?:\\Windows\\*", "?:\\Program Files*", "*.exe!*", "*.exe+*")) and
not process.parent.thread.Ext.call_stack_summary : ("*|python*.dll|*", "*|isrt.dll*", "|issetup.dll*") and
not _arraysearch(process.parent.thread.Ext.call_stack, $entry, $entry.callsite_trailing_bytes : ("85c00f8?a6000000*", "8d45f253508*", "8b4df464890d*", "6a006890751*"))
] by process.parent.entity_id
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.Ext.device.product_id | wildcard |
| field:"process.Ext.device.product_id" kind:wildcard |
process.Ext.relative_file_creation_time | le |
| field:"process.Ext.relative_file_creation_time" kind:le value:"300" |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.hash.sha256 | is_not_null | field:"Hashes" kind:is_not_null | |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.parent.thread.Ext.call_stack_summary | wildcard |
| field:"process.parent.thread.Ext.call_stack_summary" kind:wildcard value:"?*" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.code_signature.status | eq | trusted, errorExpired | excludes:process.code_signature.status field:"process.code_signature.status" value:"trusted" field:"process.code_signature.status" value:"errorExpired" |
process.executable | wildcard | ?:\Users\*\Downloads\* | excludes:process.executable field:"process.executable" value:"?:\Users\*\Downloads\*" |
process.executable | wildcard | ?:\Windows\Installer\MSI*.tmp, ?:\Program Files\*.exe, ?:\Program Files (x86)\*.exe, ?:\Users\*\AppData\Local\Temp\_ir_sf*_temp_*\irsetup.exe, ?:\Users\*\AppData\Local\Temp\~nsuA.tmp\*.exe, ?:\Users\*\AppData\Local\Temp\INS*.tmp | excludes:process.executable |
process.hash.sha256 | eq | 9ad4c8d68a26f6feb2287e9d9895358a5a560ecc34cb3649edade01b054e1dd5, aaa782279126c5e78dda4ab68e1d9f2da2d4b87b183b9ed24546637d25e5d3c6, 80be4152f9bdb4631ec7f12da1dc8dae1037b340753a1552c3e4cd8dfdd05d2d, 2cd1b00947abe2df2cba3997d7bdd5a9043ebe598987f0e9cade0aceb73f9edd, c15f1490506641b2e93239830d4707074d4690e947138df86a61c82a29cf4230, e95b57c5a9decfa6ad11b187172c61a3c480ff26c6520ae8251f97e868e3e9a6, 805190b03fe6179269e536f3be50a2432466af2716cd931e50ffcfffb910fd9d, 2eae330562f3eaa5d889b58cac5e7e14757cea683b03c9850cf6ca99abe557f8, 67b2c31ad5c94d5d3a2e9380a66393551dfb6498889952e968437bca306a1eba, f840099459d5780f2a8f637f96b1656f84473a2bb6ddf6600aad8c9b31a797c7 | excludes:process.hash.sha256 |
process.parent.thread.Ext.call_stack_summary | wildcard | *|python*.dll|* | excludes:process.parent.thread.Ext.call_stack_summary field:"process.parent.thread.Ext.call_stack_summary" value:"*|python*.dll|*" |
process.pe.original_file_name | eq | python.exe | excludes:process.pe.original_file_name field:"process.pe.original_file_name" value:"python.exe" |
process.parent.thread.Ext.call_stack | array_any | excludes:process.parent.thread.Ext.call_stack | |
process.executable | eq | ?:\Program Files\AutoHotkey\UX\AutoHotkeyUX.exe | excludes:process.executable field:"process.executable" value:"?:\Program Files\AutoHotkey\UX\AutoHotkeyUX.exe" |
process.parent.thread.Ext.call_stack_contains_unbacked | eq | true | excludes:process.parent.thread.Ext.call_stack_contains_unbacked field:"process.parent.thread.Ext.call_stack_contains_unbacked" value:"true" |
process.parent.thread.Ext.call_stack_summary | match | Unbacked, clr.dll, Unknown | excludes:process.parent.thread.Ext.call_stack_summary field:"process.parent.thread.Ext.call_stack_summary" value:"Unbacked" field:"process.parent.thread.Ext.call_stack_summary" value:"clr.dll" field:"process.parent.thread.Ext.call_stack_summary" value:"Unknown" |
process.parent.thread.Ext.call_stack_summary | wildcard | *|python*.dll|*, *|isrt.dll*, |issetup.dll* | excludes:process.parent.thread.Ext.call_stack_summary field:"process.parent.thread.Ext.call_stack_summary" value:"*|python*.dll|*" field:"process.parent.thread.Ext.call_stack_summary" value:"*|isrt.dll*" field:"process.parent.thread.Ext.call_stack_summary" value:"|issetup.dll*" |
Sensitive File Access - System Admin Utilities
#Identifies an unusual process accessing common third party system utilities sensitive files and registries. Adversaries may search local file systems and remote file shares for files containing insecurely stored credentials.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Rule Body
[rule]
description = """
Identifies an unusual process accessing common third party system utilities sensitive files and registries. Adversaries
may search local file systems and remote file shares for files containing insecurely stored credentials.
"""
id = "949c72ee-a283-4673-afe0-7fa72bddc2f6"
license = "Elastic License v2"
name = "Sensitive File Access - System Admin Utilities"
os_list = ["windows"]
reference = ["https://github.com/GhostPack/Seatbelt", "https://github.com/AlessandroZ/LaZagne"]
version = "1.0.30"
query = '''
sequence by process.entity_id with maxspan=5m
[process where event.action == "start" and
user.id like ("S-1-5-21*", "S-1-12-*") and process.executable : "?:\\*" and
not process.executable :
(
/* third party programs common install path - requires local admin */
"?:\\Program Files\\*",
"?:\\Program Files (x86)\\*",
/*
dllhost.exe (IFileOperation like view/changing security permission of a file/folder).
explorer.exe for directory and file discovery.
SearchProtocolHost.exe is for file searches and indexing.
*/
"?:\\Windows\\explorer.exe",
"?:\\Windows\\System32\\dllhost.exe",
"?:\\Windows\\System32\\SearchProtocolHost.exe",
"?:\\Windows\\regedit.exe",
"?:\\Windows\\system32\\reg.exe",
"?:\\Windows\\System32\\userinit.exe",
"?:\\Windows\\System32\\notepad.exe",
"?:\\Windows\\System32\\Robocopy.exe",
"?:\\Windows\\System32\\cmd.exe",
/* Windows Defender */
"?:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\*\\MsMpEng.exe",
"?:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\*\\MpCopyAccelerator.exe",
"?:\\Windows\\_ScriptingFramework\\Modul\\Engine.exe",
/* lot of legit access from mounted sysadmin file shares */
"\\Device\\Mup\\*.exe") and
not (process.code_signature.subject_name :
("Martin Prikryl",
"OpenVPN Technologies, Inc.",
"TeamViewer Germany GmbH",
"Open Source Developer, Dominik Reichl",
"Tim Kosse",
"TEFINCOM S.A.",
"nordvpn s.a.") and
process.code_signature.trusted == true)
]
[any where event.category in ("registry", "file") and
event.action in ("query", "open") and
(
file.path : ("?:\\Users\\*\\AppData\\Roaming\\KeePass\\KeePass.config.xml",
"?:\\Users\\*\\AppData\\*\\NordVPN\\NordVPN.exe*\\user.config",
"?:\\Users\\*\\AppData\\*\\FileZilla\\recentservers.xml",
"?:\\Users\\*\\AppData\\*\\FileZilla\\sitemanager.xml") or
registry.path : ("HKEY_USERS\\S-1-5-21*\\software\\Martin Prikryl\\WinSCP *\\Sessions\\*\\Password*",
"HKEY_USERS\\S-1-5-21*\\SOFTWARE\\WOW6432Node\\TeamViewer\\ProxyPassword",
"HKEY_USERS\\S-1-5-21*\\Software\\OpenVPN-GUI\\Configs\\*auth-data*",
"HKEY_USERS\\S-1-12-1-*\\software\\Martin Prikryl\\WinSCP *\\Sessions\\*\\Password*",
"HKEY_USERS\\S-1-12-1-*\\SOFTWARE\\WOW6432Node\\TeamViewer\\ProxyPassword",
"HKEY_USERS\\S-1-12-1-*\\Software\\OpenVPN-GUI\\Configs\\*auth-data*")
) and
/* unsigned KeePass */
not (process.name : "KeePass.exe" and file.name : "KeePass.config.xml")]
'''
min_endpoint_version = "7.15.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1552"
name = "Unsecured Credentials"
reference = "https://attack.mitre.org/techniques/T1552/"
[[threat.technique.subtechnique]]
id = "T1552.001"
name = "Credentials In Files"
reference = "https://attack.mitre.org/techniques/T1552/001/"
[threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[internal]
min_endpoint_version = "7.15.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 5m, correlated by process.entity_id.
Stage 1: process
[process where event.action == "start" and
user.id like ("S-1-5-21*", "S-1-12-*") and process.executable : "?:\\*" and
not process.executable :
(
"?:\\Program Files\\*",
"?:\\Program Files (x86)\\*",
/*
dllhost.exe (IFileOperation like view/changing security permission of a file/folder).
explorer.exe for directory and file discovery.
SearchProtocolHost.exe is for file searches and indexing.
*/
"?:\\Windows\\explorer.exe",
"?:\\Windows\\System32\\dllhost.exe",
"?:\\Windows\\System32\\SearchProtocolHost.exe",
"?:\\Windows\\regedit.exe",
"?:\\Windows\\system32\\reg.exe",
"?:\\Windows\\System32\\userinit.exe",
"?:\\Windows\\System32\\notepad.exe",
"?:\\Windows\\System32\\Robocopy.exe",
"?:\\Windows\\System32\\cmd.exe",
"?:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\*\\MsMpEng.exe",
"?:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\*\\MpCopyAccelerator.exe",
"?:\\Windows\\_ScriptingFramework\\Modul\\Engine.exe",
"\\Device\\Mup\\*.exe") and
not (process.code_signature.subject_name :
("Martin Prikryl",
"OpenVPN Technologies, Inc.",
"TeamViewer Germany GmbH",
"Open Source Developer, Dominik Reichl",
"Tim Kosse",
"TEFINCOM S.A.",
"nordvpn s.a.") and
process.code_signature.trusted == true)
]
Stage 2: any
[any where event.category in ("registry", "file") and
event.action in ("query", "open") and
(
file.path : ("?:\\Users\\*\\AppData\\Roaming\\KeePass\\KeePass.config.xml",
"?:\\Users\\*\\AppData\\*\\NordVPN\\NordVPN.exe*\\user.config",
"?:\\Users\\*\\AppData\\*\\FileZilla\\recentservers.xml",
"?:\\Users\\*\\AppData\\*\\FileZilla\\sitemanager.xml") or
registry.path : ("HKEY_USERS\\S-1-5-21*\\software\\Martin Prikryl\\WinSCP *\\Sessions\\*\\Password*",
"HKEY_USERS\\S-1-5-21*\\SOFTWARE\\WOW6432Node\\TeamViewer\\ProxyPassword",
"HKEY_USERS\\S-1-5-21*\\Software\\OpenVPN-GUI\\Configs\\*auth-data*",
"HKEY_USERS\\S-1-12-1-*\\software\\Martin Prikryl\\WinSCP *\\Sessions\\*\\Password*",
"HKEY_USERS\\S-1-12-1-*\\SOFTWARE\\WOW6432Node\\TeamViewer\\ProxyPassword",
"HKEY_USERS\\S-1-12-1-*\\Software\\OpenVPN-GUI\\Configs\\*auth-data*")
) and
not (process.name : "KeePass.exe" and file.name : "KeePass.config.xml")]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
event.action | in |
| field:"EventType" kind:in |
event.category | in |
| field:"event.category" kind:in |
file.path | wildcard |
| field:"TargetFilename" kind:wildcard |
process.executable | wildcard |
| field:"Image" kind:wildcard value:"?:\*" |
registry.path | wildcard |
| field:"TargetObject" kind:wildcard |
user.id | wildcard |
| field:"user.id" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.code_signature.subject_name | eq | Martin Prikryl, OpenVPN Technologies, Inc., TeamViewer Germany GmbH, Open Source Developer, Dominik Reichl, Tim Kosse, TEFINCOM S.A., nordvpn s.a. | excludes:process.code_signature.subject_name |
process.code_signature.trusted | eq | true | excludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true" |
process.executable | wildcard | ?:\Program Files\*, ?:\Program Files (x86)\*, ?:\Windows\explorer.exe, ?:\Windows\System32\dllhost.exe, ?:\Windows\System32\SearchProtocolHost.exe, ?:\Windows\regedit.exe, ?:\Windows\system32\reg.exe, ?:\Windows\System32\userinit.exe, ?:\Windows\System32\notepad.exe, ?:\Windows\System32\Robocopy.exe, ?:\Windows\System32\cmd.exe, ?:\ProgramData\Microsoft\Windows Defender\Platform\*\MsMpEng.exe, ?:\ProgramData\Microsoft\Windows Defender\Platform\*\MpCopyAccelerator.exe, ?:\Windows\_ScriptingFramework\Modul\Engine.exe, \Device\Mup\*.exe | excludes:process.executable |
file.name | eq | KeePass.config.xml | excludes:file.name field:"file.name" value:"KeePass.config.xml" |
process.name | eq | KeePass.exe | excludes:process.name field:"process.name" value:"KeePass.exe" |
Suspicious API from an Unsigned Service DLL
#Identifies the execution of a new service via unsigned ServiceDLL subsequently followed by suspicious Windows API calls. Adversaries may use this technique to maintain persistence or run with System privileges.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Rule Body
[rule]
description = """
Identifies the execution of a new service via unsigned ServiceDLL subsequently followed by suspicious Windows API calls.
Adversaries may use this technique to maintain persistence or run with System privileges.
"""
id = "1a16b12e-6719-4f58-8835-84880092f3a0"
license = "Elastic License v2"
name = "Suspicious API from an Unsigned Service DLL"
os_list = ["windows"]
reference = ["https://www.elastic.co/security-labs/doubling-down-etw-callstacks"]
version = "1.0.12"
query = '''
sequence by process.entity_id with maxspan=2m
[library where
(dll.Ext.relative_file_creation_time <= 900 or dll.Ext.relative_file_name_modify_time <= 900) and
(dll.code_signature.trusted == false or dll.code_signature.exists == false or dll.path : "\\Device\\Mup*") and
process.executable : ("?:\\Windows\\System32\\svchost.exe", "?:\\Windows\\SysWOW64\\svchost.exe") and
not dll.hash.sha256 in ("c8bf101bab6d5400f892ee92f2e788a7096192a417707c4fa91f54ee2c29d394", "d615af8e012426c8847c750a0838159d6c41385d2e50388cea28a97999b81614")] as event0
[api where
process.executable : ("?:\\Windows\\System32\\svchost.exe", "?:\\Windows\\SysWOW64\\svchost.exe") and
(
process.Ext.api.name : ("WriteProcessMemory", "VirtualProtectEx") or
(process.Ext.api.name : ("VirtualAlloc*", "MapViewOfFile*") and
process.Ext.api.parameters.protection : "*X*" and process.Ext.api.parameters.size >= 4000)
) and
/* API stack is originating from a service DLL */
_arraysearch(process.thread.Ext.call_stack, $entry, stringcontains~($entry.symbol_info, concat(event0.dll.name, "!ServiceMain")))]
'''
min_endpoint_version = "8.8.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[[threat.technique.subtechnique]]
id = "T1543.003"
name = "Windows Service"
reference = "https://attack.mitre.org/techniques/T1543/003/"
[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[internal]
min_endpoint_version = "8.8.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 2m, correlated by process.entity_id.
Stage 1: library
[library where
(dll.Ext.relative_file_creation_time <= 900 or dll.Ext.relative_file_name_modify_time <= 900) and
(dll.code_signature.trusted == false or dll.code_signature.exists == false or dll.path : "\\Device\\Mup*") and
process.executable : ("?:\\Windows\\System32\\svchost.exe", "?:\\Windows\\SysWOW64\\svchost.exe") and
not dll.hash.sha256 in ("c8bf101bab6d5400f892ee92f2e788a7096192a417707c4fa91f54ee2c29d394", "d615af8e012426c8847c750a0838159d6c41385d2e50388cea28a97999b81614")] as event0
Stage 2: api
[api where
process.executable : ("?:\\Windows\\System32\\svchost.exe", "?:\\Windows\\SysWOW64\\svchost.exe") and
(
process.Ext.api.name : ("WriteProcessMemory", "VirtualProtectEx") or
(process.Ext.api.name : ("VirtualAlloc*", "MapViewOfFile*") and
process.Ext.api.parameters.protection : "*X*" and process.Ext.api.parameters.size >= 4000)
) and
_arraysearch(process.thread.Ext.call_stack, $entry, stringcontains~($entry.symbol_info, concat(event0.dll.name, "!ServiceMain")))]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
dll.Ext.relative_file_creation_time | le |
| field:"dll.Ext.relative_file_creation_time" kind:le value:"900" |
dll.Ext.relative_file_name_modify_time | le |
| field:"dll.Ext.relative_file_name_modify_time" kind:le value:"900" |
dll.code_signature.exists | eq |
| field:"dll.code_signature.exists" kind:eq value:"false" |
dll.code_signature.trusted | eq |
| field:"dll.code_signature.trusted" kind:eq value:"false" |
dll.path | wildcard |
| field:"ImageLoaded" kind:wildcard value:"\Device\Mup*" |
process.Ext.api.name | wildcard |
| field:"process.Ext.api.name" kind:wildcard |
process.Ext.api.parameters.protection | wildcard |
| field:"process.Ext.api.parameters.protection" kind:wildcard value:"*X*" |
process.Ext.api.parameters.size | ge |
| field:"process.Ext.api.parameters.size" kind:ge value:"4000" |
process.executable | wildcard |
| field:"Image" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
dll.hash.sha256 | in | c8bf101bab6d5400f892ee92f2e788a7096192a417707c4fa91f54ee2c29d394, d615af8e012426c8847c750a0838159d6c41385d2e50388cea28a97999b81614 | excludes:dll.hash.sha256 field:"dll.hash.sha256" value:"c8bf101bab6d5400f892ee92f2e788a7096192a417707c4fa91f54ee2c29d394" field:"dll.hash.sha256" value:"d615af8e012426c8847c750a0838159d6c41385d2e50388cea28a97999b81614" |
Suspicious MS Office Child Process
#Identifies suspicious child processes of frequently targeted Microsoft Office applications (Word, PowerPoint, Excel). These child processes are often launched during exploitation of Office applications or from documents with malicious macros.
MITRE ATT&CK Coverage
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 1: Process creation |
| Security-Auditing | Event ID 4688: A new process has been created. |
Rule Body
[metadata]
creation_date = "2020/02/18"
integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
maturity = "production"
updated_date = "2026/05/04"
[rule]
author = ["Elastic"]
description = """
Identifies suspicious child processes of frequently targeted Microsoft Office applications (Word, PowerPoint, Excel).
These child processes are often launched during exploitation of Office applications or from documents with malicious
macros.
"""
from = "now-9m"
index = [
"endgame-*",
"logs-crowdstrike.fdr*",
"logs-endpoint.events.process-*",
"logs-m365_defender.event-*",
"logs-sentinel_one_cloud_funnel.*",
"logs-system.security*",
"logs-windows.forwarded*",
"logs-windows.sysmon_operational-*",
"winlogbeat-*",
]
language = "eql"
license = "Elastic License v2"
name = "Suspicious MS Office Child Process"
note = """## Triage and analysis
### Investigating Suspicious MS Office Child Process
Microsoft Office (MS Office) is a suite of applications designed to help with productivity and completing common tasks on a computer. You can create and edit documents containing text and images, work with data in spreadsheets and databases, and create presentations and posters. As it is some of the most-used software across companies, MS Office is frequently targeted for initial access. It also has a wide variety of capabilities that attackers can take advantage of.
This rule looks for suspicious processes spawned by MS Office programs. This is generally the result of the execution of malicious documents.
#### Possible investigation steps
- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files for prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Retrieve MS Office documents received and opened by the user that could cause this behavior. Common locations include, but are not limited to, the Downloads and Document folders and the folder configured at the email client.
- Determine if the collected files are malicious:
- Use a private sandboxed malware analysis system to perform analysis.
- Observe and collect information about the following activities:
- Attempts to contact external domains and addresses.
- File and registry access, modification, and creation activities.
- Service creation and launch activities.
- Scheduled task creation.
- Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.
- Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.
### False positive analysis
- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.
### Response and remediation
- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- If the triage identified malware, search the environment for additional compromised hosts.
- Implement temporary network rules, procedures, and segmentation to contain the malware.
- Stop suspicious processes.
- Immediately block the identified indicators of compromise (IoCs).
- Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
- Remove and block malicious artifacts identified during triage.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- If the malicious file was delivered via phishing:
- Block the email sender from sending future emails.
- Block the malicious web pages.
- Remove emails from the sender from mailboxes.
- Consider improvements to the security awareness program.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""
setup = """## Setup
This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
Setup instructions: https://ela.st/install-elastic-defend
### Additional data sources
This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
- [CrowdStrike](https://ela.st/crowdstrike-integration)
- [Microsoft Defender XDR](https://ela.st/m365-defender)
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
- [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup)
- [Windows Process Creation Logs](https://ela.st/audit-process-creation)
"""
references = ["https://www.elastic.co/blog/vulnerability-summary-follina"]
risk_score = 47
rule_id = "a624863f-a70d-417f-a7d2-7a404638d47f"
severity = "medium"
tags = [
"Domain: Endpoint",
"OS: Windows",
"Use Case: Threat Detection",
"Tactic: Initial Access",
"Tactic: Defense Evasion",
"Tactic: Execution",
"Resources: Investigation Guide",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Data Source: Windows Security Event Logs",
"Data Source: Microsoft Defender XDR",
"Data Source: Sysmon",
"Data Source: SentinelOne",
"Data Source: Crowdstrike",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "windows" and event.type == "start" and
process.parent.name : (
"eqnedt32.exe", "excel.exe", "fltldr.exe", "msaccess.exe",
"mspub.exe", "powerpnt.exe", "winword.exe", "outlook.exe"
) and
process.name : (
"Microsoft.Workflow.Compiler.exe", "arp.exe", "atbroker.exe", "bginfo.exe", "bitsadmin.exe", "cdb.exe",
"certutil.exe", "cmd.exe", "cmstp.exe", "control.exe", "cscript.exe", "csi.exe", "dnx.exe", "dsget.exe",
"dsquery.exe", "forfiles.exe", "fsi.exe", "ftp.exe", "gpresult.exe", "hostname.exe", "ieexec.exe", "iexpress.exe",
"installutil.exe", "ipconfig.exe", "mshta.exe", "msxsl.exe", "nbtstat.exe", "net.exe", "net1.exe", "netsh.exe",
"netstat.exe", "nltest.exe", "odbcconf.exe", "ping.exe", "powershell.exe", "pwsh.exe", "qprocess.exe",
"quser.exe", "qwinsta.exe", "rcsi.exe", "reg.exe", "regasm.exe", "regsvcs.exe", "regsvr32.exe", "sc.exe",
"schtasks.exe", "systeminfo.exe", "tasklist.exe", "tracert.exe", "whoami.exe", "wmic.exe", "wscript.exe",
"xwizard.exe", "explorer.exe", "rundll32.exe", "hh.exe", "msdt.exe"
) and
not (
process.parent.name : "outlook.exe" and
process.name : "rundll32.exe" and
process.args : "shell32.dll,Control_RunDLL" and
process.args : "srchadmin.dll"
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[rule.threat.technique.subtechnique]]
id = "T1566.001"
name = "Spearphishing Attachment"
reference = "https://attack.mitre.org/techniques/T1566/001/"
[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"
[[rule.threat.technique.subtechnique]]
id = "T1059.003"
name = "Windows Command Shell"
reference = "https://attack.mitre.org/techniques/T1059/003/"
[[rule.threat.technique]]
id = "T1203"
name = "Exploitation for Client Execution"
reference = "https://attack.mitre.org/techniques/T1203/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[[rule.threat.technique.subtechnique]]
id = "T1218.001"
name = "Compiled HTML File"
reference = "https://attack.mitre.org/techniques/T1218/001/"
[[rule.threat.technique.subtechnique]]
id = "T1218.002"
name = "Control Panel"
reference = "https://attack.mitre.org/techniques/T1218/002/"
[[rule.threat.technique.subtechnique]]
id = "T1218.003"
name = "CMSTP"
reference = "https://attack.mitre.org/techniques/T1218/003/"
[[rule.threat.technique.subtechnique]]
id = "T1218.004"
name = "InstallUtil"
reference = "https://attack.mitre.org/techniques/T1218/004/"
[[rule.threat.technique.subtechnique]]
id = "T1218.005"
name = "Mshta"
reference = "https://attack.mitre.org/techniques/T1218/005/"
[[rule.threat.technique.subtechnique]]
id = "T1218.008"
name = "Odbcconf"
reference = "https://attack.mitre.org/techniques/T1218/008/"
[[rule.threat.technique.subtechnique]]
id = "T1218.009"
name = "Regsvcs/Regasm"
reference = "https://attack.mitre.org/techniques/T1218/009/"
[[rule.threat.technique.subtechnique]]
id = "T1218.010"
name = "Regsvr32"
reference = "https://attack.mitre.org/techniques/T1218/010/"
[[rule.threat.technique.subtechnique]]
id = "T1218.011"
name = "Rundll32"
reference = "https://attack.mitre.org/techniques/T1218/011/"
[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1016"
name = "System Network Configuration Discovery"
reference = "https://attack.mitre.org/techniques/T1016/"
[[rule.threat.technique]]
id = "T1033"
name = "System Owner/User Discovery"
reference = "https://attack.mitre.org/techniques/T1033/"
[[rule.threat.technique]]
id = "T1049"
name = "System Network Connections Discovery"
reference = "https://attack.mitre.org/techniques/T1049/"
[[rule.threat.technique]]
id = "T1057"
name = "Process Discovery"
reference = "https://attack.mitre.org/techniques/T1057/"
[[rule.threat.technique]]
id = "T1082"
name = "System Information Discovery"
reference = "https://attack.mitre.org/techniques/T1082/"
[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
Stages and Predicates
Stage 1: process
process where host.os.type == "windows" and event.type == "start" and
process.parent.name : (
"eqnedt32.exe", "excel.exe", "fltldr.exe", "msaccess.exe",
"mspub.exe", "powerpnt.exe", "winword.exe", "outlook.exe"
) and
process.name : (
"Microsoft.Workflow.Compiler.exe", "arp.exe", "atbroker.exe", "bginfo.exe", "bitsadmin.exe", "cdb.exe",
"certutil.exe", "cmd.exe", "cmstp.exe", "control.exe", "cscript.exe", "csi.exe", "dnx.exe", "dsget.exe",
"dsquery.exe", "forfiles.exe", "fsi.exe", "ftp.exe", "gpresult.exe", "hostname.exe", "ieexec.exe", "iexpress.exe",
"installutil.exe", "ipconfig.exe", "mshta.exe", "msxsl.exe", "nbtstat.exe", "net.exe", "net1.exe", "netsh.exe",
"netstat.exe", "nltest.exe", "odbcconf.exe", "ping.exe", "powershell.exe", "pwsh.exe", "qprocess.exe",
"quser.exe", "qwinsta.exe", "rcsi.exe", "reg.exe", "regasm.exe", "regsvcs.exe", "regsvr32.exe", "sc.exe",
"schtasks.exe", "systeminfo.exe", "tasklist.exe", "tracert.exe", "whoami.exe", "wmic.exe", "wscript.exe",
"xwizard.exe", "explorer.exe", "rundll32.exe", "hh.exe", "msdt.exe"
) and
not (
process.parent.name : "outlook.exe" and
process.name : "rundll32.exe" and
process.args : "shell32.dll,Control_RunDLL" and
process.args : "srchadmin.dll"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.name | wildcard |
| field:"process_basename" kind:wildcard |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | eq | shell32.dll,Control_RunDLL | excludes:process.args field:"process.args" value:"shell32.dll,Control_RunDLL" |
process.args | eq | srchadmin.dll | excludes:process.args field:"process.args" value:"srchadmin.dll" |
process.name | eq | rundll32.exe | excludes:process.name field:"process.name" value:"rundll32.exe" |
process.parent.name | eq | outlook.exe | excludes:process.parent.name field:"process.parent.name" value:"outlook.exe" |
Unusual D-Bus Daemon Child Process
#This rule detects when an unusual child process is spawned from the dbus-daemon parent process. The dbus-daemon process is a message bus system that provides a way for applications to talk to each other. Attackers may abuse this process to execute malicious code or escalate privileges.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Persistence | |
| Privilege Escalation |
Rule Body
[metadata]
creation_date = "2025/01/21"
integration = ["endpoint", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/03/24"
[rule]
author = ["Elastic"]
description = """
This rule detects when an unusual child process is spawned from the `dbus-daemon` parent process. The `dbus-daemon`
process is a message bus system that provides a way for applications to talk to each other. Attackers may abuse this
process to execute malicious code or escalate privileges.
"""
from = "now-9m"
index = ["logs-endpoint.events.process*", "endgame-*", "logs-sentinel_one_cloud_funnel.*"]
language = "eql"
license = "Elastic License v2"
name = "Unusual D-Bus Daemon Child Process"
note = """## Triage and analysis
> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
### Investigating Unusual D-Bus Daemon Child Process
The D-Bus daemon is a crucial component in Linux environments, facilitating inter-process communication by allowing applications to exchange information. Adversaries may exploit this by spawning unauthorized child processes to execute malicious code or gain elevated privileges. The detection rule identifies anomalies by monitoring child processes of the D-Bus daemon, excluding known benign processes and paths, thus highlighting potential threats.
### Possible investigation steps
- Review the process details to identify the unusual child process spawned from the dbus-daemon, focusing on the process name and executable path to determine if it is known or potentially malicious.
- Examine the command-line arguments (process.args) of the unusual child process to understand its intended function and assess if it aligns with typical usage patterns.
- Investigate the parent process arguments (process.parent.args) to confirm whether the dbus-daemon was running in a session context or another mode that might explain the unusual child process.
- Check the process start time and correlate it with other system events or logs to identify any related activities or anomalies occurring around the same time.
- Look into the user context under which the unusual child process was executed to determine if it was initiated by a legitimate user or potentially compromised account.
- Search for any network connections or file modifications associated with the unusual child process to identify potential data exfiltration or lateral movement activities.
### False positive analysis
- Known benign processes such as gnome-keyring-daemon and abrt-dbus may trigger the rule. Users can exclude these processes by adding them to the exception list in the detection rule.
- Processes executed from common library paths like /usr/lib/ or /usr/local/lib/ are typically non-threatening. Users should review these paths and consider excluding them if they are consistently generating false positives.
- The dbus-daemon with the --session argument is generally safe. Users can ensure this argument is included in the exception criteria to prevent unnecessary alerts.
- Specific applications like software-properties-dbus and serviceHelper.py are known to be benign. Users should verify these applications' legitimacy in their environment and exclude them if they are frequently flagged.
- Regularly review and update the exception list to include any new benign processes or paths that are identified over time, ensuring the rule remains effective without generating excessive false positives.
### Response and remediation
- Immediately isolate the affected system from the network to prevent potential lateral movement by the adversary.
- Terminate any suspicious child processes spawned by the dbus-daemon that are not recognized as legitimate or necessary for system operations.
- Conduct a thorough review of the affected system's logs to identify any unauthorized access or changes made by the suspicious process.
- Restore any altered or compromised system files from a known good backup to ensure system integrity.
- Update and patch the affected system and any related software to close vulnerabilities that may have been exploited.
- Implement stricter access controls and monitoring on the dbus-daemon to prevent unauthorized process execution in the future.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems are affected."""
risk_score = 21
rule_id = "9705b458-689a-4ec6-afe8-b4648d090612"
setup = """## Setup
This rule requires data coming in from Elastic Defend.
### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.
#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "low"
tags = [
"Domain: Endpoint",
"OS: Linux",
"Use Case: Threat Detection",
"Tactic: Persistence",
"Tactic: Privilege Escalation",
"Tactic: Execution",
"Data Source: Elastic Endgame",
"Data Source: Elastic Defend",
"Data Source: SentinelOne",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "exec_event", "start") and
process.parent.name == "dbus-daemon" and process.args_count > 1 and not (
process.parent.args == "--session" or
process.args in ("/usr/lib/software-properties/software-properties-dbus", "/usr/share/backintime/qt/serviceHelper.py") or
process.name in ("dbus-daemon-launch-helper", "gnome-keyring-daemon", "abrt-dbus", "aptd", "usb-creator-helper") or
process.executable like (
"/usr/lib/*", "/usr/local/lib/*", "/usr/libexec/*", "/tmp/newroot/*", "/usr/sbin/setroubleshootd",
"/usr/share/setroubleshoot/SetroubleshootPrivileged.py",
"/var/lib/awx/.local/share/containers/storage/overlay/*/SetroubleshootPrivileged.py",
"/home/*/.local/share/containers/storage/overlay/*/SetroubleshootPrivileged.py",
"/bin/rpm", "/run/user/*/.bubblewrap/newroot/usr/libexec/rhsmd", "/opt/CrowdStrike/sandbox/usr/libexec/rhsmd",
"/run/user/*/.bubblewrap/*/setroubleshootd"
) or
(
process.name like "python*" and
process.args in (
"/usr/share/usb-creator/usb-creator-helper", "/usr/sbin/aptd", "/usr/sbin/aptk", "/usr/bin/hp-pkservice",
"/usr/libexec/language-selector/ls-dbus-backend"
)
) or
(process.name == "perl" and process.args like "/usr/share/system-tools-backends-*.pl") or
?process.working_directory like "/run/user/*/.bubblewrap/newroot/var/lib/gdm/"
)
'''
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"
[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"
[[rule.threat.technique]]
id = "T1559"
name = "Inter-Process Communication"
reference = "https://attack.mitre.org/techniques/T1559/"
[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
Stages and Predicates
Stage 1: process
process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "exec_event", "start") and
process.parent.name == "dbus-daemon" and process.args_count > 1 and not (
process.parent.args == "--session" or
process.args in ("/usr/lib/software-properties/software-properties-dbus", "/usr/share/backintime/qt/serviceHelper.py") or
process.name in ("dbus-daemon-launch-helper", "gnome-keyring-daemon", "abrt-dbus", "aptd", "usb-creator-helper") or
process.executable like (
"/usr/lib/*", "/usr/local/lib/*", "/usr/libexec/*", "/tmp/newroot/*", "/usr/sbin/setroubleshootd",
"/usr/share/setroubleshoot/SetroubleshootPrivileged.py",
"/var/lib/awx/.local/share/containers/storage/overlay/*/SetroubleshootPrivileged.py",
"/home/*/.local/share/containers/storage/overlay/*/SetroubleshootPrivileged.py",
"/bin/rpm", "/run/user/*/.bubblewrap/newroot/usr/libexec/rhsmd", "/opt/CrowdStrike/sandbox/usr/libexec/rhsmd",
"/run/user/*/.bubblewrap/*/setroubleshootd"
) or
(
process.name like "python*" and
process.args in (
"/usr/share/usb-creator/usb-creator-helper", "/usr/sbin/aptd", "/usr/sbin/aptk", "/usr/bin/hp-pkservice",
"/usr/libexec/language-selector/ls-dbus-backend"
)
) or
(process.name == "perl" and process.args like "/usr/share/system-tools-backends-*.pl") or
?process.working_directory like "/run/user/*/.bubblewrap/newroot/var/lib/gdm/"
)
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | in |
| field:"EventType" kind:in |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args_count | gt |
| field:"process.args_count" kind:gt value:"1" |
process.parent.name | eq |
| field:"parent_process_basename" kind:eq value:"dbus-daemon" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | in | /usr/bin/hp-pkservice, /usr/libexec/language-selector/ls-dbus-backend, /usr/sbin/aptd, /usr/sbin/aptk, /usr/share/usb-creator/usb-creator-helper | excludes:process.args |
process.name | starts_with | python | excludes:process.name field:"process.name" value:"python" |
process.args | wildcard | /usr/share/system-tools-backends-*.pl | excludes:process.args field:"process.args" value:"/usr/share/system-tools-backends-*.pl" |
process.name | eq | perl | excludes:process.name field:"process.name" value:"perl" |
process.args | in | /usr/lib/software-properties/software-properties-dbus, /usr/share/backintime/qt/serviceHelper.py | excludes:process.args field:"process.args" value:"/usr/lib/software-properties/software-properties-dbus" field:"process.args" value:"/usr/share/backintime/qt/serviceHelper.py" |
process.executable | wildcard | /usr/lib/*, /usr/local/lib/*, /usr/libexec/*, /tmp/newroot/*, /usr/sbin/setroubleshootd, /usr/share/setroubleshoot/SetroubleshootPrivileged.py, /var/lib/awx/.local/share/containers/storage/overlay/*/SetroubleshootPrivileged.py, /home/*/.local/share/containers/storage/overlay/*/SetroubleshootPrivileged.py, /bin/rpm, /run/user/*/.bubblewrap/newroot/usr/libexec/rhsmd, /opt/CrowdStrike/sandbox/usr/libexec/rhsmd, /run/user/*/.bubblewrap/*/setroubleshootd | excludes:process.executable |
process.name | in | abrt-dbus, aptd, dbus-daemon-launch-helper, gnome-keyring-daemon, usb-creator-helper | excludes:process.name |
process.parent.args | eq | --session | excludes:process.parent.args field:"process.parent.args" value:"--session" |
process.working_directory | wildcard | /run/user/*/.bubblewrap/newroot/var/lib/gdm/ | excludes:process.working_directory field:"process.working_directory" value:"/run/user/*/.bubblewrap/newroot/var/lib/gdm/" |