Detection rules › Elastic

Elastic rules: 36

RuleSeverity
Accepted Default Telnet Port Connectionmedium
AWS EKS Access Entry Created Then Deleted by Same Identitymedium
Binary Proxy Execution via Pester
Curl Hidden Binary Modification via Osascript
Entra ID OAuth ROPC Grant Login Detectedmedium
GKE Unusual Service Account Secret Access via New User Agentlow
High Number of Process Terminationsmedium
Interactive Terminal Spawned via Perlhigh
Keystrokes Input Capture from Suspicious CallStack
Kubernetes and Cloud Credential Path Access via Process Argumentshigh
LSASS Memory Dump Creationhigh
M365 OneDrive Malware File Uploadhigh
M365 SharePoint Search for Sensitive Contentlow
Multi-Cloud CLI Token and Credential Access Commandshigh
Network Connect API from Modified Memory
Potential Endpoint Security Evasion via FirewallRules
Potential Execution via SSH Backdoormedium
Potential Injection via Module Stomping
Potential Remote Execution via IMsiServer
Potential SSH Reverse Port Forwardinglow
Potential Subnet Scanning Activity from Compromised Hostmedium
QoS Policy Group Policy Registry Overwrite via WMI
React2Shell Network Security Alerthigh
Remote Execution via File Sharesmedium
Repeated Stalled TLS Handshakes via ALPN acme-tls/1 Extensionlow
ROT encoded Python Script Execution
Service Creation via Local Kerberos Authenticationhigh
SUID/SGID Bit Setlow
Suspicious Dynamic Linker Discovery via odhigh
Suspicious Process Access via Direct System Callhigh
Suspicious SeIncreaseBasePriorityPrivilege Usehigh
Systemd-udevd Rule File Creationlow
Unusual Print Spooler Child Processmedium

Accepted Default Telnet Port Connection

#
Status
production
Severity
medium
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

This rule detects network events that may indicate the use of Telnet traffic. Telnet is commonly used by system administrators to remotely control older or embedded systems using the command line shell. It should almost never be directly exposed to the Internet, as it is frequently targeted and exploited by threat actors as an initial access or backdoor vector. As a plain-text protocol, it may also expose usernames and passwords to anyone capable of observing the traffic.

Known False Positives

  • IoT (Internet of Things) devices and networks may use telnet and can be excluded if desired. Some business work-flows may use Telnet for administration of older devices. These often have a predictable behavior. Telnet activity involving an unusual source or destination may be more suspicious. Telnet activity involving a production server that has no known associated Telnet work-flow or business requirement is often suspicious.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2020/02/18"
integration = ["network_traffic", "panw", "fortinet_fortigate", "pfsense", "sonicwall_firewall", "suricata"]
maturity = "production"
updated_date = "2026/09/03"

[rule]
author = ["Elastic"]
description = """
This rule detects network events that may indicate the use of Telnet traffic. Telnet is commonly used by system
administrators to remotely control older or embedded systems using the command line shell. It should almost never be
directly exposed to the Internet, as it is frequently targeted and exploited by threat actors as an initial access or
backdoor vector. As a plain-text protocol, it may also expose usernames and passwords to anyone capable of observing the
traffic.
"""
false_positives = [
    """
    IoT (Internet of Things) devices and networks may use telnet and can be excluded if desired. Some business
    work-flows may use Telnet for administration of older devices. These often have a predictable behavior. Telnet
    activity involving an unusual source or destination may be more suspicious. Telnet activity involving a production
    server that has no known associated Telnet work-flow or business requirement is often suspicious.
    """,
]
from = "now-9m"
index = [
    "packetbeat-*",
    "auditbeat-*",
    "filebeat-*",
    "logs-network_traffic.*",
    "logs-panw.panos*",
    "logs-fortinet_fortigate.log-*",
    "logs-pfsense.log-*",
    "logs-sonicwall_firewall.log-*",
    "logs-suricata.*",
]
language = "kuery"
license = "Elastic License v2"
name = "Accepted Default Telnet Port Connection"
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 Accepted Default Telnet Port Connection

Telnet, a protocol for remote command-line access, is often used in legacy systems. Its lack of encryption makes it vulnerable, allowing attackers to intercept credentials or use it as a backdoor. The detection rule identifies unencrypted Telnet traffic on port 23, flagging connections that bypass typical security measures, thus highlighting potential unauthorized access attempts.

### Possible investigation steps

- Review the network traffic logs to identify the source IP address associated with the Telnet connection on port 23. Determine if the source IP is internal or external to the organization.
- Check the destination IP address to ascertain if it belongs to a critical system or a legacy device that might still use Telnet for management purposes.
- Investigate the timeline of the connection event to see if there are any patterns or repeated attempts, which could indicate a persistent threat or automated attack.
- Analyze any associated user accounts or credentials used during the Telnet session to verify if they are legitimate and authorized for remote access.
- Correlate the Telnet connection event with other security alerts or logs to identify any related suspicious activities, such as failed login attempts or unusual data transfers.
- Assess the network segment where the Telnet traffic was detected to determine if it is appropriately segmented and secured against unauthorized access.
- Consider implementing network security measures, such as disabling Telnet on devices or replacing it with secure alternatives like SSH, to prevent future unauthorized access attempts.

### False positive analysis

- Legacy systems or devices that require Telnet for management may trigger alerts. To manage this, create exceptions for specific IP addresses or subnets known to host these systems.
- Internal network monitoring tools that use Telnet for legitimate purposes might be flagged. Identify these tools and exclude their traffic from the rule to prevent unnecessary alerts.
- Lab environments or test networks where Telnet is used for educational or testing purposes can cause false positives. Implement network segmentation and apply exceptions to these environments to reduce noise.
- Automated scripts or maintenance tasks that utilize Telnet for routine operations may be mistakenly identified. Document these tasks and whitelist their associated traffic patterns to avoid false alerts.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further unauthorized access or data exfiltration.
- Terminate any active Telnet sessions on the affected system to disrupt potential attacker activities.
- Conduct a thorough review of system logs and network traffic to identify any unauthorized access or data manipulation that may have occurred.
- Change all credentials that may have been exposed through Telnet traffic, prioritizing those with administrative privileges.
- Implement network segmentation to restrict Telnet access to only necessary internal systems, ensuring it is not exposed to the internet.
- Deploy encryption protocols such as SSH to replace Telnet for remote command-line access, enhancing security for remote management.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to assess the need for additional security measures."""
risk_score = 47
rule_id = "34fde489-94b0-4500-a76f-b8a157cf9269"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "Use Case: Threat Detection",
    "Tactic: Command and Control",
    "Tactic: Lateral Movement",
    "Tactic: Initial Access",
    "Data Source: Fortinet",
    "Data Source: PAN-OS",
    "Data Source: pfSense",
    "Data Source: SonicWall",
    "Data Source: Suricata",
    "Resources: Investigation Guide",
]
timeline_id = "300afc76-072d-4261-864d-4149714bf3f1"
timeline_title = "Comprehensive Network Timeline"
timestamp_override = "event.ingested"
type = "query"

query = '''
(data_stream.dataset:(fortinet_fortigate.log or network_traffic.flow
        or panw.panos or pfsense.log or sonicwall_firewall.log or suricata.eve)
    or event.category:(network or network_traffic))
    and event.type:(connection and not (denied or end))
    and not event.action:(Reject or client-rst or connection-denied or
        connection-end or denied or deny or flow_denied or flow_dropped or
        flow_terminated or network_flow or server-rst or timeout)
    and not (event.action:netflow_flow and not network.packets > 1)
    and not network.application:(stretchoid-scanning or traceroute)
    and destination.port:23
    and (network.protocol:(telnet or not *) or data_stream.dataset:fortinet_fortigate.log)
'''


[[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/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1021"
name = "Remote Services"
reference = "https://attack.mitre.org/techniques/T1021/"


[rule.threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1133"
name = "External Remote Services"
reference = "https://attack.mitre.org/techniques/T1133/"

[[rule.threat.technique]]
id = "T1190"
name = "Exploit Public-Facing Application"
reference = "https://attack.mitre.org/techniques/T1190/"


[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"

[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: query

(data_stream.dataset:(fortinet_fortigate.log or network_traffic.flow
        or panw.panos or pfsense.log or sonicwall_firewall.log or suricata.eve)
    or event.category:(network or network_traffic))
    and event.type:(connection and not (denied or end))
    and not event.action:(Reject or client-rst or connection-denied or
        connection-end or denied or deny or flow_denied or flow_dropped or
        flow_terminated or network_flow or server-rst or timeout)
    and not (event.action:netflow_flow and not network.packets > 1)
    and not network.application:(stretchoid-scanning or traceroute)
    and destination.port:23
    and (network.protocol:(telnet or not *) or data_stream.dataset:fortinet_fortigate.log)

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
network.packetsgt1excludes:network.packets field:"network.packets" value:"1"
event.actioneqnetflow_flowexcludes:event.action field:"event.action" value:"netflow_flow"
event.actioninReject, client-rst, connection-denied, connection-end, denied, deny, flow_denied, flow_dropped, flow_terminated, network_flow, server-rst, timeoutexcludes:event.action
event.typeindenied, endexcludes:event.type field:"event.type" value:"denied" field:"event.type" value:"end"
network.applicationinstretchoid-scanning, tracerouteexcludes:network.application field:"network.application" value:"stretchoid-scanning" field:"network.application" value:"traceroute"

AWS EKS Access Entry Created Then Deleted by Same Identity

#
Status
production
Severity
medium
Time window
5m
Sequence by
aws.cloudtrail.user_identity.arn
Author
Elastic
Source
github.com/elastic/detection-rules

Detects the creation of an Amazon EKS access entry followed by its deletion by the same identity within a short time window. EKS access entries define Kubernetes RBAC-level permissions for IAM principals in an EKS cluster. An adversary with EKS administrative access may temporarily grant themselves cluster access, use those permissions to create Kubernetes RBAC resources (ClusterRoleBindings, ServiceAccounts with privileged roles), and then delete the access entry to hide the evidence of the initial grant while retaining access through the Kubernetes-level backdoor.

Known False Positives

  • Automated infrastructure tests that create and immediately tear down EKS access entries as part of CI/CD validation may trigger this rule. Validate that the sequence corresponds to a documented test pipeline.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2026/08/14"
integration = ["aws"]
maturity = "production"
updated_date = "2026/08/14"

[rule]
author = ["Elastic"]
description = """
Detects the creation of an Amazon EKS access entry followed by its deletion by the same
identity within a short time window. EKS access entries define Kubernetes RBAC-level
permissions for IAM principals in an EKS cluster. An adversary with EKS administrative
access may temporarily grant themselves cluster access, use those permissions to create
Kubernetes RBAC resources (ClusterRoleBindings, ServiceAccounts with privileged roles),
and then delete the access entry to hide the evidence of the initial grant while retaining
access through the Kubernetes-level backdoor.
"""
false_positives = [
    """
    Automated infrastructure tests that create and immediately tear down EKS access entries
    as part of CI/CD validation may trigger this rule. Validate that the sequence corresponds
    to a documented test pipeline.
    """,
]
from = "now-15m"
index = ["logs-aws.cloudtrail-*"]
language = "eql"
license = "Elastic License v2"
name = "AWS EKS Access Entry Created Then Deleted by Same Identity"
note = """## Triage and analysis

### Investigating AWS EKS Access Entry Created Then Deleted by Same Identity

EKS access entries (introduced in EKS API mode) map IAM principals to Kubernetes access policies or allow associating Kubernetes groups to IAM principals. An adversary who obtains `eks:CreateAccessEntry` and `eks:DeleteAccessEntry` permissions can:

1. Create an access entry for their own IAM principal with cluster-admin level access.
2. Use that access to create persistent Kubernetes RBAC resources (ClusterRoleBindings, privileged ServiceAccounts, rogue DaemonSets).
3. Delete the access entry, removing the CloudTrail evidence of the initial grant while retaining Kubernetes-level access.

This sequence is analogous to adding a backdoor user, using it, then deleting it to cover tracks. The deletion within a short window of creation is the key behavioral indicator.

### Possible investigation steps

- Identify the calling identity from `aws.cloudtrail.user_identity.arn` and the targeted cluster from `aws.cloudtrail.request_parameters`.
- Review Kubernetes audit logs for the affected cluster in the time window between the `CreateAccessEntry` and `DeleteAccessEntry` events. Look for `create` verbs on ClusterRoleBindings, RoleBindings, ServiceAccounts, or DaemonSets.
- Check the cluster's current RBAC configuration for persistent backdoor resources.
- Determine whether the identity had a legitimate reason to create an access entry for the targeted cluster.

### False positive analysis

- Infrastructure-as-code and CI/CD pipelines that create and tear down EKS access entries as part of cluster validation — Terraform or eksctl apply/destroy cycles, ephemeral test clusters — will produce this exact sequence. Correlate with the pipeline identity and change records before triaging further.
- Short-lived break-glass or just-in-time administrative access that is granted and revoked by the same operator within minutes is legitimate; confirm against access-request tickets or change approvals.
- Migration tooling that switches clusters between authentication modes may churn access entries in bulk under a single automation role.
- The sequence correlates on the calling identity only, so confirm the `CreateAccessEntry` and `DeleteAccessEntry` events reference the same cluster and principal ARN in the request parameters before treating them as one grant-and-revoke cycle.
- Scope any exceptions by the calling ARN or automation role rather than excluding the behavior globally.

### Response and remediation

- Audit all Kubernetes RBAC resources for unauthorized ClusterRoleBindings or privileged ServiceAccounts created in the suspect window.
- Rotate credentials for the calling identity.
- Apply IAM policies restricting `eks:CreateAccessEntry` and `eks:DeleteAccessEntry` to designated EKS administrative roles.
"""
references = [
    "https://docs.aws.amazon.com/eks/latest/APIReference/API_CreateAccessEntry.html",
    "https://docs.aws.amazon.com/eks/latest/APIReference/API_DeleteAccessEntry.html",
    "https://www.wiz.io/blog/new-attack-vectors-emerge-via-recent-eks-access-entries-and-pod-identity-features",
    "https://securitylabs.datadoghq.com/articles/eks-cluster-access-management-deep-dive/",
]
risk_score = 47
rule_id = "2b60fb61-d0c7-405e-9f33-a66d8729628d"
setup = "The AWS integration must be ingesting management events into `logs-aws.cloudtrail-*`. EKS management events are logged by default."
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: Kubernetes",
    "Platform: AWS",
    "Platform: Kubernetes",
    "Data Source: AWS CloudTrail",
    "Service: AWS EKS",
    "Rule Type: Event Correlation (EQL)",
    "Tactic: Persistence",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
sequence by aws.cloudtrail.user_identity.arn with maxspan=5m
  [any where data_stream.dataset == "aws.cloudtrail" and event.provider == "eks.amazonaws.com" and event.action == "CreateAccessEntry" and event.outcome == "success" and aws.cloudtrail.user_identity.arn != null]
  [any where data_stream.dataset == "aws.cloudtrail" and event.provider == "eks.amazonaws.com" and event.action == "DeleteAccessEntry" and event.outcome == "success" and aws.cloudtrail.user_identity.arn != null]
'''

[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"
[[rule.threat.technique.subtechnique]]
id = "T1098.006"
name = "Additional Container Cluster Roles"
reference = "https://attack.mitre.org/techniques/T1098/006/"

[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "aws.cloudtrail.user_identity.arn",
    "aws.cloudtrail.user_identity.type",
    "user.name",
    "event.action",
    "event.outcome",
    "aws.cloudtrail.request_parameters",
    "source.ip",
    "cloud.region",
    "cloud.account.id",
]

Stages and Predicates

Ordered sequence: each step below must occur in order within 5m, correlated by aws.cloudtrail.user_identity.arn.

Stage 1: any

[any where data_stream.dataset == "aws.cloudtrail" and event.provider == "eks.amazonaws.com" and event.action == "CreateAccessEntry" and event.outcome == "success" and aws.cloudtrail.user_identity.arn != null]

Stage 2: any

[any where data_stream.dataset == "aws.cloudtrail" and event.provider == "eks.amazonaws.com" and event.action == "DeleteAccessEntry" and event.outcome == "success" and aws.cloudtrail.user_identity.arn != null]

Indicators

These rows show field, operator, and value matches.

Binary Proxy Execution via Pester

#
Source
github.com/elastic/protections-artifacts

Identifies the execution of a binary via the Pester PowerShell module. Adversaries may bypass process and signature-based defenses by proxying execution of malicious content with signed, or otherwise trusted, binaries.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the execution of a binary via the Pester PowerShell module. Adversaries may bypass process and
signature-based defenses by proxying execution of malicious content with signed, or otherwise trusted, binaries.
"""
id = "bbc7e649-dc8e-401f-a6e4-d2d668aef4ac"
license = "Elastic License v2"
name = "Binary Proxy Execution via Pester"
os_list = ["windows"]
reference = ["https://lolbas-project.github.io/lolbas/Scripts/pester/"]
version = "1.0.5"

query = '''
process where event.action == "start" and
(
 (process.parent.name : "powershell.exe" and
  process.parent.command_line : "powershell*WindowsPowerShell\\Modules*\\Pester.psm1*;*" and
 not process.executable : ("?:\\Windows\\Microsoft.NET\\Framework*\\csc.exe", "?:\\Windows\\Sys*\\conhost.exe")) or

 (process.name : "powershell.exe" and process.command_line : "*\\Pester.psm1*;*http*")
)
'''

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 = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"


[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.action == "start" and
(
 (process.parent.name : "powershell.exe" and
  process.parent.command_line : "powershell*WindowsPowerShell\\Modules*\\Pester.psm1*;*" and
 not process.executable : ("?:\\Windows\\Microsoft.NET\\Framework*\\csc.exe", "?:\\Windows\\Sys*\\conhost.exe")) or

 (process.name : "powershell.exe" and process.command_line : "*\\Pester.psm1*;*http*")
)

Indicators

These rows show field, operator, and value matches.

Curl Hidden Binary Modification via Osascript

#
Time window
30s
Sequence by
process.entity_id
Source
github.com/elastic/protections-artifacts

Detects osascript spawning curl followed by creation of hidden binary files with Mach-O headers within 30 seconds. This indicates malicious AppleScript workflows downloading and staging executable payloads.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[rule]
description = """
Detects osascript spawning curl followed by creation of hidden binary files with Mach-O headers within 30 seconds. This
indicates malicious AppleScript workflows downloading and staging executable payloads.
"""
id = "3c3aaa63-d213-486f-b157-e4b1a45d9913"
license = "Elastic License v2"
name = "Curl Hidden Binary Modification via Osascript"
os_list = ["macos"]
version = "1.0.3"

query = '''
sequence by process.entity_id with maxspan=30s
[process where event.type == "start" and event.action == "exec" and process.name == "curl" and process.parent.name == "osascript"]
[file where event.action == "modification" and file.Ext.header_bytes like~ ("cffaedfe*", "cafebabe*") and file.name like~ ".*"]
'''

min_endpoint_version = "8.16.0"
optional_actions = []
[[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.002"
name = "AppleScript"
reference = "https://attack.mitre.org/techniques/T1059/002/"



[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.16.0"

Stages and Predicates

Ordered sequence: each step below must occur in order within 30s, correlated by process.entity_id.

Stage 1: process

[process where event.type == "start" and event.action == "exec" and process.name == "curl" and process.parent.name == "osascript"]

Stage 2: file

[file where event.action == "modification" and file.Ext.header_bytes like~ ("cffaedfe*", "cafebabe*") and file.name like~ ".*"]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • exec corpus 547 (elastic 547)
  • modification corpus 72 (elastic 72)
field:"EventType" kind:eq
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
file.Ext.header_byteswildcard
  • cafebabe* corpus 19 (elastic 19)
  • cffaedfe* corpus 19 (elastic 19)
field:"file.Ext.header_bytes" kind:wildcard
file.namewildcard
  • .* corpus 6 (elastic 6)
field:"file.name" kind:wildcard value:".*"
process.nameeq
  • curl corpus 13 (elastic 13)
field:"process_basename" kind:eq value:"curl"
process.parent.nameeq
  • osascript corpus 11 (elastic 11)
field:"parent_process_basename" kind:eq value:"osascript"

Entra ID OAuth ROPC Grant Login Detected

#
Status
production
Severity
medium
Time window
9m
Group by
azure.signinlogs.properties.user_principal_name
Author
Elastic
Source
github.com/elastic/detection-rules

Detects unusual resource owner password credential (ROPC) login attempts by a user principal in Microsoft Entra ID. ROPC is a legacy authentication flow that allows applications to obtain tokens by directly providing user credentials. This method is less secure and can be exploited by adversaries to gain access to user accounts without requiring multi-factor authentication (MFA), especially during enumeration or password spraying. This is a New Terms rule that identifies when user principals are involved in ROPC login attempts, not seen before in the last 10 days, indicating potential abuse or unusual activity.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2025/07/02"
integration = ["azure"]
maturity = "production"
updated_date = "2026/07/02"

[rule]
author = ["Elastic"]
description = """
Detects unusual resource owner password credential (ROPC) login attempts by a user principal in Microsoft Entra ID. ROPC
is a legacy authentication flow that allows applications to obtain tokens by directly providing user credentials. This
method is less secure and can be exploited by adversaries to gain access to user accounts without requiring multi-factor
authentication (MFA), especially during enumeration or password spraying. This is a New Terms rule that identifies when
user principals are involved in ROPC login attempts, not seen before in the last 10 days, indicating potential abuse or
unusual activity.
"""
from = "now-9m"
index = ["filebeat-*", "logs-azure.signinlogs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Entra ID OAuth ROPC Grant Login Detected"
note = """## Triage and analysis

### Investigating Entra ID OAuth ROPC Grant Login Detected

This rule detects unusual login attempts using the Resource Owner Password Credentials (ROPC) flow in Microsoft Entra ID. ROPC allows applications to obtain tokens by directly providing user credentials, bypassing multi-factor authentication (MFA). This method is less secure and can be exploited by adversaries to gain access to user accounts, especially during enumeration or password spraying.

### Possible investigation steps
- Review the `azure.signinlogs.properties.user_principal_name` field to identify the user principal involved in the ROPC login attempt. Check if this user is expected to use ROPC or if it is an unusual account for this type of authentication.
- Analyze the `azure.signinlogs.properties.authentication_protocol` field to confirm that the authentication protocol is indeed ROPC. This protocol is typically used in legacy applications or scripts that do not support modern authentication methods.
- Check the `user_agent.original` field to identify potentially abused open-source tools or scripts that may be using ROPC for unauthorized access such as TeamFiltration or other enumeration tools.
- Review the `azure.signinlogs.properties.app_display_name` or `azure.signinlogs.properties.app_id` to determine which application is attempting the ROPC login. FOCI applications are commonly used for enumeration and password spraying.
- Investigate the `azure.signinlogs.properties.client_ip` to identify the source of the login attempt. Check if the IP address is associated with known malicious activity or if it is a legitimate user location.
- Review the `azure.signinlogs.properties.authentication_details` field for any additional context on the authentication attempt, such as whether it was successful or if there were any errors.
- Examine the `azure.signinlogs.properties.applied_conditional_access_policies` to see if any conditional access policies were applied during the login attempt. If no policies were applied, this could indicate a potential bypass of security controls.
- Identify the resource requested access to by checking the `azure.signinlogs.properties.resource_display_name` or `azure.signinlogs.properties.resource_id`. This can help determine if the login attempt was targeting sensitive resources or applications such as Exchange Online, SharePoint, or Teams.

### False positive analysis
- Legitimate applications or scripts that use ROPC for automation purposes may trigger this rule.
- Some legacy applications may still rely on ROPC for authentication, especially in environments where modern authentication methods are not fully implemented.
- Internal security tools or scripts that perform automated tasks using ROPC may generate false positives if they are not properly whitelisted or excluded from the rule.

### Response and remediation
- If the ROPC login attempt is confirmed to be malicious, immediately block the user account and reset the password to prevent further unauthorized access.
- Consider enforcing multi-factor authentication (MFA) for the user account to enhance security and prevent future unauthorized access attempts.
- Review and update conditional access policies to restrict the use of ROPC for sensitive accounts or applications, ensuring that MFA is required for all login attempts.
- Investigate the source of the ROPC login attempt, including the application and IP address, to determine if there are any additional indicators of compromise or ongoing malicious activity.
- Monitor the user account and related resources for any further suspicious activity or unauthorized access attempts, and take appropriate actions to mitigate any risks identified.
- Educate users about the risks associated with ROPC and encourage them to use more secure authentication methods, such as OAuth 2.0 or OpenID Connect, whenever possible.
"""
references = [
    "https://www.proofpoint.com/us/blog/threat-insight/attackers-unleash-teamfiltration-account-takeover-campaign",
    "https://dirkjanm.io/assets/raw/Finding%20Entra%20ID%20CA%20Bypasses%20-%20the%20structured%20way.pdf",
    "https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth-ropc",
    "https://redcanary.com/blog/threat-detection/bav2ropc/",
    "https://www.huntress.com/blog/lshiy-password-spray-attack"
]
risk_score = 47
rule_id = "8d696bd0-5756-11f0-8e3b-f661ea17fbcd"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: Identity",
    "Data Source: Azure",
    "Data Source: Microsoft Entra ID",
    "Data Source: Microsoft Entra ID Sign-In Logs",
    "Use Case: Identity and Access Audit",
    "Tactic: Initial Access",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
data_stream.dataset: "azure.signinlogs" and
    (
        azure.signinlogs.properties.authentication_protocol: "ropc" or
        user_agent.original: "BAV2ROPC"
    ) and
    azure.signinlogs.properties.authentication_requirement: "singleFactorAuthentication" and
    azure.signinlogs.properties.user_type: "Member" and
    event.outcome: "success"
'''


[[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/"

[[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 = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[rule.new_terms]
field = "new_terms_fields"
value = ["azure.signinlogs.properties.user_principal_name"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-10d"


Stages and Predicates

Stage 1: new_terms

data_stream.dataset: "azure.signinlogs" and
    (
        azure.signinlogs.properties.authentication_protocol: "ropc" or
        user_agent.original: "BAV2ROPC"
    ) and
    azure.signinlogs.properties.authentication_requirement: "singleFactorAuthentication" and
    azure.signinlogs.properties.user_type: "Member" and
    event.outcome: "success"

Indicators

These rows show field, operator, and value matches.

GKE Unusual Service Account Secret Access via New User Agent

#
Status
production
Severity
low
Time window
6m
Group by
client.user.email, source.ip, user_agent.original
Author
Elastic
Source
github.com/elastic/detection-rules

Detects the first successful GKE secrets.get by a pod service account from a previously unseen combination of service-account identity, user agent, and source IP. Controllers routinely read secrets with a stable client fingerprint; a new user agent or source for that service account could indicate a stolen token used outside the workload (for example curl, a custom script, or kubectl from an unexpected host).

Known False Positives

  • Controller upgrades, sidecar replacements, or client library version bumps change user agents and can produce a first-seen alert for known service accounts. Confirm the new client is expected before treating as compromise.
  • Newly deployed operators or workloads that change egress IP will alert once while the history window learns their client fingerprint.

MITRE ATT&CK Coverage

TacticTechniques
Credential Access

Telemetry Coverage

PlatformRecord / event type
Kubernetesget-secrets: get secrets

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2026/07/17"
integration = ["gcp"]
maturity = "production"
updated_date = "2026/07/31"

[rule]
author = ["Elastic"]
description = """
Detects the first successful GKE secrets.get by a pod service account from a previously unseen combination of
service-account identity, user agent, and source IP. Controllers routinely read secrets with a stable client
fingerprint; a new user agent or source for that service account could indicate a stolen token used outside
the workload (for example curl, a custom script, or kubectl from an unexpected host).
"""
false_positives = [
    """
    Controller upgrades, sidecar replacements, or client library version bumps change user agents and can produce
    a first-seen alert for known service accounts. Confirm the new client is expected before treating as compromise.
    """,
    """
    Newly deployed operators or workloads that change egress IP will alert once while the history window learns
    their client fingerprint.
    """,
]
from = "now-6m"
index = ["logs-gcp.audit-*"]
language = "kuery"
license = "Elastic License v2"
name = "GKE Unusual Service Account Secret Access via New User Agent"
note = """## Triage and analysis

### Investigating GKE Unusual Service Account Secret Access via New User Agent

This new-terms rule alerts when a `system:serviceaccount:*` identity successfully calls `secrets.get` with a
`client.user.email` + `user_agent.original` + `source.ip` combination not seen in the history window.

### Possible investigation steps

- Confirm whether the service account normally uses this user agent or whether the client looks like an interactive
  or scripting tool (`curl`, `python`, `kubectl`, generic HTTP libraries).
- Review `gcp.audit.resource_name` and namespace scope against the workload's expected secret mounts and RBAC.
- Pivot on the same `client.user.email` or `source.ip` for secret list/get bursts, exec, or RBAC changes.
- Compare to recent deployments or operator upgrades that would legitimately introduce a new client string.

### False positive analysis

- Operator or library upgrades that change the user-agent string for an otherwise unchanged service account.
- First enablement of the rule will surface baseline controller clients until the history window fills.

### Response and remediation

- If malicious, revoke the service-account token, rotate exposed secrets, isolate the originating workload or
  host, and tighten RBAC so the identity can only read required secrets.
"""
setup = "The GCP Fleet integration with GKE audit logs enabled is required to be compatible with this rule."
references = [
    "https://kubernetes.io/docs/reference/access-authn-authz/authentication/#service-account-tokens",
]
risk_score = 21
rule_id = "5dd3358c-4664-4b4c-aca1-b3fa4a4c83c9"
severity = "low"
tags = [
    "Domain: Cloud",
    "Domain: Kubernetes",
    "Data Source: GCP",
    "Data Source: Google Cloud Platform",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
data_stream.dataset:gcp.audit and service.name:k8s.io and event.outcome:success and
event.action:"io.k8s.core.v1.secrets.get" and
client.user.email:system\:serviceaccount\:* and
user_agent.original:(* and not *kubernetes/$Format*) and
source.ip:(* and not (127.0.0.1 or "::1"))
'''

[rule.new_terms]
field = "new_terms_fields"
value = ["client.user.email", "user_agent.original", "source.ip"]

[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-7d"

[[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.007"
name = "Container API"
reference = "https://attack.mitre.org/techniques/T1552/007/"

[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "client.user.email",
    "source.ip",
    "user_agent.original",
    "event.action",
    "event.outcome",
    "gcp.audit.resource_name",
    "data_stream.namespace",
]

Stages and Predicates

Stage 1: new_terms

data_stream.dataset:gcp.audit and service.name:k8s.io and event.outcome:success and
event.action:"io.k8s.core.v1.secrets.get" and
client.user.email:system\:serviceaccount\:* and
user_agent.original:(* and not *kubernetes/$Format*) and
source.ip:(* and not (127.0.0.1 or "::1"))

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

High Number of Process Terminations

#
Status
production
Severity
medium
Time window
9m
Group by
host.id, process.executable, user.name
Author
Elastic
Source
github.com/elastic/detection-rules

This rule identifies a high number (10) of process terminations via pkill from the same host within a short time period.

MITRE ATT&CK Coverage

TacticTechniques
Defense Impairment
Impact

Rule Body

[metadata]
creation_date = "2022/07/27"
integration = ["endpoint", "auditd_manager", "crowdstrike"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = "This rule identifies a high number (10) of process terminations via pkill from the same host within a short time period.\n"
from = "now-9m"
index = ["logs-endpoint.events.*", "endgame-*", "auditbeat-*", "logs-auditd_manager.auditd-*", "logs-crowdstrike.fdr*"]
language = "kuery"
license = "Elastic License v2"
name = "High Number of Process Terminations"
note = """## Triage and analysis

### Investigating High Number of Process Terminations

Attackers can kill processes for a variety of purposes. For example, they can kill process associated with business applications and databases to release the lock on files used by these applications so they may be encrypted,or stop security and backup solutions, etc.

This rule identifies a high number (10) of process terminations via pkill from the same host within a short time period.

#### Possible investigation steps

- Examine the entry point to the host and user in action via the Analyse View.
  - Identify the session entry leader and session user.
- Examine the contents of session leading to the process termination(s) via the Session View.
  - Examine the command execution pattern in the session, which may lead to suspricous activities.
- Examine the process killed during the malicious execution
  - Identify imment threat to the system from the process killed.
  - Take necessary incident response actions to respawn necessary process.

### 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 destructive behavior, which is commonly associated with this activity.
- 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.
- Reimage the host operating system or restore it to the operational state.
- If any other destructive action was identified on the host, it is recommended to prioritize the investigation and look for ransomware preparation and execution activities.
- 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).
"""
risk_score = 47
rule_id = "67f8443a-4ff3-4a70-916d-3cfa3ae9f02b"
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: Impact",
  "Resources: Investigation Guide",
  "Data Source: Elastic Endgame",
  "Data Source: Elastic Defend",
  "Data Source: Auditd Manager",
  "Data Source: Crowdstrike",
]
timestamp_override = "event.ingested"
type = "threshold"
query = '''
event.category:process and host.os.type:linux and event.type:start and (
  (process.name:"pkill" and process.args:"-f") or
  (process.name:kill and process.args:"-9") or
  (process.name:killall)
)
'''

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1489"
name = "Service Stop"
reference = "https://attack.mitre.org/techniques/T1489/"

[rule.threat.tactic]
id = "TA0040"
name = "Impact"
reference = "https://attack.mitre.org/tactics/TA0040/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"

[[rule.threat.technique.subtechnique]]
id = "T1562.001"
name = "Disable or Modify Tools"
reference = "https://attack.mitre.org/techniques/T1562/001/"

[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[rule.threshold]
field = ["host.id", "process.executable", "user.name"]
value = 15

Stages and Predicates

Stage 1: query

event.category:process and host.os.type:linux and event.type:start and (
  (process.name:"pkill" and process.args:"-f") or
  (process.name:kill and process.args:"-9") or
  (process.name:killall)
)
Threshold
gte 15

Indicators

These rows show field, operator, and value matches.

Interactive Terminal Spawned via Perl

#
Status
production
Severity
high
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies when a terminal (tty) is spawned via Perl. Attackers may upgrade a simple reverse shell to a fully interactive tty after obtaining initial access to a host.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2020/04/16"
integration = ["endpoint", "auditd_manager", "crowdstrike", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
Identifies when a terminal (tty) is spawned via Perl. Attackers may upgrade a simple reverse shell to a fully
interactive tty after obtaining initial access to a host.
"""
from = "now-9m"
index = [
    "auditbeat-*",
    "endgame-*",
    "logs-auditd_manager.auditd-*",
    "logs-crowdstrike.fdr*",
    "logs-endpoint.events.process*",
    "logs-sentinel_one_cloud_funnel.*",
]
language = "eql"
license = "Elastic License v2"
name = "Interactive Terminal Spawned via Perl"
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 Interactive Terminal Spawned via Perl

Perl, a versatile scripting language, can execute system commands, making it a target for adversaries seeking to escalate privileges or maintain persistence. Attackers may exploit Perl to spawn interactive terminals, transforming basic shells into robust command interfaces. The detection rule identifies such activity by monitoring process events on Linux systems, specifically when Perl executes shell commands, signaling potential misuse.

### Possible investigation steps

- Review the process event logs to confirm the presence of a Perl process with arguments indicating the execution of a shell, such as "exec \\"/bin/sh\\";", "exec \\"/bin/dash\\";", or "exec \\"/bin/bash\\";".
- Identify the user account associated with the Perl process to determine if it aligns with expected activity or if it suggests unauthorized access.
- Examine the parent process of the Perl execution to understand how the Perl script was initiated and assess if it correlates with legitimate user activity or a potential compromise.
- Check for any network connections or data transfers initiated by the Perl process to identify possible exfiltration or communication with external command and control servers.
- Investigate any recent changes to user accounts, permissions, or scheduled tasks that might indicate privilege escalation or persistence mechanisms associated with the Perl activity.
- Correlate the event with other security alerts or logs from the same host to identify patterns or additional indicators of compromise that could suggest a broader attack campaign.

### False positive analysis

- System maintenance scripts that use Perl to execute shell commands may trigger this rule. Review and whitelist known maintenance scripts by adding exceptions for specific script paths or process arguments.
- Automated deployment tools that utilize Perl for executing shell commands can cause false positives. Identify these tools and exclude their specific process arguments or execution paths from the detection rule.
- Development environments where Perl is used for testing or debugging purposes might inadvertently spawn interactive terminals. Consider excluding processes initiated by known development user accounts or within specific development directories.
- Backup or monitoring scripts that rely on Perl to perform system checks or data collection could be flagged. Analyze these scripts and create exceptions based on their unique process arguments or execution context.

### Response and remediation

- Immediately isolate the affected host from the network to prevent further unauthorized access or lateral movement.
- Terminate any suspicious Perl processes identified by the detection rule to halt any ongoing malicious activity.
- Conduct a thorough review of the affected system's logs and process history to identify any additional indicators of compromise or related malicious activity.
- Reset credentials and review access permissions for any accounts that may have been compromised or used in the attack.
- Restore the affected system from a known good backup to ensure any malicious changes are removed.
- Implement additional monitoring on the affected host and network to detect any further attempts to exploit Perl for spawning interactive terminals.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if broader organizational impacts exist."""
risk_score = 73
rule_id = "05e5a668-7b51-4a67-93ab-e9af405c9ef3"
setup = """## Setup

This rule requires data coming in from one of the following integrations:
- Elastic Defend
- Auditbeat

### 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).

### Auditbeat Setup
Auditbeat is a lightweight shipper that you can install on your servers to audit the activities of users and processes on your systems. For example, you can use Auditbeat to collect and centralize audit events from the Linux Audit Framework. You can also use Auditbeat to detect changes to critical files, like binaries and configuration files, and identify potential security policy violations.

#### The following steps should be executed in order to add the Auditbeat on a Linux System:
- Elastic provides repositories available for APT and YUM-based distributions. Note that we provide binary packages, but no source packages.
- To install the APT and YUM repositories follow the setup instructions in this [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/setup-repositories.html).
- To run Auditbeat on Docker follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/running-on-docker.html).
- To run Auditbeat on Kubernetes follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/running-on-kubernetes.html).
- For complete “Setup and Run Auditbeat” information refer to the [helper guide](https://www.elastic.co/guide/en/beats/auditbeat/current/setting-up-and-running.html).
"""
severity = "high"
tags = [
  "Domain: Endpoint",
  "OS: Linux",
  "Use Case: Threat Detection",
  "Tactic: Execution",
  "Data Source: Elastic Defend",
  "Data Source: Elastic Endgame",
  "Data Source: Auditd Manager",
  "Data Source: Crowdstrike",
  "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", "ProcessRollup2", "executed", "process_started") and
process.name == "perl" and process.args == "exec" and
process.args in (
  "\"sh\";", "\"dash\";", "\"bash\";", "\"zsh\";",
  "\"/bin/sh\";", "\"/bin/dash\";", "\"/bin/bash\";", "\"/bin/zsh\";",
  "\"/usr/bin/sh\";", "\"/usr/bin/dash\";", "\"/usr/bin/bash\";", "\"/usr/bin/zsh\";",
  "\"/usr/local/bin/sh\";", "\"/usr/local/bin/dash\";", "\"/usr/local/bin/bash\";", "\"/usr/local/bin/zsh\";"
)
'''

[[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.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", "ProcessRollup2", "executed", "process_started") and
process.name == "perl" and process.args == "exec" and
process.args in (
  "\"sh\";", "\"dash\";", "\"bash\";", "\"zsh\";",
  "\"/bin/sh\";", "\"/bin/dash\";", "\"/bin/bash\";", "\"/bin/zsh\";",
  "\"/usr/bin/sh\";", "\"/usr/bin/dash\";", "\"/usr/bin/bash\";", "\"/usr/bin/zsh\";",
  "\"/usr/local/bin/sh\";", "\"/usr/local/bin/dash\";", "\"/usr/local/bin/bash\";", "\"/usr/local/bin/zsh\";"
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionin
  • ProcessRollup2
  • exec
  • exec_event
  • executed
  • process_started
  • start
field:"EventType" kind:in
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.argseq
  • exec
field:"process.args" kind:eq value:"exec"
process.argsin
  • "/bin/bash";
  • "/bin/dash";
  • "/bin/sh";
  • "/bin/zsh";
  • "/usr/bin/bash";
  • "/usr/bin/dash";
  • "/usr/bin/sh";
  • "/usr/bin/zsh";
  • "/usr/local/bin/bash";
  • "/usr/local/bin/dash";
  • "/usr/local/bin/sh";
  • "/usr/local/bin/zsh";
  • "bash";
  • "dash";
  • "sh";
  • "zsh";
field:"process.args" kind:in
process.nameeq
  • perl
field:"process_basename" kind:eq value:"perl"

Keystrokes Input Capture from Suspicious CallStack

#
Source
github.com/elastic/protections-artifacts

Identifies attempts to enumerate the state of keyboard keys and the call is coming from a suspicious call stack. Adversaries may log user keystrokes to intercept credentials or other information from the user as the user types them.

MITRE ATT&CK Coverage

TacticTechniques
Collection

Rule Body

[rule]
description = """
Identifies attempts to enumerate the state of keyboard keys and the call is coming from a suspicious call stack.
Adversaries may log user keystrokes to intercept credentials or other information from the user as the user types them.
"""
id = "6ef43c9a-25af-449c-8416-20349780a146"
license = "Elastic License v2"
name = "Keystrokes Input Capture from Suspicious CallStack"
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.22"

query = '''
api where
 process.thread.Ext.call_stack_final_user_module.hash.sha256 != null and
 (
  process.Ext.api.name == "GetAsyncKeyState" or
  (process.Ext.api.name == "RegisterRawInputDevices" and
   process.Ext.api.parameters.usage == "KEYBOARD" and process.Ext.api.parameters.flags like "*INPUTSINK*") or
  (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.thread.Ext.call_stack_final_user_module.name != null and process.executable != null and 
  process.thread.Ext.call_stack_summary :
           ("win32u.dll|Unknown|*",
            "*win32u.dll|user32.dll|Unknown|*",
            "win32u.dll|Unbacked|*",
            "*win32u.dll|user32.dll|Unbacked|*",
            "win32u.dll|user32.dll|Unbacked",
            "*|python*.dll*",
            "Unknown",
            "Unbacked") and 
  not (process.thread.Ext.call_stack_summary : "*clr.dll*" and process.thread.Ext.call_stack_final_user_module.name : "Unbacked") and 
  not process.thread.Ext.call_stack_final_user_module.path : 
                              ("?:\\Program Files\\*",
                               "?:\\Program Files (x86)\\*",
                               "?:\\Windows\\*", 
                               "\\Program Files\\*",
                               "\\Program Files (x86)\\*",
                               "\\Windows\\*") and 
  not process.thread.Ext.call_stack_final_user_module.name : ("Unknown", "Undetermined") and
  not _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.trusted == true and
                   $entry.subject_name in (".NET", "Microsoft Corporation", "Microsoft Windows", "Sophos Limited", "EOG Resources, Inc.")) and
  not process.executable : 
                   ("?:\\Program Files (x86)\\Image Express\\ixDrill\\ixDrill.exe", 
                    "?:\\Windows\\System32\\DellTPad\\ApMsgFwd.exe", 
                    "?:\\Windows\\System32\\FMAPP.exe",
                    "?:\\Program Files (x86)\\Power Automate Desktop\\PAD.Console.Host.exe",
                    "?:\\Program Files (x86)\\SuperPuTTY\\SuperPutty.exe",
                    "?:\\Program Files\\SuperPuTTY*\\SuperPutty.exe",
                    "C:\\Program Files\\Four Winds Interactive\\Content Player\\Signage.exe",
                    "C:\\Program Files\\WindowsApps\\Microsoft.PowerAutomateDesktop_*\\dotnet\\PAD.Console.Host.exe",
                    "C:\\Program Files (x86)\\Hyland\\OCR for AnyDoc\\OCRforAnyDoc.exe",
                    "C:\\Program Files\\Dell\\Dell Display and Peripheral Manager\\Plugins\\DDPM.Subagent.User\\DDPM.Subagent.User.exe") and
  not (process.code_signature.trusted == true and
       process.code_signature.subject_name in ("Grammarly, Inc.", "HP Inc.", "Proofpoint, Inc.", "ETH Zürich", "Learnpulse",
        "Qisda Corporation", "ONELAUNCH TECHNOLOGIES INC.", "Laserfiche", "ARTICULATE GLOBAL, LLC",
        "Connectwise, LLC", "Carl Zeiss Microscopy GmbH", "Articulate Global, Inc.", "JItbit LP", "Dell Inc.",
        "Roblox Corporation", "Colony Labs, Inc.", "Devolutions Inc", "Wispr AI, Inc.", "Adobe Inc.", "Activision Publishing Inc")) and
  not process.thread.Ext.call_stack_final_user_module.hash.sha256 in ("120446e2c7729a7ae15e08bcc5cdb95c35151aa0f7e803e53dc7e92a1579783d",
                                                                      "46327ac3d7979cfc254ba0e76cd17b3a72128034f3618e8247bdcc9f6d84aea2",
                                                                      "557ae751c11dfb2a9a976c3312f469a4f0b776c1088aeeefdee99b5327aa2fed",
                                                                      "a57b437a7fe4eb285830564839f37a6704fa1f9dfe4a9a631cd28db43a83320c",
                                                                      "604d2cddc32d62da41c9553f35eb9aac442574db219cb63caae25205bbff88f8")
'''

min_endpoint_version = "8.12.0"
optional_actions = []
reputation = true
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[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.thread.Ext.call_stack_final_user_module.hash.sha256 != null and
 (
  process.Ext.api.name == "GetAsyncKeyState" or
  (process.Ext.api.name == "RegisterRawInputDevices" and
   process.Ext.api.parameters.usage == "KEYBOARD" and process.Ext.api.parameters.flags like "*INPUTSINK*") or
  (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.thread.Ext.call_stack_final_user_module.name != null and process.executable != null and 
  process.thread.Ext.call_stack_summary :
           ("win32u.dll|Unknown|*",
            "*win32u.dll|user32.dll|Unknown|*",
            "win32u.dll|Unbacked|*",
            "*win32u.dll|user32.dll|Unbacked|*",
            "win32u.dll|user32.dll|Unbacked",
            "*|python*.dll*",
            "Unknown",
            "Unbacked") and 
  not (process.thread.Ext.call_stack_summary : "*clr.dll*" and process.thread.Ext.call_stack_final_user_module.name : "Unbacked") and 
  not process.thread.Ext.call_stack_final_user_module.path : 
                              ("?:\\Program Files\\*",
                               "?:\\Program Files (x86)\\*",
                               "?:\\Windows\\*", 
                               "\\Program Files\\*",
                               "\\Program Files (x86)\\*",
                               "\\Windows\\*") and 
  not process.thread.Ext.call_stack_final_user_module.name : ("Unknown", "Undetermined") and
  not _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.trusted == true and
                   $entry.subject_name in (".NET", "Microsoft Corporation", "Microsoft Windows", "Sophos Limited", "EOG Resources, Inc.")) and
  not process.executable : 
                   ("?:\\Program Files (x86)\\Image Express\\ixDrill\\ixDrill.exe", 
                    "?:\\Windows\\System32\\DellTPad\\ApMsgFwd.exe", 
                    "?:\\Windows\\System32\\FMAPP.exe",
                    "?:\\Program Files (x86)\\Power Automate Desktop\\PAD.Console.Host.exe",
                    "?:\\Program Files (x86)\\SuperPuTTY\\SuperPutty.exe",
                    "?:\\Program Files\\SuperPuTTY*\\SuperPutty.exe",
                    "C:\\Program Files\\Four Winds Interactive\\Content Player\\Signage.exe",
                    "C:\\Program Files\\WindowsApps\\Microsoft.PowerAutomateDesktop_*\\dotnet\\PAD.Console.Host.exe",
                    "C:\\Program Files (x86)\\Hyland\\OCR for AnyDoc\\OCRforAnyDoc.exe",
                    "C:\\Program Files\\Dell\\Dell Display and Peripheral Manager\\Plugins\\DDPM.Subagent.User\\DDPM.Subagent.User.exe") and
  not (process.code_signature.trusted == true and
       process.code_signature.subject_name in ("Grammarly, Inc.", "HP Inc.", "Proofpoint, Inc.", "ETH Zürich", "Learnpulse",
        "Qisda Corporation", "ONELAUNCH TECHNOLOGIES INC.", "Laserfiche", "ARTICULATE GLOBAL, LLC",
        "Connectwise, LLC", "Carl Zeiss Microscopy GmbH", "Articulate Global, Inc.", "JItbit LP", "Dell Inc.",
        "Roblox Corporation", "Colony Labs, Inc.", "Devolutions Inc", "Wispr AI, Inc.", "Adobe Inc.", "Activision Publishing Inc")) and
  not process.thread.Ext.call_stack_final_user_module.hash.sha256 in ("120446e2c7729a7ae15e08bcc5cdb95c35151aa0f7e803e53dc7e92a1579783d",
                                                                      "46327ac3d7979cfc254ba0e76cd17b3a72128034f3618e8247bdcc9f6d84aea2",
                                                                      "557ae751c11dfb2a9a976c3312f469a4f0b776c1088aeeefdee99b5327aa2fed",
                                                                      "a57b437a7fe4eb285830564839f37a6704fa1f9dfe4a9a631cd28db43a83320c",
                                                                      "604d2cddc32d62da41c9553f35eb9aac442574db219cb63caae25205bbff88f8")

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.thread.Ext.call_stack_final_user_module.code_signaturearray_any(no value, null check)excludes:process.thread.Ext.call_stack_final_user_module.code_signature
process.code_signature.subject_nameinARTICULATE GLOBAL, LLC, Activision Publishing Inc, Adobe Inc., Articulate Global, Inc., Carl Zeiss Microscopy GmbH, Colony Labs, Inc., Connectwise, LLC, Dell Inc., Devolutions Inc, ETH Zürich, Grammarly, Inc., HP Inc., JItbit LP, Laserfiche, Learnpulse, ONELAUNCH TECHNOLOGIES INC., Proofpoint, Inc., Qisda Corporation, Roblox Corporation, Wispr AI, Inc.excludes:process.code_signature.subject_name
process.code_signature.trustedeqtrueexcludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true"
process.thread.Ext.call_stack_final_user_module.nameeqUnbackedexcludes:process.thread.Ext.call_stack_final_user_module.name field:"process.thread.Ext.call_stack_final_user_module.name" value:"Unbacked"
process.thread.Ext.call_stack_summarymatchclr.dllexcludes:process.thread.Ext.call_stack_summary field:"process.thread.Ext.call_stack_summary" value:"clr.dll"
process.executablewildcard?:\Program Files (x86)\Image Express\ixDrill\ixDrill.exe, ?:\Windows\System32\DellTPad\ApMsgFwd.exe, ?:\Windows\System32\FMAPP.exe, ?:\Program Files (x86)\Power Automate Desktop\PAD.Console.Host.exe, ?:\Program Files (x86)\SuperPuTTY\SuperPutty.exe, ?:\Program Files\SuperPuTTY*\SuperPutty.exe, C:\Program Files\Four Winds Interactive\Content Player\Signage.exe, C:\Program Files\WindowsApps\Microsoft.PowerAutomateDesktop_*\dotnet\PAD.Console.Host.exe, C:\Program Files (x86)\Hyland\OCR for AnyDoc\OCRforAnyDoc.exe, C:\Program Files\Dell\Dell Display and Peripheral Manager\Plugins\DDPM.Subagent.User\DDPM.Subagent.User.exeexcludes:process.executable
process.thread.Ext.call_stack_final_user_module.hash.sha256in120446e2c7729a7ae15e08bcc5cdb95c35151aa0f7e803e53dc7e92a1579783d, 46327ac3d7979cfc254ba0e76cd17b3a72128034f3618e8247bdcc9f6d84aea2, 557ae751c11dfb2a9a976c3312f469a4f0b776c1088aeeefdee99b5327aa2fed, 604d2cddc32d62da41c9553f35eb9aac442574db219cb63caae25205bbff88f8, a57b437a7fe4eb285830564839f37a6704fa1f9dfe4a9a631cd28db43a83320cexcludes:process.thread.Ext.call_stack_final_user_module.hash.sha256
process.thread.Ext.call_stack_final_user_module.nameeqUnknown, Undeterminedexcludes:process.thread.Ext.call_stack_final_user_module.name field:"process.thread.Ext.call_stack_final_user_module.name" value:"Unknown" field:"process.thread.Ext.call_stack_final_user_module.name" value:"Undetermined"
process.thread.Ext.call_stack_final_user_module.pathstarts_with?:\Program Files\, ?:\Program Files (x86)\, ?:\Windows\, \Program Files\, \Program Files (x86)\, \Windows\excludes:process.thread.Ext.call_stack_final_user_module.path

Kubernetes and Cloud Credential Path Access via Process Arguments

#
Status
production
Severity
high
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Flags Linux process executions whose arguments reference high-value Kubernetes service-account material, kubeconfig or node PKI paths, or common cloud files, when invoked via typical file-reading utilities or from ephemeral directories. Useful for spotting in-cluster and hybrid credential theft early.

Known False Positives

  • Legitimate backup, compliance scanners, or admin scripts that enumerate paths under /home or /var/run/secrets may match. Tune by parent process, image, or automation identity.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2026/04/29"
integration = ["endpoint", "auditd_manager"]
maturity = "production"
updated_date = "2026/05/26"

[rule]
author = ["Elastic"]
description = """
Flags Linux process executions whose arguments reference high-value Kubernetes service-account material, kubeconfig or
node PKI paths, or common cloud files, when invoked via typical file-reading utilities or from ephemeral directories. 
Useful for spotting in-cluster and hybrid credential theft early.
"""
false_positives = [
    """
    Legitimate backup, compliance scanners, or admin scripts that enumerate paths under /home or /var/run/secrets may
    match. Tune by parent process, image, or automation identity.
    """,
]
from = "now-9m"
index = ["auditbeat-*", "logs-auditd_manager.auditd-*", "logs-endpoint.events.process*"]
language = "kuery"
license = "Elastic License v2"
name = "Kubernetes and Cloud Credential Path Access via Process Arguments"
note = """## Triage and analysis

### Investigating Kubernetes and Cloud Credential Path Access via Process Arguments

Confirm whether the process user and parent chain are expected to read the matched path (for example a CI job,
bootstrap script, or kubelet). Reconstruct the full command line and check for piping, encoding, or exfiltration
patterns immediately after the read.

### Possible investigation steps

- Map the workload or login session to an identity; prioritize events from nodes, jump hosts, or pods with mounted
  service account tokens.
- Correlate with file, network, and Kubernetes audit telemetry for secret reads, token minting, or API calls using
  harvested material.

### Response and remediation

- Rotate affected service account tokens, kubeconfigs, and cloud keys when access was unauthorized; review RBAC and
  secret mount policy for the workload.
"""
references = [
    "https://attack.mitre.org/techniques/T1552/",
    "https://kubernetes.io/docs/concepts/security/service-accounts/",
]
risk_score = 73
rule_id = "5f0fff18-f340-444b-9a98-c49ade766ff4"
setup = """## Setup

Requires **Elastic Defend** and/or **Auditd Manager** process telemetry (`logs-endpoint.events.process*`,
`logs-auditd_manager.auditd-*`, `auditbeat-*`) with command-line argument capture for exec events.

### Elastic Defend
Install the Elastic Defend integration via Fleet on Linux hosts and use a policy that collects process events with
arguments.

### Auditd Manager
Deploy Auditd Manager and ensure execve (or equivalent process) auditing is enabled so `process.args` and
`process.executable` populate for monitored binaries.

See https://docs.elastic.co/integrations/auditd_manager
"""
severity = "high"
tags = [
    "Data Source: Auditd Manager",
    "Data Source: Elastic Defend",
    "Domain: Endpoint",
    "Domain: Kubernetes",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
host.os.type:linux and event.category:process and event.action:(exec or executed) and 
(
  process.name:(
    busybox or cat or head or tail or more or less or sed or awk or 
    find or grep or ls or whereis or cp or mv or ln or
    curl or wget or scp or rsync or tar or zip or gzip or
    base64 or xxd or od or dd or tee or strings or xargs or jq or yq or
    openssl or ssh or sftp or nc or ncat or netcat or socat or
    python* or perl* or ruby* or node or php* or lua* or .*
  ) or
  process.args:(
    cat or head or tail or more or less or sed or awk or 
    find or grep or cp or mv or curl or wget or base64 or 
    tar or scp or dd or strings or xargs
  ) or
  process.executable:(/tmp/* or /var/tmp/* or /dev/shm/* or /home/* or /run/user/*)
) and process.args:(
  "/var/run/secrets/kubernetes.io/serviceaccount/token" or
  "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" or
  "/var/run/secrets/eks.amazonaws.com/serviceaccount/token" or
  "/var/run/secrets/azure/tokens/azure-identity-token" or
  "/var/run/secrets/tokens/azure-identity-token" or
  "/var/lib/kubelet/kubeconfig" or
  "/etc/kubernetes/admin.conf" or
  "/etc/kubernetes/pki/ca.key" or
  "/etc/kubernetes/pki/apiserver-kubelet-client.key" or
  "/var/lib/kubelet/pki/kubelet-client-current.pem" or
  "/etc/rancher/k3s/k3s.yaml" or
  */.aws/credentials or
  */.aws/cli/cache/*.json or
  */.aws/sso/cache/*.json or
  */.azure/accessTokens.json or
  */.azure/azureProfile.json or
  */.azure/msal_token_cache.json or
  */confluence/confluence.cfg.xml or 
  *confluence/conf/server.xml
  */.config/gcloud/application_default_credentials.json or
  */.config/gcloud/credentials.db or
  */.config/gcloud/access_tokens.db or
  */.config/gcloud/legacy_credentials or
  */.kube/config or
  */.docker/config.json
) 
'''

[[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.001"
name = "Credentials In Files"
reference = "https://attack.mitre.org/techniques/T1552/001/"


[[rule.threat.technique]]
id = "T1528"
name = "Steal Application Access Token"
reference = "https://attack.mitre.org/techniques/T1528/"

[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"

Stages and Predicates

Stage 1: query

host.os.type:linux and event.category:process and event.action:(exec or executed) and 
(
  process.name:(
    busybox or cat or head or tail or more or less or sed or awk or 
    find or grep or ls or whereis or cp or mv or ln or
    curl or wget or scp or rsync or tar or zip or gzip or
    base64 or xxd or od or dd or tee or strings or xargs or jq or yq or
    openssl or ssh or sftp or nc or ncat or netcat or socat or
    python* or perl* or ruby* or node or php* or lua* or .*
  ) or
  process.args:(
    cat or head or tail or more or less or sed or awk or 
    find or grep or cp or mv or curl or wget or base64 or 
    tar or scp or dd or strings or xargs
  ) or
  process.executable:(/tmp/* or /var/tmp/* or /dev/shm/* or /home/* or /run/user/*)
) and process.args:(
  "/var/run/secrets/kubernetes.io/serviceaccount/token" or
  "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" or
  "/var/run/secrets/eks.amazonaws.com/serviceaccount/token" or
  "/var/run/secrets/azure/tokens/azure-identity-token" or
  "/var/run/secrets/tokens/azure-identity-token" or
  "/var/lib/kubelet/kubeconfig" or
  "/etc/kubernetes/admin.conf" or
  "/etc/kubernetes/pki/ca.key" or
  "/etc/kubernetes/pki/apiserver-kubelet-client.key" or
  "/var/lib/kubelet/pki/kubelet-client-current.pem" or
  "/etc/rancher/k3s/k3s.yaml" or
  */.aws/credentials or
  */.aws/cli/cache/*.json or
  */.aws/sso/cache/*.json or
  */.azure/accessTokens.json or
  */.azure/azureProfile.json or
  */.azure/msal_token_cache.json or
  */confluence/confluence.cfg.xml or 
  *confluence/conf/server.xml
  */.config/gcloud/application_default_credentials.json or
  */.config/gcloud/credentials.db or
  */.config/gcloud/access_tokens.db or
  */.config/gcloud/legacy_credentials or
  */.kube/config or
  */.docker/config.json
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionin
  • exec
  • executed
field:"EventType" kind:in
event.categoryeq
  • process
field:"event.category" kind:eq value:"process"
process.argseq
  • /etc/kubernetes/admin.conf
  • /etc/kubernetes/pki/apiserver-kubelet-client.key
  • /etc/kubernetes/pki/ca.key
  • /etc/rancher/k3s/k3s.yaml
  • /var/lib/kubelet/kubeconfig
  • /var/lib/kubelet/pki/kubelet-client-current.pem
  • /var/run/secrets/azure/tokens/azure-identity-token
  • /var/run/secrets/eks.amazonaws.com/serviceaccount/token
  • /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
  • /var/run/secrets/kubernetes.io/serviceaccount/token
  • /var/run/secrets/tokens/azure-identity-token
field:"process.args" kind:eq
process.argsin
  • awk
  • base64
  • cat
  • cp
  • curl
  • dd
  • find
  • grep
  • head
  • less
  • more
  • mv
  • scp
  • sed
  • strings
  • tail
  • tar
  • wget
  • xargs
field:"process.args" kind:in
process.argswildcard
  • */.aws/cli/cache/*.json
  • */.aws/credentials
  • */.aws/sso/cache/*.json
  • */.azure/accessTokens.json
  • */.azure/azureProfile.json
  • */.azure/msal_token_cache.json
  • */.config/gcloud/access_tokens.db
  • */.config/gcloud/credentials.db
  • */.config/gcloud/legacy_credentials
  • */.docker/config.json
  • */.kube/config
  • */confluence/confluence.cfg.xml
  • *confluence/conf/server.xml */.config/gcloud/application_default_credentials.json
field:"process.args" kind:wildcard
process.executablewildcard
  • /dev/shm/*
  • /home/*
  • /run/user/*
  • /tmp/*
  • /var/tmp/*
field:"Image" kind:wildcard
process.nameeq
  • awk
  • base64
  • busybox
  • cat
  • cp
  • curl
  • dd
  • find
  • grep
  • gzip
  • head
  • jq
  • less
  • ln
  • ls
  • more
  • mv
  • nc
  • ncat
  • netcat
  • node
  • od
  • openssl
  • rsync
  • scp
  • sed
  • sftp
  • socat
  • ssh
  • strings
  • tail
  • tar
  • tee
  • wget
  • whereis
  • xargs
  • xxd
  • yq
  • zip
field:"process_basename" kind:eq
process.namewildcard
  • .*
  • lua*
  • perl*
  • php*
  • python*
  • ruby*
field:"process_basename" kind:wildcard

LSASS Memory Dump Creation

#
Status
production
Severity
high
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies creation of LSASS memory dump artifacts with filenames matching LSASS dumps or common dumping-tool outputs, including dumpert.dmp, Andrew.dmp, SQLDmpr*.mdmp, and Coredump.dmp. This can indicate credential access through trusted utilities such as Task Manager or SQLDumper, or known tooling such as Dumpert and AndrewSpecial.

MITRE ATT&CK Coverage

TacticTechniques
Credential Access

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2020/11/24"
integration = ["endpoint", "windows", "m365_defender", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/04/24"

[rule]
author = ["Elastic"]
description = """
Identifies creation of LSASS memory dump artifacts with filenames matching LSASS dumps or common dumping-tool outputs,
including dumpert.dmp, Andrew.dmp, SQLDmpr*.mdmp, and Coredump.dmp. This can indicate credential access through
trusted utilities such as Task Manager or SQLDumper, or known tooling such as Dumpert and AndrewSpecial.
"""
from = "now-9m"
index = [
    "winlogbeat-*",
    "logs-endpoint.events.file-*",
    "logs-windows.sysmon_operational-*",
    "endgame-*",
    "logs-m365_defender.event-*",
    "logs-sentinel_one_cloud_funnel.*",
]
language = "eql"
license = "Elastic License v2"
name = "LSASS Memory Dump Creation"
references = ["https://github.com/outflanknl/Dumpert", "https://github.com/hoangprod/AndrewSpecial"]
risk_score = 73
rule_id = "f2f46686-6f3c-4724-bd7d-24e31c70f98f"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Data Source: Elastic Endgame",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
    "Data Source: Sysmon",
    "Data Source: Microsoft Defender XDR",
    "Data Source: SentinelOne",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
file where host.os.type == "windows" and event.action != "deletion" and
  file.name : ("lsass*.dmp", "dumpert.dmp", "Andrew.dmp", "SQLDmpr*.mdmp", "Coredump.dmp") and

  not (
        process.executable : (
          "?:\\Program Files\\Microsoft SQL Server\\*\\Shared\\SqlDumper.exe",
          "?:\\Program Files\\Microsoft SQL Server Reporting Services\\SSRS\\ReportServer\\bin\\SqlDumper.exe",
          "?:\\Windows\\System32\\dllhost.exe"
        ) and
        file.path : (
          "?:\\*\\Reporting Services\\Logfiles\\SQLDmpr*.mdmp",
          "?:\\Program Files\\Microsoft SQL Server Reporting Services\\SSRS\\Logfiles\\SQLDmpr*.mdmp",
          "?:\\Program Files\\Microsoft SQL Server\\*\\Shared\\ErrorDumps\\SQLDmpr*.mdmp",
          "?:\\Program Files\\Microsoft SQL Server\\*\\MSSQL\\LOG\\SQLDmpr*.mdmp"
        )
      ) and

  not (
        process.executable : (
          "?:\\Windows\\system32\\WerFault.exe",
          "?:\\Windows\\System32\\WerFaultSecure.exe"
          ) and
        file.path : (
          "?:\\Windows\\System32\\config\\systemprofile\\AppData\\Local\\CrashDumps\\lsass.exe.*.dmp",
          "?:\\Windows\\System32\\%LOCALAPPDATA%\\CrashDumps\\lsass.exe.*.dmp"
        )
  )
'''

note = """## Triage and analysis

### Investigating LSASS Memory Dump Creation

#### Possible investigation steps

- What dump artifact did the alert record, and does it look like crash handling or credential collection?
  - Focus: `file.path`, `file.name`, `file.extension`, `file.size`, and the alerting `process.entity_id`.
  - Implication: escalate when the path is user-writable, remote, hidden, or deceptive, or when `file.name` is "dumpert.dmp", "Andrew.dmp", "Coredump.dmp", or an LSASS-named dump outside a recognized crash location; lower suspicion only when the artifact fits a known crash-analysis, vendor support, or IR acquisition path for this `host.id`.
  - Hint: the rule already filters common WER LSASS crash paths and expected SQLDumper dump locations, so a remaining SQLDmpr or LSASS dump path needs its own workflow explanation.

- Is the writer an expected dump utility in an expected execution context?
  - Focus: `process.executable`, `process.pe.original_file_name`, `process.code_signature.subject_name`, `process.code_signature.trusted`, and `process.command_line`. $investigate_4
  - Implication: escalate when the writer is unsigned, renamed, user-writable, launched with dump-specific arguments, or matches a "rundll32.exe" Dumpert DLL chain; reduce concern only when signer, path, arguments, and parent context all fit the same recognized diagnostic or IR workflow. Identity alone does not clear LSASS dumping.

- Does the parent chain and user context explain why this account created an LSASS dump?
  - Focus: `process.parent.executable`, `process.parent.command_line`, `process.Ext.ancestry`, `user.id`, and `user.name`.
  - Implication: escalate when shells, script hosts, Office, browsers, remote-admin tooling, or an unexpected user launch the writer; lower suspicion only when lineage and `user.id` match the same recognized support, vendor, or forensic collection workflow.

- Did the same writer hide, move, archive, or copy the dump after creation?
  - Focus: same-writer file events for `host.id` and `process.entity_id`, especially `file.path`, `file.Ext.original.path`, `file.name`, and `file.size`. $investigate_0
  - Implication: escalate when the dump is renamed, compressed, copied to a share, moved into hidden or user-controlled paths, or removed after staging; unresolved when same-writer file telemetry does not explain the dump's handling.
  - Hint: use `file.Ext.original.path` on rename events to connect a detected dump name to a later archive, deceptive extension, or alternate staging path.

- Did child processes use or clean up the dump?
  - Focus: child process events on `host.id` where `process.parent.entity_id` equals the writer `process.entity_id`, with `process.executable`, `process.command_line`, and `@timestamp`. $investigate_1
  - Implication: escalate when archivers, copy tools, PowerShell, "rundll32.exe", dump parsers such as Mimikatz, or deletion commands follow the dump write; no child follow-on only narrows this path and does not rule out in-process or remote retrieval.

- Does the host or session make the exposed credential material high impact?
  - Focus: `host.id`, `host.name`, `user.domain`, `user.id`, and `process.Ext.session_info.logon_type`; asset or host-role context when available.
  - Implication: raise urgency when the dump is on a server, jump host, domain controller, privileged admin workstation, or from an unexpected administrative session; a lab or diagnostics host lowers urgency only after artifact, writer, lineage, and handling evidence fit one recognized workflow.

- If local evidence is suspicious or unresolved, do related alerts change scope?
  - Focus: related credential-access, staging, privilege, or lateral-movement alerts for `user.id`. $investigate_2
  - Hint: compare related alerts for `host.id` separately to determine whether activity is isolated to this host or part of broader compromise. $investigate_3
  - Implication: broaden containment when the same user or host has related credential-access or post-compromise alerts; keep scope local when related alerts are quiet, but do not use quiet scoping to close unresolved dump evidence.

- Escalate when artifact, writer, lineage, staging, child-process, host-role, or related-alert evidence shows deliberate LSASS collection or broader compromise; close only when those categories bind to one recognized troubleshooting, vendor support, or IR workflow for this host; preserve artifacts and escalate when evidence is mixed or incomplete.

### False positive analysis

- Recognized crash analysis, vendor support, Task Manager troubleshooting, SQL Server diagnostics outside filtered paths, or IR/forensic acquisition can legitimately create LSASS dumps. Confirm by aligning identity (`process.executable`, `process.code_signature.subject_name`, `process.pe.original_file_name`), artifact (`file.path`, `file.name`, `file.size`, rename history), lineage (`process.parent.executable`, `process.parent.command_line`), actor (`user.id`, `user.domain`), and host (`host.id`, role) to the same exact workflow. If any dimension contradicts the workflow or telemetry cannot explain why LSASS was dumped, do not close on owner or change-record claims alone.
- If workflow records or owner confirmation are unavailable, require telemetry-only stability for the same workflow pattern on the same `host.id` and `user.id` across prior alerts before considering closure; a first-time or one-off LSASS dump remains suspicious unless artifact, writer, lineage, and handling evidence are clean.
- Build exceptions from the minimum confirmed pattern: `process.executable`, `process.code_signature.subject_name`, `process.pe.original_file_name`, parent workflow, `file.path` pattern, `user.id`, and `host.id`. Avoid exceptions on `file.name`, `process.name`, LSASS naming, or host alone.

### Response and remediation

- If confirmed benign, reverse temporary containment and document the dump path, writer identity, signer, parent workflow, user, host role, and confirming workflow evidence. Create an exception only when the same workflow recurs consistently for the same scope.
- If suspicious but unconfirmed, preserve the dump or case-safe copy, `file.path`, rename/archive paths, writer `process.entity_id`, `process.command_line`, parent chain, child-process records, `user.id`, and `host.id` before containment or cleanup. Apply reversible containment first, such as restricting outbound administrative access or suspending the writer when operationally safe. Escalate to host isolation or account containment only when staging, transfer, parsing, or related-alert evidence shows likely credential theft.
- If confirmed malicious, isolate the host when host role permits, or escalate with the preserved artifact set to the team that can contain it. Record artifacts before terminating processes or deleting dumps, archives, or tools.
- Treat confirmed LSASS dump exposure on servers, jump hosts, domain controllers, or privileged administration assets as credential compromise risk. Scope which local, cached, service, or administrative credentials may have been present and begin credential hygiene for implicated accounts and systems.
- Eradicate unauthorized dump utilities, scripts, archives, copied dumps, and persistence mechanisms found during the investigation, then remediate the privilege path or initial access route that allowed dump creation.
- After containment, hunt for the same writer paths, dump-file naming patterns, "rundll32.exe" Dumpert launch chains, and archive or copy commands across other hosts.
"""

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 11 - File Create](https://ela.st/sysmon-event-11-setup)
"""

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "host.name",
    "host.id",
    "user.id",
    "process.entity_id",
    "process.executable",
    "process.command_line",
    "process.pe.original_file_name",
    "process.parent.executable",
    "process.parent.command_line",
    "process.code_signature.subject_name",
    "process.code_signature.trusted",
    "process.Ext.session_info.logon_type",
    "file.path",
    "file.Ext.original.path",
]

[[transform.investigate]]
label = "File events by dump writer"
description = ""
providers = [
  [
    { 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" },
    { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[transform.investigate]]
label = "Child processes by dump writer"
description = ""
providers = [
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[transform.investigate]]
label = "Alerts associated with the user"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", 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"

[[transform.investigate]]
label = "Process events by dump writer"
description = ""
providers = [
  [
    { 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" },
    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[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.subtechnique]]
id = "T1003.001"
name = "LSASS Memory"
reference = "https://attack.mitre.org/techniques/T1003/001/"

[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"

Stages and Predicates

Stage 1: file

file where host.os.type == "windows" and event.action != "deletion" and
  file.name : ("lsass*.dmp", "dumpert.dmp", "Andrew.dmp", "SQLDmpr*.mdmp", "Coredump.dmp") and

  not (
        process.executable : (
          "?:\\Program Files\\Microsoft SQL Server\\*\\Shared\\SqlDumper.exe",
          "?:\\Program Files\\Microsoft SQL Server Reporting Services\\SSRS\\ReportServer\\bin\\SqlDumper.exe",
          "?:\\Windows\\System32\\dllhost.exe"
        ) and
        file.path : (
          "?:\\*\\Reporting Services\\Logfiles\\SQLDmpr*.mdmp",
          "?:\\Program Files\\Microsoft SQL Server Reporting Services\\SSRS\\Logfiles\\SQLDmpr*.mdmp",
          "?:\\Program Files\\Microsoft SQL Server\\*\\Shared\\ErrorDumps\\SQLDmpr*.mdmp",
          "?:\\Program Files\\Microsoft SQL Server\\*\\MSSQL\\LOG\\SQLDmpr*.mdmp"
        )
      ) and

  not (
        process.executable : (
          "?:\\Windows\\system32\\WerFault.exe",
          "?:\\Windows\\System32\\WerFaultSecure.exe"
          ) and
        file.path : (
          "?:\\Windows\\System32\\config\\systemprofile\\AppData\\Local\\CrashDumps\\lsass.exe.*.dmp",
          "?:\\Windows\\System32\\%LOCALAPPDATA%\\CrashDumps\\lsass.exe.*.dmp"
        )
  )

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionne
  • deletion corpus 90 (elastic 90)
field:"EventType" kind:ne value:"deletion"
file.namewildcard
  • Andrew.dmp
  • Coredump.dmp
  • SQLDmpr*.mdmp
  • dumpert.dmp
  • lsass*.dmp corpus 2 (elastic 2)
field:"file.name" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
file.pathwildcard?:\*\Reporting Services\Logfiles\SQLDmpr*.mdmp, ?:\Program Files\Microsoft SQL Server Reporting Services\SSRS\Logfiles\SQLDmpr*.mdmp, ?:\Program Files\Microsoft SQL Server\*\Shared\ErrorDumps\SQLDmpr*.mdmp, ?:\Program Files\Microsoft SQL Server\*\MSSQL\LOG\SQLDmpr*.mdmpexcludes:file.path
process.executablewildcard?:\Program Files\Microsoft SQL Server\*\Shared\SqlDumper.exe, ?:\Program Files\Microsoft SQL Server Reporting Services\SSRS\ReportServer\bin\SqlDumper.exe, ?:\Windows\System32\dllhost.exeexcludes:process.executable field:"process.executable" value:"?:\Program Files\Microsoft SQL Server\*\Shared\SqlDumper.exe" field:"process.executable" value:"?:\Program Files\Microsoft SQL Server Reporting Services\SSRS\ReportServer\bin\SqlDumper.exe" field:"process.executable" value:"?:\Windows\System32\dllhost.exe"
file.pathwildcard?:\Windows\System32\config\systemprofile\AppData\Local\CrashDumps\lsass.exe.*.dmp, ?:\Windows\System32\%LOCALAPPDATA%\CrashDumps\lsass.exe.*.dmpexcludes:file.path field:"file.path" value:"?:\Windows\System32\config\systemprofile\AppData\Local\CrashDumps\lsass.exe.*.dmp" field:"file.path" value:"?:\Windows\System32\%LOCALAPPDATA%\CrashDumps\lsass.exe.*.dmp"
process.executableeq?:\Windows\system32\WerFault.exe, ?:\Windows\System32\WerFaultSecure.exeexcludes:process.executable field:"process.executable" value:"?:\Windows\system32\WerFault.exe" field:"process.executable" value:"?:\Windows\System32\WerFaultSecure.exe"

M365 OneDrive Malware File Upload

#
Status
production
Severity
high
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies the occurrence of files uploaded to OneDrive being detected as Malware by the file scanning engine. Attackers can use File Sharing and Organization Repositories to spread laterally within the company and amplify their access. Users can inadvertently share these files without knowing their maliciousness, giving adversaries an opportunity to gain initial access to other endpoints in the environment.

Known False Positives

  • Benign files can trigger signatures in the built-in virus protection

MITRE ATT&CK Coverage

TacticTechniques
Resource Development
Lateral Movement

Telemetry Coverage

PlatformRecord / event type
Microsoft 365FileMalwareDetected

Rule Body

[metadata]
creation_date = "2022/01/10"
integration = ["o365"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Identifies the occurrence of files uploaded to OneDrive being detected as Malware by the file scanning engine. Attackers
can use File Sharing and Organization Repositories to spread laterally within the company and amplify their access.
Users can inadvertently share these files without knowing their maliciousness, giving adversaries an opportunity to gain
initial access to other endpoints in the environment.
"""
false_positives = ["Benign files can trigger signatures in the built-in virus protection"]
from = "now-9m"
index = ["logs-o365.audit-*", "filebeat-*"]
language = "kuery"
license = "Elastic License v2"
name = "M365 OneDrive Malware File Upload"
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 OneDrive Malware File Upload

OneDrive, a cloud storage service, facilitates file sharing and collaboration within organizations. However, adversaries can exploit this by uploading malware, which can spread across shared environments, leading to lateral movement within a network. The detection rule identifies such threats by monitoring OneDrive activities for malware detection events, focusing on file operations flagged by Microsoft's security engine. This proactive approach helps in identifying and mitigating potential breaches.

### Possible investigation steps

- Review the alert details to confirm the event dataset is 'o365.audit' and the event provider is 'OneDrive' to ensure the alert is relevant to OneDrive activities.
- Examine the specific file operation flagged by the event code 'SharePointFileOperation' and action 'FileMalwareDetected' to identify the file in question and understand the nature of the detected malware.
- Identify the user account associated with the file upload to determine if the account has been compromised or if the user inadvertently uploaded the malicious file.
- Check the sharing settings of the affected file to assess the extent of exposure and identify any other users or systems that may have accessed the file.
- Investigate the file's origin and history within the organization to trace how it was introduced into the environment and whether it has been shared or accessed by other users.
- Review any additional security alerts or logs related to the user account or file to identify potential patterns of malicious activity or further compromise.
- Coordinate with IT and security teams to isolate the affected file and user account, and initiate remediation steps to prevent further spread of the malware.

### False positive analysis

- Legitimate software updates or patches may be flagged as malware if they are not yet recognized by the security engine. Users should verify the source and integrity of the file and consider adding it to an exception list if confirmed safe.
- Files containing scripts or macros used for automation within the organization might trigger false positives. Review the file's purpose and origin, and whitelist it if it is a known and trusted internal tool.
- Shared files from trusted partners or vendors could be mistakenly identified as threats. Establish a process to verify these files with the sender and use exceptions for recurring, verified files.
- Archived or compressed files that contain known safe content might be flagged due to their format. Decompress and scan the contents separately to confirm their safety before adding exceptions.
- Files with unusual or encrypted content used for legitimate business purposes may be misclassified. Ensure these files are documented and approved by IT security before excluding them from alerts.

### Response and remediation

- Immediately isolate the affected OneDrive account to prevent further file sharing and potential spread of malware within the organization.
- Notify the user associated with the account about the detected malware and instruct them to cease any file sharing activities until further notice.
- Conduct a thorough scan of the affected files using an updated antivirus or endpoint detection and response (EDR) solution to confirm the presence of malware and identify any additional infected files.
- Remove or quarantine the identified malicious files from OneDrive and any other locations they may have been shared to prevent further access or execution.
- Review and revoke any shared links or permissions associated with the infected files to ensure no unauthorized access is possible.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to determine if any lateral movement or additional compromise has occurred.
- Implement enhanced monitoring and alerting for similar OneDrive activities to quickly detect and respond to any future malware uploads or related threats.

## Setup

The Office 365 Logs Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = [
    "https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/virus-detection-in-spo?view=o365-worldwide",
]
risk_score = 73
rule_id = "bba1b212-b85c-41c6-9b28-be0e5cdfc9b1"
severity = "high"
tags = ["Domain: Cloud", "Data Source: Microsoft 365", "Tactic: Lateral Movement", "Resources: Investigation Guide"]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:o365.audit and event.provider:OneDrive and event.code:SharePointFileOperation and event.action:FileMalwareDetected
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1080"
name = "Taint Shared Content"
reference = "https://attack.mitre.org/techniques/T1080/"


[rule.threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1608"
name = "Stage Capabilities"
reference = "https://attack.mitre.org/techniques/T1608/"
[[rule.threat.technique.subtechnique]]
id = "T1608.001"
name = "Upload Malware"
reference = "https://attack.mitre.org/techniques/T1608/001/"


[rule.threat.tactic]
id = "TA0042"
name = "Resource Development"
reference = "https://attack.mitre.org/tactics/TA0042/"

Stages and Predicates

Stage 1: query

data_stream.dataset:o365.audit and event.provider:OneDrive and event.code:SharePointFileOperation and event.action:FileMalwareDetected

Indicators

These rows show field, operator, and value matches.

M365 SharePoint Search for Sensitive Content

#
Status
production
Severity
low
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies search queries in SharePoint containing sensitive terms related to credentials, financial data, PII, legal matters, or infrastructure information. Adversaries who compromise user accounts often search for high-value files before exfiltration. This rule detects searches containing terms across multiple sensitivity categories, regardless of the access method (browser, PowerShell, or API). The actual search query text is analyzed against a curated list of sensitive terms to identify potential reconnaissance activity.

Known False Positives

  • Security or compliance teams using eDiscovery or Content Search for legitimate investigations.
  • HR or finance personnel legitimately searching for employee or financial records.
  • IT administrators searching for configuration or infrastructure documentation.
  • Legal teams searching for contract or privileged documents.

MITRE ATT&CK Coverage

Telemetry Coverage

PlatformRecord / event type
Microsoft 365SearchQueryPerformed

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2026/02/24"
integration = ["o365"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Identifies search queries in SharePoint containing sensitive terms related to credentials, financial data,
PII, legal matters, or infrastructure information. Adversaries who compromise user accounts often search for high-value
files before exfiltration. This rule detects searches containing terms across multiple sensitivity categories,
regardless of the access method (browser, PowerShell, or API). The actual search query text is analyzed against a
curated list of sensitive terms to identify potential reconnaissance activity.
"""
false_positives = [
    "Security or compliance teams using eDiscovery or Content Search for legitimate investigations.",
    "HR or finance personnel legitimately searching for employee or financial records.",
    "IT administrators searching for configuration or infrastructure documentation.",
    "Legal teams searching for contract or privileged documents.",
]
from = "now-9m"
index = ["filebeat-*", "logs-o365.audit-*"]
language = "eql"
license = "Elastic License v2"
name = "M365 SharePoint Search for Sensitive Content"
note = """## Triage and Analysis

### Investigating M365 SharePoint Search for Sensitive Content

This rule detects search queries in SharePoint or OneDrive that contain sensitive terms. The Microsoft 365 Unified Audit Log captures the actual search query text in the `SearchQueryText` field, allowing detection of reconnaissance activity targeting credentials, financial data, PII, legal documents, or infrastructure information.

#### Possible Investigation Steps

- Identify who performed the search and determine if this user has a legitimate business need to search for this type of content.
- Review the exact search terms used. Multiple sensitive terms in one query are more suspicious.
- Determine if the search was via browser, automation tool (PnP PowerShell), or API.
- Review the source IP and correlate with the user's typical access patterns.
- Look for subsequent file download or access events from the same user/session within minutes of the search.
- Determine if the user is a member of roles that would legitimately search for sensitive content (HR, Finance, Legal, Security, Compliance).
- Check Azure AD sign-in logs for authentication anomalies (device code flow, unusual location).

### Response and Remediation

- If unauthorized search activity is confirmed, immediately review what files were accessed or downloaded following the search.
- Revoke the user's session tokens and require reauthentication with MFA.
- If the account was compromised, reset credentials and investigate the compromise vector.
- Review Data Loss Prevention (DLP) policies to ensure sensitive content is properly protected.
- Consider implementing sensitivity labels and access restrictions on high-value content.
"""
references = ["https://cloud.google.com/blog/topics/threat-intelligence/expansion-shinyhunters-saas-data-theft"]
risk_score = 21
rule_id = "4f2654e4-125b-11f1-af7d-f661ea17fbce"
severity = "low"
tags = [
    "Domain: Cloud",
    "Domain: SaaS",
    "Data Source: Microsoft 365",
    "Data Source: Microsoft 365 Audit Logs",
    "Use Case: Threat Detection",
    "Tactic: Discovery",
    "Tactic: Collection",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
web where data_stream.dataset == "o365.audit" and
    event.provider == "SharePoint" and
    event.action == "SearchQueryPerformed" and
    event.outcome == "success" and
    o365.audit.SearchQueryText != null and
    o365.audit.SearchQueryText != "" and
    o365.audit.SearchQueryText like~ (
        /* Credentials and Secrets */
        "*password*", "*credential*", "*secret*", "*api key*", "*apikey*",
        "*token*", "*private key*", "*certificate*", "*ssh*", "*aws*",
        "*azure*", "*gcp*", "*oauth*", "*bearer*", "*connection string*",
        "*access key*", "*secret key*",
        /* Financial */
        "*salary*", "*payroll*", "*compensation*", "*budget*", "*revenue*",
        "*financial*", "*banking*", "*invoice*", "*wire transfer*", "*account number*",
        "*credit card*", "*routing number*", "*profit*", "*expense*", "*1099*",
        /* Legal and Compliance */
        "*confidential*", "*privileged*", "*attorney*", "*legal hold*", "*settlement*",
        "*contract*", "*nda*", "*merger*", "*acquisition*", "*litigation*",
        "*subpoena*", "*trade secret*", "*intellectual property*", "*proprietary*",
        "*internal*", "*proposal*", "*poc*",
        /* HR and PII */
        "*ssn*", "*social security*", "*employee*", "*personnel*", "*performance review*",
        "*termination*", "*tax*", "*w2*", "*benefits*", "*background check*",
        "*medical*", "*hipaa*", "*passport*", "*driver license*", "*dob*",
        /* Infrastructure and IT */
        "*admin*", "*root*", "*vpn*", "*firewall*", "*network diagram*",
        "*architecture*", "*topology*", "*production*", "*database*", "*config*",
        "*backup*", "*disaster recovery*", "*vulnerability*", "*pentest*", "*security audit*",
        "*salesforce*"
    )
'''

[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1619"
name = "Cloud Storage Object Discovery"
reference = "https://attack.mitre.org/techniques/T1619/"

[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"

[[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.technique.subtechnique]]
id = "T1213.002"
name = "Sharepoint"
reference = "https://attack.mitre.org/techniques/T1213/002/"

[[rule.threat.technique]]
id = "T1530"
name = "Data from Cloud Storage"
reference = "https://attack.mitre.org/techniques/T1530/"


[rule.threat.tactic]
id = "TA0009"
name = "Collection"
reference = "https://attack.mitre.org/tactics/TA0009/"

Stages and Predicates

Stage 1: web

web where data_stream.dataset == "o365.audit" and
    event.provider == "SharePoint" and
    event.action == "SearchQueryPerformed" and
    event.outcome == "success" and
    o365.audit.SearchQueryText != null and
    o365.audit.SearchQueryText != "" and
    o365.audit.SearchQueryText like~ (
        "*password*", "*credential*", "*secret*", "*api key*", "*apikey*",
        "*token*", "*private key*", "*certificate*", "*ssh*", "*aws*",
        "*azure*", "*gcp*", "*oauth*", "*bearer*", "*connection string*",
        "*access key*", "*secret key*",
        "*salary*", "*payroll*", "*compensation*", "*budget*", "*revenue*",
        "*financial*", "*banking*", "*invoice*", "*wire transfer*", "*account number*",
        "*credit card*", "*routing number*", "*profit*", "*expense*", "*1099*",
        "*confidential*", "*privileged*", "*attorney*", "*legal hold*", "*settlement*",
        "*contract*", "*nda*", "*merger*", "*acquisition*", "*litigation*",
        "*subpoena*", "*trade secret*", "*intellectual property*", "*proprietary*",
        "*internal*", "*proposal*", "*poc*",
        "*ssn*", "*social security*", "*employee*", "*personnel*", "*performance review*",
        "*termination*", "*tax*", "*w2*", "*benefits*", "*background check*",
        "*medical*", "*hipaa*", "*passport*", "*driver license*", "*dob*",
        "*admin*", "*root*", "*vpn*", "*firewall*", "*network diagram*",
        "*architecture*", "*topology*", "*production*", "*database*", "*config*",
        "*backup*", "*disaster recovery*", "*vulnerability*", "*pentest*", "*security audit*",
        "*salesforce*"
    )

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data_stream.dataseteq
  • o365.audit corpus 8 (elastic 8)
field:"data_stream.dataset" kind:eq value:"o365.audit"
event.actioneq
  • SearchQueryPerformed
field:"EventType" kind:eq value:"SearchQueryPerformed"
event.outcomeeq
  • success corpus 82 (elastic 82)
field:"event.outcome" kind:eq value:"success"
event.providereq
  • SharePoint
field:"Provider_Name" kind:eq value:"SharePoint"
o365.audit.SearchQueryTextis_not_null
  • (no value, null check)
field:"o365.audit.SearchQueryText" kind:is_not_null
o365.audit.SearchQueryTextwildcard
  • *1099*
  • *access key*
  • *account number*
  • *acquisition*
  • *admin*
  • *api key*
  • *apikey*
  • *architecture*
  • *attorney*
  • *aws*
  • *azure*
  • *background check*
  • *backup*
  • *banking*
  • *bearer*
  • *benefits*
  • *budget*
  • *certificate*
  • *compensation*
  • *confidential*
  • *config*
  • *connection string*
  • *contract*
  • *credential*
  • *credit card*
  • *database*
  • *disaster recovery*
  • *dob*
  • *driver license*
  • *employee*
  • *expense*
  • *financial*
  • *firewall*
  • *gcp*
  • *hipaa*
  • *intellectual property*
  • *internal*
  • *invoice*
  • *legal hold*
  • *litigation*
  • +40 more values (see full rule source)
field:"o365.audit.SearchQueryText" kind:wildcard

Multi-Cloud CLI Token and Credential Access Commands

#
Status
production
Severity
high
Time window
6m
Group by
host.id, host.name, user.name
Author
Elastic
Source
github.com/elastic/detection-rules

Correlates process telemetry for shells and major cloud/Kubernetes CLIs when command lines match token or credential material access patterns (GCP, Azure, AWS, GitHub, kubectl, DigitalOcean, OCI). Flags hosts where multiple cloud targets appear within a five-minute window.

Known False Positives

  • Automation, CI runners, and platform engineering scripts may legitimately print tokens or dump kubeconfig across providers in one session. Baseline approved identities and runner images before tuning thresholds.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2026/04/29"
integration = ["endpoint", "windows", "system"]
maturity = "production"
updated_date = "2026/04/29"

[rule]
author = ["Elastic"]
description = """
Correlates process telemetry for shells and major cloud/Kubernetes CLIs when command lines match token or credential
material access patterns (GCP, Azure, AWS, GitHub, kubectl, DigitalOcean, OCI). Flags hosts where multiple cloud
targets appear within a five-minute window.
"""
false_positives = [
    """
    Automation, CI runners, and platform engineering scripts may legitimately print tokens or dump kubeconfig across
    providers in one session. Baseline approved identities and runner images before tuning thresholds.
    """,
]
from = "now-6m"
language = "esql"
license = "Elastic License v2"
name = "Multi-Cloud CLI Token and Credential Access Commands"
note = """## Triage and analysis

### Investigating Multi-Cloud CLI Token and Credential Access Commands

Each result row summarizes activity for one host, user, and five-minute time bucket. Review `Esql.process_command_line_values` for the
exact invocations and confirm whether the session was interactive, automated, or tied to a known pipeline.

### Possible investigation steps

- Map `Esql.cloud_targets` and `Esql.unique_clouds` to the underlying `process.command_line` values and parent
  executables.
- Correlate with authentication, Kubernetes audit, and cloud API logs for misuse of printed tokens.
- Identify whether the parent chain indicates a remote shell, RMM, or scheduled task.

### Response and remediation

- If unauthorized, isolate the host, invalidate any printed material at the identity provider, and hunt for lateral
  movement using the same time window as the alert.

**GCP (gcloud / application-default credentials)**

- Sign the user or build identity out of local gcloud sessions on the affected machine (example host session):

  `gcloud auth revoke --all`

- Remove leaked Application Default Credentials on that host (often used by client libraries):

  `gcloud auth application-default revoke`

- If a user OAuth refresh token or service account key was exposed, revoke or rotate it in Google Cloud Console (IAM
  and admin: delete compromised keys; for end users, revoke OAuth tokens under Security or Workspace admin tools as
  applicable).

**Azure (`az` / `azd`)**

- Clear cached CLI sessions on the host so new tokens are not silently reusable from disk:

  `az logout`

  `az account clear`

- If `az account get-access-token`, `Get-AzAccessToken`, or `azd auth token` output was captured, treat the bearer as
  compromised: rotate the underlying secret (for example app registration client secret or federated credential),
  revoke sessions in Microsoft Entra ID where supported, and enforce re-authentication with Conditional Access.

**GitHub (`gh` / PATs)**

- Remove the GitHub CLI session from the affected profile:

  `gh auth logout`

- If a personal access token or fine-grained token was printed, revoke it under GitHub user or organization settings
  (Developer settings → Personal access tokens), and rotate any secrets or deploy keys that were readable with that
  token.

For all providers, prefer provider-console revocation and rotation when a token string left the trust boundary; local
`logout`/`revoke` alone does not invalidate tokens that were already copied off-host.
"""
references = [
    "https://attack.mitre.org/techniques/T1528/",
    "https://attack.mitre.org/techniques/T1552/",
]
risk_score = 73
rule_id = "2b9a3b7a-0891-4a89-abbe-dca753c403cd"
severity = "high"
tags = [
    "Domain: Endpoint",
    "Domain: Cloud",
    "OS: Windows",
    "OS: Linux",
    "OS: macOS",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Data Source: Elastic Defend",
    "Data Source: Windows Security Event Logs",
    "Data Source: Sysmon",
    "Resources: Investigation Guide"
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
FROM logs-endpoint.events.process-*, logs-system.security-*, logs-windows.sysmon_operational-* METADATA _id, _index, _version
| WHERE event.category == "process" AND KQL(""" event.type : "start" and not event.action : "fork" """)
  AND process.command_line IS NOT NULL 
  AND (
    TO_LOWER(process.name) IN (
      "cmd.exe", "powershell.exe", "pwsh.exe", 
      "sh", "bash", "zsh", "dash", "fish", "ksh",
      "gcloud", "gcloud.cmd", "az", "az.cmd", "azd", "azd.exe",
      "gh", "gh.exe", "aws", "aws.exe",
      "kubectl", "kubectl.exe",
      "doctl", "doctl.exe",
      "oci", "oci.exe"
    ) OR
    TO_LOWER(process.parent.name) IN (
      "cmd.exe", "powershell.exe", "pwsh.exe",
      "sh", "bash", "zsh", "dash", "fish", "ksh", "bun", "bun.exe", 
      "node", "node.exe", "java", "java.exe"
    )
  )
  AND process.command_line RLIKE """.*(config-helper\s.*--format|auth\s+print-access-token|auth\s+print-identity-token|auth\s+application-default\s+print|get-access-token\s.*--output|Get-AzAccessToken|azd\s+auth\s+token|az\s+account\s+get-access-token|gh\s+auth\s+(token|status)|aws\s+sts\s+(get-session-token|get-caller-identity|assume-role)|aws\s+configure\s+(export-credentials|list)|kubectl\s+config\s+view\s.*--raw|kubectl\s+get\s+secret|doctl\s+auth\s+(list|init)|oci\s+session\s+authenticate|oci\s+iam\s.*token).*"""
| EVAL cloud_target = CASE(
    process.command_line RLIKE ".*(gcloud|config-helper|print-access-token|print-identity-token).*", "GCP",
    process.command_line RLIKE ".*(azd auth|az account|Get-AzAccessToken).*", "AZURE",
    process.command_line RLIKE ".*(aws sts|aws configure).*", "AWS",
    process.command_line RLIKE ".*(gh auth).*", "GITHUB",
    process.command_line RLIKE ".*(kubectl config|kubectl get secret).*", "KUBERNETES",
    process.command_line RLIKE ".*(doctl).*", "DIGITALOCEAN",
    process.command_line RLIKE ".*(oci session|oci iam).*", "ORACLE"
  )
| WHERE cloud_target IS NOT NULL // drop unclassified events before aggregation
| STATS
    Esql.cloud_targets = VALUES(cloud_target),
    Esql.unique_clouds = COUNT_DISTINCT(cloud_target),
    Esql.process_command_line_values = VALUES(process.command_line),
    Esql.process_parent_executable_values = VALUES(process.parent.executable),
    Esql.first_seen = MIN(@timestamp),
    Esql.last_seen = MAX(@timestamp),
    Esql.event_count = COUNT(*)
  BY host.name, host.id, user.name
| WHERE Esql.unique_clouds >= 2
| KEEP Esql.*, user.name, host.name, host.id
'''

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1528"
name = "Steal Application Access Token"
reference = "https://attack.mitre.org/techniques/T1528/"

[[rule.threat.technique]]
id = "T1552"
name = "Unsecured Credentials"
reference = "https://attack.mitre.org/techniques/T1552/"

[[rule.threat.technique.subtechnique]]
id = "T1552.001"
name = "Credentials In Files"
reference = "https://attack.mitre.org/techniques/T1552/001/"

[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"

Stages and Predicates

Stage 1: from

FROM logs-endpoint.events.process-*, logs-system.security-*, logs-windows.sysmon_operational-* METADATA _id, _index, _version

Stage 2: where

| WHERE event.category == "process" AND KQL(""" event.type : "start" and not event.action : "fork" """)
  AND process.command_line IS NOT NULL 
  AND (
    TO_LOWER(process.name) IN (
      "cmd.exe", "powershell.exe", "pwsh.exe", 
      "sh", "bash", "zsh", "dash", "fish", "ksh",
      "gcloud", "gcloud.cmd", "az", "az.cmd", "azd", "azd.exe",
      "gh", "gh.exe", "aws", "aws.exe",
      "kubectl", "kubectl.exe",
      "doctl", "doctl.exe",
      "oci", "oci.exe"
    ) OR
    TO_LOWER(process.parent.name) IN (
      "cmd.exe", "powershell.exe", "pwsh.exe",
      "sh", "bash", "zsh", "dash", "fish", "ksh", "bun", "bun.exe", 
      "node", "node.exe", "java", "java.exe"
    )
  )
  AND process.command_line RLIKE """.*(config-helper\s.*--format|auth\s+print-access-token|auth\s+print-identity-token|auth\s+application-default\s+print|get-access-token\s.*--output|Get-AzAccessToken|azd\s+auth\s+token|az\s+account\s+get-access-token|gh\s+auth\s+(token|status)|aws\s+sts\s+(get-session-token|get-caller-identity|assume-role)|aws\s+configure\s+(export-credentials|list)|kubectl\s+config\s+view\s.*--raw|kubectl\s+get\s+secret|doctl\s+auth\s+(list|init)|oci\s+session\s+authenticate|oci\s+iam\s.*token).*"""

Stage 3: eval

| EVAL cloud_target = CASE(
    process.command_line RLIKE ".*(gcloud|config-helper|print-access-token|print-identity-token).*", "GCP",
    process.command_line RLIKE ".*(azd auth|az account|Get-AzAccessToken).*", "AZURE",
    process.command_line RLIKE ".*(aws sts|aws configure).*", "AWS",
    process.command_line RLIKE ".*(gh auth).*", "GITHUB",
    process.command_line RLIKE ".*(kubectl config|kubectl get secret).*", "KUBERNETES",
    process.command_line RLIKE ".*(doctl).*", "DIGITALOCEAN",
    process.command_line RLIKE ".*(oci session|oci iam).*", "ORACLE"
  )
cloud_target =
ifprocess.command_line RLIKE ".*(gcloud|config-helper|print-access-token|print-identity-token).*""GCP"
elifprocess.command_line RLIKE ".*(azd auth|az account|Get-AzAccessToken).*""AZURE"
elifprocess.command_line RLIKE ".*(aws sts|aws configure).*""AWS"
elifprocess.command_line RLIKE ".*(gh auth).*""GITHUB"
elifprocess.command_line RLIKE ".*(kubectl config|kubectl get secret).*""KUBERNETES"
elifprocess.command_line RLIKE ".*(doctl).*""DIGITALOCEAN"
else"ORACLE"

Stage 4: where

| WHERE cloud_target IS NOT NULL

Stage 5: stats

| STATS
    Esql.cloud_targets = VALUES(cloud_target),
    Esql.unique_clouds = COUNT_DISTINCT(cloud_target),
    Esql.process_command_line_values = VALUES(process.command_line),
    Esql.process_parent_executable_values = VALUES(process.parent.executable),
    Esql.first_seen = MIN(@timestamp),
    Esql.last_seen = MAX(@timestamp),
    Esql.event_count = COUNT(*)
  BY host.name, host.id, user.name

Stage 6: where

| WHERE Esql.unique_clouds >= 2

Stage 7: keep

| KEEP Esql.*, user.name, host.name, host.id

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
Esql.unique_cloudsge
  • 2
field:"Esql.unique_clouds" kind:ge value:"2"
cloud_targetis_not_null
  • (no value, null check)
field:"cloud_target" kind:is_not_null
event.categoryeq
  • process corpus 38 (elastic 38)
field:"event.category" kind:eq value:"process"
event.typeeq
  • start corpus 67 (elastic 67)
field:"event.type" kind:eq value:"start"
process.command_lineis_not_null
  • (no value, null check)
field:"CommandLine" kind:is_not_null
process.command_lineregex_match
  • .*(config-helper\s.*--format|auth\s+print-access-token|auth\s+print-identity-token|auth\s+application-default\s+print|get-access-token\s.*--output|Get-AzAccessToken|azd\s+auth\s+token|az\s+account\s+get-access-token|gh\s+auth\s+(token|status)|aws\s+sts\s+(get-session-token|get-caller-identity|assume-role)|aws\s+configure\s+(export-credentials|list)|kubectl\s+config\s+view\s.*--raw|kubectl\s+get\s+secret|doctl\s+auth\s+(list|init)|oci\s+session\s+authenticate|oci\s+iam\s.*token).*
field:"CommandLine" kind:regex_match value:".*(config-helper\s.*--format|auth\s+print-access-token|auth\s+print-identity-token|auth\s+application-default\s+print|get-access-token\s.*--output|Get-AzAccessToken|azd\s+auth\s+token|az\s+account\s+get-access-token|gh\s+auth\s+(token|status)|aws\s+sts\s+(get-session-token|get-caller-identity|assume-role)|aws\s+configure\s+(export-credentials|list)|kubectl\s+config\s+view\s.*--raw|kubectl\s+get\s+secret|doctl\s+auth\s+(list|init)|oci\s+session\s+authenticate|oci\s+iam\s.*token).*"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
event.actioneqforkexcludes:event.action field:"event.action" value:"fork"

Output Fields

These fields are emitted when the rule matches.

FieldSource
Esql.*KEEP Esql.*
user.nameKEEP user.name
host.nameKEEP host.name
host.idKEEP host.id

Network Connect API from Modified Memory

#
Source
github.com/elastic/protections-artifacts

Identifies attempts to perform a network connection from a suspicious backed memory block. This may be the result of code injection via module stomping.

MITRE ATT&CK Coverage

TacticTechniques
Stealth

Rule Body

[rule]
description = """
Identifies attempts to perform a network connection from a suspicious backed memory block. This may be the result of
code injection via module stomping.
"""
id = "8092c7fc-2cd4-4630-84b0-b9c9ea140856"
license = "Elastic License v2"
name = "Network Connect API from Modified Memory"
os_list = ["windows"]
version = "1.0.4"

query = '''
api where process.Ext.api.name == "connect" and
 (
   (process.thread.Ext.call_stack_summary regex """ntdll.dll\|mswsock.dll\|[a-z0-9]+\.dll""" and
    _arraysearch(process.thread.Ext.call_stack, $entry,
                 stringcontains~($entry.symbol_info, substring(process.thread.Ext.call_stack_summary, 22, length(process.thread.Ext.call_stack_summary))) and ($entry.callsite_trailing_bytes : "?*" and $entry.allocation_private_bytes >= 100000))) or

   (process.thread.Ext.call_stack_summary regex """ntdll.dll\|mswsock.dll\|ws2_32.dll\|[a-z0-9]+\.dll""" and
    _arraysearch(process.thread.Ext.call_stack, $entry,
                 stringcontains~($entry.symbol_info, substring(process.thread.Ext.call_stack_summary, 33, length(process.thread.Ext.call_stack_summary))) and ($entry.callsite_trailing_bytes : "?*" and $entry.allocation_private_bytes >= 100000))) or

   (process.thread.Ext.call_stack_summary regex """wow64cpu.dll\|wow64.dll\|ntdll.dll\|mswsock.dll\|[a-z0-9]+\.dll""" and
    _arraysearch(process.thread.Ext.call_stack, $entry,
                 stringcontains~($entry.symbol_info, substring(process.thread.Ext.call_stack_summary, 45, length(process.thread.Ext.call_stack_summary))) and ($entry.callsite_trailing_bytes : "?*" and $entry.allocation_private_bytes >= 100000))) or

   (process.thread.Ext.call_stack_summary regex """wow64cpu.dll\|wow64.dll\|ntdll.dll\|mswsock.dll\|ws2_32.dll\|[a-z0-9]+\.dll""" and
    _arraysearch(process.thread.Ext.call_stack, $entry,
                 stringcontains~($entry.symbol_info, substring(process.thread.Ext.call_stack_summary, 56, length(process.thread.Ext.call_stack_summary))) and ($entry.callsite_trailing_bytes : "?*" and $entry.allocation_private_bytes >= 100000)))
  ) and

  not process.thread.Ext.call_stack_summary in
                            ("wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|ws2_32.dll|vfp?r.dll",
                             "wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|ws2_32.dll|ftacommonex.dll",
                             "wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|asproxy.dll",
                             "ntdll.dll|mswsock.dll|ws2_32.dll|xdlicense.dll") and
  not _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature,
                   $entry, $entry.status == "trusted" and
                   $entry.subject_name in ("Microsoft Windows Hardware Compatibility Publisher",
                                           "Asesoria Informatica Gallega SL", "Astrill Systems Corp.",
                                           "Rockwell Automation Inc", "Star Finanz-Software Entwicklung und Vertriebs GmbH",
                                           "Siemens Industry Software Inc.", "Bitdefender SRL"))
'''

min_endpoint_version = "8.14.0"
optional_actions = []
[[actions]]
action = "kill_process"
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/"
[[threat]]
framework = "MITRE ATT&CK"

[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"

[internal]
min_endpoint_version = "8.14.0"

Stages and Predicates

Stage 1: api

api where process.Ext.api.name == "connect" and
 (
   (process.thread.Ext.call_stack_summary regex """ntdll.dll\|mswsock.dll\|[a-z0-9]+\.dll""" and
    _arraysearch(process.thread.Ext.call_stack, $entry,
                 stringcontains~($entry.symbol_info, substring(process.thread.Ext.call_stack_summary, 22, length(process.thread.Ext.call_stack_summary))) and ($entry.callsite_trailing_bytes : "?*" and $entry.allocation_private_bytes >= 100000))) or

   (process.thread.Ext.call_stack_summary regex """ntdll.dll\|mswsock.dll\|ws2_32.dll\|[a-z0-9]+\.dll""" and
    _arraysearch(process.thread.Ext.call_stack, $entry,
                 stringcontains~($entry.symbol_info, substring(process.thread.Ext.call_stack_summary, 33, length(process.thread.Ext.call_stack_summary))) and ($entry.callsite_trailing_bytes : "?*" and $entry.allocation_private_bytes >= 100000))) or

   (process.thread.Ext.call_stack_summary regex """wow64cpu.dll\|wow64.dll\|ntdll.dll\|mswsock.dll\|[a-z0-9]+\.dll""" and
    _arraysearch(process.thread.Ext.call_stack, $entry,
                 stringcontains~($entry.symbol_info, substring(process.thread.Ext.call_stack_summary, 45, length(process.thread.Ext.call_stack_summary))) and ($entry.callsite_trailing_bytes : "?*" and $entry.allocation_private_bytes >= 100000))) or

   (process.thread.Ext.call_stack_summary regex """wow64cpu.dll\|wow64.dll\|ntdll.dll\|mswsock.dll\|ws2_32.dll\|[a-z0-9]+\.dll""" and
    _arraysearch(process.thread.Ext.call_stack, $entry,
                 stringcontains~($entry.symbol_info, substring(process.thread.Ext.call_stack_summary, 56, length(process.thread.Ext.call_stack_summary))) and ($entry.callsite_trailing_bytes : "?*" and $entry.allocation_private_bytes >= 100000)))
  ) and

  not process.thread.Ext.call_stack_summary in
                            ("wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|ws2_32.dll|vfp?r.dll",
                             "wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|ws2_32.dll|ftacommonex.dll",
                             "wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|asproxy.dll",
                             "ntdll.dll|mswsock.dll|ws2_32.dll|xdlicense.dll") and
  not _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature,
                   $entry, $entry.status == "trusted" and
                   $entry.subject_name in ("Microsoft Windows Hardware Compatibility Publisher",
                                           "Asesoria Informatica Gallega SL", "Astrill Systems Corp.",
                                           "Rockwell Automation Inc", "Star Finanz-Software Entwicklung und Vertriebs GmbH",
                                           "Siemens Industry Software Inc.", "Bitdefender SRL"))

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
process.Ext.api.nameeq
  • connect corpus 5 (elastic 5)
field:"process.Ext.api.name" kind:eq value:"connect"
process.thread.Ext.call_stack_summaryregex_match
  • ntdll.dll|mswsock.dll|[a-z0-9]+.dll
  • ntdll.dll|mswsock.dll|ws2_32.dll|[a-z0-9]+.dll
  • wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|[a-z0-9]+.dll
  • wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|ws2_32.dll|[a-z0-9]+.dll
field:"process.thread.Ext.call_stack_summary" kind:regex_match

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.thread.Ext.call_stack_final_user_module.code_signaturearray_any(no value, null check)excludes:process.thread.Ext.call_stack_final_user_module.code_signature
process.thread.Ext.call_stack_summaryinntdll.dll|mswsock.dll|ws2_32.dll|xdlicense.dll, wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|asproxy.dll, wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|ws2_32.dll|ftacommonex.dll, wow64cpu.dll|wow64.dll|ntdll.dll|mswsock.dll|ws2_32.dll|vfp?r.dllexcludes:process.thread.Ext.call_stack_summary

Potential Endpoint Security Evasion via FirewallRules

#
Source
github.com/elastic/protections-artifacts

Identifies attempts to create custom Windows Firewall rules to block traffic originating from Endpoint security file paths. Such actions could aid an adversary in evading the transmission of alerts and telemetry to the server side.

MITRE ATT&CK Coverage

TacticTechniques
Defense Impairment

Rule Body

[rule]
description = """
Identifies attempts to create custom Windows Firewall rules to block traffic originating from Endpoint security file
paths. Such actions could aid an adversary in evading the transmission of alerts and telemetry to the server side.
"""
id = "7cfc9edd-d180-43ba-a1d4-7f2eb4285787"
license = "Elastic License v2"
name = "Potential Endpoint Security Evasion via FirewallRules"
os_list = ["windows"]
reference = [
    "https://medium.com/csis-techblog/silencing-microsoft-defender-for-endpoint-using-firewall-rules-3839a8bf8d18",
]
version = "1.0.4"

query = '''
registry where 
 registry.path : "HKLM\\SYSTEM\\*ControlSet*\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\FirewallRules\\*" and 
 registry.data.strings : ("*Block*App*\\Elastic\\*", 
                          "*Block*App*\\Windows Defender Advanced Threat Protection\\*", 
                          "*Block*App*\\CrowdStrike\\*", 
                          "*Block*App*\\SentinelOne\\*", 
                          "*Block*App*\\Palo Alto Networks\\*")
'''

min_endpoint_version = "7.16.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 = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[threat.technique.subtechnique]]
id = "T1562.001"
name = "Disable or Modify Tools"
reference = "https://attack.mitre.org/techniques/T1562/001/"



[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

[internal]
min_endpoint_version = "7.16.0"

Stages and Predicates

Stage 1: registry

registry where 
 registry.path : "HKLM\\SYSTEM\\*ControlSet*\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\FirewallRules\\*" and 
 registry.data.strings : ("*Block*App*\\Elastic\\*", 
                          "*Block*App*\\Windows Defender Advanced Threat Protection\\*", 
                          "*Block*App*\\CrowdStrike\\*", 
                          "*Block*App*\\SentinelOne\\*", 
                          "*Block*App*\\Palo Alto Networks\\*")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
registry.data.stringswildcard
  • *Block*App*\CrowdStrike\*
  • *Block*App*\Elastic\*
  • *Block*App*\Palo Alto Networks\*
  • *Block*App*\SentinelOne\*
  • *Block*App*\Windows Defender Advanced Threat Protection\*
field:"Details" kind:wildcard
registry.pathwildcard
  • HKLM\SYSTEM\*ControlSet*\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules\*
field:"TargetObject" kind:wildcard value:"HKLM\SYSTEM\*ControlSet*\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules\*"

Potential Execution via SSH Backdoor

#
Status
production
Severity
medium
Time window
1m
Sequence by
host.id, process.entity_id, process.parent.entity_id
Author
Elastic
Source
github.com/elastic/detection-rules

It identifies potential malicious shell executions through remote SSH and detects cases where the sshd service suddenly terminates soon after successful execution, suggesting suspicious behavior similar to the XZ backdoor.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2024/04/01"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
It identifies potential malicious shell executions through remote SSH and detects cases where the sshd service suddenly
terminates soon after successful execution, suggesting suspicious behavior similar to the XZ backdoor.
"""
from = "now-9m"
index = ["logs-endpoint.events.network*", "logs-endpoint.events.process*"]
language = "eql"
license = "Elastic License v2"
name = "Potential Execution via SSH Backdoor"
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 Execution via SSH Backdoor

Linux SSH backdoors, such as the XZBackdoor, leverage SSH, a secure protocol for remote access, to execute malicious commands stealthily. Adversaries exploit SSH by initiating sessions that mimic legitimate activity, then abruptly terminate them post-execution to evade detection. The detection rule identifies anomalies by tracking SSH processes that start and end unexpectedly, especially when non-standard executables are invoked, signaling potential backdoor activity.

### Possible investigation steps

- Review the SSH session logs on the affected host to identify any unusual or unauthorized access attempts, focusing on sessions that match the process.pid and process.entity_id from the alert.
- Examine the command history and executed commands for the user associated with the user.id in the alert to identify any suspicious or unexpected activities.
- Investigate the non-standard executables invoked by the SSH session by checking the process.executable field to determine if they are legitimate or potentially malicious.
- Analyze the network activity associated with the SSH session, particularly any disconnect_received events, to identify any unusual patterns or connections to suspicious IP addresses.
- Check the exit codes of the SSH processes, especially those with a non-zero process.exit_code, to understand the reason for the abrupt termination and whether it aligns with typical error codes or indicates malicious activity.

### False positive analysis

- Legitimate administrative SSH sessions may trigger the rule if they involve non-standard executables. To manage this, create exceptions for known administrative scripts or tools that are frequently used in your environment.
- Automated processes or scripts that use SSH for routine tasks might mimic the behavior of the XZBackdoor. Identify these processes and exclude them by specifying their executable paths or command-line patterns in the rule exceptions.
- Security tools or monitoring solutions that perform SSH-based checks could be mistaken for malicious activity. Review these tools and add their signatures to the exclusion list to prevent false alerts.
- Custom applications that use SSH for communication might be flagged. Document these applications and adjust the rule to recognize their specific execution patterns as non-threatening.
- Temporary network issues causing abrupt SSH session terminations could be misinterpreted as suspicious behavior. Monitor network stability and consider excluding known transient disconnections from triggering alerts.

### Response and remediation

- Immediately isolate the affected host from the network to prevent further unauthorized access or lateral movement.
- Terminate any suspicious SSH sessions identified by the detection rule to stop ongoing malicious activity.
- Conduct a thorough review of the affected host's SSH configuration and logs to identify unauthorized changes or access patterns.
- Reset credentials for any user accounts involved in the suspicious SSH activity to prevent further unauthorized access.
- Restore the affected system from a known good backup if any unauthorized changes or malware are detected.
- Implement network segmentation to limit SSH access to critical systems and reduce the attack surface.
- Escalate the incident to the security operations center (SOC) for further investigation and to determine if additional systems are compromised."""
references = [
    "https://github.com/amlweems/xzbot",
    "https://access.redhat.com/security/cve/CVE-2024-3094",
    "https://www.elastic.co/security-labs/500ms-to-midnight",
]
risk_score = 47
rule_id = "7afc6cc9-8800-4c7f-be6b-b688d2dea248"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Tactic: Persistence",
    "Tactic: Lateral Movement",
    "Data Source: Elastic Defend",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
sequence by host.id with maxspan=1m
  [process where host.os.type == "linux" and event.action == "end" and process.name == "sshd" and process.exit_code != 0 and
   process.command_line == "/usr/sbin/sshd -D -R" and process.parent.command_line == "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"] by process.entity_id
  [process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and
   process.parent.name == "sshd" and process.parent.command_line == "/usr/sbin/sshd -D -R" and
   process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and process.args == "-c" and not (
     process.args like (
       "rsync*", "systemctl*", "/usr/sbin/unix_chkpwd", "/usr/bin/google_authorized_keys", "/usr/sbin/aad_certhandler*",
        "bash -c bash -s", "/usr/lib/ssh/sftp-server", "stat /etc/is_upgrade_install > /dev/null 2>&1",
        "stat /opt/qradar/ha/.*", "/usr/bin/env -i PATH=*", "/opt/gitlab/*", "clamdscan*", "wc*", "export*",
        "test*", "md5sum*", "check_mk_agent", "/usr/bin/env*", "/usr/bin/check_mk_agent", "timeout*", "/usr/sbin/haproxy*",
        "/usr/libexec/openssh/sftp-server", "command*", "find*", "cd *", "scp*", "while*", "pvesh*", "/bin/true",
        "/usr/sbin/qm mtunnel", "multipath*", "/usr/lib/openssh/sftp-server"
     ) or
     process.command_line like ("sh -c /usr/bin/env -i PATH=*", "sh -c -- /usr/bin/env -i PATH=*", "*ansible*", "*BECOME-SUCCESS*")
   )
  ] by process.parent.entity_id
'''

[[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 = "T1556"
name = "Modify Authentication Process"
reference = "https://attack.mitre.org/techniques/T1556/"

[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 = "T1021"
name = "Remote Services"
reference = "https://attack.mitre.org/techniques/T1021/"

[[rule.threat.technique.subtechnique]]
id = "T1021.004"
name = "SSH"
reference = "https://attack.mitre.org/techniques/T1021/004/"

[[rule.threat.technique]]
id = "T1563"
name = "Remote Service Session Hijacking"
reference = "https://attack.mitre.org/techniques/T1563/"

[[rule.threat.technique.subtechnique]]
id = "T1563.001"
name = "SSH Hijacking"
reference = "https://attack.mitre.org/techniques/T1563/001/"

[rule.threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"

[[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.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"

Stages and Predicates

Ordered sequence: each step below must occur in order within 1m, correlated by host.id, process.entity_id, process.parent.entity_id.

Stage 1: process

[process where host.os.type == "linux" and event.action == "end" and process.name == "sshd" and process.exit_code != 0 and
   process.command_line == "/usr/sbin/sshd -D -R" and process.parent.command_line == "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"] by process.entity_id

Stage 2: process

[process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and
   process.parent.name == "sshd" and process.parent.command_line == "/usr/sbin/sshd -D -R" and
   process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and process.args == "-c" and not (
     process.args like (
       "rsync*", "systemctl*", "/usr/sbin/unix_chkpwd", "/usr/bin/google_authorized_keys", "/usr/sbin/aad_certhandler*",
        "bash -c bash -s", "/usr/lib/ssh/sftp-server", "stat /etc/is_upgrade_install > /dev/null 2>&1",
        "stat /opt/qradar/ha/.*", "/usr/bin/env -i PATH=*", "/opt/gitlab/*", "clamdscan*", "wc*", "export*",
        "test*", "md5sum*", "check_mk_agent", "/usr/bin/env*", "/usr/bin/check_mk_agent", "timeout*", "/usr/sbin/haproxy*",
        "/usr/libexec/openssh/sftp-server", "command*", "find*", "cd *", "scp*", "while*", "pvesh*", "/bin/true",
        "/usr/sbin/qm mtunnel", "multipath*", "/usr/lib/openssh/sftp-server"
     ) or
     process.command_line like ("sh -c /usr/bin/env -i PATH=*", "sh -c -- /usr/bin/env -i PATH=*", "*ansible*", "*BECOME-SUCCESS*")
   )
  ] by process.parent.entity_id

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argswildcardrsync*, systemctl*, /usr/sbin/unix_chkpwd, /usr/bin/google_authorized_keys, /usr/sbin/aad_certhandler*, bash -c bash -s, /usr/lib/ssh/sftp-server, stat /etc/is_upgrade_install > /dev/null 2>&1, stat /opt/qradar/ha/.*, /usr/bin/env -i PATH=*, /opt/gitlab/*, clamdscan*, wc*, export*, test*, md5sum*, check_mk_agent, /usr/bin/env*, /usr/bin/check_mk_agent, timeout*, /usr/sbin/haproxy*, /usr/libexec/openssh/sftp-server, command*, find*, cd *, scp*, while*, pvesh*, /bin/true, /usr/sbin/qm mtunnel, multipath*, /usr/lib/openssh/sftp-serverexcludes:process.args
process.command_linewildcardsh -c /usr/bin/env -i PATH=*, sh -c -- /usr/bin/env -i PATH=*, *ansible*, *BECOME-SUCCESS*excludes:process.command_line

Potential Injection via Module Stomping

#
Sequence by
process.entity_id
Source
github.com/elastic/protections-artifacts

Identifies the load of a library with a unusual memory private bytes allocation. This may be the result of a code injection using module stomping or DLL hollowing via overwriting the content of legit DLL with malicious code.

MITRE ATT&CK Coverage

TacticTechniques
Stealth

Rule Body

[rule]
description = """
Identifies the load of a library with a unusual memory private bytes allocation. This may be the result of a code
injection using module stomping or DLL hollowing via overwriting the content of legit DLL with malicious code.
"""
id = "ace1b159-be74-413c-bbe0-b5383fb9770b"
license = "Elastic License v2"
name = "Potential Injection via Module Stomping"
os_list = ["windows"]
reference = [
    "https://www.ired.team/offensive-security/code-injection-process-injection/modulestomping-dll-hollowing-shellcode-injection",
]
version = "1.0.21"

query = '''
sequence by process.entity_id
[process where event.type:"start" and
 not process.Ext.token.integrity_level_name == "low" and
 not process.hash.sha256 : "123c8b533f529fcfda0fd48077c79fd2c71750237741fbd771ece8244550303e" and
 not process.executable :
            ("?:\\Program Files (x86)\\*",
             "?:\\Program Files\\*",
             "?:\\Windows\\SysWOW64\\rpcnet.exe",
             "?:\\Windows\\System32\\rpcnet.exe")]
[library where

 dll.name in~ ("ws2_32.dll", "wininet.dll", "winhttp.dll") and

 _arraysearch(process.thread.Ext.call_stack, $entry, $entry.allocation_private_bytes >= 100000 and
             $entry.symbol_info: ("?:\\windows\\System32\\*.dll", "?:\\windows\\SysWOW64\\*.dll")) and length(process.thread.Ext.call_stack_summary) <= 60 and

 /* critical for a process, often hooked by other EPP or AV, EPP or AV own DLLs */
 not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.allocation_private_bytes >= 100000 and
                  $entry.symbol_info:
                        ("?:\\Windows\\SysWOW64\\KernelBase.dll*",
                         "?:\\Windows\\System32\\KernelBase.dll*",
                         "?:\\Windows\\System32\\ntdll.dll*",
                         "?:\\Windows\\SysWOW64\\ScriptControl32_*.dll!*",
                         "?:\\Windows\\SysWOW64\\rpcrt4.dll!*",
                         "?:\\Windows\\System32\\rpcrt4.dll!",
                         "?:\\Windows\\SysWOW64\\combase.dll!*",
                         "?:\\Windows\\System32\\combase.dll!*",
                         "?:\\Windows\\SysWOW64\\webio.dll*",
                         "?:\\Windows\\SysWOW64\\TWAINDSM.dll*",
                         "?:\\Windows\\Sys*\\ws2_32.dll*",
                         "?:\\Windows\\Sys*\\user32.dll*",
                         "?:\\Windows\\Sys*\\cyinjct.dll*",
                         "?:\\Windows\\SysWOW64\\twpix32.dll*",
                         "?:\\Windows\\SysWOW64\\IMCRCMN3.DLL*",
                         "?:\\Windows\\SysWOW64\\Windows.Security.Authentication.Web.Core.dll*",
                         "?:\\Windows\\assembly\\NativeImages_*",
                         "?:\\Windows\\System32\\DriverStore\\FileRepository\\*",
                         "?:\\Windows\\Sys*\\spool\\drivers\\*")) and

 not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.allocation_private_bytes >= 100000 and
                  startswith~($entry.symbol_info, process.executable)) and

 not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info:
                                                                ("?:\\Program Files (x86)\\*.dll*",
                                                                 "?:\\Program Files\\*.dll*",
                                                                 "?:\\Windows\\Sys*\\hmpalert.dll*",
                                                                 "?:\\Windows\\System32\\umppc*.dll*"))]
until [process where event.action == "end"]
'''

min_endpoint_version = "8.8.0"
optional_actions = []
[[actions]]
action = "kill_process"
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, correlated by process.entity_id.

Stage 1: process

[process where event.type:"start" and
 not process.Ext.token.integrity_level_name == "low" and
 not process.hash.sha256 : "123c8b533f529fcfda0fd48077c79fd2c71750237741fbd771ece8244550303e" and
 not process.executable :
            ("?:\\Program Files (x86)\\*",
             "?:\\Program Files\\*",
             "?:\\Windows\\SysWOW64\\rpcnet.exe",
             "?:\\Windows\\System32\\rpcnet.exe")]

Stage 2: library

[library where
 dll.name in~ ("ws2_32.dll", "wininet.dll", "winhttp.dll") and
 _arraysearch(process.thread.Ext.call_stack, $entry, $entry.allocation_private_bytes >= 100000 and
             $entry.symbol_info: ("?:\\windows\\System32\\*.dll", "?:\\windows\\SysWOW64\\*.dll")) and length(process.thread.Ext.call_stack_summary) <= 60 and
 not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.allocation_private_bytes >= 100000 and
                  $entry.symbol_info:
                        ("?:\\Windows\\SysWOW64\\KernelBase.dll*",
                         "?:\\Windows\\System32\\KernelBase.dll*",
                         "?:\\Windows\\System32\\ntdll.dll*",
                         "?:\\Windows\\SysWOW64\\ScriptControl32_*.dll!*",
                         "?:\\Windows\\SysWOW64\\rpcrt4.dll!*",
                         "?:\\Windows\\System32\\rpcrt4.dll!",
                         "?:\\Windows\\SysWOW64\\combase.dll!*",
                         "?:\\Windows\\System32\\combase.dll!*",
                         "?:\\Windows\\SysWOW64\\webio.dll*",
                         "?:\\Windows\\SysWOW64\\TWAINDSM.dll*",
                         "?:\\Windows\\Sys*\\ws2_32.dll*",
                         "?:\\Windows\\Sys*\\user32.dll*",
                         "?:\\Windows\\Sys*\\cyinjct.dll*",
                         "?:\\Windows\\SysWOW64\\twpix32.dll*",
                         "?:\\Windows\\SysWOW64\\IMCRCMN3.DLL*",
                         "?:\\Windows\\SysWOW64\\Windows.Security.Authentication.Web.Core.dll*",
                         "?:\\Windows\\assembly\\NativeImages_*",
                         "?:\\Windows\\System32\\DriverStore\\FileRepository\\*",
                         "?:\\Windows\\Sys*\\spool\\drivers\\*")) and
 not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.allocation_private_bytes >= 100000 and
                  startswith~($entry.symbol_info, process.executable)) and
 not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info:
                                                                ("?:\\Program Files (x86)\\*.dll*",
                                                                 "?:\\Program Files\\*.dll*",
                                                                 "?:\\Windows\\Sys*\\hmpalert.dll*",
                                                                 "?:\\Windows\\System32\\umppc*.dll*"))]

Until: process

until [process where event.action == "end"]

Ends the sequence: the steps above must complete before an event matching this clause occurs.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
dll.namein
  • winhttp.dll corpus 5 (elastic 5)
  • wininet.dll corpus 5 (elastic 5)
  • ws2_32.dll corpus 5 (elastic 5)
field:"dll.name" kind:in
event.actioneq
  • end corpus 13 (elastic 13)
field:"EventType" kind:eq value:"end"
event.typewildcard
  • start corpus 67 (elastic 67)
field:"event.type" kind:wildcard value:"start"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.Ext.token.integrity_level_nameeqlowexcludes:process.Ext.token.integrity_level_name field:"process.Ext.token.integrity_level_name" value:"low"
process.executablewildcard?:\Program Files (x86)\*, ?:\Program Files\*, ?:\Windows\SysWOW64\rpcnet.exe, ?:\Windows\System32\rpcnet.exeexcludes:process.executable
process.hash.sha256eq123c8b533f529fcfda0fd48077c79fd2c71750237741fbd771ece8244550303eexcludes:process.hash.sha256 field:"process.hash.sha256" value:"123c8b533f529fcfda0fd48077c79fd2c71750237741fbd771ece8244550303e"
process.thread.Ext.call_stackarray_any(no value, null check)excludes:process.thread.Ext.call_stack

Potential Remote Execution via IMsiServer

#
Time window
5s
Sequence by
source.ip
Source
github.com/elastic/protections-artifacts

Identifies potential attempts to abuse the IMsiServer Component Object Model (COM) interface to start a remote instance of the msiexec.exe service for lateral movement.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies potential attempts to abuse the IMsiServer Component Object Model (COM) interface to start a remote instance
of the msiexec.exe service for lateral movement.
"""
id = "40696acd-67c8-473e-a8ee-9ade3506d141"
license = "Elastic License v2"
name = "Potential Remote Execution via IMsiServer"
os_list = ["windows"]
reference = ["https://www.deepinstinct.com/blog/forget-psexec-dcom-upload-execute-backdoor"]
version = "1.0.3"

query = '''
sequence by source.ip with maxspan=5s
 [authentication where event.action == "log_on" and process.Ext.session_info.logon_type == "Network" and
  (user.effective.id != null and user.effective.id like ("S-1-5-21*", "S-1-12-*"))]
 [network where event.action in ("connection_accepted", "disconnect_received") and process.name == "msiexec.exe" and
  source.port >= 49152 and destination.port >= 49152 and not cidrmatch(source.ip, "127.0.0.0/8", "::1")]
'''

min_endpoint_version = "8.15.1"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1218"
name = "System Binary Proxy Execution"
reference = "https://attack.mitre.org/techniques/T1218/"
[[threat.technique.subtechnique]]
id = "T1218.007"
name = "Msiexec"
reference = "https://attack.mitre.org/techniques/T1218/007/"



[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1021"
name = "Remote Services"
reference = "https://attack.mitre.org/techniques/T1021/"


[threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"

[internal]
min_endpoint_version = "8.15.1"

Stages and Predicates

Ordered sequence: each step below must occur in order within 5s, correlated by source.ip.

Stage 1: authentication

[authentication where event.action == "log_on" and process.Ext.session_info.logon_type == "Network" and
  (user.effective.id != null and user.effective.id like ("S-1-5-21*", "S-1-12-*"))]

Stage 2: network

[network where event.action in ("connection_accepted", "disconnect_received") and process.name == "msiexec.exe" and
  source.port >= 49152 and destination.port >= 49152 and not cidrmatch(source.ip, "127.0.0.0/8", "::1")]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
destination.portge
  • 49152 transforms: number corpus 4 (elastic 4)
field:"DestinationPort" kind:ge value:"49152"
event.actioneq
  • log_on corpus 8 (elastic 8)
field:"EventType" kind:eq value:"log_on"
event.actionin
  • connection_accepted corpus 14 (elastic 14)
  • disconnect_received corpus 11 (elastic 11)
field:"EventType" kind:in
process.Ext.session_info.logon_typeeq
  • Network corpus 4 (elastic 4)
field:"process.Ext.session_info.logon_type" kind:eq value:"Network"
process.nameeq
  • msiexec.exe corpus 2 (elastic 1, kusto 1)
field:"process_basename" kind:eq value:"msiexec.exe"
source.portge
  • 49152 transforms: number corpus 16 (elastic 16)
field:"SourcePort" kind:ge value:"49152"
user.effective.idis_not_null
  • (no value, null check)
field:"user.effective.id" kind:is_not_null
user.effective.idwildcard
  • S-1-12-* corpus 4 (elastic 4)
  • S-1-5-21* corpus 4 (elastic 4)
field:"user.effective.id" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
source.ipcidr_match127.0.0.0/8, ::1excludes:source.ip field:"source.ip" value:"127.0.0.0/8" field:"source.ip" value:"::1"

Potential SSH Reverse Port Forwarding

#
Status
production
Severity
low
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies the use of Windows OpenSSH or Plink to create a reverse SSH port forward or reverse dynamic SOCKS proxy. Adversaries may abuse reverse forwarding to expose an internal service or proxy listener through an external SSH server, establishing an outbound tunnel that bypasses direct inbound connectivity controls.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2026/06/24"
integration = ["endpoint", "windows", "sentinel_one_cloud_funnel", "m365_defender", "system", "crowdstrike"]
maturity = "production"
updated_date = "2026/08/03"

[rule]
author = ["Elastic"]
description = """
Identifies the use of Windows OpenSSH or Plink to create a reverse SSH port forward or reverse dynamic SOCKS proxy.
Adversaries may abuse reverse forwarding to expose an internal service or proxy listener through an external SSH server,
establishing an outbound tunnel that bypasses direct inbound connectivity controls.
"""
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 SSH Reverse Port Forwarding"
references = [
  "https://thedfirreport.com/2025/11/04/from-bing-search-to-ransomware-bumblebee-and-adaptixc2-deliver-akira-2/",
  "https://thedfirreport.com/2023/10/30/netsupport-intrusion-results-in-domain-compromise/",
  "https://x.com/Securityinbits/status/2067602540209021196",
]
risk_score = 21
rule_id = "86817045-ea22-4038-9959-c3437bc4c064"
severity = "low"
tags = [
  "Domain: Endpoint",
  "OS: Windows",
  "Use Case: Threat Detection",
  "Tactic: Command and Control",
  "Tactic: Lateral Movement",
  "Data Source: Elastic Defend",
  "Data Source: SentinelOne",
  "Data Source: Microsoft Defender XDR",
  "Data Source: Windows Security Event Logs",
  "Data Source: Crowdstrike",
  "Data Source: Sysmon",
  "Data Source: Elastic Endgame",
  "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "windows" and event.type == "start" and
  (
    process.name : ("ssh.exe", "plink.exe") or
    ?process.pe.original_file_name : ("Plink", "plink.exe")
  ) and
  (
    process.args like "-R*" or
    process.args : "-oRemoteForward*" or
    (process.args == "-o" and process.args : "*RemoteForward*") or

    /* -R can be combined with ~20 no-arg SSH flags (e.g. -NR, -fNR) */
    process.args regex """-[46AaCfGgKkMNnqsTtVvXxYy]+R.*"""
  )
'''

note = """## Triage and analysis

### Investigating Potential SSH Reverse Port Forwarding Detected

#### Possible investigation steps

- What reverse-forward command triggered the alert?
  - Focus: `@timestamp`, `host.id`, `user.name`, `process.name`, `process.command_line`
  - Implication: Confirm via $investigate_0 a process start for `ssh.exe` or `plink.exe`/Plink with the matched `-R` or `RemoteForward` artifact. Suspicious when the command exposes an internal service or SOCKS listener without host/account owner confirmation; close only when command, host, account, parent, and remote-forward values match a recognized recurring tunnel workflow for this account.
- Is the process lineage and executable consistent with the expected workflow?
  - Focus: `process.parent.command_line`, `process.executable`, `process.hash.sha256`, `process.working_directory`, `process.Ext.relative_file_creation_time`
  - Implication: Via $investigate_0, compare parent, path, hash, and file age. Escalate when shells, script interpreters, unusual parents, recently created binaries, or a Plink original name under another process name appear; benign requires the same artifact and parent tied to the verified host/account reverse-forward workflow.
- Is the tunnel active or recurring on this host?
  - Focus: `host.id`, `process.entity_id`, `process.pid`, `process.uptime`, `process.exit_code`
  - Implication: Use $investigate_1 to check whether the SSH/Plink process remained running, exited, or relaunched with reverse-forward arguments. Recurring or long-lived commands outside a confirmed window are suspicious; a single exited process supports closure only with owner confirmation and no unresolved process or network evidence.
- What remote SSH server and exposed service are implied?
  - Focus: `process.args`, `process.command_line`, `destination.ip`, `destination.port`, `network.direction`
  - Implication: Parse `-R`/`RemoteForward` syntax, then recover same-process connection events if network telemetry exists; `destination.*` and `network.*` are connection-event fields not present on the process alert. Missing network telemetry is unresolved, not benign. Escalate when the remote host, port, or exposed service does not match the confirmed workflow.
- Where else does the same binary or reverse-forward pattern appear?
  - Focus: `process.hash.sha256`, `process.name`, `host.name`, `user.name`, `process.command_line`
  - Implication: Use $investigate_2 to scope the same hash, comparing command lines for `-R`/`RemoteForward` on other hosts/accounts. Absence of matches is not benign; broaden containment when the artifact appears beyond the source host/account. Close recurrence only when each match ties to the same confirmed workflow.

Disposition: Escalate suspicious or unresolved commands; close only when alert-local and recovered evidence confirm the exact host/account/process/remote-forward scope; preserve and escalate mixed cases.

### False positive analysis

- Benign activity is limited to a confirmed reverse SSH forwarding workflow where `process.command_line`, `host.id`, `user.name`, parent process, executable, remote server, and forward port are verified.
- Do not close because the binary is named `ssh.exe`/`plink.exe`, has a familiar path, or a trusted signature — the matched command and owner workflow must explain the `-R`/`RemoteForward` artifact.
- Scope exceptions to `host.id`, `user.name`, `process.executable` or `process.hash.sha256`, `process.parent.executable` or `process.parent.command_line`, and the exact reverse-forward args. Do not suppress all reverse forwarding across hosts or accounts.

### Response and remediation

- Scope first by reviewing the exact command, same-process network evidence, same executable hash, same user/host activity, and related alerts for the same remote SSH server or port before cleanup.
- Preserve or export case evidence plus volatile process, memory, executable, and file-system artifacts before isolation, process termination, or other disruptive action.
- After evidence capture, use reversible containment such as isolating the affected host or blocking egress to the confirmed SSH server/port while credential and session review proceeds.
- For confirmed malicious tunneling, terminate the SSH/Plink process, remove persistence or scripts that launched it, rotate exposed credentials, and clean staged binaries only after scoping.
- Record confirmed indicators and logging or detection gaps for the responsible detection or logging owners after containment.
"""
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.investigation_fields]
field_names = [
  "@timestamp",
  "host.name",
  "user.name",
  "user.id",
  "user.domain",
  "process.entity_id",
  "process.name",
  "process.executable",
  "process.command_line",
  "process.parent.executable",
  "process.parent.command_line",
]

[[transform.investigate]]
label = "Matched process context"
description = "Recover the process start event and immediate process context for the alerted OpenSSH or Plink reverse-forward command."
providers = [
  [
    { 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 = "Same host process launches"
description = "Find other process events with the same alerted process name on the same host for local recurrence and parent/account comparison."
providers = [
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "process.name", queryType = "phrase", value = "{{process.name}}", valueType = "string" },
  ],
]
relativeFrom = "now-24h"
relativeTo = "now"

[[transform.investigate]]
label = "Executable hash scope"
description = "Find other events for the same executable hash to scope repeated use of the matched OpenSSH or Plink binary after local validation."
providers = [
  [
    { excluded = false, field = "process.hash.sha256", queryType = "phrase", value = "{{process.hash.sha256}}", valueType = "string" },
  ],
]
relativeFrom = "now-7d"
relativeTo = "now"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1090"
name = "Proxy"
reference = "https://attack.mitre.org/techniques/T1090/"

[[rule.threat.technique.subtechnique]]
id = "T1090.002"
name = "External Proxy"
reference = "https://attack.mitre.org/techniques/T1090/002/"

[[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/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1021"
name = "Remote Services"
reference = "https://attack.mitre.org/techniques/T1021/"

[[rule.threat.technique.subtechnique]]
id = "T1021.004"
name = "SSH"
reference = "https://attack.mitre.org/techniques/T1021/004/"

[rule.threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"

Stages and Predicates

Stage 1: process

process where host.os.type == "windows" and event.type == "start" and
  (
    process.name : ("ssh.exe", "plink.exe") or
    ?process.pe.original_file_name : ("Plink", "plink.exe")
  ) and
  (
    process.args like "-R*" or
    process.args : "-oRemoteForward*" or
    (process.args == "-o" and process.args : "*RemoteForward*") or
    process.args regex """-[46AaCfGgKkMNnqsTtVvXxYy]+R.*"""
  )

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.argseq
  • -o corpus 5 (elastic 5)
field:"process.args" kind:eq value:"-o"
process.argsregex_match
  • -[46AaCfGgKkMNnqsTtVvXxYy]+R.*
field:"process.args" kind:regex_match value:"-[46AaCfGgKkMNnqsTtVvXxYy]+R.*"
process.argswildcard
  • *RemoteForward* corpus 2 (elastic 2)
  • -R* corpus 6 (elastic 6)
  • -oRemoteForward*
field:"process.args" kind:wildcard
process.namewildcard
  • plink.exe corpus 2 (elastic 1, splunk 1)
  • ssh.exe corpus 8 (elastic 8)
field:"process_basename" kind:wildcard
process.pe.original_file_namewildcard
  • Plink corpus 3 (sigma 1, elastic 1, splunk 1)
  • plink.exe
field:"OriginalFileName" kind:wildcard

Potential Subnet Scanning Activity from Compromised Host

#
Status
production
Severity
medium
Time window
61m
Group by
process.executable
Author
Elastic
Source
github.com/elastic/detection-rules

This rule detects potential subnet scanning activity from a compromised host. Subnet scanning is a common reconnaissance technique used by attackers to identify live hosts within a network range. A compromised host may exhibit subnet scanning behavior when an attacker is attempting to map out the network topology, identify vulnerable hosts, or prepare for further exploitation. This rule identifies potential subnet scanning activity by monitoring network connection attempts from a single host to a large number of hosts within a short time frame. ESQL rules have limited fields available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2025/03/04"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
This rule detects potential subnet scanning activity from a compromised host. Subnet scanning is a common reconnaissance
technique used by attackers to identify live hosts within a network range. A compromised host may exhibit subnet
scanning behavior when an attacker is attempting to map out the network topology, identify vulnerable hosts, or prepare
for further exploitation. This rule identifies potential subnet scanning activity by monitoring network connection
attempts from a single host to a large number of hosts within a short time frame. ESQL rules have limited fields
available in its alert documents. Make sure to review the original documents to aid in the investigation of this alert.
"""
from = "now-61m"
interval = "1h"
language = "esql"
license = "Elastic License v2"
name = "Potential Subnet Scanning Activity from Compromised Host"
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 Subnet Scanning Activity from Compromised Host

Subnet scanning is a reconnaissance method used by attackers to map network topology and identify active hosts. Adversaries exploit compromised hosts to perform these scans, seeking vulnerabilities for further attacks. The detection rule identifies such activity by monitoring Linux hosts for numerous connection attempts to different IPs within a short period, indicating potential scanning behavior. This helps in early detection and mitigation of network threats.

### Possible investigation steps

- Review the process executable identified in the alert to determine if it is a known or legitimate application that should be making network connections.
- Examine the destination IP addresses to identify any patterns or known malicious IPs, and check if these IPs are part of the organization's network or external.
- Investigate the specific host (using the agent.id) to assess if there are any signs of compromise, such as unusual processes or unauthorized access.
- Correlate the event timestamp with other logs or alerts to identify any concurrent suspicious activities or anomalies on the host.
- Check for any recent changes or updates on the host that might explain the scanning behavior, such as new software installations or configuration changes.

### False positive analysis

- High-volume legitimate network monitoring tools may trigger the rule. Identify and exclude these tools by adding their process executables to an exception list.
- Automated backup systems that connect to multiple hosts within a short timeframe can be mistaken for scanning activity. Review and exclude these systems by their process executable or agent ID.
- Security software performing routine network health checks might generate false positives. Verify these activities and create exceptions based on the specific process executable involved.
- Internal IT scripts or administrative tasks that involve connecting to numerous hosts for maintenance purposes can trigger alerts. Document these tasks and exclude them by process executable or agent ID.
- Cloud-based services or applications that require frequent connections to various hosts for functionality may appear as scanning. Identify these services and exclude them by their process executable or agent ID.

### Response and remediation

- Isolate the compromised host immediately from the network to prevent further scanning and potential lateral movement by the attacker.
- Terminate any suspicious processes identified by the executable name in the alert to stop ongoing scanning activities.
- Conduct a thorough examination of the compromised host to identify and remove any malware or unauthorized access tools that may have been installed.
- Reset credentials and review access permissions for the compromised host to ensure no unauthorized access persists.
- Update and patch the compromised host and any other vulnerable systems identified during the investigation to close security gaps.
- Monitor network traffic closely for any signs of continued scanning or other suspicious activities from other hosts, indicating potential further compromise.
- Escalate the incident to the security operations center (SOC) or incident response team for a comprehensive investigation and to determine if additional hosts are affected.
"""
risk_score = 47
rule_id = "860f2a03-a1cf-48d6-a674-c6d62ae608a1"
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: Discovery",
    "Data Source: Elastic Defend",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-endpoint.events.network-* metadata _id, _index, _version
| mv_expand event.action
| where
    host.os.type == "linux" and
    event.type == "start" and
    event.action == "connection_attempted" and
    not (
      process.executable in ("/usr/local/bin/prometheus", "/app/extra/chrome", "/usr/lib/virtualbox/VBoxHeadless", "/usr/bin/prometheus") or
      process.executable like "/usr/local/prometheus/*/prometheus" or
      process.executable like "/usr/share/elastic-agent/*" or
      process.executable like "/var/lib/docker/overlay*connectord" or
      process.executable like "/opt/rumble/bin/rumble-agent*" or
      process.executable like "/opt/gitlab/*" or
      process.executable like "/opt/google/chrome/chrome*" or
      process.executable like "/snap/firefox/*/firefox" or
      process.executable like "/var/lib/docker/overlay2/*/qbittorrent-nox"
    )
| keep
    @timestamp,
    _id,
    _index,
    _version,
    host.os.type,
    event.type,
    event.action,
    process.executable,
    destination.ip,
    agent.id,
    host.name,
    data_stream.dataset,
    data_stream.namespace

| stats
    Esql.event_count = count(),
    Esql.destination_ip_count_distinct = count_distinct(destination.ip),
    Esql.agent_id_count_distinct = count_distinct(agent.id),
    Esql.host_name_values = values(host.name),
    Esql.agent_id_values = values(agent.id),
    Esql.data_stream_dataset_values = values(data_stream.dataset),
    Esql.data_stream_namespace_values = values(data_stream.namespace)
  by process.executable

| where
    Esql.agent_id_count_distinct == 1 and
    Esql.destination_ip_count_distinct > 250
| sort Esql.event_count asc

// Extract unique values to ECS fields for alerts exclusion
| eval agent.id = mv_min(Esql.agent_id_values),
       host.name = mv_min(Esql.host_name_values)

| keep agent.id, host.name, process.executable, Esql.*
'''

[[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/"

Stages and Predicates

Stage 1: from

from logs-endpoint.events.network-* metadata _id, _index, _version

Stage 2: mv_expand

| mv_expand event.action

Stage 3: where

| where
    host.os.type == "linux" and
    event.type == "start" and
    event.action == "connection_attempted" and
    not (
      process.executable in ("/usr/local/bin/prometheus", "/app/extra/chrome", "/usr/lib/virtualbox/VBoxHeadless", "/usr/bin/prometheus") or
      process.executable like "/usr/local/prometheus/*/prometheus" or
      process.executable like "/usr/share/elastic-agent/*" or
      process.executable like "/var/lib/docker/overlay*connectord" or
      process.executable like "/opt/rumble/bin/rumble-agent*" or
      process.executable like "/opt/gitlab/*" or
      process.executable like "/opt/google/chrome/chrome*" or
      process.executable like "/snap/firefox/*/firefox" or
      process.executable like "/var/lib/docker/overlay2/*/qbittorrent-nox"
    )

Stage 4: keep

| keep
    @timestamp,
    _id,
    _index,
    _version,
    host.os.type,
    event.type,
    event.action,
    process.executable,
    destination.ip,
    agent.id,
    host.name,
    data_stream.dataset,
    data_stream.namespace

Stage 5: stats

| stats
    Esql.event_count = count(),
    Esql.destination_ip_count_distinct = count_distinct(destination.ip),
    Esql.agent_id_count_distinct = count_distinct(agent.id),
    Esql.host_name_values = values(host.name),
    Esql.agent_id_values = values(agent.id),
    Esql.data_stream_dataset_values = values(data_stream.dataset),
    Esql.data_stream_namespace_values = values(data_stream.namespace)
  by process.executable

Stage 6: where

| where
    Esql.agent_id_count_distinct == 1 and
    Esql.destination_ip_count_distinct > 250

Stage 7: sort

| sort Esql.event_count asc

Stage 8: eval

| eval agent.id = mv_min(Esql.agent_id_values),
       host.name = mv_min(Esql.host_name_values)

Stage 9: keep

| keep agent.id, host.name, process.executable, Esql.*

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.executablein/app/extra/chrome, /usr/bin/prometheus, /usr/lib/virtualbox/VBoxHeadless, /usr/local/bin/prometheusexcludes:process.executable
process.executablestarts_with/opt/gitlab/excludes:process.executable field:"process.executable" value:"/opt/gitlab/"
process.executablestarts_with/opt/google/chrome/chromeexcludes:process.executable field:"process.executable" value:"/opt/google/chrome/chrome"
process.executablestarts_with/opt/rumble/bin/rumble-agentexcludes:process.executable field:"process.executable" value:"/opt/rumble/bin/rumble-agent"
process.executablestarts_with/usr/share/elastic-agent/excludes:process.executable field:"process.executable" value:"/usr/share/elastic-agent/"
process.executablewildcard/snap/firefox/*/firefoxexcludes:process.executable field:"process.executable" value:"/snap/firefox/*/firefox"
process.executablewildcard/usr/local/prometheus/*/prometheusexcludes:process.executable field:"process.executable" value:"/usr/local/prometheus/*/prometheus"
process.executablewildcard/var/lib/docker/overlay*connectordexcludes:process.executable field:"process.executable" value:"/var/lib/docker/overlay*connectord"
process.executablewildcard/var/lib/docker/overlay2/*/qbittorrent-noxexcludes:process.executable field:"process.executable" value:"/var/lib/docker/overlay2/*/qbittorrent-nox"

Output Fields

These fields are emitted when the rule matches.

FieldSource
agent.idKEEP agent.id
host.nameKEEP host.name
process.executableKEEP process.executable
Esql.*KEEP Esql.*

QoS Policy Group Policy Registry Overwrite via WMI

#
Source
github.com/elastic/protections-artifacts

Identifies the overwrite of the machine Group Policy registry file Registry.pol by WmiPrvSE.exe with a call stack indicating QoS WMI policy configuration through gpedit.dll and qoswmi.dll. Tools such as EDRChoker abuse Policy-based Quality of Service to throttle Endpoint Detection and Response agents by persisting bandwidth caps in Group Policy, causing telemetry uploads to time out.

MITRE ATT&CK Coverage

TacticTechniques
Defense Impairment

Rule Body

[rule]
description = """
Identifies the overwrite of the machine Group Policy registry file Registry.pol by WmiPrvSE.exe with a call stack
indicating QoS WMI policy configuration through gpedit.dll and qoswmi.dll. Tools such as EDRChoker abuse Policy-based
Quality of Service to throttle Endpoint Detection and Response agents by persisting bandwidth caps in Group Policy,
causing telemetry uploads to time out.
"""
id = "0c206fcc-ad17-4aee-84df-767ab74c28a1"
license = "Elastic License v2"
name = "QoS Policy Group Policy Registry Overwrite via WMI"
os_list = ["windows"]
reference = ["https://github.com/TwoSevenOneT/EDRChoker"]
version = "1.0.1"

query = '''
file where event.action == "overwrite" and
  file.path : "?:\\Windows\\System32\\GroupPolicy\\Machine\\Registry.pol" and
  process.name : "WmiPrvSE.exe" and
  Effective_process.name != null and
  process.thread.Ext.call_stack_summary like "ntdll.dll*|kernelbase.dll|gpedit.dll|qoswmi.dll|*" and 
  not (user.id == "S-1-5-18" and Effective_process.name : "powershell.exe")
'''

min_endpoint_version = "8.7.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "Effective_process.entity_id"
state = 0

[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[threat.technique.subtechnique]]
id = "T1562.001"
name = "Disable or Modify Tools"
reference = "https://attack.mitre.org/techniques/T1562/001/"



[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

[internal]
min_endpoint_version = "8.7.0"

Stages and Predicates

Stage 1: file

file where event.action == "overwrite" and
  file.path : "?:\\Windows\\System32\\GroupPolicy\\Machine\\Registry.pol" and
  process.name : "WmiPrvSE.exe" and
  Effective_process.name != null and
  process.thread.Ext.call_stack_summary like "ntdll.dll*|kernelbase.dll|gpedit.dll|qoswmi.dll|*" and 
  not (user.id == "S-1-5-18" and Effective_process.name : "powershell.exe")

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

React2Shell Network Security Alert

#
Status
production
Severity
high
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

This rule identifies network security alerts related to CVE-2025-55182 exploitation attempts from different network security integrations. CVE-2025-55182 is a critical remote code execution vulnerability in React Server Components (RSC) Flight protocol. The vulnerability allows attackers to execute arbitrary code on the server by sending specially crafted deserialization payloads that exploit prototype chain traversal to access the Function constructor.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2025/12/10"
integration = ["panw", "cisco_ftd", "fortinet_fortigate", "suricata"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
This rule identifies network security alerts related to CVE-2025-55182 exploitation attempts from different network security
integrations. CVE-2025-55182 is a critical remote code execution vulnerability in React Server Components (RSC) Flight protocol.
The vulnerability allows attackers to execute arbitrary code on the server by sending specially crafted deserialization payloads
that exploit prototype chain traversal to access the Function constructor.
"""
from = "now-9m"
index = ["logs-panw.panos*", "logs-cisco_ftd.*", "logs-fortinet_fortigate.*", "logs-suricata.*"]
language = "kuery"
license = "Elastic License v2"
name = "React2Shell Network Security Alert"
note = """## Triage and analysis

### Investigating React2Shell Network Security Alert

This rule detects exploitation attempts targeting CVE-2025-55182, a critical remote code execution vulnerability in React's Flight protocol used by Next.js and other RSC implementations. The vulnerability stems from insecure prototype chain traversal in the Flight deserializer, allowing attackers to access `__proto__`, `constructor`, and ultimately the `Function` constructor to execute arbitrary code.

### Possible investigation steps

- Examine the full HTTP request body to identify the specific attack payload and command being executed.
- Check the response body for `E{"digest":"..."}` patterns which contain command output from successful exploitation.
- Identify the target application and verify if it runs vulnerable React (< 19.1.0) or Next.js (< 15.3.2) versions.
- Review the source IP for other reconnaissance or exploitation attempts against web applications.
- Check for the `Next-Action` header which is required for the exploit to work.
- Correlate with process execution logs to identify if child processes (e.g., shell commands) were spawned by the Node.js process.

### False positive analysis

- Legitimate React Server Components traffic will NOT contain `__proto__`, `constructor:constructor`, or code execution patterns.
- Security scanning tools like react2shell-scanner may trigger this rule during authorized penetration testing.
- The combination of prototype pollution patterns with RSC-specific syntax is highly indicative of malicious activity.

### Response and remediation

- Immediately update affected applications: React >= 19.1.0, Next.js >= 15.3.2.
- Block the source IP at the WAF/reverse proxy if exploitation is confirmed.
- If HTTP 500 or 303 responses with `digest` output were observed, assume successful code execution and investigate for compromise.
- Review server logs for evidence of command execution (file creation, network connections, process spawning).
- Implement WAF rules to block requests containing `__proto__` or `constructor:constructor` in POST bodies.
"""
references = [
    "https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182",
    "https://github.com/assetnote/react2shell-scanner",
    "https://slcyber.io/research-center/high-fidelity-detection-mechanism-for-rsc-next-js-rce-cve-2025-55182-cve-2025-66478/",
    "https://github.com/msanft/CVE-2025-55182",
]
risk_score = 73
rule_id = "1aefed68-eecd-47cc-9044-4a394b60061d"
severity = "high"
tags = [
    "Domain: Network",
    "Domain: Application",
    "Domain: Web",
    "Use Case: Threat Detection",
    "Use Case: Vulnerability",
    "Tactic: Initial Access",
    "Tactic: Execution",
    "Data Source: PAN-OS",
    "Data Source: Fortinet",
    "Data Source: Suricata",
    "Data Source: Cisco FTD",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
(data_stream.dataset:"cisco_ftd.log" and message:"SERVER-WEBAPP React Server Components remote code execution attempt") or
(data_stream.dataset:"fortinet_fortigate.log" and message:"applications3: React.Server.Components.react-flight.Remote.Code.Execution") or
(data_stream.dataset:"panw.panos" and event.action:"exploit_detected" and event.original :*React*Server*) or
(data_stream.dataset:("suricata_corelight" or "suricata.eve") and rule.name:*CVE-2025-55182*)
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1190"
name = "Exploit Public-Facing Application"
reference = "https://attack.mitre.org/techniques/T1190/"


[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.007"
name = "JavaScript"
reference = "https://attack.mitre.org/techniques/T1059/007/"



[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"

Stages and Predicates

Stage 1: query

(data_stream.dataset:"cisco_ftd.log" and message:"SERVER-WEBAPP React Server Components remote code execution attempt") or
(data_stream.dataset:"fortinet_fortigate.log" and message:"applications3: React.Server.Components.react-flight.Remote.Code.Execution") or
(data_stream.dataset:"panw.panos" and event.action:"exploit_detected" and event.original :*React*Server*) or
(data_stream.dataset:("suricata_corelight" or "suricata.eve") and rule.name:*CVE-2025-55182*)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data_stream.dataseteq
  • cisco_ftd.log
  • fortinet_fortigate.log
  • panw.panos
field:"data_stream.dataset" kind:eq
data_stream.datasetin
  • suricata.eve
  • suricata_corelight
field:"data_stream.dataset" kind:in
event.actioneq
  • exploit_detected
field:"EventType" kind:eq value:"exploit_detected"
event.originalwildcard
  • *React*Server*
field:"event.original" kind:wildcard value:"*React*Server*"
messageeq
  • SERVER-WEBAPP React Server Components remote code execution attempt
  • applications3: React.Server.Components.react-flight.Remote.Code.Execution
field:"message" kind:eq
rule.namewildcard
  • *CVE-2025-55182*
field:"rule.name" kind:wildcard value:"*CVE-2025-55182*"

Remote Execution via File Shares

#
Status
production
Severity
medium
Time window
1m
Sequence by
file.path, host.id, process.executable
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies the execution of a file that was created by the virtual system process. This may indicate lateral movement via network file shares.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/11/03"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/05/04"

[transform]
[[transform.osquery]]
label = "Osquery - Retrieve DNS Cache"
query = "SELECT * FROM dns_cache"

[[transform.osquery]]
label = "Osquery - Retrieve All Services"
query = "SELECT description, display_name, name, path, pid, service_type, start_type, status, user_account FROM services"

[[transform.osquery]]
label = "Osquery - Retrieve Services Running on User Accounts"
query = """
SELECT description, display_name, name, path, pid, service_type, start_type, status, user_account FROM services WHERE
NOT (user_account LIKE '%LocalSystem' OR user_account LIKE '%LocalService' OR user_account LIKE '%NetworkService' OR
user_account == null)
"""

[[transform.osquery]]
label = "Osquery - Retrieve Service Unsigned Executables with Virustotal Link"
query = """
SELECT concat('https://www.virustotal.com/gui/file/', sha1) AS VtLink, name, description, start_type, status, pid,
services.path FROM services JOIN authenticode ON services.path = authenticode.path OR services.module_path =
authenticode.path JOIN hash ON services.path = hash.path WHERE authenticode.result != 'trusted'
"""


[rule]
author = ["Elastic"]
description = """
Identifies the execution of a file that was created by the virtual system process. This may indicate lateral movement
via network file shares.
"""
from = "now-9m"
index = ["logs-endpoint.events.process-*", "logs-endpoint.events.file-*"]
language = "eql"
license = "Elastic License v2"
name = "Remote Execution via File Shares"
note = """## Triage and analysis

### Investigating Remote Execution via File Shares

Adversaries can use network shares to host tooling to support the compromise of other hosts in the environment. These tools can include discovery utilities, credential dumpers, malware, etc.

> **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.

#### 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.
- Review adjacent login events (e.g., 4624) in the alert timeframe to identify the account used to perform this action.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Examine the host for derived artifacts that indicate suspicious activities:
  - Analyze the process executable using a private sandboxed analysis system.
  - Observe and collect information about the following activities in both the sandbox and the alert subject host:
    - Attempts to contact external domains and addresses.
      - Use the Elastic Defend network events to determine domains and addresses contacted by the subject process by filtering by the process' `process.entity_id`.
      - Examine the DNS cache for suspicious or anomalous entries.
        - $osquery_0
    - Use the Elastic Defend registry events to examine registry keys accessed, modified, or created by the related processes in the process tree.
    - Examine the host services for suspicious or anomalous entries.
      - $osquery_1
      - $osquery_2
      - $osquery_3
  - Retrieve the files' SHA-256 hash values using the PowerShell `Get-FileHash` cmdlet and search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.
- Investigate potentially compromised accounts. Analysts can do this by searching for login events (for example, 4624) to the target host after the registry modification.

### False positive analysis

- This activity can happen legitimately. Consider adding exceptions if it is expected and noisy in your environment.

### 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.
- Remove and block malicious artifacts identified during triage.
- Review the privileges needed to write to the network share and restrict write access as needed.
- 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
"""

references = [
    "http://web.archive.org/web/20230329172636/https://blog.menasec.net/2020/08/new-trick-to-detect-lateral-movement.html",
    "https://www.elastic.co/security-labs/hunting-for-lateral-movement-using-event-query-language",
]
risk_score = 47
rule_id = "ab75c24b-2502-43a0-bf7c-e60e662c811e"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Lateral Movement",
    "Resources: Investigation Guide",
    "Data Source: Elastic Endgame",
    "Data Source: Elastic Defend",
]
type = "eql"

query = '''
sequence with maxspan=1m
  [file where host.os.type == "windows" and event.type in ("creation", "change") and 
   process.pid == 4 and (file.extension : ("exe", "scr", "pif", "com") or file.Ext.header_bytes : "4d5a*")] by host.id, file.path
  [process where host.os.type == "windows" and event.type == "start" and
    not (
      (
        process.code_signature.trusted == true and
        process.code_signature.subject_name : (
              "Veeam Software Group GmbH",
              "Elasticsearch, Inc.",
              "PDQ.com Corporation",
              "CrowdStrike, Inc.",
              "Microsoft Windows Hardware Compatibility Publisher",
              "ZOHO Corporation Private Limited",
              "BeyondTrust Corporation", 
              "CyberArk Software Ltd.", 
              "Sophos Ltd",
              "AO Kaspersky Lab",
              "Anthropic, PBC",
              "Adobe Inc.",
              "Netwrix Corporation"
        )
      ) or
      (
        process.executable : (
          "?:\\Windows\\ccmsetup\\ccmsetup.exe",
          "?:\\Windows\\SoftwareDistribution\\Download\\Install\\*.exe",
          "?:\\Windows\\CAInvokerService.exe",
          "?:\\Users\\*\\AppData\\Local\\Microsoft\\OneDrive\\*\\OneDriveSetup.exe"
        ) and process.code_signature.trusted == true
      ) or
      (
        process.executable : "?:\\SMS_*\\srvboot.exe" and 
        process.code_signature.trusted == true and process.code_signature.subject_name : "Microsoft Corporation"
      )
    )
  ] by host.id, process.executable
'''


[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1021"
name = "Remote Services"
reference = "https://attack.mitre.org/techniques/T1021/"

[[rule.threat.technique.subtechnique]]
id = "T1021.002"
name = "SMB/Windows Admin Shares"
reference = "https://attack.mitre.org/techniques/T1021/002/"

[[rule.threat.technique]]
id = "T1570"
name = "Lateral Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1570/"

[rule.threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"

Stages and Predicates

Ordered sequence: each step below must occur in order within 1m, correlated by file.path, host.id, process.executable.

Stage 1: file

[file where host.os.type == "windows" and event.type in ("creation", "change") and 
   process.pid == 4 and (file.extension : ("exe", "scr", "pif", "com") or file.Ext.header_bytes : "4d5a*")] by host.id, file.path

Stage 2: process

[process where host.os.type == "windows" and event.type == "start" and
    not (
      (
        process.code_signature.trusted == true and
        process.code_signature.subject_name : (
              "Veeam Software Group GmbH",
              "Elasticsearch, Inc.",
              "PDQ.com Corporation",
              "CrowdStrike, Inc.",
              "Microsoft Windows Hardware Compatibility Publisher",
              "ZOHO Corporation Private Limited",
              "BeyondTrust Corporation", 
              "CyberArk Software Ltd.", 
              "Sophos Ltd",
              "AO Kaspersky Lab",
              "Anthropic, PBC",
              "Adobe Inc.",
              "Netwrix Corporation"
        )
      ) or
      (
        process.executable : (
          "?:\\Windows\\ccmsetup\\ccmsetup.exe",
          "?:\\Windows\\SoftwareDistribution\\Download\\Install\\*.exe",
          "?:\\Windows\\CAInvokerService.exe",
          "?:\\Users\\*\\AppData\\Local\\Microsoft\\OneDrive\\*\\OneDriveSetup.exe"
        ) and process.code_signature.trusted == true
      ) or
      (
        process.executable : "?:\\SMS_*\\srvboot.exe" and 
        process.code_signature.trusted == true and process.code_signature.subject_name : "Microsoft Corporation"
      )
    )
  ] by host.id, process.executable

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
event.typein
  • change corpus 18 (elastic 18)
  • creation corpus 17 (elastic 17)
field:"event.type" kind:in
file.Ext.header_byteswildcard
  • 4d5a* corpus 45 (elastic 45)
field:"file.Ext.header_bytes" kind:wildcard value:"4d5a*"
file.extensionwildcard
  • com corpus 16 (elastic 16)
  • exe corpus 32 (elastic 32)
  • pif corpus 18 (elastic 18)
  • scr corpus 17 (elastic 17)
field:"file.extension" kind:wildcard
process.pideq
  • 4 transforms: number corpus 17 (elastic 17)
field:"process_id" kind:eq value:"4"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.code_signature.subject_nameeqMicrosoft Corporationexcludes:process.code_signature.subject_name field:"process.code_signature.subject_name" value:"Microsoft Corporation"
process.code_signature.trustedeqtrueexcludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true"
process.executablewildcard?:\SMS_*\srvboot.exeexcludes:process.executable field:"process.executable" value:"?:\SMS_*\srvboot.exe"
process.code_signature.subject_nameeqVeeam Software Group GmbH, Elasticsearch, Inc., PDQ.com Corporation, CrowdStrike, Inc., Microsoft Windows Hardware Compatibility Publisher, ZOHO Corporation Private Limited, BeyondTrust Corporation, CyberArk Software Ltd., Sophos Ltd, AO Kaspersky Lab, Anthropic, PBC, Adobe Inc., Netwrix Corporationexcludes:process.code_signature.subject_name
process.executablewildcard?:\Windows\ccmsetup\ccmsetup.exe, ?:\Windows\SoftwareDistribution\Download\Install\*.exe, ?:\Windows\CAInvokerService.exe, ?:\Users\*\AppData\Local\Microsoft\OneDrive\*\OneDriveSetup.exeexcludes:process.executable

Repeated Stalled TLS Handshakes via ALPN acme-tls/1 Extension

#
Status
production
Severity
low
Time window
9m
Group by
destination.ip, source.ip
Author
Elastic
Source
github.com/elastic/detection-rules

This rule detects two ALPN-based denial-of-service patterns against TLS servers. The first identifies repeated stalled handshakes advertising the acme-tls/1 ALPN extension with no session established, indicating potential goroutine or worker exhaustion in reverse proxies. The second matches connections where a malformed ALPN extension triggers TLS alerts such as decode_error or illegal_parameter, consistent with zero-length ALPN list exploitation. Both patterns are anomalous outside of scheduled ACME TLS-ALPN-01 certificate validation activity.

Known False Positives

  • Legitimate ACME certificate renewal agents (cert-manager, Certbot, Caddy) use acme-tls/1 during TLS-ALPN-01 challenges. A single incomplete challenge due to a network timeout can occur normally, but five or more incomplete sessions from the same source within the detection window is abnormal even for misconfigured ACME clients. TLS decode_error or illegal_parameter alerts can also be produced by buggy TLS clients or misconfigured load balancers. Suppress by adding known ACME client source IPs or ACME CA validation IP ranges to an exception list.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2026/06/12"
integration = ["network_traffic"]
maturity = "production"
updated_date = "2026/06/12"

[rule]
author = ["Elastic"]
description = """
This rule detects two ALPN-based denial-of-service patterns against TLS servers. The first identifies repeated stalled
handshakes advertising the acme-tls/1 ALPN extension with no session established, indicating potential goroutine or
worker exhaustion in reverse proxies. The second matches connections where a malformed ALPN extension triggers TLS
alerts such as decode_error or illegal_parameter, consistent with zero-length ALPN list exploitation. Both patterns are
anomalous outside of scheduled ACME TLS-ALPN-01 certificate validation activity.
"""
false_positives = [
    """
    Legitimate ACME certificate renewal agents (cert-manager, Certbot, Caddy) use acme-tls/1 during TLS-ALPN-01
    challenges. A single incomplete challenge due to a network timeout can occur normally, but five or more incomplete
    sessions from the same source within the detection window is abnormal even for misconfigured ACME clients. TLS
    decode_error or illegal_parameter alerts can also be produced by buggy TLS clients or misconfigured load balancers.
    Suppress by adding known ACME client source IPs or ACME CA validation IP ranges to an exception list.
    """,
]
from = "now-9m"
language = "esql"
license = "Elastic License v2"
max_signals = 5
name = "Repeated Stalled TLS Handshakes via ALPN acme-tls/1 Extension"
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 Repeated Stalled TLS Handshakes via ALPN acme-tls/1 Extension

This rule fires when five or more TLS connections from the same source IP to the same destination IP
are recorded where the ClientHello advertises `acme-tls/1` as an ALPN protocol, the handshake never
completes (`tls.established: false`), or where malformed ALPN data produces a relevant TLS alert.
Individually, an incomplete ACME challenge can be a transient network issue. In volume, this pattern is
consistent with attempts to exhaust reverse proxy resources, including CVE-2026-22045, and cause a
denial of service.

Packetbeat TLS events describe the TLS handshake and do not include connection byte totals or reliable
elapsed duration for an incomplete handshake. Use `network_traffic.flow` events correlated by
`network.community_id` when byte counts or connection duration are required during investigation.

`acme-tls/1` is legitimately used only by ACME certificate clients performing TLS-ALPN-01 domain
validation. Repeated stalled sessions outside of scheduled certificate renewal windows are anomalous.

### Possible investigation steps

- Identify the source IP (`source.ip`) and verify whether it belongs to a known ACME certificate
  authority (Let's Encrypt: 66.133.109.0/24, 172.65.32.248/28; ZeroSSL; Buypass) or an authorized
  internal ACME renewal agent. Traffic from unexpected sources is the primary indicator of exploitation.
- Pivot to `destination.ip` and `destination.port` to determine which TLS listener is targeted and
  whether it is internet-exposed. Traefik, nginx, HAProxy, and similar reverse proxies are the
  most likely targets.
- Count total stalled events from the same `source.ip` over the past hour to understand the full
  attack volume:
  ```esql
  FROM logs-network_traffic.tls*
  | WHERE tls.detailed.client_hello.extensions.application_layer_protocol_negotiation == "acme-tls/1"
    AND tls.established == false
  | STATS count = COUNT(*) BY source.ip, destination.ip, destination.port
  | SORT count DESC
  ```
- If flow reporting is enabled, correlate `logs-network_traffic.flow-*` events on `network.community_id`
  to review `network.bytes`, `source.bytes`, `destination.bytes`, and `event.duration`.
- Check server-side metrics on the destination host around the alert time: goroutine count for Go
  services (Traefik, Caddy), worker or thread count for nginx or HAProxy, and TCP accept queue depth.
  Saturation aligned with the alert window confirms impact.
- Review whether the targeted service is patched for CVE-2026-22045. Traefik versions before the
  fix did not enforce handshake timeouts on acme-tls/1 listeners, allowing indefinite goroutine hold.

### False positive analysis

- cert-manager, Certbot, or Caddy ACME clients produce `acme-tls/1` connections during certificate
  renewal. These complete quickly under normal conditions; isolated stalled events from recognized
  ACME client IPs are likely transient network issues, not attacks. The threshold of five events within
  the detection window suppresses most one-off failures.
- Load balancer health checks misconfigured to probe with TLS-ALPN-01 can generate this pattern;
  identify the health check source IP and add it to the exception list.

### Response and remediation

- If the source IP is not a known ACME CA or authorized renewal agent, block it at the perimeter.
- Upgrade Traefik to a version patched for CVE-2026-22045. Apply equivalent handshake-timeout
  configurations on other reverse proxies (`ssl_handshake_timeout` in nginx).
- Enforce a TLS handshake timeout at the listener level to bound how long any stalled connection
  can hold a goroutine or worker slot.
- Rate-limit inbound TLS connections per source IP at the network boundary to limit the blast radius
  of connection-exhaustion attacks.
- If service degradation is confirmed, restart the affected reverse proxy after applying timeout
  mitigations to recover exhausted resources.
"""
references = [
    "https://nvd.nist.gov/vuln/detail/CVE-2026-22045",
    "https://nvd.nist.gov/vuln/detail/CVE-2024-5535",
    "https://www.rfc-editor.org/rfc/rfc8737",
    "https://www.elastic.co/guide/en/beats/packetbeat/current/configuration-tls.html",
]
risk_score = 21
rule_id = "581bd9b4-ee08-415a-97d7-756e6c53c264"
setup = """## Setup

This rule requires the Elastic Agent `network_traffic` integration with TLS protocol parsing enabled
and `include_detailed_fields: true` (the default). Without this setting, the field
`tls.detailed.client_hello.extensions.application_layer_protocol_negotiation` is not populated and
the rule will not match.

Verify your `network_traffic` integration configuration includes:

```yaml
packetbeat.protocols:
  - type: tls
    ports: [443, 8443, 9443]
    include_detailed_fields: true
    transaction_timeout: 30s
```

Adjust the port list to cover all TLS listeners in your environment that could be targeted, including
reverse proxy listeners and custom TLS service ports. The `include_detailed_fields` key defaults to
`true`; if it was explicitly disabled, re-enable it and restart the agent.

Packetbeat's default TLS `transaction_timeout` is 10 seconds. Incomplete handshakes that remain idle
beyond this timeout can expire without producing a `network_traffic.tls` event. Configure
`transaction_timeout` to exceed the longest incomplete-handshake interval you intend to observe. The
example above uses 30 seconds; increasing this value retains connection state longer and can increase
memory usage on high-volume sensors.
"""
severity = "low"
tags = [
    "Domain: Network",
    "Use Case: Threat Detection",
    "Use Case: Network Security Monitoring",
    "Use Case: Vulnerability",
    "Data Source: Network Traffic",
    "Tactic: Impact",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
from logs-network_traffic.tls*
| where source.ip is not null and destination.ip is not null and (
    (
      tls.detailed.client_hello.extensions.application_layer_protocol_negotiation == "acme-tls/1" and
      tls.established == false
    ) or (
      CONTAINS(TO_LOWER(tls.detailed.client_hello.extensions._unparsed_), "alpn") and
      tls.detailed.alert_types in ("decode_error", "illegal_parameter")
    )
  )
| stats
    Esql.event_count = COUNT(*),
    Esql.destination_port_values = MV_SLICE(MV_DEDUPE(TOP(destination.port, 10, "asc")), 0, 10),
    Esql.network_community_id_values = MV_SLICE(MV_DEDUPE(TOP(network.community_id, 10, "asc")), 0, 10),
    Esql.alpn_values = MV_SLICE(
      MV_DEDUPE(TOP(tls.detailed.client_hello.extensions.application_layer_protocol_negotiation, 10, "asc")),
      0,
      10
    ),
    Esql.alert_type_values = MV_SLICE(MV_DEDUPE(TOP(tls.detailed.alert_types, 10, "asc")), 0, 10)
  by source.ip, destination.ip
| where Esql.event_count >= 5
| keep
    source.ip,
    destination.ip,
    Esql.event_count,
    Esql.destination_port_values,
    Esql.network_community_id_values,
    Esql.alpn_values,
    Esql.alert_type_values
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1499"
name = "Endpoint Denial of Service"
reference = "https://attack.mitre.org/techniques/T1499/"
[[rule.threat.technique.subtechnique]]
id = "T1499.002"
name = "Service Exhaustion Flood"
reference = "https://attack.mitre.org/techniques/T1499/002/"



[rule.threat.tactic]
id = "TA0040"
name = "Impact"
reference = "https://attack.mitre.org/tactics/TA0040/"

Stages and Predicates

Stage 1: from

from logs-network_traffic.tls*

Stage 2: where

| where source.ip is not null and destination.ip is not null and (
    (
      tls.detailed.client_hello.extensions.application_layer_protocol_negotiation == "acme-tls/1" and
      tls.established == false
    ) or (
      CONTAINS(TO_LOWER(tls.detailed.client_hello.extensions._unparsed_), "alpn") and
      tls.detailed.alert_types in ("decode_error", "illegal_parameter")
    )
  )

Stage 3: stats

| stats
    Esql.event_count = COUNT(*),
    Esql.destination_port_values = MV_SLICE(MV_DEDUPE(TOP(destination.port, 10, "asc")), 0, 10),
    Esql.network_community_id_values = MV_SLICE(MV_DEDUPE(TOP(network.community_id, 10, "asc")), 0, 10),
    Esql.alpn_values = MV_SLICE(
      MV_DEDUPE(TOP(tls.detailed.client_hello.extensions.application_layer_protocol_negotiation, 10, "asc")),
      0,
      10
    ),
    Esql.alert_type_values = MV_SLICE(MV_DEDUPE(TOP(tls.detailed.alert_types, 10, "asc")), 0, 10)
  by source.ip, destination.ip

Stage 4: where

| where Esql.event_count >= 5

Stage 5: keep

| keep
    source.ip,
    destination.ip,
    Esql.event_count,
    Esql.destination_port_values,
    Esql.network_community_id_values,
    Esql.alpn_values,
    Esql.alert_type_values

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

FieldSource
source.ipKEEP source.ip
destination.ipKEEP destination.ip
Esql.event_countKEEP Esql.event_count
Esql.destination_port_valuesKEEP Esql.destination_port_values
Esql.network_community_id_valuesKEEP Esql.network_community_id_values
Esql.alpn_valuesKEEP Esql.alpn_values
Esql.alert_type_valuesKEEP Esql.alert_type_values

ROT encoded Python Script Execution

#
Time window
10s
Sequence by
process.entity_id
Source
github.com/elastic/protections-artifacts

Detects Python execution followed by creation of ROT cipher-encoded bytecode files (rot_XX.cpython-*.pyc) within 10 seconds. This pattern indicates malicious Python packages using ROT encoding to obfuscate code and evade static analysis. The technique has been observed in supply chain attacks, particularly by DPRK groups targeting cryptocurrency sectors.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[rule]
description = """
Detects Python execution followed by creation of ROT cipher-encoded bytecode files (rot_XX.cpython-*.pyc) within 10
seconds. This pattern indicates malicious Python packages using ROT encoding to obfuscate code and evade static
analysis. The technique has been observed in supply chain attacks, particularly by DPRK groups targeting cryptocurrency
sectors.
"""
id = "fdbe99cd-6633-4775-9535-9fd3095ac77a"
license = "Elastic License v2"
name = "ROT encoded Python Script Execution"
os_list = ["macos"]
reference = ["https://www.elastic.co/security-labs/dprk-code-of-conduct"]
version = "1.0.7"

query = '''
sequence by process.entity_id with maxspan=10s
 [process where event.type == "start" and event.action == "exec" and process.name like~ "python*" and process.args like~ ("*.py", "*.pyc") and
   not process.parent.executable in ("/Library/Developer/CommandLineTools/usr/bin/make", "/Applications/Xcode.app/Contents/Developer/usr/bin/make")]
 [file where event.action == "modification" and process.name like~ "python*" and file.name like~ "rot_??.cpython-*.pyc*"]
'''

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 = "T1027"
name = "Obfuscated Files or Information"
reference = "https://attack.mitre.org/techniques/T1027/"
[[threat.technique.subtechnique]]
id = "T1027.013"
name = "Encrypted/Encoded File"
reference = "https://attack.mitre.org/techniques/T1027/013/"


[[threat.technique]]
id = "T1140"
name = "Deobfuscate/Decode Files or Information"
reference = "https://attack.mitre.org/techniques/T1140/"


[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

[internal]
min_endpoint_version = "8.11.0"

Stages and Predicates

Ordered sequence: each step below must occur in order within 10s, correlated by process.entity_id.

Stage 1: process

[process where event.type == "start" and event.action == "exec" and process.name like~ "python*" and process.args like~ ("*.py", "*.pyc") and
   not process.parent.executable in ("/Library/Developer/CommandLineTools/usr/bin/make", "/Applications/Xcode.app/Contents/Developer/usr/bin/make")]

Stage 2: file

[file where event.action == "modification" and process.name like~ "python*" and file.name like~ "rot_??.cpython-*.pyc*"]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • exec corpus 547 (elastic 547)
  • modification corpus 72 (elastic 72)
field:"EventType" kind:eq
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
file.namewildcard
  • rot_??.cpython-*.pyc* corpus 2 (elastic 2)
field:"file.name" kind:wildcard value:"rot_??.cpython-*.pyc*"
process.argswildcard
  • *.py corpus 2 (elastic 2)
  • *.pyc
field:"process.args" kind:wildcard
process.namewildcard
  • python* corpus 55 (elastic 55)
field:"process_basename" kind:wildcard value:"python*"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.parent.executablein/Applications/Xcode.app/Contents/Developer/usr/bin/make, /Library/Developer/CommandLineTools/usr/bin/makeexcludes:process.parent.executable field:"process.parent.executable" value:"/Applications/Xcode.app/Contents/Developer/usr/bin/make" field:"process.parent.executable" value:"/Library/Developer/CommandLineTools/usr/bin/make"

Service Creation via Local Kerberos Authentication

#
Status
production
Severity
high
Time window
5m
Sequence by
winlog.computer_name, winlog.event_data.SubjectLogonId, winlog.event_data.TargetLogonId
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies a suspicious local successful logon event where the Logon Package is Kerberos, the remote address is set to localhost, followed by service creation from the same LogonId. This may indicate an attempt to leverage a Kerberos relay attack variant that can elevate privileges locally from a domain-joined user to LocalSystem privileges.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2022/04/27"
integration = ["system", "windows"]
maturity = "production"
updated_date = "2026/05/03"

[rule]
author = ["Elastic"]
description = """
Identifies a suspicious local successful logon event where the Logon Package is Kerberos, the remote address is set to
localhost, followed by service creation from the same LogonId. This may indicate an attempt to leverage a Kerberos relay
attack variant that can elevate privileges locally from a domain-joined user to LocalSystem privileges.
"""
from = "now-9m"
index = ["logs-system.security*", "logs-windows.forwarded*", "winlogbeat-*"]
language = "eql"
license = "Elastic License v2"
name = "Service Creation via Local Kerberos Authentication"
references = [
    "https://github.com/Dec0ne/KrbRelayUp",
    "https://googleprojectzero.blogspot.com/2021/10/using-kerberos-for-authentication-relay.html",
    "https://github.com/cube0x0/KrbRelay",
    "https://gist.github.com/tyranid/c24cfd1bd141d14d4925043ee7e03c82",
]
risk_score = 73
rule_id = "e4e31051-ee01-4307-a6ee-b21b186958f4"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Privilege Escalation",
    "Use Case: Active Directory Monitoring",
    "Data Source: Active Directory",
    "Data Source: Windows Security Event Logs",
    "Resources: Investigation Guide",
]
type = "eql"

query = '''
sequence by winlog.computer_name with maxspan=5m
 [authentication where host.os.type == "windows" and

  /* event 4624 need to be logged */
  event.action == "logged-in" and event.outcome == "success" and winlog.event_data.ElevatedToken == "%%1843" and process.pid == 0 and 

  /* authenticate locally using relayed kerberos Ticket */
  winlog.event_data.AuthenticationPackageName :"Kerberos" and winlog.logon.type == "Network" and cidrmatch(source.ip, "127.0.0.0/8", "::1")] by winlog.event_data.TargetLogonId

  [any where host.os.type == "windows" and
   /* event 4697 need to be logged */
   event.action : "service-installed"] by winlog.event_data.SubjectLogonId
'''

note = """## Triage and analysis

### Investigating Service Creation via Local Kerberos Authentication
#### Possible investigation steps

- Do the source events show a loopback Kerberos logon followed by service creation in the same session?
  - Why: sequence alerts merge fields; recover the 4624 and 4697 Timeline source events before interpreting grouped meaning.
  - Focus: `winlog.computer_name`: 4624 `source.ip`, `winlog.logon.type`, `winlog.event_data.AuthenticationPackageName`, `winlog.event_data.TargetLogonId`; 4697 `winlog.event_data.SubjectLogonId`.
  - Implication: escalate when loopback Kerberos network logon and 4697 service install share the same logon ID; lower suspicion when recovery shows no matching 4697, non-loopback source, or a different session.
- Which identity received the elevated loopback Kerberos session?
  - Focus: 4624 `winlog.event_data.TargetUserName`, `winlog.event_data.TargetDomainName`, `winlog.event_data.TargetUserSid`, `user.id`, and `winlog.event_data.ElevatedToken`; Subject fields are the local initiator, not the authenticated identity.
  - Implication: escalate when the authenticated identity is an unexpected admin, service, or machine-account path for this host; lower suspicion only when the same identity and lab or deployment host cohort are recognized for this validation pattern.
- What service did the recovered 4697 install?
  - Focus: 4697 `winlog.event_data.ServiceName`, `winlog.event_data.ServiceFileName`, `winlog.event_data.ServiceAccount`, `winlog.event_data.ServiceStartType`, and `winlog.event_data.ServiceType`.
  - Implication: escalate when the service uses a throwaway name, shell or script command, user-writable payload, or LocalSystem execution. Public tools may use "KrbSCM" or "UACBypassedService"; lower suspicion only when stable service metadata, account, and host cohort match the same authorized validation or owner-confirmed deployment workflow.
- Do same-session Windows Security events show credential use, privilege activation, or additional service activity?
  - Focus: same-host Windows Security events surrounding the sequence, keyed on `winlog.event_data.SubjectLogonId`; read 4624, 4648, and additional 4697 records. $investigate_0
  - Hint: query `winlog.computer_name` plus either recovered logon ID across the alert window first; expand only if source-event ordering is unclear.
  - Hint: Missing authentication telemetry is unresolved, not benign.
  - Implication: escalate when the same session shows explicit credentials or multiple service installs; keep scope local when evidence remains one recovered 4624-to-4697 chain with no contradictory activity.
- If local evidence remains suspicious or unresolved, do related alerts show the same relay-to-service chain elsewhere?
  - Focus: related alerts for `winlog.computer_name` in the last 48 hours that reuse the same service name or command, or show Kerberos or service-install abuse on this host. $investigate_1
  - Hint: compare `user.id` only if the host view does not show whether one operator or account cohort is involved. $investigate_2
  - Implication: broaden scope when related alerts show the same host or user preparing, reusing, or expanding the service-creation chain; keep response local when related-alert review is quiet and source events already resolve the case.
- Escalate when source recovery confirms loopback Kerberos followed by suspicious LocalSystem service creation; close only when the session, identity, service metadata, and surrounding Windows Security evidence fit one exact benign activity with corroborating owner or test records when telemetry cannot prove legitimacy; preserve and escalate when evidence is mixed.

### False positive analysis

- Authorized exploit validation, red-team work, or security research can reproduce this rule on lab systems. Confirm the 4624-to-4697 chain, `winlog.event_data.ServiceName`, `winlog.event_data.ServiceFileName`, `user.id`, and `winlog.computer_name` match test scope and timing. Without change or test records, close only when telemetry independently proves that validation scope; mark a one-off test as non-exceptionable instead of requiring recurrence.
- Treat loopback Kerberos plus service creation as an operational anti-pattern outside authorized validation. A deployment or support claim is benign only when owner or runbook confirmation and source events prove this exact local SCM path, stable `winlog.event_data.ServiceName`, `winlog.event_data.ServiceFileName`, `winlog.event_data.ServiceAccount`, `user.id`, `winlog.computer_name`, and no relay-prerequisite or follow-on alerts.
- Before creating an exception, pin `winlog.event_data.ServiceName`, `winlog.event_data.ServiceFileName`, `winlog.event_data.ServiceAccount`, `user.id`, and `winlog.computer_name`, and add an expiry or test-scope constraint for one-off validation. Avoid exceptions on loopback `source.ip`, event 4624, event 4697, or Kerberos alone because those conditions are broader than the confirmed workflow.

### Response and remediation

- If confirmed benign, preserve the source-event chain and service evidence that proved the authorized workflow, then reverse temporary containment. Create an exception only from the pinned workflow fields, with an expiry or test-scope constraint for one-off validation.
- If suspicious but unconfirmed, preserve the Timeline source events, recovered logon IDs, loopback source, service metadata, and surrounding `event.code` "4648" evidence before containment. Apply reversible containment first: stop and disable the new service after evidence capture, temporarily restrict the implicated account if follow-on activity indicates active misuse, or isolate the host only when active compromise and host criticality justify interruption.
- If confirmed malicious, preserve the service record and recovered source events, then isolate the host when feasible, disable and remove the malicious service, and reset or restrict the implicated account plus any machine-account, delegation, or certificate artifacts found during scoping. If direct response is unavailable, escalate with session IDs, service metadata, `source.ip`, `user.id`, and related-alert evidence to the team that can contain the system. Scope related hosts and identities for the same service name, service command, or loopback Kerberos pattern before cleanup.
- Post-incident hardening: enforce LDAP signing and channel binding where possible, reduce ms-DS-MachineAccountQuota, protect privileged accounts from delegation, harden ADCS web enrollment with TLS and EPA if that path exists, and retain Windows Security logs long enough to reconstruct future 4624-to-4697 chains.
"""

setup = """## Setup

The following Windows audit policies must be enabled to generate the events used by this rule:
- [Audit Logon](https://ela.st/audit-logon)
- [Audit Security System Extension](https://ela.st/audit-security-system-extension)
"""

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "winlog.computer_name",
    "host.id",
    "user.id",
    "event.code",
    "event.action",
    "source.ip",
    "winlog.logon.type",
    "winlog.event_data.AuthenticationPackageName",
    "winlog.event_data.ElevatedToken",
    "winlog.event_data.TargetLogonId",
    "winlog.event_data.SubjectLogonId",
    "winlog.event_data.ServiceName",
    "winlog.event_data.ServiceFileName",
    "winlog.event_data.ServiceAccount",
]

[transform]

[[transform.investigate]]
label = "Windows Security events for the same logon session"
description = ""
providers = [
  [
    { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" },
    { excluded = false, field = "winlog.event_data.SubjectLogonId", queryType = "phrase", value = "{{winlog.event_data.SubjectLogonId}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4624", valueType = "string" }
  ],
  [
    { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" },
    { excluded = false, field = "winlog.event_data.SubjectLogonId", queryType = "phrase", value = "{{winlog.event_data.SubjectLogonId}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4648", valueType = "string" }
  ],
  [
    { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" },
    { excluded = false, field = "winlog.event_data.SubjectLogonId", queryType = "phrase", value = "{{winlog.event_data.SubjectLogonId}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4697", valueType = "string" }
  ],
  [
    { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" },
    { excluded = false, field = "winlog.event_data.TargetLogonId", queryType = "phrase", value = "{{winlog.event_data.SubjectLogonId}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4624", valueType = "string" }
  ],
  [
    { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" },
    { excluded = false, field = "winlog.event_data.TargetLogonId", queryType = "phrase", value = "{{winlog.event_data.SubjectLogonId}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4648", valueType = "string" }
  ],
  [
    { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" },
    { excluded = false, field = "winlog.event_data.TargetLogonId", queryType = "phrase", value = "{{winlog.event_data.SubjectLogonId}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4697", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[transform.investigate]]
label = "Alerts associated with the host in the last 48h"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "winlog.computer_name", queryType = "phrase", value = "{{winlog.computer_name}}", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[transform.investigate]]
label = "Alerts associated with the user in the last 48h"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.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.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1557"
name = "Adversary-in-the-Middle"
reference = "https://attack.mitre.org/techniques/T1557/"

[[rule.threat.technique]]
id = "T1558"
name = "Steal or Forge Kerberos Tickets"
reference = "https://attack.mitre.org/techniques/T1558/"

[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"

Stages and Predicates

Ordered sequence: each step below must occur in order within 5m, correlated by winlog.computer_name, winlog.event_data.SubjectLogonId, winlog.event_data.TargetLogonId.

Stage 1: authentication

[authentication where host.os.type == "windows" and
  event.action == "logged-in" and event.outcome == "success" and winlog.event_data.ElevatedToken == "%%1843" and process.pid == 0 and
  winlog.event_data.AuthenticationPackageName :"Kerberos" and winlog.logon.type == "Network" and cidrmatch(source.ip, "127.0.0.0/8", "::1")] by winlog.event_data.TargetLogonId

Stage 2: any

[any where host.os.type == "windows" and
   event.action : "service-installed"] by winlog.event_data.SubjectLogonId

Indicators

These rows show field, operator, and value matches.

SUID/SGID Bit Set

#
Status
production
Severity
low
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

An adversary may add the setuid or setgid bit to a file or directory in order to run a file with the privileges of the owning user or group. An adversary can take advantage of this to either do a shell escape or exploit a vulnerability in an application with the setuid or setgid bit to get code running in a different user’s context. Additionally, adversaries can use this mechanism on their own malware to make sure they're able to execute in elevated contexts in the future.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/04/23"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
An adversary may add the setuid or setgid bit to a file or directory in order to run a file with the privileges of the
owning user or group. An adversary can take advantage of this to either do a shell escape or exploit a vulnerability in
an application with the setuid or setgid bit to get code running in a different user’s context. Additionally,
adversaries can use this mechanism on their own malware to make sure they're able to execute in elevated contexts in the
future.
"""
from = "now-9m"
index = ["auditbeat-*", "logs-endpoint.events.*"]
language = "eql"
license = "Elastic License v2"
max_signals = 33
name = "SUID/SGID Bit Set"
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 SUID/SGID Bit Set

The SUID/SGID bits in Unix-like systems allow files to execute with the privileges of the file owner or group, enabling necessary elevated permissions for certain applications. However, adversaries can exploit these bits to escalate privileges by modifying files to run with higher access rights. The detection rule identifies suspicious use of commands like `chmod` or `install` to set these bits, excluding known safe paths, to flag potential privilege escalation attempts.

### Possible investigation steps

- Review the process details to identify the user who executed the command, focusing on the process.name and process.args fields to understand the specific command and arguments used.
- Check the process.parent.executable field to determine the parent process and assess whether it is a known legitimate process or potentially malicious.
- Investigate the file or directory targeted by the SUID/SGID bit modification by examining the process.args field for any unusual or sensitive paths that could indicate privilege escalation attempts.
- Correlate the event with other recent activities from the same user or system to identify any patterns or anomalies that could suggest malicious behavior.
- Verify if the file or directory with modified SUID/SGID bits is part of a known safe path as listed in the exclusion criteria, and assess whether the modification is expected or authorized.

### False positive analysis

- System package installations or updates may trigger the rule when legitimate processes like package managers set SUID/SGID bits. To handle this, exclude paths related to package management, such as "/var/lib/dpkg/info*".
- Docker or container-related operations might set these bits during normal operations. Exclude paths like "/var/lib/docker/*" to prevent false positives from container management activities.
- Temporary directories used during system operations, such as "/tmp/newroot/*", can cause false alerts. Exclude these paths to avoid unnecessary alerts from temporary system processes.
- Specific system services or applications, like "/usr/bin/ssh-agent", may require SUID/SGID bits for legitimate functionality. Exclude these known safe executables to reduce false positives.
- Custom scripts or applications that are known to require elevated permissions should be reviewed and, if deemed safe, added to the exclusion list to prevent repeated false alerts.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further unauthorized access or privilege escalation.
- Identify and terminate any suspicious processes associated with the use of `chmod` or `install` commands that have set the SUID/SGID bits, especially those not in the excluded safe paths.
- Review and revert any unauthorized changes to file permissions, specifically those with SUID/SGID bits set, to their original state.
- Conduct a thorough audit of user accounts and privileges on the affected system to ensure no unauthorized accounts or privilege escalations have occurred.
- Implement additional monitoring on the affected system to detect any further attempts to exploit SUID/SGID bits, focusing on the specific commands and arguments identified in the detection query.
- Escalate the incident to the security operations team for a deeper investigation into potential lateral movement or persistence mechanisms that may have been established by the adversary.
- Apply patches and updates to the affected system and any vulnerable applications to mitigate known vulnerabilities that could be exploited in conjunction with SUID/SGID bit abuse."""
references = ["https://www.elastic.co/security-labs/primer-on-persistence-mechanisms"]
risk_score = 21
rule_id = "8a1b0278-0f9a-487d-96bd-d4833298e87a"
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "OS: macOS",
    "Use Case: Threat Detection",
    "Tactic: Privilege Escalation",
    "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 == "exec" and (
  (process.name == "chmod" and (process.args : ("+s", "u+s", "g+s") or process.args regex "[24][0-9]{3}")) or
  (process.name == "install" and process.args : "-m" and
  (process.args : ("+s", "u+s", "g+s") or process.args regex "[24][0-9]{3}"))
) and not (
  process.parent.executable : (
    "/usr/NX/*", "/var/lib/docker/*", "/var/lib/dpkg/info*", "/tmp/newroot/*", "/usr/bin/find", "/opt/commvault/Base/Galaxy",
    "/System/Library/PrivateFrameworks/PackageKit.framework/Versions/A/XPCServices/package_script_service.xpc/Contents/MacOS/package_script_service",
    "/opt/metallic/Base/Galaxy"
  ) or
  process.args : (
    "/run/*", "/var/run/*", "/usr/bin/keybase-redirector", "/usr/local/share/fonts", "/usr/bin/ssh-agent"
  ) or
  process.parent.args like ("/var/lib/dpkg/info/*", "/var/tmp/rpm-tmp*", "/usr/NX/*")
)
'''

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"

[[rule.threat.technique.subtechnique]]
id = "T1548.001"
name = "Setuid and Setgid"
reference = "https://attack.mitre.org/techniques/T1548/001/"

[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1548"
name = "Abuse Elevation Control Mechanism"
reference = "https://attack.mitre.org/techniques/T1548/"

[[rule.threat.technique.subtechnique]]
id = "T1548.001"
name = "Setuid and Setgid"
reference = "https://attack.mitre.org/techniques/T1548/001/"

[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 == "exec" and (
  (process.name == "chmod" and (process.args : ("+s", "u+s", "g+s") or process.args regex "[24][0-9]{3}")) or
  (process.name == "install" and process.args : "-m" and
  (process.args : ("+s", "u+s", "g+s") or process.args regex "[24][0-9]{3}"))
) and not (
  process.parent.executable : (
    "/usr/NX/*", "/var/lib/docker/*", "/var/lib/dpkg/info*", "/tmp/newroot/*", "/usr/bin/find", "/opt/commvault/Base/Galaxy",
    "/System/Library/PrivateFrameworks/PackageKit.framework/Versions/A/XPCServices/package_script_service.xpc/Contents/MacOS/package_script_service",
    "/opt/metallic/Base/Galaxy"
  ) or
  process.args : (
    "/run/*", "/var/run/*", "/usr/bin/keybase-redirector", "/usr/local/share/fonts", "/usr/bin/ssh-agent"
  ) or
  process.parent.args like ("/var/lib/dpkg/info/*", "/var/tmp/rpm-tmp*", "/usr/NX/*")
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • exec corpus 547 (elastic 547)
field:"EventType" kind:eq value:"exec"
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.argsregex_match
  • [24][0-9]{3}
field:"process.args" kind:regex_match value:"[24][0-9]{3}"
process.argswildcard
  • +s
  • -m corpus 2 (elastic 2)
  • g+s
  • u+s
field:"process.args" kind:wildcard
process.nameeq
  • chmod corpus 10 (elastic 10)
  • install corpus 2 (elastic 2)
field:"process_basename" kind:eq

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argswildcard/run/*, /var/run/*, /usr/bin/keybase-redirector, /usr/local/share/fonts, /usr/bin/ssh-agentexcludes:process.args
process.parent.argsstarts_with/var/lib/dpkg/info/, /var/tmp/rpm-tmp, /usr/NX/excludes:process.parent.args field:"process.parent.args" value:"/var/lib/dpkg/info/" field:"process.parent.args" value:"/var/tmp/rpm-tmp" field:"process.parent.args" value:"/usr/NX/"
process.parent.executablewildcard/usr/NX/*, /var/lib/docker/*, /var/lib/dpkg/info*, /tmp/newroot/*, /usr/bin/find, /opt/commvault/Base/Galaxy, /System/Library/PrivateFrameworks/PackageKit.framework/Versions/A/XPCServices/package_script_service.xpc/Contents/MacOS/package_script_service, /opt/metallic/Base/Galaxyexcludes:process.parent.executable

Suspicious Dynamic Linker Discovery via od

#
Status
production
Severity
high
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Monitors for dynamic linker discovery via the od utility. od (octal dump) is a command-line utility in Unix operating systems used for displaying data in various formats, including octal, hexadecimal, decimal, and ASCII, primarily used for examining and debugging binary files or data streams. Attackers can leverage od to analyze the dynamic linker by identifying injection points and craft exploits based on the observed behaviors and structures within these files.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2024/02/01"
integration = ["endpoint", "auditd_manager", "crowdstrike", "sentinel_one_cloud_funnel"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
Monitors for dynamic linker discovery via the od utility. od (octal dump) is a command-line utility in Unix operating
systems used for displaying data in various formats, including octal, hexadecimal, decimal, and ASCII, primarily used
for examining and debugging binary files or data streams. Attackers can leverage od to analyze the dynamic linker by
identifying injection points and craft exploits based on the observed behaviors and structures within these files.
"""
from = "now-9m"
index = [
    "auditbeat-*",
    "endgame-*",
    "logs-auditd_manager.auditd-*",
    "logs-crowdstrike.fdr*",
    "logs-endpoint.events.process*",
    "logs-sentinel_one_cloud_funnel.*",
]
language = "eql"
license = "Elastic License v2"
name = "Suspicious Dynamic Linker Discovery via od"
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 Suspicious Dynamic Linker Discovery via od

The dynamic linker in Linux environments is crucial for loading shared libraries needed by programs. Attackers may exploit the `od` utility to inspect these linkers, seeking vulnerabilities for code injection. The detection rule identifies suspicious use of `od` targeting specific linker files, flagging potential reconnaissance activities that could precede an exploit attempt.

### Possible investigation steps

- Review the process execution details to confirm the use of the 'od' utility, focusing on the process name and arguments to ensure they match the suspicious patterns identified in the query.
- Investigate the user account associated with the process execution to determine if the activity aligns with their typical behavior or if it appears anomalous.
- Check the system's process execution history for any other unusual or related activities around the same time, such as attempts to access or modify linker files.
- Analyze any network connections or data transfers initiated by the host around the time of the alert to identify potential data exfiltration or communication with known malicious IPs.
- Correlate this event with other security alerts or logs from the same host to identify patterns or sequences of actions that could indicate a broader attack campaign.

### False positive analysis

- System administrators or developers may use the od utility to inspect dynamic linker files for legitimate debugging or system maintenance purposes. To handle this, create exceptions for known user accounts or processes that regularly perform these activities.
- Automated scripts or monitoring tools might invoke od on dynamic linker files as part of routine system checks. Identify these scripts and whitelist their execution paths to prevent unnecessary alerts.
- Security researchers or penetration testers could use od during authorized security assessments. Establish a process to temporarily disable the rule or add exceptions for the duration of the assessment to avoid false positives.
- Some software installations or updates might involve the use of od to verify linker integrity. Monitor installation logs and correlate with od usage to determine if the activity is benign, and consider adding exceptions for these specific scenarios.

### Response and remediation

- Immediately isolate the affected system from the network to prevent potential lateral movement or further exploitation.
- Terminate any suspicious processes associated with the `od` utility that are targeting dynamic linker files to halt any ongoing reconnaissance or exploitation attempts.
- Conduct a thorough review of system logs and process execution history to identify any unauthorized access or modifications to the dynamic linker files.
- Restore any altered or compromised dynamic linker files from a known good backup to ensure system integrity.
- Implement stricter access controls and monitoring on critical system files, including dynamic linkers, to prevent unauthorized access and modifications.
- Escalate the incident to the security operations team for further analysis and to determine if additional systems are affected or if there is a broader threat campaign.
- Update detection and monitoring systems to enhance visibility and alerting for similar suspicious activities involving the `od` utility and critical system files."""
references = ["https://github.com/arget13/DDexec"]
risk_score = 73
rule_id = "0369e8a6-0fa7-4e7a-961a-53180a4c966e"
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 = "high"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Discovery",
    "Data Source: Elastic Defend",
    "Data Source: Elastic Endgame",
    "Data Source: Auditd Manager",
    "Data Source: Crowdstrike",
    "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", "ProcessRollup2", "executed", "process_started")
 and process.name == "od" and process.args in (
  "/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2", "/etc/ld.so.preload", "/lib64/ld-linux-x86-64.so.2",
  "/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2", "/usr/lib64/ld-linux-x86-64.so.2"
)
'''

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1057"
name = "Process Discovery"
reference = "https://attack.mitre.org/techniques/T1057/"

[[rule.threat.technique]]
id = "T1083"
name = "File and Directory Discovery"
reference = "https://attack.mitre.org/techniques/T1083/"

[rule.threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"

[[rule.threat.technique.subtechnique]]
id = "T1574.006"
name = "Dynamic Linker Hijacking"
reference = "https://attack.mitre.org/techniques/T1574/006/"

[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 in ("exec", "exec_event", "start", "ProcessRollup2", "executed", "process_started")
 and process.name == "od" and process.args in (
  "/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2", "/etc/ld.so.preload", "/lib64/ld-linux-x86-64.so.2",
  "/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2", "/usr/lib64/ld-linux-x86-64.so.2"
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionin
  • ProcessRollup2
  • exec
  • exec_event
  • executed
  • process_started
  • start
field:"EventType" kind:in
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.argsin
  • /etc/ld.so.preload
  • /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
  • /lib64/ld-linux-x86-64.so.2
  • /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
  • /usr/lib64/ld-linux-x86-64.so.2
field:"process.args" kind:in
process.nameeq
  • od
field:"process_basename" kind:eq value:"od"

Suspicious Process Access via Direct System Call

#
Status
production
Severity
high
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies suspicious process access events from an unknown memory region. Endpoint security solutions usually hook userland Windows APIs in order to decide if the code that is being executed is malicious or not. It's possible to bypass hooked functions by writing malicious functions that call syscalls directly.

MITRE ATT&CK Coverage

TacticTechniques
Execution
Stealth

Telemetry Coverage

ProviderRecord / event type
SysmonEvent ID 10: ProcessAccess

Rule Body

[metadata]
creation_date = "2021/10/11"
integration = ["windows"]
maturity = "production"
updated_date = "2026/04/30"

[rule]
author = ["Elastic"]
description = """
Identifies suspicious process access events from an unknown memory region. Endpoint security solutions usually hook
userland Windows APIs in order to decide if the code that is being executed is malicious or not. It's possible to bypass
hooked functions by writing malicious functions that call syscalls directly.
"""
from = "now-9m"
index = ["winlogbeat-*", "logs-windows.sysmon_operational-*"]
language = "eql"
license = "Elastic License v2"
name = "Suspicious Process Access via Direct System Call"
references = [
    "https://twitter.com/SBousseaden/status/1278013896440324096",
    "https://www.ired.team/offensive-security/defense-evasion/using-syscalls-directly-from-visual-studio-to-bypass-avs-edrs",
]
risk_score = 73
rule_id = "2dd480be-1263-4d9c-8672-172928f6789a"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Tactic: Execution",
    "Resources: Investigation Guide",
    "Data Source: Sysmon",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "windows" and event.code == "10" and
 length(winlog.event_data.CallTrace) > 0 and

 /* Sysmon CallTrace starting with unknown memory module instead of ntdll which host Windows NT Syscalls */
 not winlog.event_data.CallTrace :
            ("?:\\WINDOWS\\SYSTEM32\\ntdll.dll*",
             "?:\\WINDOWS\\SysWOW64\\ntdll.dll*",
             "?:\\Windows\\System32\\sysfer.dll*",
             "?:\\Windows\\System32\\wow64cpu.dll*",
             "?:\\WINDOWS\\System32\\wow64win.dll*",
             "?:\\Windows\\System32\\win32u.dll*",
             "?:\\ProgramData\\Symantec\\Symantec Endpoint Protection\\*\\sysfer.dll*") and

 not winlog.event_data.TargetImage :
            ("?:\\Program Files (x86)\\Malwarebytes Anti-Exploit\\mbae-svc.exe",
             "?:\\Program Files\\Cisco\\AMP\\*\\sfc.exe",
             "?:\\Program Files (x86)\\Microsoft\\EdgeWebView\\Application\\*\\msedgewebview2.exe",
             "?:\\Program Files\\Adobe\\Acrobat DC\\Acrobat\\*\\AcroCEF.exe") and

 not (process.executable : ("?:\\Program Files\\Adobe\\Acrobat DC\\Acrobat\\Acrobat.exe",
                            "?:\\Program Files (x86)\\World of Warcraft\\_classic_\\WowClassic.exe") and
      not winlog.event_data.TargetImage : "?:\\WINDOWS\\system32\\lsass.exe")
'''

note = """## Triage and analysis

### Investigating Suspicious Process Access via Direct System Call

#### Possible investigation steps

- What did the Sysmon process-access event prove?
  - Focus: `winlog.event_data.SourceImage`, `winlog.event_data.SourceProcessGUID`, `winlog.event_data.TargetImage`, `winlog.event_data.GrantedAccess`, and `winlog.event_data.CallTrace`.
  - Implication: escalate when the call trace starts in UNKNOWN or unbacked memory before the Windows syscall layer and the source opens lsass.exe, a browser, or a security process with memory-read, memory-write, thread, duplicate-handle, or all-access rights; lower concern only when the same source-target-access pattern matches recognized EDR, anti-exploit, debugger, accessibility, anti-cheat, or browser instrumentation.
- Which source process instance made the access?
  - Focus: recover the source process start on `host.id` using `process.entity_id`, or `winlog.event_data.SourceProcessGUID` plus `process.pid` and alert-time proximity as a weaker fallback; review `process.executable`, `process.hash.sha256`, PE metadata, and code signature. $investigate_0
  - Hint: hash, PE metadata, and signature fields are optional; if absent, keep disposition tied to source path, GUID/PID recovery, parent or command context, and target/access evidence rather than closing.
  - Implication: escalate when the source is unsigned, recently dropped, user-writable, renamed, or mismatched to PE metadata; lower concern only when identity, signer or hash, path, and recovery context fit the same recognized security, debugger, accessibility, anti-cheat, or instrumentation workflow.
- Did launch and user context fit that workflow?
  - Focus: recovered `process.command_line`, parent executable/command line, alert `user.id`, and session context.
  - Hint: join `process.Ext.authentication_id` to `winlog.event_data.TargetLogonId` only when session origin changes severity; if absent, keep origin unresolved and rely on alert user plus recovered session context.
  - Implication: escalate when Office, browsers, script hosts, archive tools, LOLBins, or remote-interactive sessions launch the accessor; lower concern when parent, command line, account, and session type fit the same recognized low-level tool. If process/session fields cannot be recovered, treat the gap as unresolved, not benign.
- Did the same source process create dumping, injection, or staging artifacts?
  - Focus: same-source child starts and file events where `file.path` shows dump output, temp staging, payload drops, or renamed executable content. $investigate_1 $investigate_2
  - Hint: use the transform when `process.entity_id` is present; otherwise repeat the `host.id` plus `process.pid` alert-time fallback from source recovery.
  - Implication: escalate when the source writes dumps, stages payloads, or spawns tooling after access; missing process or file telemetry is unresolved, not benign.
- Did the same source process communicate after access?
  - Focus: process-scoped DNS `dns.question.name` and connections to `destination.ip`.
  - Hint: correlate DNS to destination IP only after matching the same recovered process, `host.id`, and surrounding time window. $investigate_3
  - Implication: escalate when the source reaches rare or misaligned destinations, connects directly to public IPs, or talks outbound after accessing a sensitive process; missing network telemetry is unresolved, not benign.
- If local evidence remains suspicious or unresolved, is there related activity for the same user, host, or source binary?
  - Focus: related alerts for `user.id`, `host.id`, and recovered `process.hash.sha256` when available, especially process-access, dump-file, injection, credential-access, or persistence alerts.
  - Hint: start with user-scoped alerts when the alert user is meaningful. $investigate_4
  - Hint: use host-scoped alerts when the source runs as a service identity or user context is sparse. $investigate_5
  - Implication: broaden scope only when local source, target, access, identity, or follow-on evidence remains suspicious or unresolved; expand containment and credential scoping when related alerts show the same access pattern beyond one process.
- Escalate unauthorized direct-syscall access to credential-bearing, browser, or security processes when source-target-access-call-trace, recovered identity, launch/session context, or follow-on evidence remain suspicious; close only when those categories bind to one recognized workflow with outside confirmation for any legitimacy gap; preserve and escalate mixed evidence or visibility gaps.

### False positive analysis

- Security agents, anti-exploit tools, debuggers, accessibility tools, anti-cheat systems, browser or PDF instrumentation, backup, and virtualization tools can perform low-level process access. Confirm source executable, signer or hash history, parent workflow, target cohort, access mask, call-trace shape, user/session context, recurrence, and quiet follow-on telemetry all align with one exact product workflow; require owner, inventory, vendor, or change evidence for legitimacy gaps. Recurrence is only corroboration: require the same stable source identity, parent/session context, target cohort, access pattern, and lack of dump or staging artifacts for the same `host.id` and `user.id`.
- Build exceptions from the minimum confirmed pattern: recovered source executable or signer, recovered parent workflow, `winlog.event_data.TargetImage`, access-mask class, first-frame call-trace shape, and relevant `host.id` or `user.id` scope. Avoid exceptions on `winlog.event_data.GrantedAccess`, `winlog.event_data.CallTrace`, process name, or target image alone.

### Response and remediation

- If confirmed benign, reverse temporary containment and document the source identity, launch/session context, source-target-access-call-trace tuple, target cohort, and evidence that confirmed the product workflow. Create an exception only for the exact recurring pattern.
- If suspicious but unconfirmed, preserve the alert record, Sysmon Event ID 10 details, source and target process GUIDs, call trace string, recovered process start, relevant authentication records, dump files, staged payloads, and network indicators before containment or cleanup.
- Apply reversible containment first: heightened monitoring, temporary outbound restrictions, or response-tool policy on the affected `host.id`. Escalate to host isolation or process suspension only when the target sensitivity, access rights, identity evidence, or follow-on artifacts indicate likely dumping, injection, or credential theft.
- If confirmed malicious, isolate the endpoint and suspend or terminate the recovered source process after recording its identity, command line, parent chain, source-target pair, access mask, call trace, staged files, and network indicators. If direct response is unavailable, hand off that evidence set to the team that can isolate the host or account.
- If the target process held credentials, browser secrets, or security-product context, scope related users, sessions, tokens, and hosts before credential resets or broad process termination so evidence and blast radius are not lost.
- Eradicate only the dump files, injectors, loaders, persistence artifacts, or staged payloads identified during the investigation, then remediate the launcher, delivery path, or exposed credential path that enabled the direct-syscall process access.
- Post-incident hardening: retain Sysmon Event ID 10 plus supporting process, file, network, and Windows Security telemetry, and document direct NtOpenProcess, unhooking, or call-stack-spoofing variants observed in the case for future detection review."""

setup = """## Setup

This rule requires Sysmon telemetry to be enabled and ingested.

Setup instructions: https://ela.st/sysmon-event-10-setup
"""

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "event.code",
    "host.name",
    "host.id",
    "user.id",
    "process.entity_id",
    "process.pid",
    "process.name",
    "process.executable",
    "winlog.event_data.SourceProcessGUID",
    "winlog.event_data.SourceImage",
    "winlog.event_data.TargetProcessGUID",
    "winlog.event_data.TargetImage",
    "winlog.event_data.GrantedAccess",
    "winlog.event_data.CallTrace",
]

[transform]

[[transform.investigate]]
label = "Events for the same source process on this host"
description = ""
providers = [
  [
    { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[transform.investigate]]
label = "Child process starts from the source process"
description = ""
providers = [
  [
    { excluded = false, field = "process.parent.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
    { excluded = false, field = "event.type", queryType = "phrase", value = "start", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[transform.investigate]]
label = "File events for the source process"
description = ""
providers = [
  [
    { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[transform.investigate]]
label = "Network and DNS events for the source process"
description = ""
providers = [
  [
    { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" }
  ],
  [
    { excluded = false, field = "process.entity_id", queryType = "phrase", value = "{{process.entity_id}}", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "event.category", queryType = "phrase", value = "dns", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[transform.investigate]]
label = "Alerts associated with the user"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", 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 = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"

[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 = "T1106"
name = "Native API"
reference = "https://attack.mitre.org/techniques/T1106/"

[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 == "windows" and event.code == "10" and
 length(winlog.event_data.CallTrace) > 0 and
 not winlog.event_data.CallTrace :
            ("?:\\WINDOWS\\SYSTEM32\\ntdll.dll*",
             "?:\\WINDOWS\\SysWOW64\\ntdll.dll*",
             "?:\\Windows\\System32\\sysfer.dll*",
             "?:\\Windows\\System32\\wow64cpu.dll*",
             "?:\\WINDOWS\\System32\\wow64win.dll*",
             "?:\\Windows\\System32\\win32u.dll*",
             "?:\\ProgramData\\Symantec\\Symantec Endpoint Protection\\*\\sysfer.dll*") and
 not winlog.event_data.TargetImage :
            ("?:\\Program Files (x86)\\Malwarebytes Anti-Exploit\\mbae-svc.exe",
             "?:\\Program Files\\Cisco\\AMP\\*\\sfc.exe",
             "?:\\Program Files (x86)\\Microsoft\\EdgeWebView\\Application\\*\\msedgewebview2.exe",
             "?:\\Program Files\\Adobe\\Acrobat DC\\Acrobat\\*\\AcroCEF.exe") and
 not (process.executable : ("?:\\Program Files\\Adobe\\Acrobat DC\\Acrobat\\Acrobat.exe",
                            "?:\\Program Files (x86)\\World of Warcraft\\_classic_\\WowClassic.exe") and
      not winlog.event_data.TargetImage : "?:\\WINDOWS\\system32\\lsass.exe")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.codeeq
  • 10 corpus 7 (elastic 6, kusto 1)
field:"EventID" kind:eq value:"10"
winlog.event_data.TargetImagewildcard
  • ?:\WINDOWS\system32\lsass.exe corpus 4 (elastic 4)
field:"TargetImage" kind:wildcard value:"?:\WINDOWS\system32\lsass.exe"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
winlog.event_data.TargetImageeq?:\WINDOWS\system32\lsass.exeexcludes:winlog.event_data.TargetImage field:"winlog.event_data.TargetImage" value:"?:\WINDOWS\system32\lsass.exe"
process.executableeq?:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe, ?:\Program Files (x86)\World of Warcraft\_classic_\WowClassic.exeexcludes:process.executable field:"process.executable" value:"?:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe" field:"process.executable" value:"?:\Program Files (x86)\World of Warcraft\_classic_\WowClassic.exe"
winlog.event_data.CallTracewildcard?:\WINDOWS\SYSTEM32\ntdll.dll*, ?:\WINDOWS\SysWOW64\ntdll.dll*, ?:\Windows\System32\sysfer.dll*, ?:\Windows\System32\wow64cpu.dll*, ?:\WINDOWS\System32\wow64win.dll*, ?:\Windows\System32\win32u.dll*, ?:\ProgramData\Symantec\Symantec Endpoint Protection\*\sysfer.dll*excludes:winlog.event_data.CallTrace
winlog.event_data.TargetImagewildcard?:\Program Files (x86)\Malwarebytes Anti-Exploit\mbae-svc.exe, ?:\Program Files\Cisco\AMP\*\sfc.exe, ?:\Program Files (x86)\Microsoft\EdgeWebView\Application\*\msedgewebview2.exe, ?:\Program Files\Adobe\Acrobat DC\Acrobat\*\AcroCEF.exeexcludes:winlog.event_data.TargetImage

Suspicious SeIncreaseBasePriorityPrivilege Use

#
Status
production
Severity
high
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies attempts to use the SeIncreaseBasePriorityPrivilege privilege by an unusual process. This could be related to hijack execution flow of a process via threats priority manipulation.

MITRE ATT&CK Coverage

TacticTechniques
Privilege Escalation

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2025/09/25"
integration = ["system", "windows"]
maturity = "production"
updated_date = "2026/05/03"

[rule]
author = ["Elastic"]
description = """
Identifies attempts to use the SeIncreaseBasePriorityPrivilege privilege by an unusual process. This could be related to
hijack execution flow of a process via threats priority manipulation.
"""
from = "now-9m"
index = ["logs-system.security*", "logs-windows.forwarded*", "winlogbeat-*"]
language = "kuery"
license = "Elastic License v2"
name = "Suspicious SeIncreaseBasePriorityPrivilege Use"
references = [
    "https://github.com/Octoberfest7/ThreadCPUAssignment_POC/tree/main",
    "https://x.com/sixtyvividtails/status/1970721197617717483",
    "https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/event-4674"
]
risk_score = 73
rule_id = "6fa0f15b-1926-419b-8de2-fce1429797ba"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Privilege Escalation",
    "Data Source: Windows Security Event Logs",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
event.category:iam and host.os.type:"windows" and event.code:"4674" and
winlog.event_data.PrivilegeList:"SeIncreaseBasePriorityPrivilege" and event.outcome:"success" and
winlog.event_data.AccessMask:"512" and not winlog.event_data.SubjectUserSid:("S-1-5-18" or "S-1-5-19" or "S-1-5-20")
'''

note = """## Triage and analysis

### Investigating Suspicious SeIncreaseBasePriorityPrivilege Use

#### Possible investigation steps

- What priority-change path did 4674 preserve?
  - Why: this privilege manipulates process or thread priority; the target object matters as much as the requester.
  - Focus: Security 4674 on `host.id`: `winlog.event_data.PrivilegeList`, `winlog.event_data.AccessMask`, `winlog.event_data.ProcessName`, `winlog.event_data.ObjectType`, and `winlog.event_data.ObjectName`.
  - Hint: sparse or numeric-only `winlog.event_data.ObjectName` is the main visibility gap; keep the target unresolved and use same-session Security records, not assumed self-tuning.
  - Implication: escalate when the object is a "Process" or "Thread" tied to security tooling, LSASS, or another user's workload; lower suspicion only when requester, object, and `host.name` fit bounded tuning or testing.

- Is the requesting image path expected for priority control on this host?
  - Focus: `winlog.event_data.ProcessName`, `winlog.event_data.ProcessId`, `winlog.event_data.SubjectUserSid`, `host.name`, and `@timestamp`.
  - Hint: `winlog.event_data.ProcessId` is hexadecimal; use it only inside a tight host/time window; PID reuse can mislead.
  - Implication: escalate when the path is user-writable, temporary, renamed, or unrelated to local tuning; treat a recurring full path and SID as identity support, not closure, until object and session evidence align.

- Which subject and local session requested this privilege use?
  - Focus: `winlog.event_data.SubjectUserSid`, `winlog.event_data.SubjectUserName`, `winlog.event_data.SubjectDomainName`, and `winlog.event_data.SubjectLogonId`.
  - Implication: escalate when a normal user, rare admin, machine account, or service account lacks a clear scheduling-priority role; matching SID, domain, and session support benignity only with matching requester and object evidence.

- Does the 4624 session origin fit a priority-tuning operator?
  - Focus: on the same `host.id`, match alert `winlog.event_data.SubjectLogonId` to 4624 `winlog.event_data.TargetLogonId`, then read `source.ip`, `winlog.logon.type`, and `winlog.event_data.AuthenticationPackageName`.
  - Hint: query `event.code` 4624 with alert `host.id` and `winlog.event_data.TargetLogonId`; search backward from `@timestamp` because the session can predate 4674. $investigate_0 Missing 4624 or empty `source.ip` is unresolved, not benign.
  - Implication: escalate when source, logon type, or authentication method is rare for `host.name` or subject SID; matching origin supports authorized tuning only after requester path and target object fit.

- Do surrounding Security records show repeated or multi-target priority use by the same requester?
  - Focus: Security events around `@timestamp` on the same `host.id`, grouped by `winlog.event_data.SubjectLogonId`, `winlog.event_data.ProcessId`, `winlog.event_data.ProcessName`, and `winlog.event_data.ObjectName`.
  - Hint: start in the alert window with `event.code` 4674 and alert `winlog.event_data.SubjectLogonId`; expand only if the same session continues around `@timestamp`. Add `event.outcome` to separate failed attempts from successful use. $investigate_1
  - Implication: escalate when one session or requester touches multiple process/thread objects, repeats against security targets, or continues after failures; a single 4674 keeps scope local but still requires requester, object, and session answers for closure.

- If local evidence is suspicious or unresolved, do related alerts expand scope or urgency?
  - Focus: related alerts for the same `host.id`, prioritizing privilege abuse, defense evasion, security-tool interference, service-control, or authentication findings. $investigate_2
  - Hint: if the subject remains suspicious, use the subject pivot; use the `user.id` provider only after confirming it maps to `winlog.event_data.SubjectUserSid`. $investigate_3
  - Implication: broaden scope when the host or user also shows privilege escalation, defense evasion, or unusual authentication; keep scope local when related alerts are absent and 4674/session evidence supports bounded work.

- Escalate for unauthorized process/thread priority manipulation or security-tool interference; close only when object, requester, subject, session, and related alerts bind to one authorized tuning or troubleshooting workflow; preserve 4674 and recovered 4624 evidence and escalate when sparse object or session evidence leaves suspicious findings unresolved.

### False positive analysis

- Performance engineering, benchmark, QA, vendor, or internal support work can trigger when an administrator adjusts scheduling priority or CPU assignment for a test or latency-sensitive workload. Confirm only when `winlog.event_data.ProcessName`, `winlog.event_data.ObjectType`, `winlog.event_data.ObjectName`, `winlog.event_data.SubjectUserSid`, recovered `source.ip`, and `winlog.logon.type` align with the same recognized host, accounts, and workload. If records are unavailable, require telemetry-only recurrence of the same full requester path, SID, object family, and host class before treating as benign.
- If the target object is sparse or numeric-only, do not close solely on tool name or user claim.
- Before creating an exception, validate that `winlog.event_data.ProcessName`, `winlog.event_data.ObjectType`, `winlog.event_data.ObjectName`, `winlog.event_data.SubjectUserSid`, `host.id`, and recovered `source.ip` or `winlog.logon.type` stay stable across known-benign occurrences. Build the exception from that minimum confirmed pattern; avoid exceptions on `winlog.event_data.PrivilegeList` or `user.name` alone.

### Response and remediation

- If confirmed benign, reverse temporary containment and document the validated `winlog.event_data.ProcessName`, `winlog.event_data.ObjectType`, `winlog.event_data.ObjectName`, `winlog.event_data.SubjectUserSid`, recovered `source.ip`, `winlog.logon.type`, and `host.id` values proving the tuning or troubleshooting workflow. Create an exception only after the same pattern repeats benignly.
- If suspicious but unconfirmed, preserve a case export of triggering 4674, recovered 4624 session record, surrounding same-session Security records, and related-alert links before containment. Record requester path and PID, subject SID, target object, session origin, and event time as case anchors.
- If suspicious but unconfirmed, apply reversible containment first, such as restricting the subject's remote access, pausing the support workflow, or raising monitoring on `host.id`. Escalate to host isolation or account disablement only if the target maps to a security-critical process, related alerts show additional privilege abuse or defense evasion, or the recovered session suggests credential misuse.
- If confirmed malicious, isolate the host when the object, requester, session, or related-alert evidence shows unauthorized priority manipulation of a security-critical process or another user's workload. Record the requester path and PID, subject SID, target object, recovered session origin, and event time before stopping processes or deleting tooling.
- Reset or suspend the implicated account only when the recovered session and related alerts show likely credential misuse, and review other hosts for the same `winlog.event_data.ProcessName`, `winlog.event_data.ObjectName`, or `winlog.event_data.SubjectUserSid` before eradicating artifacts so scoping finishes before evidence is destroyed.
- Eradicate only the unauthorized tuning or interference tooling and any persistence or launcher artifacts identified during the investigation, then restore affected security or service configurations to a known-good state.
- Hardening: restrict assignment of "SeIncreaseBasePriorityPrivilege" to the smallest admin cohort, retain Security 4674 and 4624 visibility, and record visibility gaps that limited the case decision.
"""

setup = """## Setup

Audit Sensitive Privilege Use must be enabled to generate the events used by this rule.
Setup instructions: https://ela.st/audit-sensitive-privilege-use
"""

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "event.outcome",
    "host.id",
    "user.id",
    "winlog.event_data.SubjectUserName",
    "winlog.event_data.SubjectUserSid",
    "winlog.event_data.SubjectLogonId",
    "winlog.event_data.ProcessName",
    "winlog.event_data.ProcessId",
    "winlog.event_data.ObjectType",
    "winlog.event_data.ObjectName",
    "winlog.event_data.PrivilegeList",
    "winlog.event_data.AccessMask",
    "winlog.activity_id",
]

[transform]

[[transform.investigate]]
label = "Linked logon for the priority-change session"
description = ""
providers = [
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4624", valueType = "string" },
    { excluded = false, field = "winlog.event_data.TargetLogonId", queryType = "phrase", value = "{{winlog.event_data.SubjectLogonId}}", valueType = "string" }
  ]
]
relativeFrom = "now-24h/h"
relativeTo = "now"

[[transform.investigate]]
label = "4674 priority-use events from this requester session"
description = ""
providers = [
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4674", valueType = "string" },
    { excluded = false, field = "winlog.event_data.SubjectLogonId", queryType = "phrase", value = "{{winlog.event_data.SubjectLogonId}}", valueType = "string" },
    { excluded = false, field = "winlog.event_data.ProcessId", queryType = "phrase", value = "{{winlog.event_data.ProcessId}}", valueType = "string" }
  ],
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4674", valueType = "string" },
    { excluded = false, field = "winlog.event_data.SubjectLogonId", queryType = "phrase", value = "{{winlog.event_data.SubjectLogonId}}", valueType = "string" },
    { excluded = false, field = "winlog.event_data.ProcessName", queryType = "phrase", value = "{{winlog.event_data.ProcessName}}", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
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"

[[transform.investigate]]
label = "Alerts associated with the subject"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "winlog.event_data.SubjectUserSid", queryType = "phrase", value = "{{winlog.event_data.SubjectUserSid}}", valueType = "string" }
  ],
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1134"
name = "Access Token Manipulation"
reference = "https://attack.mitre.org/techniques/T1134/"

[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"

Stages and Predicates

Stage 1: query

event.category:iam and host.os.type:"windows" and event.code:"4674" and
winlog.event_data.PrivilegeList:"SeIncreaseBasePriorityPrivilege" and event.outcome:"success" and
winlog.event_data.AccessMask:"512" and not winlog.event_data.SubjectUserSid:("S-1-5-18" or "S-1-5-19" or "S-1-5-20")

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

Systemd-udevd Rule File Creation

#
Status
production
Severity
low
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Monitors for the creation of rule files that are used by systemd-udevd to manage device nodes and handle kernel device events in the Linux operating system. Systemd-udevd can be exploited for persistence by adversaries by creating malicious udev rules that trigger on specific events, executing arbitrary commands or payloads whenever a certain device is plugged in or recognized by the system.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2023/10/26"
integration = ["endpoint"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
Monitors for the creation of rule files that are used by systemd-udevd to manage device nodes and handle kernel device
events in the Linux operating system. Systemd-udevd can be exploited for persistence by adversaries by creating
malicious udev rules that trigger on specific events, executing arbitrary commands or payloads whenever a certain device
is plugged in or recognized by the system.
"""
from = "now-9m"
index = ["logs-endpoint.events.file*"]
language = "eql"
license = "Elastic License v2"
name = "Systemd-udevd Rule File Creation"
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 Systemd-udevd Rule File Creation

Systemd-udevd manages device nodes and handles kernel device events in Linux, using rule files to automate responses to hardware changes. Adversaries can exploit this by creating malicious rules that execute commands when specific devices are connected. The detection rule monitors the creation of these rule files, excluding legitimate processes, to identify potential abuse and ensure system integrity.

### Possible investigation steps

- Review the file path and name to determine if the rule file is located in a directory commonly used for udev rules, such as /etc/udev/rules.d/ or /lib/udev/.
- Examine the process executable that created or renamed the rule file to identify if it is a known legitimate process or an unexpected one, as specified in the query.
- Check the file extension and ensure it is .rules, confirming it is intended for udev rule configuration.
- Investigate the process name and path to determine if it matches any of the excluded legitimate processes or paths, which could indicate a false positive.
- Analyze the contents of the newly created or modified rule file to identify any suspicious or malicious commands that could be executed when a device is connected.
- Correlate the event with other system logs to identify any related activities or anomalies around the time of the rule file creation or modification.
- Assess the risk and impact of the rule file creation by considering the context of the system and any potential persistence mechanisms it might enable for an adversary.

### False positive analysis

- System updates and package installations can trigger rule file creations. Exclude processes like dpkg, rpm, and yum by adding them to the exception list to prevent false positives during legitimate system maintenance.
- Container management tools such as Docker and Podman may create or modify udev rules. Exclude these processes to avoid alerts when containers are being managed.
- Automated system configuration tools like Puppet and Chef can modify udev rules as part of their operations. Add these tools to the exception list to reduce noise from routine configuration changes.
- Snap package installations and updates can lead to rule file changes. Exclude snapd and related processes to prevent false positives during snap operations.
- Netplan and systemd processes may generate or modify udev rules as part of network configuration or system initialization. Exclude these processes to avoid unnecessary alerts during legitimate system activities.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further execution of malicious udev rules and potential lateral movement.
- Identify and review the newly created or modified udev rule files in the specified directories to determine if they contain malicious commands or payloads.
- Remove any unauthorized or malicious udev rule files to prevent them from executing on device connection events.
- Restore any affected system configurations or files from a known good backup to ensure system integrity.
- Conduct a thorough scan of the system using updated antivirus or endpoint detection tools to identify and remove any additional malware or persistence mechanisms.
- Monitor the system for any further suspicious activity or attempts to recreate malicious udev rules, adjusting detection mechanisms as necessary.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems are affected, ensuring comprehensive threat containment and remediation."""

references = ["https://www.elastic.co/security-labs/sequel-on-persistence-mechanisms"]
risk_score = 21
rule_id = "054db96b-fd34-43b3-9af2-587b3bd33964"
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 to select "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",
    "Data Source: Elastic Defend",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where host.os.type == "linux" and event.action == "creation" and
process.executable != null and file.extension == "rules" and
file.path like (
  "/lib/udev/*", "/etc/udev/rules.d/*", "/usr/lib/udev/rules.d/*", "/run/udev/rules.d/*", "/usr/local/lib/udev/rules.d/*"
) and not (
  process.executable in (
    "/bin/dpkg", "/usr/bin/dpkg", "/bin/dockerd", "/usr/bin/dockerd", "/usr/sbin/dockerd", "/bin/microdnf",
    "/usr/bin/microdnf", "/bin/rpm", "/usr/bin/rpm", "/bin/snapd", "/usr/bin/snapd", "/bin/yum", "/usr/bin/yum",
    "/bin/dnf", "/usr/bin/dnf", "/bin/podman", "/usr/bin/podman", "/bin/dnf-automatic", "/usr/bin/dnf-automatic",
    "/bin/pacman", "/usr/bin/pacman", "/usr/bin/dpkg-divert", "/bin/dpkg-divert", "/sbin/apk", "/usr/sbin/apk",
    "/usr/local/sbin/apk", "/usr/bin/apt", "/usr/sbin/pacman", "/bin/podman", "/usr/bin/podman", "/usr/bin/puppet",
    "/bin/puppet", "/opt/puppetlabs/puppet/bin/puppet", "/usr/bin/chef-client", "/bin/chef-client",
    "/bin/autossl_check", "/usr/bin/autossl_check", "/proc/self/exe",  "/usr/bin/pamac-daemon", "./usr/bin/podman",
    "/bin/pamac-daemon", "/usr/lib/snapd/snapd", "/usr/local/bin/dockerd", "/usr/libexec/netplan/generate",
    "/lib/systemd/system-generators/netplan", "/lib/systemd/systemd", "/usr/bin/containerd", "/usr/sbin/sshd",
    "/kaniko/executor", "/usr/local/bin/defender", "/usr/bin/dnf5", "/opt/kaniko/executor", "/lib/netplan/generate"
  ) or
  file.Ext.original.extension == "dpkg-new" or
  process.executable like (
    "/nix/store/*", "/var/lib/dpkg/*", "/snap/*", "/dev/fd/*", "/usr/lib/*", "/usr/libexec/*",
     "/var/lib/docker/overlay2/*/dockerd", "/var/lib/containers/storage/overlay*/dockerd"
  ) or
  process.name in (
    "systemd", "netplan", "apt-get", "vmware-config-tools.pl", "systemd-hwdb", "ssm-agent-worker", "crio", "cloud-init", "convert2rhel" 
  ) or
  process.name like ("python*", "perl*") or
  (process.name == "sed" and file.name : "sed*")
)
'''

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1037"
name = "Boot or Logon Initialization Scripts"
reference = "https://attack.mitre.org/techniques/T1037/"

[[rule.threat.technique]]
id = "T1546"
name = "Event Triggered Execution"
reference = "https://attack.mitre.org/techniques/T1546/"

[[rule.threat.technique.subtechnique]]
id = "T1546.017"
name = "Udev Rules"
reference = "https://attack.mitre.org/techniques/T1546/017/"

[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1546"
name = "Event Triggered Execution"
reference = "https://attack.mitre.org/techniques/T1546/"

[[rule.threat.technique.subtechnique]]
id = "T1546.017"
name = "Udev Rules"
reference = "https://attack.mitre.org/techniques/T1546/017/"

[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"

Stages and Predicates

Stage 1: file

file where host.os.type == "linux" and event.action == "creation" and
process.executable != null and file.extension == "rules" and
file.path like (
  "/lib/udev/*", "/etc/udev/rules.d/*", "/usr/lib/udev/rules.d/*", "/run/udev/rules.d/*", "/usr/local/lib/udev/rules.d/*"
) and not (
  process.executable in (
    "/bin/dpkg", "/usr/bin/dpkg", "/bin/dockerd", "/usr/bin/dockerd", "/usr/sbin/dockerd", "/bin/microdnf",
    "/usr/bin/microdnf", "/bin/rpm", "/usr/bin/rpm", "/bin/snapd", "/usr/bin/snapd", "/bin/yum", "/usr/bin/yum",
    "/bin/dnf", "/usr/bin/dnf", "/bin/podman", "/usr/bin/podman", "/bin/dnf-automatic", "/usr/bin/dnf-automatic",
    "/bin/pacman", "/usr/bin/pacman", "/usr/bin/dpkg-divert", "/bin/dpkg-divert", "/sbin/apk", "/usr/sbin/apk",
    "/usr/local/sbin/apk", "/usr/bin/apt", "/usr/sbin/pacman", "/bin/podman", "/usr/bin/podman", "/usr/bin/puppet",
    "/bin/puppet", "/opt/puppetlabs/puppet/bin/puppet", "/usr/bin/chef-client", "/bin/chef-client",
    "/bin/autossl_check", "/usr/bin/autossl_check", "/proc/self/exe",  "/usr/bin/pamac-daemon", "./usr/bin/podman",
    "/bin/pamac-daemon", "/usr/lib/snapd/snapd", "/usr/local/bin/dockerd", "/usr/libexec/netplan/generate",
    "/lib/systemd/system-generators/netplan", "/lib/systemd/systemd", "/usr/bin/containerd", "/usr/sbin/sshd",
    "/kaniko/executor", "/usr/local/bin/defender", "/usr/bin/dnf5", "/opt/kaniko/executor", "/lib/netplan/generate"
  ) or
  file.Ext.original.extension == "dpkg-new" or
  process.executable like (
    "/nix/store/*", "/var/lib/dpkg/*", "/snap/*", "/dev/fd/*", "/usr/lib/*", "/usr/libexec/*",
     "/var/lib/docker/overlay2/*/dockerd", "/var/lib/containers/storage/overlay*/dockerd"
  ) or
  process.name in (
    "systemd", "netplan", "apt-get", "vmware-config-tools.pl", "systemd-hwdb", "ssm-agent-worker", "crio", "cloud-init", "convert2rhel" 
  ) or
  process.name like ("python*", "perl*") or
  (process.name == "sed" and file.name : "sed*")
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • creation
field:"EventType" kind:eq value:"creation"
file.extensioneq
  • rules
field:"file.extension" kind:eq value:"rules"
file.pathwildcard
  • /etc/udev/rules.d/*
  • /lib/udev/*
  • /run/udev/rules.d/*
  • /usr/lib/udev/rules.d/*
  • /usr/local/lib/udev/rules.d/*
field:"TargetFilename" kind:wildcard
process.executableis_not_null
  • (no value, null check)
field:"Image" kind:is_not_null

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
file.namestarts_withsedexcludes:file.name field:"file.name" value:"sed"
process.nameeqsedexcludes:process.name field:"process.name" value:"sed"
file.Ext.original.extensioneqdpkg-newexcludes:file.Ext.original.extension field:"file.Ext.original.extension" value:"dpkg-new"
process.executablein./usr/bin/podman, /bin/autossl_check, /bin/chef-client, /bin/dnf, /bin/dnf-automatic, /bin/dockerd, /bin/dpkg, /bin/dpkg-divert, /bin/microdnf, /bin/pacman, /bin/pamac-daemon, /bin/podman, /bin/puppet, /bin/rpm, /bin/snapd, /bin/yum, /kaniko/executor, /lib/netplan/generate, /lib/systemd/system-generators/netplan, /lib/systemd/systemd, /opt/kaniko/executor, /opt/puppetlabs/puppet/bin/puppet, /proc/self/exe, /sbin/apk, /usr/bin/apt, /usr/bin/autossl_check, /usr/bin/chef-client, /usr/bin/containerd, /usr/bin/dnf, /usr/bin/dnf-automatic, /usr/bin/dnf5, /usr/bin/dockerd, /usr/bin/dpkg, /usr/bin/dpkg-divert, /usr/bin/microdnf, /usr/bin/pacman, /usr/bin/pamac-daemon, /usr/bin/podman, /usr/bin/puppet, /usr/bin/rpm, /usr/bin/snapd, /usr/bin/yum, /usr/lib/snapd/snapd, /usr/libexec/netplan/generate, /usr/local/bin/defender, /usr/local/bin/dockerd, /usr/local/sbin/apk, /usr/sbin/apk, /usr/sbin/dockerd, /usr/sbin/pacman, /usr/sbin/sshdexcludes:process.executable
process.executablewildcard/nix/store/*, /var/lib/dpkg/*, /snap/*, /dev/fd/*, /usr/lib/*, /usr/libexec/*, /var/lib/docker/overlay2/*/dockerd, /var/lib/containers/storage/overlay*/dockerdexcludes:process.executable
process.nameinapt-get, cloud-init, convert2rhel, crio, netplan, ssm-agent-worker, systemd, systemd-hwdb, vmware-config-tools.plexcludes:process.name
process.namestarts_withpython, perlexcludes:process.name field:"process.name" value:"python" field:"process.name" value:"perl"

Unusual Print Spooler Child Process

#
Status
production
Severity
medium
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

Detects unusual Print Spooler service (spoolsv.exe) child processes. This may indicate an attempt to exploit privilege escalation vulnerabilities related to the Printing Service on Windows.

Known False Positives

  • Install or update of a legitimate printing driver. Verify the printer driver file metadata such as manufacturer and signature information.

MITRE ATT&CK Coverage

TacticTechniques
Privilege Escalation

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2021/07/06"
integration = ["endpoint", "windows", "system", "crowdstrike", "sentinel_one_cloud_funnel", "m365_defender"]
maturity = "production"
updated_date = "2026/05/04"

[rule]
author = ["Elastic"]
description = """
Detects unusual Print Spooler service (spoolsv.exe) child processes. This may indicate an attempt to exploit privilege
escalation vulnerabilities related to the Printing Service on Windows.
"""
false_positives = [
    """
    Install or update of a legitimate printing driver. Verify the printer driver file metadata such as manufacturer and
    signature information.
    """,
]
from = "now-9m"
index = [
    "logs-endpoint.events.process-*",
    "logs-system.security*",
    "logs-windows.forwarded*",
    "winlogbeat-*",
    "logs-crowdstrike.fdr*",
    "logs-sentinel_one_cloud_funnel.*",
    "logs-m365_defender.event-*",
    "endgame-*",
    "logs-windows.sysmon_operational-*",
]
language = "eql"
license = "Elastic License v2"
name = "Unusual Print Spooler 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 Print Spooler Child Process

The Print Spooler service, integral to Windows environments, manages print jobs and interactions with printers. Adversaries may exploit vulnerabilities in this service to escalate privileges, gaining unauthorized access or control. The detection rule identifies suspicious child processes spawned by the Print Spooler, excluding known legitimate processes, to flag potential exploitation attempts, focusing on unusual command lines and integrity levels.

### Possible investigation steps

- Review the process details to identify the unusual child process spawned by spoolsv.exe, focusing on the process name and command line arguments to understand its purpose and potential malicious intent.
- Check the integrity level of the process using the fields process.Ext.token.integrity_level_name or winlog.event_data.IntegrityLevel to confirm if it is running with elevated privileges, which could indicate an exploitation attempt.
- Investigate the parent-child relationship by examining the process tree to determine if there are any other suspicious processes associated with the same parent process, spoolsv.exe.
- Cross-reference the process executable path against known legitimate software paths to ensure it is not a false positive, especially if the executable is not listed in the exclusion paths.
- Analyze recent system logs and security events around the time of the alert to identify any other anomalous activities or patterns that could be related to the potential exploitation attempt.
- If the process is confirmed suspicious, isolate the affected system to prevent further exploitation and conduct a deeper forensic analysis to understand the scope and impact of the incident.

### False positive analysis

- Legitimate print-related processes like splwow64.exe, PDFCreator.exe, and acrodist.exe may trigger alerts. These are excluded in the rule to prevent false positives.
- System processes such as msiexec.exe, route.exe, and WerFault.exe are known to be legitimate child processes of the Print Spooler and are excluded to reduce false alerts.
- Commands involving net.exe for starting or stopping services are common in administrative tasks and are excluded to avoid unnecessary alerts.
- Command-line operations involving cmd.exe or powershell.exe that reference .spl files or system paths are often legitimate and are excluded to minimize false positives.
- Network configuration changes using netsh.exe, such as adding port openings or rules, are typical in network management and are excluded to prevent false alerts.
- Registration of PrintConfig.dll via regsvr32.exe is a known legitimate operation and is excluded to avoid false positives.
- Executables from known paths like CutePDF Writer and GPLGS are excluded to prevent alerts from common, non-threatening applications.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further exploitation or lateral movement by the adversary.
- Terminate any suspicious child processes spawned by the Print Spooler service that do not match known legitimate processes or command lines.
- Conduct a thorough review of the system's security logs to identify any unauthorized access or privilege escalation attempts related to the Print Spooler service.
- Apply the latest security patches and updates to the Windows operating system and specifically to the Print Spooler service to mitigate known vulnerabilities.
- Restore the system from a clean backup if any unauthorized changes or malicious activities are confirmed.
- Monitor the system closely for any recurrence of similar suspicious activities, ensuring enhanced logging and alerting are in place for spoolsv.exe and its child processes.
- Escalate the incident to the security operations center (SOC) or incident response team for further investigation and to assess the potential impact on other systems within the network."""
references = ["https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-34527"]
risk_score = 47
rule_id = "ee5300a7-7e31-4a72-a258-250abb8b3aa1"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Privilege Escalation",
    "Use Case: Vulnerability",
    "Data Source: Elastic Defend",
    "Data Source: Windows Security Event Logs",
    "Resources: Investigation Guide",
    "Data Source: Crowdstrike",
    "Data Source: SentinelOne",
    "Data Source: Microsoft Defender XDR",
    "Data Source: Elastic Endgame",
    "Data Source: Sysmon",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "windows" and event.type == "start" and
 process.parent.name : "spoolsv.exe" and process.command_line != null and
 (?process.Ext.token.integrity_level_name : "System" or ?winlog.event_data.IntegrityLevel : "System") and

 /* exclusions for FP control below */
 not process.name : ("splwow64.exe", "PDFCreator.exe", "acrodist.exe", "spoolsv.exe", "msiexec.exe", "route.exe", "WerFault.exe") and
 not process.command_line : "*\\WINDOWS\\system32\\spool\\DRIVERS*" and
 not (process.name : "net.exe" and process.command_line : ("*stop*", "*start*")) and
 not (process.name : ("cmd.exe", "powershell.exe") and process.command_line : ("*.spl*", "*\\program files*", "*route add*")) and
 not (process.name : "netsh.exe" and process.command_line : ("*add portopening*", "*rule name*")) and
 not (process.name : "regsvr32.exe" and process.command_line : "*PrintConfig.dll*") and
 not process.executable : (
    "?:\\Program Files (x86)\\CutePDF Writer\\CPWriter2.exe",
    "?:\\Program Files (x86)\\GPLGS\\gswin32c.exe",
    "?:\\Program Files (x86)\\Acro Software\\CutePDF Writer\\CPWSave.exe",
    "?:\\Program Files (x86)\\Acro Software\\CutePDF Writer\\CPWriter2.exe",
    "?:\\Program Files (x86)\\CutePDF Writer\\CPWSave.exe",
    "?:\\Program Files (x86)\\TSplus\\UniversalPrinter\\CPWriter2.exe",
    "?:\\Program Files\\Seagull\\Printer Drivers\\Packages\\*\\DriverEnvironmentSetup.exe",
    "?:\\Windows\\system32\\CNAB4RPD.EXE",

    /* Crowdstrike specific condition as it uses NT Object paths */
    "\\Device\\HarddiskVolume*\\Program Files (x86)\\CutePDF Writer\\CPWriter2.exe",
    "\\Device\\HarddiskVolume*\\Program Files (x86)\\GPLGS\\gswin32c.exe",
    "\\Device\\HarddiskVolume*\\Program Files (x86)\\Acro Software\\CutePDF Writer\\CPWSave.exe",
    "\\Device\\HarddiskVolume*\\Program Files (x86)\\Acro Software\\CutePDF Writer\\CPWriter2.exe",
    "\\Device\\HarddiskVolume*\\Program Files (x86)\\CutePDF Writer\\CPWSave.exe",
    "\\Device\\HarddiskVolume*\\Program Files (x86)\\TSplus\\UniversalPrinter\\CPWriter2.exe",
    "\\Device\\HarddiskVolume*\\Program Files\\Seagull\\Printer Drivers\\Packages\\*\\DriverEnvironmentSetup.exe",
    "\\Device\\HarddiskVolume*\\Windows\\system32\\CNAB4RPD.EXE"
 )
'''

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 = "T1068"
name = "Exploitation for Privilege Escalation"
reference = "https://attack.mitre.org/techniques/T1068/"


[rule.threat.tactic]
id = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"

Stages and Predicates

Stage 1: process

process where host.os.type == "windows" and event.type == "start" and
 process.parent.name : "spoolsv.exe" and process.command_line != null and
 (?process.Ext.token.integrity_level_name : "System" or ?winlog.event_data.IntegrityLevel : "System") and
 not process.name : ("splwow64.exe", "PDFCreator.exe", "acrodist.exe", "spoolsv.exe", "msiexec.exe", "route.exe", "WerFault.exe") and
 not process.command_line : "*\\WINDOWS\\system32\\spool\\DRIVERS*" and
 not (process.name : "net.exe" and process.command_line : ("*stop*", "*start*")) and
 not (process.name : ("cmd.exe", "powershell.exe") and process.command_line : ("*.spl*", "*\\program files*", "*route add*")) and
 not (process.name : "netsh.exe" and process.command_line : ("*add portopening*", "*rule name*")) and
 not (process.name : "regsvr32.exe" and process.command_line : "*PrintConfig.dll*") and
 not process.executable : (
    "?:\\Program Files (x86)\\CutePDF Writer\\CPWriter2.exe",
    "?:\\Program Files (x86)\\GPLGS\\gswin32c.exe",
    "?:\\Program Files (x86)\\Acro Software\\CutePDF Writer\\CPWSave.exe",
    "?:\\Program Files (x86)\\Acro Software\\CutePDF Writer\\CPWriter2.exe",
    "?:\\Program Files (x86)\\CutePDF Writer\\CPWSave.exe",
    "?:\\Program Files (x86)\\TSplus\\UniversalPrinter\\CPWriter2.exe",
    "?:\\Program Files\\Seagull\\Printer Drivers\\Packages\\*\\DriverEnvironmentSetup.exe",
    "?:\\Windows\\system32\\CNAB4RPD.EXE",
    "\\Device\\HarddiskVolume*\\Program Files (x86)\\CutePDF Writer\\CPWriter2.exe",
    "\\Device\\HarddiskVolume*\\Program Files (x86)\\GPLGS\\gswin32c.exe",
    "\\Device\\HarddiskVolume*\\Program Files (x86)\\Acro Software\\CutePDF Writer\\CPWSave.exe",
    "\\Device\\HarddiskVolume*\\Program Files (x86)\\Acro Software\\CutePDF Writer\\CPWriter2.exe",
    "\\Device\\HarddiskVolume*\\Program Files (x86)\\CutePDF Writer\\CPWSave.exe",
    "\\Device\\HarddiskVolume*\\Program Files (x86)\\TSplus\\UniversalPrinter\\CPWriter2.exe",
    "\\Device\\HarddiskVolume*\\Program Files\\Seagull\\Printer Drivers\\Packages\\*\\DriverEnvironmentSetup.exe",
    "\\Device\\HarddiskVolume*\\Windows\\system32\\CNAB4RPD.EXE"
 )

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.command_linematch.spl, \program files, route addexcludes:process.command_line field:"process.command_line" value:".spl" field:"process.command_line" value:"\program files" field:"process.command_line" value:"route add"
process.nameeqcmd.exe, powershell.exeexcludes:process.name field:"process.name" value:"cmd.exe" field:"process.name" value:"powershell.exe"
process.command_linematchPrintConfig.dllexcludes:process.command_line field:"process.command_line" value:"PrintConfig.dll"
process.nameeqregsvr32.exeexcludes:process.name field:"process.name" value:"regsvr32.exe"
process.command_linematchadd portopening, rule nameexcludes:process.command_line field:"process.command_line" value:"add portopening" field:"process.command_line" value:"rule name"
process.nameeqnetsh.exeexcludes:process.name field:"process.name" value:"netsh.exe"
process.command_linematchstop, startexcludes:process.command_line field:"process.command_line" value:"stop" field:"process.command_line" value:"start"
process.nameeqnet.exeexcludes:process.name field:"process.name" value:"net.exe"
process.command_linematch\WINDOWS\system32\spool\DRIVERSexcludes:process.command_line field:"process.command_line" value:"\WINDOWS\system32\spool\DRIVERS"
process.executablewildcard?:\Program Files (x86)\CutePDF Writer\CPWriter2.exe, ?:\Program Files (x86)\GPLGS\gswin32c.exe, ?:\Program Files (x86)\Acro Software\CutePDF Writer\CPWSave.exe, ?:\Program Files (x86)\Acro Software\CutePDF Writer\CPWriter2.exe, ?:\Program Files (x86)\CutePDF Writer\CPWSave.exe, ?:\Program Files (x86)\TSplus\UniversalPrinter\CPWriter2.exe, ?:\Program Files\Seagull\Printer Drivers\Packages\*\DriverEnvironmentSetup.exe, ?:\Windows\system32\CNAB4RPD.EXE, \Device\HarddiskVolume*\Program Files (x86)\CutePDF Writer\CPWriter2.exe, \Device\HarddiskVolume*\Program Files (x86)\GPLGS\gswin32c.exe, \Device\HarddiskVolume*\Program Files (x86)\Acro Software\CutePDF Writer\CPWSave.exe, \Device\HarddiskVolume*\Program Files (x86)\Acro Software\CutePDF Writer\CPWriter2.exe, \Device\HarddiskVolume*\Program Files (x86)\CutePDF Writer\CPWSave.exe, \Device\HarddiskVolume*\Program Files (x86)\TSplus\UniversalPrinter\CPWriter2.exe, \Device\HarddiskVolume*\Program Files\Seagull\Printer Drivers\Packages\*\DriverEnvironmentSetup.exe, \Device\HarddiskVolume*\Windows\system32\CNAB4RPD.EXEexcludes:process.executable
process.nameeqsplwow64.exe, PDFCreator.exe, acrodist.exe, spoolsv.exe, msiexec.exe, route.exe, WerFault.exeexcludes:process.name

Back to all Elastic rules