Detection rules › Elastic

Elastic rules: 00

Abnormal Process ID or Lock File Created

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

Identifies the creation of a Process ID (PID), lock or reboot file created in temporary file storage paradigm (tmpfs) directory /var/run. On Linux, the PID files typically hold the process ID to track previous copies running and manage other tasks. Certain Linux malware use the /var/run directory for holding data, executables and other tasks, disguising itself or these files as legitimate PID files.

Known False Positives

  • False-Positives (FP) can appear if the PID file is legitimate and holding a process ID as intended. To differentiate, if the PID file is an executable or larger than 10 bytes, it should be ruled suspicious.

MITRE ATT&CK Coverage

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Identifies the creation of a Process ID (PID), lock or reboot file created in temporary file storage paradigm (tmpfs)
directory /var/run. On Linux, the PID files typically hold the process ID to track previous copies running and manage
other tasks. Certain Linux malware use the /var/run directory for holding data, executables and other tasks, disguising
itself or these files as legitimate PID files.
"""
false_positives = [
    """
    False-Positives (FP) can appear if the PID file is legitimate and holding a process ID as intended. To
    differentiate, if the PID file is an executable or larger than 10 bytes, it should be ruled suspicious.
    """,
]
from = "now-9m"
index = ["logs-endpoint.events.*", "endgame-*"]
language = "kuery"
license = "Elastic License v2"
name = "Abnormal Process ID or Lock File Created"
note = """## Triage and analysis

### Investigating Abnormal Process ID or Lock File Created

Linux applications may need to save their process identification number (PID) for various purposes: from signaling that a program is running to serving as a signal that a previous instance of an application didn't exit successfully. PID files contain its creator process PID in an integer value.

Linux lock files are used to coordinate operations in files so that conflicts and race conditions are prevented.

This rule identifies the creation of PID, lock, or reboot files in the /var/run/ directory. Attackers can masquerade malware, payloads, staged data for exfiltration, and more as legitimate PID files.

#### Possible investigation steps

- Retrieve the file and determine if it is malicious:
    - Check the contents of the PID files. They should only contain integer strings.
    - Check the file type of the lock and PID files to determine if they are executables. This is only observed in     malicious files.
    - Check the size of the subject file. Legitimate PID files should be under 10 bytes.
    - Check if the lock or PID file has high entropy. This typically indicates an encrypted payload.
        - Analysts can use tools like `ent` to measure entropy.
    - Examine the reputation of the SHA-256 hash in the PID file. Use a database like VirusTotal to identify additional pivots and artifacts for investigation.
- Trace the file's creation to ensure it came from a legitimate or authorized process.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Investigate any abnormal account behavior, such as command executions, file creations or modifications, and network connections.
- Investigate any abnormal behavior by the subject process such as network connections, file modifications, and any spawned child processes.

### False positive analysis

- False positives can appear if the PID file is legitimate and holding a process ID as intended. If the PID file is an executable or has a file size that's larger than 10 bytes, it should be ruled suspicious.
- If this activity is expected and noisy in your environment, consider adding exceptions — preferably with a combination of file name and process executable conditions.

### Response and remediation

- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Block the identified indicators of compromise (IoCs).
- Take actions to terminate processes and connections used by the attacker.
- 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).
"""
references = [
    "https://www.sandflysecurity.com/blog/linux-file-masquerading-and-malicious-pids-sandfly-1-2-6-update/",
    "https://twitter.com/GossiTheDog/status/1522964028284411907",
    "https://exatrack.com/public/Tricephalic_Hellkeeper.pdf",
    "https://www.elastic.co/security-labs/a-peek-behind-the-bpfdoor",
]
risk_score = 47
rule_id = "cac91072-d165-11ec-a764-f661ea17fbce"
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: Execution",
    "Threat: BPFDoor",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
    "Data Source: Elastic Endgame",
]
timestamp_override = "event.ingested"
type = "new_terms"
query = '''
host.os.type:linux and event.category:file and event.action:(creation or file_create_event) and
file.extension:(pid or lock or reboot) and file.path:(/var/run/* or /run/*) and (
  (process.name : (
    bash or dash or sh or tcsh or csh or zsh or ksh or fish or ash or touch or nano or vim or vi or editor or mv or cp)
  ) or (
  process.executable : (
    ./* or /tmp/* or /var/tmp/* or /dev/shm/* or /var/run/* or /boot/* or /srv/* or /run/*
  ))
) and not (
  process.executable : (
  /tmp/newroot/* or /run/containerd/* or /run/k3s/containerd/* or /run/k0s/container* or /snap/* or /vz/* or
  /var/lib/docker/* or /etc/*/universal-hooks/pkgs/mysql-community-server/* or /var/lib/snapd/* or /etc/rubrik/* or
  /run/udev/data/*
  ) or
  process.name : (
    go or git or containerd* or snap-confine or cron or crond or sshd or unattended-upgrade or vzctl or ifup or
    rpcbind or runc or gitlab-runner-helper or elastic-agent or metricbeat or redis-server or libvirt_leaseshelper or
    s6-ipcserver-socketbinder or xinetd or libvirtd or veeamdeploymentsvc  or dnsmasq or virtlogd or lynis or
    veeamtransport or bash or dash or sh or touch or podman or chrome_crashpad_handler or snmpd or automount or
    chrome or yumBackend.py or rhsmcertd-worker or snapd or cp or dotnet or leapp or haproxy or multipathd or
    falcond or python* or atopacctd or postmaster or httpd or pulseaudio or iptables or atd or package-cleanup or local
  ) or
  file.name : (
    jem.*.pid or lynis.pid or redis.pid or yum.pid or MFS.pid or jenkins.pid or nvmupdate.pid or openlitespeed.pid or
    rhnsd.pid
  ) or
  file.path : (/run/containerd/* or /var/run/docker/containerd/* or /var/run/jem*.pid)
)
'''

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

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

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

[[rule.threat.technique.subtechnique]]
id = "T1036.005"
name = "Match Legitimate Resource Name or Location"
reference = "https://attack.mitre.org/techniques/T1036/005/"

[rule.threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[rule.new_terms]
field = "new_terms_fields"
value = ["process.name", "file.name"]

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

Stages and Predicates

Stage 1: new_terms

host.os.type:linux and event.category:file and event.action:(creation or file_create_event) and
file.extension:(pid or lock or reboot) and file.path:(/var/run/* or /run/*) and (
  (process.name : (
    bash or dash or sh or tcsh or csh or zsh or ksh or fish or ash or touch or nano or vim or vi or editor or mv or cp)
  ) or (
  process.executable : (
    ./* or /tmp/* or /var/tmp/* or /dev/shm/* or /var/run/* or /boot/* or /srv/* or /run/*
  ))
) and not (
  process.executable : (
  /tmp/newroot/* or /run/containerd/* or /run/k3s/containerd/* or /run/k0s/container* or /snap/* or /vz/* or
  /var/lib/dockeruniversal-hooks/pkgs/mysql-community-server/* or /var/lib/snapd/* or /etc/rubrik/* or
  /run/udev/data/*
  ) or
  process.name : (
    go or git or containerd* or snap-confine or cron or crond or sshd or unattended-upgrade or vzctl or ifup or
    rpcbind or runc or gitlab-runner-helper or elastic-agent or metricbeat or redis-server or libvirt_leaseshelper or
    s6-ipcserver-socketbinder or xinetd or libvirtd or veeamdeploymentsvc  or dnsmasq or virtlogd or lynis or
    veeamtransport or bash or dash or sh or touch or podman or chrome_crashpad_handler or snmpd or automount or
    chrome or yumBackend.py or rhsmcertd-worker or snapd or cp or dotnet or leapp or haproxy or multipathd or
    falcond or python* or atopacctd or postmaster or httpd or pulseaudio or iptables or atd or package-cleanup or local
  ) or
  file.name : (
    jem.*.pid or lynis.pid or redis.pid or yum.pid or MFS.pid or jenkins.pid or nvmupdate.pid or openlitespeed.pid or
    rhnsd.pid
  ) or
  file.path : (/run/containerd/* or /var/run/docker/containerd/* or /var/run/jem*.pid)
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionin
  • creation
  • file_create_event
field:"EventType" kind:in
event.categoryeq
  • file
field:"event.category" kind:eq value:"file"
file.extensionin
  • lock
  • pid
  • reboot
field:"file.extension" kind:in
file.pathwildcard
  • /run/*
  • /var/run/*
field:"TargetFilename" kind:wildcard
process.executablewildcard
  • ./*
  • /boot/*
  • /dev/shm/*
  • /run/*
  • /srv/*
  • /tmp/*
  • /var/run/*
  • /var/tmp/*
field:"Image" kind:wildcard
process.namein
  • ash
  • bash
  • cp
  • csh
  • dash
  • editor
  • fish
  • ksh
  • mv
  • nano
  • sh
  • tcsh
  • touch
  • vi
  • vim
  • zsh
field:"process_basename" kind:in

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
file.nameeqMFS.pidexcludes:file.name field:"file.name" value:"MFS.pid"
file.nameeqjenkins.pidexcludes:file.name field:"file.name" value:"jenkins.pid"
file.nameeqlynis.pidexcludes:file.name field:"file.name" value:"lynis.pid"
file.nameeqnvmupdate.pidexcludes:file.name field:"file.name" value:"nvmupdate.pid"
file.nameeqopenlitespeed.pidexcludes:file.name field:"file.name" value:"openlitespeed.pid"
file.nameeqredis.pidexcludes:file.name field:"file.name" value:"redis.pid"
file.nameeqrhnsd.pidexcludes:file.name field:"file.name" value:"rhnsd.pid"
file.nameeqyum.pidexcludes:file.name field:"file.name" value:"yum.pid"
file.namewildcardjem.*.pidexcludes:file.name field:"file.name" value:"jem.*.pid"
file.pathstarts_with/run/containerd/excludes:file.path field:"file.path" value:"/run/containerd/"
file.pathstarts_with/var/run/docker/containerd/excludes:file.path field:"file.path" value:"/var/run/docker/containerd/"
file.pathwildcard/var/run/jem*.pidexcludes:file.path field:"file.path" value:"/var/run/jem*.pid"
process.executablestarts_with/etc/rubrik/excludes:process.executable field:"process.executable" value:"/etc/rubrik/"
process.executablestarts_with/run/containerd/excludes:process.executable field:"process.executable" value:"/run/containerd/"
process.executablestarts_with/run/k0s/containerexcludes:process.executable field:"process.executable" value:"/run/k0s/container"
process.executablestarts_with/run/k3s/containerd/excludes:process.executable field:"process.executable" value:"/run/k3s/containerd/"
process.executablestarts_with/run/udev/data/excludes:process.executable field:"process.executable" value:"/run/udev/data/"
process.executablestarts_with/snap/excludes:process.executable field:"process.executable" value:"/snap/"
process.executablestarts_with/tmp/newroot/excludes:process.executable field:"process.executable" value:"/tmp/newroot/"
process.executablestarts_with/var/lib/docker/excludes:process.executable field:"process.executable" value:"/var/lib/docker/"
process.executablestarts_with/var/lib/snapd/excludes:process.executable field:"process.executable" value:"/var/lib/snapd/"
process.executablestarts_with/vz/excludes:process.executable field:"process.executable" value:"/vz/"
process.executablewildcard/etc/*/universal-hooks/pkgs/mysql-community-server/*excludes:process.executable field:"process.executable" value:"/etc/*/universal-hooks/pkgs/mysql-community-server/*"
process.nameeqatdexcludes:process.name field:"process.name" value:"atd"
process.nameeqatopacctdexcludes:process.name field:"process.name" value:"atopacctd"
process.nameeqautomountexcludes:process.name field:"process.name" value:"automount"
process.nameeqbashexcludes:process.name field:"process.name" value:"bash"
process.nameeqchromeexcludes:process.name field:"process.name" value:"chrome"
process.nameeqchrome_crashpad_handlerexcludes:process.name field:"process.name" value:"chrome_crashpad_handler"
process.nameeqcpexcludes:process.name field:"process.name" value:"cp"
process.nameeqcronexcludes:process.name field:"process.name" value:"cron"
process.nameeqcrondexcludes:process.name field:"process.name" value:"crond"
process.nameeqdashexcludes:process.name field:"process.name" value:"dash"
process.nameeqdnsmasqexcludes:process.name field:"process.name" value:"dnsmasq"
process.nameeqdotnetexcludes:process.name field:"process.name" value:"dotnet"
process.nameeqelastic-agentexcludes:process.name field:"process.name" value:"elastic-agent"
process.nameeqfalcondexcludes:process.name field:"process.name" value:"falcond"
process.nameeqgitexcludes:process.name field:"process.name" value:"git"
process.nameeqgitlab-runner-helperexcludes:process.name field:"process.name" value:"gitlab-runner-helper"
process.nameeqgoexcludes:process.name field:"process.name" value:"go"
process.nameeqhaproxyexcludes:process.name field:"process.name" value:"haproxy"
process.nameeqhttpdexcludes:process.name field:"process.name" value:"httpd"
process.nameeqifupexcludes:process.name field:"process.name" value:"ifup"
process.nameeqiptablesexcludes:process.name field:"process.name" value:"iptables"
process.nameeqleappexcludes:process.name field:"process.name" value:"leapp"
process.nameeqlibvirt_leaseshelperexcludes:process.name field:"process.name" value:"libvirt_leaseshelper"
process.nameeqlibvirtdexcludes:process.name field:"process.name" value:"libvirtd"
process.nameeqlocalexcludes:process.name field:"process.name" value:"local"
process.nameeqlynisexcludes:process.name field:"process.name" value:"lynis"
process.nameeqmetricbeatexcludes:process.name field:"process.name" value:"metricbeat"
process.nameeqmultipathdexcludes:process.name field:"process.name" value:"multipathd"
process.nameeqpackage-cleanupexcludes:process.name field:"process.name" value:"package-cleanup"
process.nameeqpodmanexcludes:process.name field:"process.name" value:"podman"
process.nameeqpostmasterexcludes:process.name field:"process.name" value:"postmaster"
process.nameeqpulseaudioexcludes:process.name field:"process.name" value:"pulseaudio"
process.nameeqredis-serverexcludes:process.name field:"process.name" value:"redis-server"
process.nameeqrhsmcertd-workerexcludes:process.name field:"process.name" value:"rhsmcertd-worker"
process.nameeqrpcbindexcludes:process.name field:"process.name" value:"rpcbind"
process.nameeqruncexcludes:process.name field:"process.name" value:"runc"
process.nameeqs6-ipcserver-socketbinderexcludes:process.name field:"process.name" value:"s6-ipcserver-socketbinder"
process.nameeqshexcludes:process.name field:"process.name" value:"sh"
process.nameeqsnap-confineexcludes:process.name field:"process.name" value:"snap-confine"
process.nameeqsnapdexcludes:process.name field:"process.name" value:"snapd"
process.nameeqsnmpdexcludes:process.name field:"process.name" value:"snmpd"
process.nameeqsshdexcludes:process.name field:"process.name" value:"sshd"
process.nameeqtouchexcludes:process.name field:"process.name" value:"touch"
process.nameequnattended-upgradeexcludes:process.name field:"process.name" value:"unattended-upgrade"
process.nameeqveeamdeploymentsvcexcludes:process.name field:"process.name" value:"veeamdeploymentsvc"
process.nameeqveeamtransportexcludes:process.name field:"process.name" value:"veeamtransport"
process.nameeqvirtlogdexcludes:process.name field:"process.name" value:"virtlogd"
process.nameeqvzctlexcludes:process.name field:"process.name" value:"vzctl"
process.nameeqxinetdexcludes:process.name field:"process.name" value:"xinetd"
process.nameeqyumBackend.pyexcludes:process.name field:"process.name" value:"yumBackend.py"
process.namestarts_withcontainerdexcludes:process.name field:"process.name" value:"containerd"
process.namestarts_withpythonexcludes:process.name field:"process.name" value:"python"

AWS Bedrock Third-Party or External Knowledge Base Associated to Agent

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

Detects when an Amazon Bedrock agent is associated with, or updated to use, a knowledge base via the AssociateAgentKnowledgeBase, or UpdateAgentKnowledgeBase API actions. Bedrock agents consume knowledge base (RAG) content as trusted context for the model. By wiring an agent to an externally controlled or third-party knowledge base, or by swapping in an attacker-controlled knowledge base, an adversary can redraw the agent's trust boundary toward an untrusted source. This is a software-supply-chain compromise and an indirect prompt-injection delivery vector: poisoned or adversarial content served from the associated knowledge base is treated as authoritative by the agent. Validate that the associated knowledge base, and any underlying data source, is owned and controlled by your organization.

Known False Positives

  • Legitimate platform, ML, or application teams may associate or update knowledge bases on Bedrock agents as part of normal development, onboarding, or RAG pipeline changes. Verify that the actor identity, user agent, and source IP correspond to expected automation or authorized engineers, and that the associated knowledge base is an approved, organization-owned resource. If known behavior is causing false positives, it can be exempted from the rule.

MITRE ATT&CK Coverage

TacticTechniques
Persistence

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2026/06/04"
integration = ["aws"]
maturity = "production"
updated_date = "2026/06/04"

[rule]
author = ["Elastic"]
description = """
Detects when an Amazon Bedrock agent is associated with, or updated to use, a knowledge base via the AssociateAgentKnowledgeBase, 
or UpdateAgentKnowledgeBase API actions. Bedrock agents consume knowledge base (RAG) content as trusted context for the model. 
By wiring an agent to an externally controlled or third-party knowledge base, or by swapping in an attacker-controlled knowledge base, 
an adversary can redraw the agent's trust boundary toward an untrusted source. This is a software-supply-chain compromise and an indirect 
prompt-injection delivery vector: poisoned or adversarial content served from the associated knowledge base is treated as authoritative
by the agent. Validate that the associated knowledge base, and any underlying data source, is owned and controlled by your organization.
"""
false_positives = [
    """
    Legitimate platform, ML, or application teams may associate or update knowledge bases on Bedrock agents as part of
    normal development, onboarding, or RAG pipeline changes. Verify that the actor identity, user agent, and source IP
    correspond to expected automation or authorized engineers, and that the associated knowledge base is an approved,
    organization-owned resource. If known behavior is causing false positives, it can be exempted from the rule.
    """,
]
from = "now-6m"
index = ["logs-aws.cloudtrail-*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS Bedrock Third-Party or External Knowledge Base Associated to Agent"
note = """## Triage and analysis

### Investigating AWS Bedrock Third-Party or External Knowledge Base Associated to Agent

Amazon Bedrock agents use knowledge bases to retrieve content that is injected into the model's context as
trusted, authoritative information (Retrieval-Augmented Generation). The `AssociateAgentKnowledgeBase`, and 
`UpdateAgentKnowledgeBase` actions change which knowledge base an agent trusts. Because the model consumes this 
content as ground truth, redirecting an agent toward an externally controlled or attacker-supplied knowledge base 
is a supply-chain and indirect prompt-injection delivery vector — distinct from poisoning the content of a knowledge 
base the agent already trusts.

#### Possible investigation steps

- **Identify the actor and context**
  - Review `aws.cloudtrail.user_identity.arn`, `aws.cloudtrail.user_identity.type`, `user_agent.original`, and `source.ip`.
  - Confirm a related change request exists (RAG pipeline change, agent onboarding, model improvement work).
- **Validate the association**
  - In `aws.cloudtrail.flattened.request_parameters`, identify the `agentId`, `knowledgeBaseId`, and any third-party
    or external endpoint/configuration referenced.
  - Confirm the knowledge base and its underlying data source are owned by your organization and not an external account.
- **Assess blast radius**
  - Determine which applications or users invoke the affected agent and what sensitivity of decisions it drives.
  - Check `aws.cloudtrail.flattened.response_elements` for the resulting association state.
- **Correlate activity**
  - Look for preceding enumeration (`ListAgents`, `ListKnowledgeBases`, `GetAgent`) or creation of new knowledge
    bases and data sources from the same identity.

### False positive analysis

- **Planned RAG changes**: ML/platform teams routinely associate or update knowledge bases. Validate via ticket
  and confirm the resource is an approved, organization-owned knowledge base.
- **Automation**: IaC or CI/CD pipelines may manage agent–knowledge base associations during deployment.

### Response and remediation

- If unauthorized, dissociate the knowledge base from the agent and restore the approved configuration.
- Review the associated knowledge base and its data source for attacker-controlled or external content; quarantine if suspect.
- Audit the actor's recent Bedrock and IAM activity and rotate credentials if compromise is suspected.
- Restrict `bedrock:AssociateAgentKnowledgeBase`, `bedrock:UpdateAgentKnowledgeBase`, and third-party association
  permissions to a small set of trusted roles.
"""
references = [
    "https://docs.aws.amazon.com/bedrock/latest/userguide/agents.html",
    "https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base.html"
]
risk_score = 47
rule_id = "168b5538-4d54-4269-b4f5-786fa49dd850"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: LLM",
    "Data Source: Amazon Web Services",
    "Data Source: AWS",
    "Data Source: AWS CloudTrail",
    "Use Case: Threat Detection",
    "Resources: Investigation Guide",
    "Tactic: Persistence",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
data_stream.dataset: "aws.cloudtrail"
    and event.provider: "bedrock.amazonaws.com"
    and event.action: (
        "AssociateAgentKnowledgeBase" or
        "UpdateAgentKnowledgeBase"
    )
    and event.outcome: "success"
'''


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

[[rule.threat.technique]]
id = "T1505"
name = "Server Software Component"
reference = "https://attack.mitre.org/techniques/T1505/"

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

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "user.name",
    "user_agent.original",
    "source.ip",
    "aws.cloudtrail.user_identity.arn",
    "aws.cloudtrail.user_identity.type",
    "aws.cloudtrail.user_identity.access_key_id",
    "event.action",
    "event.provider",
    "event.outcome",
    "cloud.account.id",
    "cloud.region",
    "aws.cloudtrail.flattened.request_parameters",
    "aws.cloudtrail.flattened.response_elements",
]
 
[rule.new_terms]
field = "new_terms_fields"
value = ["aws.cloudtrail.user_identity.arn"]

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

Stages and Predicates

Stage 1: new_terms

data_stream.dataset: "aws.cloudtrail"
    and event.provider: "bedrock.amazonaws.com"
    and event.action: (
        "AssociateAgentKnowledgeBase" or
        "UpdateAgentKnowledgeBase"
    )
    and event.outcome: "success"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data_stream.dataseteq
  • aws.cloudtrail corpus 143 (elastic 143)
field:"data_stream.dataset" kind:eq value:"aws.cloudtrail"
event.actionin
  • AssociateAgentKnowledgeBase
  • UpdateAgentKnowledgeBase
field:"EventType" kind:in
event.outcomeeq
  • success corpus 306 (elastic 306)
field:"event.outcome" kind:eq value:"success"
event.providereq
  • bedrock.amazonaws.com corpus 13 (elastic 13)
field:"Provider_Name" kind:eq value:"bedrock.amazonaws.com"

AWS EC2 Unauthorized Admin Credential Fetch via Assumed Role

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

Identifies the first occurrence of an unauthorized attempt by an AWS role to use GetPassword to access the administrator password of an EC2 instance. Adversaries may use this API call to escalate privileges or move laterally within EC2 instances.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2024/04/10"
integration = ["aws"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Identifies the first occurrence of an unauthorized attempt by an AWS role to use `GetPassword` to access the administrator password of an EC2 instance. 
Adversaries may use this API call to escalate privileges or move laterally within EC2 instances.
"""
from = "now-6m"
interval = "5m"
index = ["filebeat-*", "logs-aws.cloudtrail*"]
language = "kuery"
license = "Elastic License v2"
name = "AWS EC2 Unauthorized Admin Credential Fetch via Assumed Role"
note = """
## Triage and analysis

### Investigating AWS EC2 Unauthorized Admin Credential Fetch via Assumed Role

This rule detects the first occurrence of a role using the `GetPasswordData` API call, which retrieves the administrator password, against an unauthorized EC2 instance in AWS. This can be an indicator of an adversary attempting to escalate privileges or move laterally within EC2 instances.

This is a New Terms rule, which means it will only trigger once for each unique value of the `aws.cloudtrail.user_identity.session_context.session_issuer.arn` field that has not been seen making this API request within the last 7 days. This field contains the Amazon Resource Name (ARN) of the assumed role that triggered the API call.

#### Possible Investigation Steps

- **Identify the User Identity and Role**: Examine the AWS CloudTrail logs to determine the user identity that made the `GetPasswordData` request. Pay special attention to the role and permissions associated with the user.
- **Review Request Parameters**: Analyze the `aws.cloudtrail.request_parameters` and `aws.cloudtrail.error_message` fields to understand the context of the API call.
- **Contextualize with User Behavior**: Compare this activity against the role's typical behavior patterns. Look for unusual login times, IP addresses, or other anomalous actions taken by the role prior to and following the incident.
- **Review EC2 Instance Details**: Check the details of the EC2 instance from which the password retrieval was attempted. Assess the criticality and sensitivity of the applications running on this instance.
- **Examine Related CloudTrail Events**: Search for other API calls made by the same role, especially those modifying security groups, network access controls, or instance metadata.
- **Investigate the Origin of the API Call**: Analyze the IP address and geographical location from which the request originated. Determine if it aligns with expected locations for legitimate administrative activity.

### False Positive Analysis

- **Legitimate Administrative Actions**: Ensure that the activity was not part of legitimate administrative tasks such as system maintenance or updates.
- **Automation Scripts**: Verify if the activity was generated by automation or deployment scripts that are authorized to use `GetPasswordData` for legitimate purposes.

### Response and Remediation

- **User Account Review**: Review the permissions of the implicated user identity. Apply the principle of least privilege by adjusting permissions to prevent misuse.
- **Enhanced Monitoring**: Increase monitoring on the user identity that triggered the rule and similar EC2 instances.
- **Incident Response**: If malicious intent is confirmed, initiate the incident response protocol. This includes further investigation, containment of the threat, eradication of any threat actor presence, and recovery of affected systems.
- **Preventative Measures**: Implement or enhance security measures such as multi-factor authentication and continuous audits of sensitive operations like `GetPasswordData`.

### Additional Information

Refer to resources like [AWS privilege escalation methods](https://cloud.hacktricks.xyz/pentesting-cloud/aws-security/aws-privilege-escalation/aws-ec2-privesc) and the MITRE ATT&CK technique [T1552.005 - Cloud Instance Metadata API](https://attack.mitre.org/techniques/T1552/005/) for more details on potential vulnerabilities and mitigation strategies.

"""
references = [
    "https://cloud.hacktricks.xyz/pentesting-cloud/aws-security/aws-privilege-escalation/aws-ec2-privesc",
]
risk_score = 47
rule_id = "8446517c-f789-11ee-8ad0-f661ea17fbce"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Data Source: AWS",
    "Data Source: Amazon Web Services",
    "Data Source: AWS EC2",
    "Use Case: Identity and Access Audit",
    "Resources: Investigation Guide",
    "Tactic: Credential Access",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
data_stream.dataset:"aws.cloudtrail"
    and event.provider:"ec2.amazonaws.com" and event.action:"GetPasswordData"
    and aws.cloudtrail.user_identity.type:"AssumedRole" and aws.cloudtrail.error_code:"Client.UnauthorizedOperation"
'''

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "user.name",
    "user_agent.original",
    "source.address",
    "aws.cloudtrail.user_identity.arn",
    "aws.cloudtrail.user_identity.type",
    "aws.cloudtrail.user_identity.session_context.session_issuer.arn",
    "aws.cloudtrail.user_identity.access_key_id",
    "event.action",
    "event.outcome",
    "aws.cloudtrail.error_code",
    "aws.cloudtrail.request_parameters",
    "cloud.account.id",
    "cloud.region"
]

[[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.005"
name = "Cloud Instance Metadata API"
reference = "https://attack.mitre.org/techniques/T1552/005/"

[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 = "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 = "TA0004"
name = "Privilege Escalation"
reference = "https://attack.mitre.org/tactics/TA0004/"
[rule.new_terms]
field = "new_terms_fields"
value = ["aws.cloudtrail.user_identity.session_context.session_issuer.arn"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-7d"


Stages and Predicates

Stage 1: new_terms

data_stream.dataset:"aws.cloudtrail"
    and event.provider:"ec2.amazonaws.com" and event.action:"GetPasswordData"
    and aws.cloudtrail.user_identity.type:"AssumedRole" and aws.cloudtrail.error_code:"Client.UnauthorizedOperation"

Indicators

These rows show field, operator, and value matches.

Bind Shell via Node

#
Source
github.com/elastic/protections-artifacts

Detects the creation of a bind shell via Node. Attackers may spawn bind shells to establish persistence onto a target system.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Detects the creation of a bind shell via Node. Attackers may spawn bind shells to establish persistence onto a target
system.
"""
id = "08697d36-4c07-4f54-b177-a39e473705c0"
license = "Elastic License v2"
name = "Bind Shell via Node"
os_list = ["linux"]
reference = ["https://gtfobins.github.io/gtfobins/node/"]
version = "1.0.5"

query = '''
process where event.type == "start" and event.action == "exec" and process.name == "node" and
process.args == "-e" and process.command_line : "*spawn*sh*" and process.command_line : "*listen*" and
not (
  process.parent.executable like (
    "*/.local/share/claude/versions/*",
    "*/extensions/anthropic.claude-code-*/resources/native-binary/claude",
    "*/@anthropic-ai/claude-agent-sdk-linux-x64/claude",
    "*/node_modules/@openai/codex-linux-x64/vendor/*/bin/codex",
    "/home/*/.local/zed.app/libexec/zed-editor"
  )
)
'''

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

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"


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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

process where event.type == "start" and event.action == "exec" and process.name == "node" and
process.args == "-e" and process.command_line : "*spawn*sh*" and process.command_line : "*listen*" and
not (
  process.parent.executable like (
    "*/.local/share/claude/versions/*",
    "*/extensions/anthropic.claude-code-*/resources/native-binary/claude",
    "*/@anthropic-ai/claude-agent-sdk-linux-x64/claude",
    "*/node_modules/@openai/codex-linux-x64/vendor/*/bin/codex",
    "/home/*/.local/zed.app/libexec/zed-editor"
  )
)

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.parent.executablewildcard*/.local/share/claude/versions/*, */extensions/anthropic.claude-code-*/resources/native-binary/claude, */@anthropic-ai/claude-agent-sdk-linux-x64/claude, */node_modules/@openai/codex-linux-x64/vendor/*/bin/codex, /home/*/.local/zed.app/libexec/zed-editorexcludes:process.parent.executable

Clearing of Shell History via Environment Variables

#
Source
github.com/elastic/protections-artifacts

This rule detects the clearing of the shell history via environment variables. Attackers may clear the shell history to hide their activities from being tracked. By leveraging environment variables such as HISTSIZE, HISTFILESIZE, HISTCONTROL, and HISTFILE, attackers can clear the shell history by setting them to 0, ignoring spaces, or redirecting the history to /dev/null, effectively erasing the command history.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
This rule detects the clearing of the shell history via environment variables. Attackers may clear the shell history to
hide their activities from being tracked. By leveraging environment variables such as HISTSIZE, HISTFILESIZE,
HISTCONTROL, and HISTFILE, attackers can clear the shell history by setting them to 0, ignoring spaces, or redirecting
the history to /dev/null, effectively erasing the command history.
"""
id = "f66e8880-ecfc-414f-8c1e-6e5892fac7e9"
license = "Elastic License v2"
name = "Clearing of Shell History via Environment Variables"
os_list = ["linux"]
reference = ["https://www.rapid7.com/blog/post/tr-new-whitepaper-stealthy-bpfdoor-variants/"]
version = "1.0.1"

query = '''
process where event.type == "start" and event.action == "exec" and process.env_vars like~ (
  "HISTSIZE=0", "HISTFILESIZE=0", "HISTCONTROL=ignorespace", "HISTFILE=/dev/null"
)
'''

min_endpoint_version = "8.6.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 = "T1070"
name = "Indicator Removal"
reference = "https://attack.mitre.org/techniques/T1070/"
[[threat.technique.subtechnique]]
id = "T1070.003"
name = "Clear Command History"
reference = "https://attack.mitre.org/techniques/T1070/003/"



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

[internal]
min_endpoint_version = "8.6.0"

Stages and Predicates

Stage 1: process

process where event.type == "start" and event.action == "exec" and process.env_vars like~ (
  "HISTSIZE=0", "HISTFILESIZE=0", "HISTCONTROL=ignorespace", "HISTFILE=/dev/null"
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • exec
field:"EventType" kind:eq value:"exec"
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.env_varswildcard
  • HISTCONTROL=ignorespace
  • HISTFILE=/dev/null
  • HISTFILESIZE=0
  • HISTSIZE=0
field:"process.env_vars" kind:wildcard

DNS Request to Crypto Miner Service

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

This rule detects DNS queries to miner services via living-off-the-land executables or executables in world/user-writable directories. Malware authors may use these services to mine cryptocurrency to generate revenue.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
This rule detects DNS queries to miner services via living-off-the-land executables or executables in
world/user-writable directories. Malware authors may use these services to mine cryptocurrency to generate revenue.
"""
id = "66d449ef-25ee-4fa6-8893-0ced843d1915"
license = "Elastic License v2"
name = "DNS Request to Crypto Miner Service"
os_list = ["linux"]
reference = ["https://xmrig.com/docs/algorithms"]
version = "1.0.2"

query = '''
sequence by process.entity_id with maxspan=1m
  [process where event.type == "start" and event.action == "exec" and (
    process.name in (
      "curl", "wget", "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox",
      "timeout", "env", "node", "deno", "nodejs"
    ) or
    process.name like (".*", "python*", "perl*", "php*", "ruby*", "lua*") or
    process.executable like (
      "./*", "/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/*", "/var/run/*", "/boot/*", "/sys/*",
      "/lost+found/*", "/proc/*", "/var/mail/*", "/var/www/*", "/home/*/*", "/root/*"
    ) or
    process.working_directory like (
      "/tmp*", "/var/tmp*", "/dev/shm*", "/run*", "/var/run*", "/boot*", "/sys*", "/lost+found*",
      "/proc*", "/var/mail*", "/var/www*", "/home/*/*", "/root/*"
    )
  ) and
  not (process.name like "php*" and process.args in ("/var/tools/koalaping/bin/ping.php", "/var/tools/lean/bin/Lean.php"))]
  [dns where event.action == "lookup_result" and dns.question.name like~ (
    "*cnpool.cc", "*lindon-pool.win", "*supportxmr.com", "*comgandalph3000.com", "*minergate.com",
    "*fjhan.club", "*emercoin.com", "*poolto.be", "*520fjh.org", "*xmrpool.xyz", "*simka.pw", "*noobxmr.com",
    "*miner.rocks", "*minerpool.pw", "*minemonero.gq", "*usxmrpool.com", "*moneroocean.stream", "*mypool.online",
    "*xmrpool.de", "*emergate.net", "*ip28.net", "*mine.bz", "*dwarfpool.com", "*xmrig.com", "*koto-pool.work",
    "*monerorx.com", "*zarabotaibitok.ru", "*mining-help.ru", "*mine2gether.com", "*moneropool.com", "*viaxmr.com",
    "*minerrocks.com", "*miningpoolhub.com", "*cortins.tk", "*pooldd.com", "*unmineable.com", "*f2pool.com",
    "*graef.in", "*nanopool.org", "*myxmr.pw", "*ratchetmining.com", "*cryptmonero.com", "*xmrminer.cc",
    "*riefly.id", "*iwanttoearn.money", "*herominers.com", "*xmrpool.me", "*miners.pro", "*luckpool.net",
    "*twotouchauthentication.online", "*hashvault.pro", "*4i7i.com", "*miningocean.org", "*2miners.com",
    "*xmrpool.eu", "*monerpool.org", "*joulecoin.org", "*suprnova.cc", "*bohemianpool.com",
    "*crypto-pool.fr", "*xmr.pt", "*alimabi.cn", "*teracycle.net", "*monerogb.com", "*armornetwork.org",
    "*emercoin.net", "*poolmining.org", "*minexmr.cn", "*moriaxmr.com", "*ethereumpool.co", "*minercircle.com",
    "*prohash.net", "*zer0day.ru", "*crypto-pool.info", "*pool.support", "*siamining.com", "*5b6b7b.ru",
    "*c3pool.com", "*somec.cc", "*hellominer.com", "*usa-138.com", "*mixpools.org", "*xmrpool.net",
    "*moneroworld.com", "*minerxmr.ru", "*d5pool.us", "*hashcity.org", "*hex7e4.ru", "*zpool.ca", "*minexmr.com",
    "*monerohash.com", "*multipool.us", "*moneropool.nl", "*nbminer.com", "*ppxxmr.com", "*xmrfast.com",
    "*webhop.net", "*ethpool.org", "*slushpool.com", "*antpool.com", "*nicehash.com", "*nicehash.net",
    "*zergpool.com", "*mining-dutch.nl", "*blockmasters.co", "*bsod.pw", "*fairpool.xyz", "*miningrigrentals.com",
    "*hashing24.com", "*ethermine.org", "*flexpool.io", "*hiveon.net", "*sparkpool.com", "*2miners.org",
    "*poolin.com", "*viabtc.com", "*f2pool.org", "*coinhive.com", "*cryptoloot.pro", "*webmine.cz",
    "*minero.cc", "*monerohash.org", "*monerohash.net", "*moneropool.ru", "*moneroocean.stream", "*rx.unmineable.com"
  )]
'''

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

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

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

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[[threat.technique.subtechnique]]
id = "T1071.004"
name = "DNS"
reference = "https://attack.mitre.org/techniques/T1071/004/"


[[threat.technique]]
id = "T1102"
name = "Web Service"
reference = "https://attack.mitre.org/techniques/T1102/"


[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1496"
name = "Resource Hijacking"
reference = "https://attack.mitre.org/techniques/T1496/"


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

[internal]
min_endpoint_version = "9.3.0"

Stages and Predicates

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

Stage 1: process

[process where event.type == "start" and event.action == "exec" and (
    process.name in (
      "curl", "wget", "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox",
      "timeout", "env", "node", "deno", "nodejs"
    ) or
    process.name like (".*", "python*", "perl*", "php*", "ruby*", "lua*") or
    process.executable like (
      "./*", "/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/*", "/var/run/*", "/boot/*", "/sys/*",
      "/lost+found/*", "/proc/*", "/var/mail/*", "/var/www/*", "/home/*/*", "/root/*"
    ) or
    process.working_directory like (
      "/tmp*", "/var/tmp*", "/dev/shm*", "/run*", "/var/run*", "/boot*", "/sys*", "/lost+found*",
      "/proc*", "/var/mail*", "/var/www*", "/home/*/*", "/root/*"
    )
  ) and
  not (process.name like "php*" and process.args in ("/var/tools/koalaping/bin/ping.php", "/var/tools/lean/bin/Lean.php"))]

Stage 2: dns

[dns where event.action == "lookup_result" and dns.question.name like~ (
    "*cnpool.cc", "*lindon-pool.win", "*supportxmr.com", "*comgandalph3000.com", "*minergate.com",
    "*fjhan.club", "*emercoin.com", "*poolto.be", "*520fjh.org", "*xmrpool.xyz", "*simka.pw", "*noobxmr.com",
    "*miner.rocks", "*minerpool.pw", "*minemonero.gq", "*usxmrpool.com", "*moneroocean.stream", "*mypool.online",
    "*xmrpool.de", "*emergate.net", "*ip28.net", "*mine.bz", "*dwarfpool.com", "*xmrig.com", "*koto-pool.work",
    "*monerorx.com", "*zarabotaibitok.ru", "*mining-help.ru", "*mine2gether.com", "*moneropool.com", "*viaxmr.com",
    "*minerrocks.com", "*miningpoolhub.com", "*cortins.tk", "*pooldd.com", "*unmineable.com", "*f2pool.com",
    "*graef.in", "*nanopool.org", "*myxmr.pw", "*ratchetmining.com", "*cryptmonero.com", "*xmrminer.cc",
    "*riefly.id", "*iwanttoearn.money", "*herominers.com", "*xmrpool.me", "*miners.pro", "*luckpool.net",
    "*twotouchauthentication.online", "*hashvault.pro", "*4i7i.com", "*miningocean.org", "*2miners.com",
    "*xmrpool.eu", "*monerpool.org", "*joulecoin.org", "*suprnova.cc", "*bohemianpool.com",
    "*crypto-pool.fr", "*xmr.pt", "*alimabi.cn", "*teracycle.net", "*monerogb.com", "*armornetwork.org",
    "*emercoin.net", "*poolmining.org", "*minexmr.cn", "*moriaxmr.com", "*ethereumpool.co", "*minercircle.com",
    "*prohash.net", "*zer0day.ru", "*crypto-pool.info", "*pool.support", "*siamining.com", "*5b6b7b.ru",
    "*c3pool.com", "*somec.cc", "*hellominer.com", "*usa-138.com", "*mixpools.org", "*xmrpool.net",
    "*moneroworld.com", "*minerxmr.ru", "*d5pool.us", "*hashcity.org", "*hex7e4.ru", "*zpool.ca", "*minexmr.com",
    "*monerohash.com", "*multipool.us", "*moneropool.nl", "*nbminer.com", "*ppxxmr.com", "*xmrfast.com",
    "*webhop.net", "*ethpool.org", "*slushpool.com", "*antpool.com", "*nicehash.com", "*nicehash.net",
    "*zergpool.com", "*mining-dutch.nl", "*blockmasters.co", "*bsod.pw", "*fairpool.xyz", "*miningrigrentals.com",
    "*hashing24.com", "*ethermine.org", "*flexpool.io", "*hiveon.net", "*sparkpool.com", "*2miners.org",
    "*poolin.com", "*viabtc.com", "*f2pool.org", "*coinhive.com", "*cryptoloot.pro", "*webmine.cz",
    "*minero.cc", "*monerohash.org", "*monerohash.net", "*moneropool.ru", "*moneroocean.stream", "*rx.unmineable.com"
  )]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
dns.question.namewildcard
  • *2miners.com
  • *2miners.org
  • *4i7i.com
  • *520fjh.org
  • *5b6b7b.ru
  • *alimabi.cn
  • *antpool.com
  • *armornetwork.org
  • *blockmasters.co
  • *bohemianpool.com
  • *bsod.pw
  • *c3pool.com
  • *cnpool.cc
  • *coinhive.com
  • *comgandalph3000.com
  • *cortins.tk
  • *cryptmonero.com
  • *crypto-pool.fr
  • *crypto-pool.info
  • *cryptoloot.pro
  • *d5pool.us
  • *dwarfpool.com
  • *emercoin.com
  • *emercoin.net
  • *emergate.net
  • *ethereumpool.co
  • *ethermine.org
  • *ethpool.org
  • *f2pool.com
  • *f2pool.org
  • *fairpool.xyz
  • *fjhan.club
  • *flexpool.io
  • *graef.in
  • *hashcity.org
  • *hashing24.com
  • *hashvault.pro
  • *hellominer.com
  • *herominers.com
  • *hex7e4.ru
  • +85 more values (see full rule source)
field:"QueryName" kind:wildcard
event.actioneq
  • exec
  • lookup_result
field:"EventType" kind:eq
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.executablewildcard
  • ./*
  • /boot/*
  • /dev/shm/*
  • /home/*/*
  • /lost+found/*
  • /proc/*
  • /root/*
  • /run/*
  • /sys/*
  • /tmp/*
  • /var/mail/*
  • /var/run/*
  • /var/tmp/*
  • /var/www/*
field:"Image" kind:wildcard
process.namein
  • bash
  • busybox
  • csh
  • curl
  • dash
  • deno
  • env
  • fish
  • ksh
  • node
  • nodejs
  • sh
  • tcsh
  • timeout
  • wget
  • zsh
field:"process_basename" kind:in
process.namewildcard
  • .*
  • lua*
  • perl*
  • php*
  • python*
  • ruby*
field:"process_basename" kind:wildcard
process.working_directorywildcard
  • /boot*
  • /dev/shm*
  • /home/*/*
  • /lost+found*
  • /proc*
  • /root/*
  • /run*
  • /sys*
  • /tmp*
  • /var/mail*
  • /var/run*
  • /var/tmp*
  • /var/www*
field:"CurrentDirectory" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argsin/var/tools/koalaping/bin/ping.php, /var/tools/lean/bin/Lean.phpexcludes:process.args field:"process.args" value:"/var/tools/koalaping/bin/ping.php" field:"process.args" value:"/var/tools/lean/bin/Lean.php"
process.namestarts_withphpexcludes:process.name field:"process.name" value:"php"

Elastic Defend Alert from GenAI Utility or Descendant

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

Detects Elastic Defend alerts (behavior, malicious file, memory signature, shellcode) where the alerted process or its direct parent is a GenAI coding or assistant utility (e.g. Cursor, Claude, Windsurf, Cody, Continue, Aider, OpenClaw, Moltbot, Clawdbot, Codeium, Tabnine, GitHub Copilot). Activity from these tools can indicate prompt injection, malicious skills, or supply-chain abuse; this Higher-Order rule helps prioritize such alerts for triage.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2026/02/27"
maturity = "production"
min_stack_comments = "ES|QL inline stats became generally available in 9.3.0 and MV_INTERSECTION is in preview since 9.3."
min_stack_version = "9.3.0"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Detects Elastic Defend alerts (behavior, malicious file, memory signature, shellcode) where the alerted process or its
direct parent is a GenAI coding or assistant utility (e.g. Cursor, Claude, Windsurf, Cody, Continue, Aider, OpenClaw,
Moltbot, Clawdbot, Codeium, Tabnine, GitHub Copilot). Activity from these tools can indicate prompt injection,
malicious skills, or supply-chain abuse; this Higher-Order rule helps prioritize such alerts for triage.
"""
from = "now-9m"
interval = "5m"
language = "esql"
license = "Elastic License v2"
name = "Elastic Defend Alert from GenAI Utility or Descendant"
note = """## Triage and analysis

### Investigating Elastic Defend Alert from GenAI Utility or Descendant

Elastic Defend has raised an alert on a process that is either a GenAI coding/assistant application or a direct child of one. This can indicate prompt injection, malicious extension/skill execution, or abuse of AI-assisted development tools (e.g. fake VS Code extensions, malicious ClawHub skills).

### Possible investigation steps

- Identify the GenAI utility by looking for a process with an entity_id in Esql.genai_ancestor_ids
- Review the alert rule name and message to understand what behavior was detected (e.g. script execution, network, file write).
- Inspect process_command_line and parent command lines for download-and-execute, encoded commands, or suspicious arguments.
- Correlate with the same host and user for other alerts or with network/DNS for C2 or exfiltration.
- If the tool is Cursor/VS Code: check for recently installed extensions.
- If OpenClaw/Moltbot/Clawdbot: review installed skills and conversation history for prompt injection or malicious skill execution.

### False positive analysis

- Legitimate use of GenAI tools (e.g. running builds, package installs, or approved scripts) can trigger behavior rules. Tune by excluding known-safe rule names or process command-line patterns, or limit to higher-severity alerts.
- Approved automation or CI that runs under a GenAI-related process may need to be allowlisted.

### Response and remediation

- If abuse is confirmed: disable or restrict the GenAI tool, remove malicious extensions/skills, rotate any exposed API keys or credentials, and block IOCs at network/EDR level.
"""
references = [
    "https://attack.mitre.org/techniques/T1059/",
    "https://attack.mitre.org/techniques/T1195/002/",
]
risk_score = 99
rule_id = "d4e5f6a7-b8c9-7d0e-1f2a-3b4c5d6e7f8a"
severity = "critical"
tags = [
    "Domain: Endpoint",
    "Domain: LLM",
    "Use Case: Threat Detection",
	"Tactic: Initial Access",
    "Rule Type: Higher-Order Rule",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
FROM logs-endpoint.alerts-*, logs-endpoint.events.process-* metadata _id, _version, _index 
| EVAL is_genai_spawn =  TO_LOWER(process.parent.name) IN (
        "claude", "claude.exe", "cursor", "cursor.exe", "cursor helper", "cursor helper (plugin)",
        "codex", "codex.exe", "cody", "cody.exe", "copilot", "copilot.exe", "gemini-cli", "gemini-cli.exe",
        "openai", "openai.exe", "ollama", "ollama.exe", "llm", "llm.exe",
        "aider", "aider.exe", "cline", "cline.exe", "continue", "continue.exe",
        "zed", "zed.exe", "windsurf", "windsurf.exe",
        "tabnine", "tabnine.exe", "codeium", "codeium.exe", "bolt", "bolt.exe",
        "devin", "devin.exe", "replit", "replit.exe", "ghostwriter", "ghostwriter.exe", "bito", "bito.exe"
    ),
     is_openclaw_spawn = process.parent.name in ("node", "node.exe") and (process.parent.command_line like "*openclaw*" or process.parent.command_line like "*moltbot*" or process.parent.command_line like "*clawdbot*")
| WHERE process.Ext.ancestry IS NOT NULL and 
   (data_stream.dataset == "endpoint.alerts" or is_genai_spawn or is_openclaw_spawn)
// Identify GenAI tool spawn events and capture their entity_ids
| EVAL genai_entity_id = CASE(is_genai_spawn or is_openclaw_spawn, process.parent.entity_id, NULL)

// Collect ALL GenAI entity_ids globally across the dataset
| INLINE STATS 
    all_genai_entity_ids = VALUES(genai_entity_id) WHERE genai_entity_id IS NOT NULL
// Find which GenAI entity_ids appear in this process's ancestry
| EVAL Esql.genai_ancestor_ids = MV_INTERSECTION(all_genai_entity_ids, process.Ext.ancestry)

// Elastic Defend alerts from a GenAI grandparent 
| WHERE Esql.genai_ancestor_ids IS NOT NULL 
        AND data_stream.dataset == "endpoint.alerts" AND not rule.name in (
            "Persistence via GenAI Tool",
            "Code Editor Untrusted or Unsigned Child Process Execution",
            "Suspicious Credential Access via GenAI Tool",
            "Credential Access via GenAI Tool Descendant"
        )

| KEEP *
'''

[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1195"
name = "Supply Chain Compromise"
reference = "https://attack.mitre.org/techniques/T1195/"
[[rule.threat.technique.subtechnique]]
id = "T1195.002"
name = "Compromise Software Supply Chain"
reference = "https://attack.mitre.org/techniques/T1195/002/"

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

Stages and Predicates

Stage 1: from

FROM logs-endpoint.alerts-*, logs-endpoint.events.process-* metadata _id, _version, _index

Stage 2: eval

| EVAL is_genai_spawn =  TO_LOWER(process.parent.name) IN (
        "claude", "claude.exe", "cursor", "cursor.exe", "cursor helper", "cursor helper (plugin)",
        "codex", "codex.exe", "cody", "cody.exe", "copilot", "copilot.exe", "gemini-cli", "gemini-cli.exe",
        "openai", "openai.exe", "ollama", "ollama.exe", "llm", "llm.exe",
        "aider", "aider.exe", "cline", "cline.exe", "continue", "continue.exe",
        "zed", "zed.exe", "windsurf", "windsurf.exe",
        "tabnine", "tabnine.exe", "codeium", "codeium.exe", "bolt", "bolt.exe",
        "devin", "devin.exe", "replit", "replit.exe", "ghostwriter", "ghostwriter.exe", "bito", "bito.exe"
    ),
     is_openclaw_spawn = process.parent.name in ("node", "node.exe") and (process.parent.command_line like "*openclaw*" or process.parent.command_line like "*moltbot*" or process.parent.command_line like "*clawdbot*")

Stage 3: where

| WHERE process.Ext.ancestry IS NOT NULL and
   (data_stream.dataset == "endpoint.alerts" or is_genai_spawn or is_openclaw_spawn)

Stage 4: eval

| EVAL genai_entity_id = CASE(is_genai_spawn or is_openclaw_spawn, process.parent.entity_id, NULL)
genai_entity_id =
ifis_genai_spawn or is_openclaw_spawnprocess.parent.entity_id
elseNULL

Stage 5: inline_stats

| INLINE STATS
    all_genai_entity_ids = VALUES(genai_entity_id) WHERE genai_entity_id IS NOT NULL

Stage 6: eval

| EVAL Esql.genai_ancestor_ids = MV_INTERSECTION(all_genai_entity_ids, process.Ext.ancestry)

Stage 7: where

| WHERE Esql.genai_ancestor_ids IS NOT NULL 
        AND data_stream.dataset == "endpoint.alerts" AND not rule.name in (
            "Persistence via GenAI Tool",
            "Code Editor Untrusted or Unsigned Child Process Execution",
            "Suspicious Credential Access via GenAI Tool",
            "Credential Access via GenAI Tool Descendant"
        )

Stage 8: keep

| KEEP *

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
rule.nameinCode Editor Untrusted or Unsigned Child Process Execution, Credential Access via GenAI Tool Descendant, Persistence via GenAI Tool, Suspicious Credential Access via GenAI Toolexcludes:rule.name

Output Fields

The rule emits every field available at its final step.

Entra ID Sign-in Brute Force Attempted (Microsoft 365)

#
Status
production
Severity
medium
Time window
1h
Group by
Esql.time_window_date_trunc
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies potential brute-force attacks targeting Microsoft 365 user accounts by analyzing failed sign-in patterns in Microsoft Entra ID Sign-In Logs. This detection focuses on a high volume of failed interactive or non-interactive authentication attempts within a short time window, often indicative of password spraying, credential stuffing, or password guessing. Adversaries may use these techniques to gain unauthorized access to Microsoft 365 services such as Exchange Online, SharePoint, or Teams.

Known False Positives

  • Automated processes that attempt to authenticate using expired credentials or have misconfigured authentication settings may lead to false positives.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2024/09/06"
integration = ["azure"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Identifies potential brute-force attacks targeting Microsoft 365 user accounts by analyzing failed sign-in patterns in
Microsoft Entra ID Sign-In Logs. This detection focuses on a high volume of failed interactive or non-interactive
authentication attempts within a short time window, often indicative of password spraying, credential stuffing, or
password guessing. Adversaries may use these techniques to gain unauthorized access to Microsoft 365 services such as
Exchange Online, SharePoint, or Teams.
"""
false_positives = [
    """
    Automated processes that attempt to authenticate using expired credentials or have misconfigured authentication
    settings may lead to false positives.
    """,
]
from = "now-60m"
interval = "15m"
language = "esql"
license = "Elastic License v2"
name = "Entra ID Sign-in Brute Force Attempted (Microsoft 365)"
note = """## Triage and analysis

### Investigating Entra ID Sign-in Brute Force Attempted (Microsoft 365)

Identifies brute-force authentication activity against Microsoft 365 services using Entra ID sign-in logs. This detection groups and classifies failed sign-in attempts based on behavior indicative of password spraying, credential stuffing, or password guessing. The classification (`bf_type`) is included for immediate triage.

### Possible investigation steps

- Review `bf_type`: Classifies the brute-force behavior (`password_spraying`, `credential_stuffing`, `password_guessing`).
- Examine `user_id_list`: Review the identities targeted. Are they admins, service accounts, or external identities?
- Review `login_errors`: Multiple identical errors (e.g., `"Invalid grant..."`) suggest automated abuse or tooling.
- Check `ip_list` and `source_orgs`: Determine if requests came from known VPNs, hosting providers, or anonymized infrastructure.
- Validate `unique_ips` and `countries`: Multiple countries or IPs in a short window may indicate credential stuffing or distributed spray attempts.
- Compare `total_attempts` vs `duration_seconds`: High volume over a short duration supports non-human interaction.
- Inspect `user_agent.original` via `device_detail_browser`: Clients like `Python Requests` or `curl` are highly suspicious.
- Investigate `client_app_display_name` and `incoming_token_type`: Identify non-browser-based logins, token abuse or commonly mimicked clients like VSCode.
- Review `target_resource_display_name`: Confirm the service being targeted (e.g., SharePoint, Exchange). This may be what authorization is being attempted against.
- Pivot using `session_id` and `device_detail_device_id`: Determine if a single device is spraying multiple accounts.
- Check `conditional_access_status`: If "notApplied", determine whether conditional access is properly scoped.
- Correlate `user_principal_name` with successful sign-ins: Investigate surrounding logs for lateral movement or privilege abuse.

### False positive analysis

- Developer automation (e.g., CI/CD logins) or mobile sync errors may create noisy but benign login failures.
- Red team exercises or pentesting can resemble brute-force patterns.
- Legacy protocols or misconfigured service principals may trigger repeated login failures from the same IP or session.

### Response and remediation

- Notify identity or security operations teams to investigate further.
- Lock or reset affected user accounts if compromise is suspected.
- Block the source IP(s) or ASN temporarily using conditional access or firewall rules.
- Review tenant-wide MFA and conditional access enforcement.
- Audit targeted accounts for password reuse across systems or tenants.
- Enable lockout or throttling policies for repeated failed login attempts.
"""
references = [
    "https://cloud.hacktricks.xyz/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-password-spraying",
    "https://learn.microsoft.com/en-us/security/operations/incident-response-playbook-password-spray",
    "https://learn.microsoft.com/en-us/purview/audit-log-detailed-properties",
    "https://securityscorecard.com/research/massive-botnet-targets-m365-with-stealthy-password-spraying-attacks/",
    "https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes",
    "https://github.com/0xZDH/Omnispray",
    "https://github.com/0xZDH/o365spray",
]
risk_score = 47
rule_id = "35ab3cfa-6c67-11ef-ab4d-f661ea17fbcc"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: SaaS",
    "Domain: Identity",
    "Data Source: Azure",
    "Data Source: Entra ID",
    "Data Source: Entra ID Sign-in Logs",
    "Use Case: Identity and Access Audit",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
from logs-azure.signinlogs-*

| eval
    Esql.time_window_date_trunc = date_trunc(15 minutes, @timestamp),
    Esql_priv.azure_signinlogs_properties_user_principal_name_lower = to_lower(azure.signinlogs.properties.user_principal_name),
    Esql.azure_signinlogs_properties_incoming_token_type_lower = to_lower(azure.signinlogs.properties.incoming_token_type),
    Esql.azure_signinlogs_properties_app_display_name_lower = to_lower(azure.signinlogs.properties.app_display_name),
    Esql.user_agent_original = user_agent.original

| where data_stream.dataset == "azure.signinlogs"
    and event.category == "authentication"
    and azure.signinlogs.category in ("NonInteractiveUserSignInLogs", "SignInLogs")
    and azure.signinlogs.properties.resource_display_name rlike "(.*)365|SharePoint|Exchange|Teams|Office(.*)"
    and event.outcome == "failure"
    and azure.signinlogs.properties.status.error_code != 50053
    and azure.signinlogs.properties.status.error_code in (
        50034,  // UserAccountNotFound
        50126,  // InvalidUsernameOrPassword
        50055,  // PasswordExpired
        50056,  // InvalidPassword
        50057,  // UserDisabled
        50064,  // CredentialValidationFailure
        50076,  // MFARequiredButNotPassed
        50079,  // MFARegistrationRequired
        50105,  // EntitlementGrantsNotFound
        70000,  // InvalidGrant
        70008,  // ExpiredOrRevokedRefreshToken
        70043,  // BadTokenDueToSignInFrequency
        80002,  // OnPremisePasswordValidatorRequestTimedOut
        80005,  // OnPremisePasswordValidatorUnpredictableWebException
        50144,  // InvalidPasswordExpiredOnPremPassword
        50135,  // PasswordChangeCompromisedPassword
        50142,  // PasswordChangeRequiredConditionalAccess
        120000, // PasswordChangeIncorrectCurrentPassword
        120002, // PasswordChangeInvalidNewPasswordWeak
        120020  // PasswordChangeFailure
    )
    and azure.signinlogs.properties.user_principal_name is not null
    and azure.signinlogs.properties.user_principal_name != ""
    and user_agent.original != "Mozilla/5.0 (compatible; MSAL 1.0) PKeyAuth/1.0"

| stats
    Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement),
    Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id),
    Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name),
    Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id),
    Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name),
    Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status),
    Esql.azure_signinlogs_properties_device_detail_browser_values = values(azure.signinlogs.properties.device_detail.browser),
    Esql.azure_signinlogs_properties_device_detail_device_id_values = values(azure.signinlogs.properties.device_detail.device_id),
    Esql.azure_signinlogs_properties_device_detail_operating_system_values = values(azure.signinlogs.properties.device_detail.operating_system),
    Esql.azure_signinlogs_properties_incoming_token_type_values = values(azure.signinlogs.properties.incoming_token_type),
    Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state),
    Esql.azure_signinlogs_properties_session_id_values = values(azure.signinlogs.properties.session_id),
    Esql.azure_signinlogs_properties_user_id_values = values(azure.signinlogs.properties.user_id),
    Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name),
    Esql.azure_signinlogs_result_description_values = values(azure.signinlogs.result_description),
    Esql.azure_signinlogs_result_signature_values = values(azure.signinlogs.result_signature),
    Esql.azure_signinlogs_result_type_values = values(azure.signinlogs.result_type),

    Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct = count_distinct(Esql_priv.azure_signinlogs_properties_user_principal_name_lower),
    Esql_priv.azure_signinlogs_properties_user_principal_name_lower_values = values(Esql_priv.azure_signinlogs_properties_user_principal_name_lower),
    Esql.azure_signinlogs_result_description_count_distinct = count_distinct(azure.signinlogs.result_description),
    Esql.azure_signinlogs_result_description_values = values(azure.signinlogs.result_description),
    Esql.azure_signinlogs_properties_status_error_code_count_distinct = count_distinct(azure.signinlogs.properties.status.error_code),
    Esql.azure_signinlogs_properties_status_error_code_values = values(azure.signinlogs.properties.status.error_code),
    Esql.azure_signinlogs_properties_incoming_token_type_lower_values = values(Esql.azure_signinlogs_properties_incoming_token_type_lower),
    Esql.azure_signinlogs_properties_app_display_name_lower_values = values(Esql.azure_signinlogs_properties_app_display_name_lower),
    Esql.source_ip_values = values(source.ip),
    Esql.source_ip_count_distinct = count_distinct(source.ip),
    Esql.source_as_organization_name_values = values(source.`as`.organization.name),
    Esql.source_as_organization_name_count_distinct = count_distinct(source.`as`.organization.name),
    Esql.source_geo_country_name_values = values(source.geo.country_name),
    Esql.source_geo_country_name_count_distinct = count_distinct(source.geo.country_name),
    Esql.@timestamp.min = min(@timestamp),
    Esql.@timestamp.max = max(@timestamp),
    Esql.event_count = count()
by Esql.time_window_date_trunc

| eval
    Esql.event_duration_seconds = date_diff("seconds", Esql.@timestamp.min, Esql.@timestamp.max),
    Esql.event_bf_type = case(
        Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct >= 10
            and Esql.event_count >= 30
            and Esql.azure_signinlogs_result_description_count_distinct <= 3
            and Esql.source_ip_count_distinct >= 5
            and Esql.event_duration_seconds <= 600
            and Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct > Esql.source_ip_count_distinct,
        "credential_stuffing",

        Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct >= 15
            and Esql.azure_signinlogs_result_description_count_distinct == 1
            and Esql.event_count >= 15
            and Esql.event_duration_seconds <= 1800,
        "password_spraying",

        (Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct == 1
            and Esql.azure_signinlogs_result_description_count_distinct == 1
            and Esql.event_count >= 30
            and Esql.event_duration_seconds <= 300)
            or (Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct <= 3
            and Esql.source_ip_count_distinct > 30
            and Esql.event_count >= 100),
        "password_guessing",

        "other"
    )

| where Esql.event_bf_type != "other"

| keep
    Esql.time_window_date_trunc,
    Esql.event_bf_type,
    Esql.event_duration_seconds,
    Esql.event_count,
    Esql.@timestamp.min,
    Esql.@timestamp.max,
    Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct,
    Esql_priv.azure_signinlogs_properties_user_principal_name_lower_values,
    Esql.azure_signinlogs_result_description_count_distinct,
    Esql.azure_signinlogs_result_description_values,
    Esql.azure_signinlogs_properties_status_error_code_count_distinct,
    Esql.azure_signinlogs_properties_status_error_code_values,
    Esql.azure_signinlogs_properties_incoming_token_type_lower_values,
    Esql.azure_signinlogs_properties_app_display_name_lower_values,
    Esql.source_ip_values,
    Esql.source_ip_count_distinct,
    Esql.source_as_organization_name_values,
    Esql.source_as_organization_name_count_distinct,
    Esql.source_geo_country_name_values,
    Esql.source_geo_country_name_count_distinct,
    Esql.azure_signinlogs_properties_authentication_requirement_values,
    Esql.azure_signinlogs_properties_app_id_values,
    Esql.azure_signinlogs_properties_app_display_name_values,
    Esql.azure_signinlogs_properties_resource_id_values,
    Esql.azure_signinlogs_properties_resource_display_name_values,
    Esql.azure_signinlogs_properties_conditional_access_status_values,
    Esql.azure_signinlogs_properties_device_detail_browser_values,
    Esql.azure_signinlogs_properties_device_detail_device_id_values,
    Esql.azure_signinlogs_properties_device_detail_operating_system_values,
    Esql.azure_signinlogs_properties_incoming_token_type_values,
    Esql.azure_signinlogs_properties_risk_state_values,
    Esql.azure_signinlogs_properties_session_id_values,
    Esql.azure_signinlogs_properties_user_id_values
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1110"
name = "Brute Force"
reference = "https://attack.mitre.org/techniques/T1110/"
[[rule.threat.technique.subtechnique]]
id = "T1110.001"
name = "Password Guessing"
reference = "https://attack.mitre.org/techniques/T1110/001/"

[[rule.threat.technique.subtechnique]]
id = "T1110.003"
name = "Password Spraying"
reference = "https://attack.mitre.org/techniques/T1110/003/"

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



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

Stages and Predicates

Stage 1: from

from logs-azure.signinlogs-*

Stage 2: eval

| eval
    Esql.time_window_date_trunc = date_trunc(15 minutes, @timestamp),
    Esql_priv.azure_signinlogs_properties_user_principal_name_lower = to_lower(azure.signinlogs.properties.user_principal_name),
    Esql.azure_signinlogs_properties_incoming_token_type_lower = to_lower(azure.signinlogs.properties.incoming_token_type),
    Esql.azure_signinlogs_properties_app_display_name_lower = to_lower(azure.signinlogs.properties.app_display_name),
    Esql.user_agent_original = user_agent.original

Stage 3: where

| where data_stream.dataset == "azure.signinlogs"
    and event.category == "authentication"
    and azure.signinlogs.category in ("NonInteractiveUserSignInLogs", "SignInLogs")
    and azure.signinlogs.properties.resource_display_name rlike "(.*)365|SharePoint|Exchange|Teams|Office(.*)"
    and event.outcome == "failure"
    and azure.signinlogs.properties.status.error_code != 50053
    and azure.signinlogs.properties.status.error_code in (
        50034,
        50126,
        50055,
        50056,
        50057,
        50064,
        50076,
        50079,
        50105,
        70000,
        70008,
        70043,
        80002,
        80005,
        50144,
        50135,
        50142,
        120000,
        120002,
        120020
    )
    and azure.signinlogs.properties.user_principal_name is not null
    and azure.signinlogs.properties.user_principal_name != ""
    and user_agent.original != "Mozilla/5.0 (compatible; MSAL 1.0) PKeyAuth/1.0"

Stage 4: stats

| stats
    Esql.azure_signinlogs_properties_authentication_requirement_values = values(azure.signinlogs.properties.authentication_requirement),
    Esql.azure_signinlogs_properties_app_id_values = values(azure.signinlogs.properties.app_id),
    Esql.azure_signinlogs_properties_app_display_name_values = values(azure.signinlogs.properties.app_display_name),
    Esql.azure_signinlogs_properties_resource_id_values = values(azure.signinlogs.properties.resource_id),
    Esql.azure_signinlogs_properties_resource_display_name_values = values(azure.signinlogs.properties.resource_display_name),
    Esql.azure_signinlogs_properties_conditional_access_status_values = values(azure.signinlogs.properties.conditional_access_status),
    Esql.azure_signinlogs_properties_device_detail_browser_values = values(azure.signinlogs.properties.device_detail.browser),
    Esql.azure_signinlogs_properties_device_detail_device_id_values = values(azure.signinlogs.properties.device_detail.device_id),
    Esql.azure_signinlogs_properties_device_detail_operating_system_values = values(azure.signinlogs.properties.device_detail.operating_system),
    Esql.azure_signinlogs_properties_incoming_token_type_values = values(azure.signinlogs.properties.incoming_token_type),
    Esql.azure_signinlogs_properties_risk_state_values = values(azure.signinlogs.properties.risk_state),
    Esql.azure_signinlogs_properties_session_id_values = values(azure.signinlogs.properties.session_id),
    Esql.azure_signinlogs_properties_user_id_values = values(azure.signinlogs.properties.user_id),
    Esql_priv.azure_signinlogs_properties_user_principal_name_values = values(azure.signinlogs.properties.user_principal_name),
    Esql.azure_signinlogs_result_description_values = values(azure.signinlogs.result_description),
    Esql.azure_signinlogs_result_signature_values = values(azure.signinlogs.result_signature),
    Esql.azure_signinlogs_result_type_values = values(azure.signinlogs.result_type),

    Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct = count_distinct(Esql_priv.azure_signinlogs_properties_user_principal_name_lower),
    Esql_priv.azure_signinlogs_properties_user_principal_name_lower_values = values(Esql_priv.azure_signinlogs_properties_user_principal_name_lower),
    Esql.azure_signinlogs_result_description_count_distinct = count_distinct(azure.signinlogs.result_description),
    Esql.azure_signinlogs_result_description_values = values(azure.signinlogs.result_description),
    Esql.azure_signinlogs_properties_status_error_code_count_distinct = count_distinct(azure.signinlogs.properties.status.error_code),
    Esql.azure_signinlogs_properties_status_error_code_values = values(azure.signinlogs.properties.status.error_code),
    Esql.azure_signinlogs_properties_incoming_token_type_lower_values = values(Esql.azure_signinlogs_properties_incoming_token_type_lower),
    Esql.azure_signinlogs_properties_app_display_name_lower_values = values(Esql.azure_signinlogs_properties_app_display_name_lower),
    Esql.source_ip_values = values(source.ip),
    Esql.source_ip_count_distinct = count_distinct(source.ip),
    Esql.source_as_organization_name_values = values(source.`as`.organization.name),
    Esql.source_as_organization_name_count_distinct = count_distinct(source.`as`.organization.name),
    Esql.source_geo_country_name_values = values(source.geo.country_name),
    Esql.source_geo_country_name_count_distinct = count_distinct(source.geo.country_name),
    Esql.@timestamp.min = min(@timestamp),
    Esql.@timestamp.max = max(@timestamp),
    Esql.event_count = count()
by Esql.time_window_date_trunc

Stage 5: eval

| eval
    Esql.event_duration_seconds = date_diff("seconds", Esql.@timestamp.min, Esql.@timestamp.max),
    Esql.event_bf_type = case(
        Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct >= 10
            and Esql.event_count >= 30
            and Esql.azure_signinlogs_result_description_count_distinct <= 3
            and Esql.source_ip_count_distinct >= 5
            and Esql.event_duration_seconds <= 600
            and Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct > Esql.source_ip_count_distinct,
        "credential_stuffing",

        Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct >= 15
            and Esql.azure_signinlogs_result_description_count_distinct == 1
            and Esql.event_count >= 15
            and Esql.event_duration_seconds <= 1800,
        "password_spraying",

        (Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct == 1
            and Esql.azure_signinlogs_result_description_count_distinct == 1
            and Esql.event_count >= 30
            and Esql.event_duration_seconds <= 300)
            or (Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct <= 3
            and Esql.source_ip_count_distinct > 30
            and Esql.event_count >= 100),
        "password_guessing",

        "other"
    )
Esql.event_bf_type =
ifEsql.azure_signinlogs_properties_user_principal_name_lower_count_distinct >= 10 and Esql.event_count >= 30 and Esql.azure_signinlogs_result_description_count_distinct <= 3 and Esql.source_ip_count_distinct >= 5 and Esql.event_duration_seconds <= 600 and Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct > Esql.source_ip_count_distinct"credential_stuffing"
elifEsql.azure_signinlogs_properties_user_principal_name_lower_count_distinct >= 15 and Esql.azure_signinlogs_result_description_count_distinct == 1 and Esql.event_count >= 15 and Esql.event_duration_seconds <= 1800"password_spraying"
elif(Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct == 1 and Esql.azure_signinlogs_result_description_count_distinct == 1 and Esql.event_count >= 30 and Esql.event_duration_seconds <= 300) or (Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct <= 3 and Esql.source_ip_count_distinct > 30 and Esql.event_count >= 100)"password_guessing"
else"other"

Stage 6: where

| where Esql.event_bf_type != "other"

Stage 7: keep

| keep
    Esql.time_window_date_trunc,
    Esql.event_bf_type,
    Esql.event_duration_seconds,
    Esql.event_count,
    Esql.@timestamp.min,
    Esql.@timestamp.max,
    Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct,
    Esql_priv.azure_signinlogs_properties_user_principal_name_lower_values,
    Esql.azure_signinlogs_result_description_count_distinct,
    Esql.azure_signinlogs_result_description_values,
    Esql.azure_signinlogs_properties_status_error_code_count_distinct,
    Esql.azure_signinlogs_properties_status_error_code_values,
    Esql.azure_signinlogs_properties_incoming_token_type_lower_values,
    Esql.azure_signinlogs_properties_app_display_name_lower_values,
    Esql.source_ip_values,
    Esql.source_ip_count_distinct,
    Esql.source_as_organization_name_values,
    Esql.source_as_organization_name_count_distinct,
    Esql.source_geo_country_name_values,
    Esql.source_geo_country_name_count_distinct,
    Esql.azure_signinlogs_properties_authentication_requirement_values,
    Esql.azure_signinlogs_properties_app_id_values,
    Esql.azure_signinlogs_properties_app_display_name_values,
    Esql.azure_signinlogs_properties_resource_id_values,
    Esql.azure_signinlogs_properties_resource_display_name_values,
    Esql.azure_signinlogs_properties_conditional_access_status_values,
    Esql.azure_signinlogs_properties_device_detail_browser_values,
    Esql.azure_signinlogs_properties_device_detail_device_id_values,
    Esql.azure_signinlogs_properties_device_detail_operating_system_values,
    Esql.azure_signinlogs_properties_incoming_token_type_values,
    Esql.azure_signinlogs_properties_risk_state_values,
    Esql.azure_signinlogs_properties_session_id_values,
    Esql.azure_signinlogs_properties_user_id_values

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
Esql.event_bf_typene
  • other
field:"Esql.event_bf_type" kind:ne value:"other"
azure.signinlogs.categoryin
  • NonInteractiveUserSignInLogs corpus 2 (elastic 2)
  • SignInLogs corpus 2 (elastic 2)
field:"azure_ad::signin_category" kind:in
azure.signinlogs.properties.resource_display_nameregex_match
    • (.*)365
    • SharePoint
    • Exchange
    • Teams
    • Office(.*)
field:"azure_ad::resource_display_name" kind:regex_match
azure.signinlogs.properties.status.error_codein
  • 120000 corpus 2 (elastic 2)
  • 120002 corpus 2 (elastic 2)
  • 120020 corpus 2 (elastic 2)
  • 50034 corpus 2 (elastic 2)
  • 50055 corpus 2 (elastic 2)
  • 50056 corpus 2 (elastic 2)
  • 50057 corpus 2 (elastic 2)
  • 50064 corpus 2 (elastic 2)
  • 50076 corpus 2 (elastic 2)
  • 50079 corpus 2 (elastic 2)
  • 50105 corpus 2 (elastic 2)
  • 50126 corpus 2 (elastic 2)
  • 50135 corpus 2 (elastic 2)
  • 50142 corpus 2 (elastic 2)
  • 50144 corpus 2 (elastic 2)
  • 70000 corpus 2 (elastic 2)
  • 70008 corpus 2 (elastic 2)
  • 70043 corpus 2 (elastic 2)
  • 80002 corpus 2 (elastic 2)
  • 80005 corpus 2 (elastic 2)
field:"azure_ad::result_type" kind:in
azure.signinlogs.properties.status.error_codene
  • 50053
field:"azure_ad::result_type" kind:ne value:"50053"
azure.signinlogs.properties.user_principal_nameis_not_null
  • (no value, null check)
field:"azure_ad::user_principal_name" kind:is_not_null
data_stream.dataseteq
  • azure.signinlogs corpus 12 (elastic 12)
field:"data_stream.dataset" kind:eq value:"azure.signinlogs"
event.categoryeq
  • authentication corpus 14 (elastic 14)
field:"event.category" kind:eq value:"authentication"
event.outcomeeq
  • failure corpus 10 (elastic 10)
field:"event.outcome" kind:eq value:"failure"
user_agent.originalne
  • Mozilla/5.0 (compatible; MSAL 1.0) PKeyAuth/1.0 corpus 2 (elastic 2)
field:"aws::userAgent" kind:ne value:"Mozilla/5.0 (compatible; MSAL 1.0) PKeyAuth/1.0"

Output Fields

These fields are emitted when the rule matches.

FieldSource
Esql.time_window_date_truncKEEP Esql.time_window_date_trunc
Esql.event_bf_typeKEEP Esql.event_bf_type
Esql.event_duration_secondsKEEP Esql.event_duration_seconds
Esql.event_countKEEP Esql.event_count
Esql.@timestamp.minKEEP Esql.@timestamp.min
Esql.@timestamp.maxKEEP Esql.@timestamp.max
Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinctKEEP Esql.azure_signinlogs_properties_user_principal_name_lower_count_distinct
Esql_priv.azure_signinlogs_properties_user_principal_name_lower_valuesKEEP Esql_priv.azure_signinlogs_properties_user_principal_name_lower_values
Esql.azure_signinlogs_result_description_count_distinctKEEP Esql.azure_signinlogs_result_description_count_distinct
Esql.azure_signinlogs_result_description_valuesKEEP Esql.azure_signinlogs_result_description_values
Esql.azure_signinlogs_properties_status_error_code_count_distinctKEEP Esql.azure_signinlogs_properties_status_error_code_count_distinct
Esql.azure_signinlogs_properties_status_error_code_valuesKEEP Esql.azure_signinlogs_properties_status_error_code_values
Esql.azure_signinlogs_properties_incoming_token_type_lower_valuesKEEP Esql.azure_signinlogs_properties_incoming_token_type_lower_values
Esql.azure_signinlogs_properties_app_display_name_lower_valuesKEEP Esql.azure_signinlogs_properties_app_display_name_lower_values
Esql.source_ip_valuesKEEP Esql.source_ip_values
Esql.source_ip_count_distinctKEEP Esql.source_ip_count_distinct
Esql.source_as_organization_name_valuesKEEP Esql.source_as_organization_name_values
Esql.source_as_organization_name_count_distinctKEEP Esql.source_as_organization_name_count_distinct
Esql.source_geo_country_name_valuesKEEP Esql.source_geo_country_name_values
Esql.source_geo_country_name_count_distinctKEEP Esql.source_geo_country_name_count_distinct
Esql.azure_signinlogs_properties_authentication_requirement_valuesKEEP Esql.azure_signinlogs_properties_authentication_requirement_values
Esql.azure_signinlogs_properties_app_id_valuesKEEP Esql.azure_signinlogs_properties_app_id_values
Esql.azure_signinlogs_properties_app_display_name_valuesKEEP Esql.azure_signinlogs_properties_app_display_name_values
Esql.azure_signinlogs_properties_resource_id_valuesKEEP Esql.azure_signinlogs_properties_resource_id_values
Esql.azure_signinlogs_properties_resource_display_name_valuesKEEP Esql.azure_signinlogs_properties_resource_display_name_values
Esql.azure_signinlogs_properties_conditional_access_status_valuesKEEP Esql.azure_signinlogs_properties_conditional_access_status_values
Esql.azure_signinlogs_properties_device_detail_browser_valuesKEEP Esql.azure_signinlogs_properties_device_detail_browser_values
Esql.azure_signinlogs_properties_device_detail_device_id_valuesKEEP Esql.azure_signinlogs_properties_device_detail_device_id_values
Esql.azure_signinlogs_properties_device_detail_operating_system_valuesKEEP Esql.azure_signinlogs_properties_device_detail_operating_system_values
Esql.azure_signinlogs_properties_incoming_token_type_valuesKEEP Esql.azure_signinlogs_properties_incoming_token_type_values
Esql.azure_signinlogs_properties_risk_state_valuesKEEP Esql.azure_signinlogs_properties_risk_state_values
Esql.azure_signinlogs_properties_session_id_valuesKEEP Esql.azure_signinlogs_properties_session_id_values
Esql.azure_signinlogs_properties_user_id_valuesKEEP Esql.azure_signinlogs_properties_user_id_values

Interactive Shell Spawn Detected via Defend for Containers

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

This rule detects when an interactive shell is spawned inside a running container. This could indicate a potential container breakout attempt or an attacker's attempt to gain unauthorized access to the underlying host.

Known False Positives

  • Legitimate users and processes, such as system administration tools, may utilize shell utilities inside a container resulting in false positives.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2023/04/26"
integration = ["cloud_defend"]
maturity = "production"
min_stack_comments = "Defend for Containers integration was re-introduced in 9.3.0"
min_stack_version = "9.3.0"
updated_date = "2026/07/29"

[rule]
author = ["Elastic"]
description = """
This rule detects when an interactive shell is spawned inside a running container. This could indicate a potential
container breakout attempt or an attacker's attempt to gain unauthorized access to the underlying host.
"""
false_positives = [
    """
    Legitimate users and processes, such as system administration tools, may utilize shell utilities inside a container
    resulting in false positives.
    """,
]
from = "now-6m"
index = ["logs-cloud_defend.process*"]
interval = "5m"
language = "eql"
license = "Elastic License v2"
name = "Interactive Shell Spawn Detected via Defend for Containers"
note = """## Setup

## 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 Shell Spawn Detected via Defend for Containers

Containers are lightweight, portable units that encapsulate applications and their dependencies, often used to ensure consistent environments across development and production. Adversaries may exploit containers by spawning interactive shells to execute unauthorized commands, potentially leading to container escape and host compromise. The detection rule identifies such threats by monitoring for shell processes initiated within containers, focusing on specific process actions and arguments indicative of interactive sessions.

### Possible investigation steps

- Review the alert details to identify the specific container ID where the interactive shell was spawned. This will help in isolating the affected container for further analysis.
- Examine the process executable and arguments, particularly looking for shell types and interactive flags (e.g., "-i", "-it"), to understand the nature of the shell session initiated.
- Check the process entry leader to determine if the shell process is part of a larger process tree, which might indicate a more complex attack chain or script execution.
- Investigate the user context under which the shell was spawned to assess if it aligns with expected user behavior or if it indicates potential unauthorized access.
- Analyze recent logs and events from the container and host to identify any preceding suspicious activities or anomalies that might have led to the shell spawning.
- Correlate the event with other security alerts or incidents to determine if this is part of a broader attack pattern or campaign targeting the environment.

### False positive analysis

- Development and testing activities may trigger this rule when developers intentionally spawn interactive shells within containers for debugging or configuration purposes. To manage this, create exceptions for specific user accounts or container IDs frequently used in development environments.
- Automated scripts or orchestration tools that use interactive shells for legitimate tasks can also cause false positives. Identify these scripts and exclude their associated process names or arguments from the rule.
- Some container management platforms might use interactive shells as part of their normal operations. Review the processes and arguments used by these platforms and add them to an exception list if they are known to be safe.
- Regular maintenance tasks that require interactive shell access, such as system updates or configuration changes, can be excluded by scheduling these tasks during known maintenance windows and temporarily adjusting the rule settings.

### Response and remediation

- Immediately isolate the affected container to prevent further unauthorized access or potential container escape. This can be done by stopping the container or disconnecting it from the network.
- Capture and preserve forensic data from the container, including logs, process lists, and network activity, to aid in further investigation and understanding of the attack vector.
- Conduct a thorough review of the container's configuration and permissions to identify and rectify any misconfigurations or vulnerabilities that may have been exploited.
- Patch and update the container image and any associated software to address known vulnerabilities that could have been leveraged by the attacker.
- Implement stricter access controls and monitoring on container environments to prevent unauthorized shell access, such as using role-based access controls and enabling audit logging.
- Escalate the incident to the security operations team for further analysis and to determine if the threat has spread to other parts of the infrastructure.
- Review and enhance detection capabilities to identify similar threats in the future, ensuring that alerts are tuned to detect unauthorized shell access attempts promptly."""
risk_score = 21
rule_id = "8d3d0794-c776-476b-8674-ee2e685f6470"
severity = "low"
tags = [
    "Data Source: Elastic Defend for Containers",
    "Domain: Container",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Execution",
    "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 in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox") and
process.entry_leader.same_as_process == false and container.id like "*" and
process.args in (
  "sh", "dash", "bash", "zsh", "fish", "busybox",
  "/bin/sh", "/bin/dash", "/bin/bash", "/bin/zsh", "/bin/fish", "/bin/busybox",
  "/usr/bin/sh", "/usr/bin/dash", "/usr/bin/bash", "/usr/bin/zsh", "/usr/bin/fish", "/usr/bin/busybox",
  "/usr/local/bin/sh", "/usr/local/bin/dash", "/usr/local/bin/bash", "/usr/local/bin/zsh", "/usr/local/bin/fish", "/usr/local/bin/busybox"
) and process.args in ("-i", "-it") 
'''

[[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 == "exec" and
process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox") and
process.entry_leader.same_as_process == false and container.id like "*" and
process.args in (
  "sh", "dash", "bash", "zsh", "fish", "busybox",
  "/bin/sh", "/bin/dash", "/bin/bash", "/bin/zsh", "/bin/fish", "/bin/busybox",
  "/usr/bin/sh", "/usr/bin/dash", "/usr/bin/bash", "/usr/bin/zsh", "/usr/bin/fish", "/usr/bin/busybox",
  "/usr/local/bin/sh", "/usr/local/bin/dash", "/usr/local/bin/bash", "/usr/local/bin/zsh", "/usr/local/bin/fish", "/usr/local/bin/busybox"
) and process.args in ("-i", "-it")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
container.idwildcard
  • *
field:"container.id" kind:wildcard value:"*"
event.actioneq
  • exec
field:"EventType" kind:eq value:"exec"
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.argsin
  • -i
  • -it
  • /bin/bash
  • /bin/busybox
  • /bin/dash
  • /bin/fish
  • /bin/sh
  • /bin/zsh
  • /usr/bin/bash
  • /usr/bin/busybox
  • /usr/bin/dash
  • /usr/bin/fish
  • /usr/bin/sh
  • /usr/bin/zsh
  • /usr/local/bin/bash
  • /usr/local/bin/busybox
  • /usr/local/bin/dash
  • /usr/local/bin/fish
  • /usr/local/bin/sh
  • /usr/local/bin/zsh
  • bash
  • busybox
  • dash
  • fish
  • sh
  • zsh
field:"process.args" kind:in
process.entry_leader.same_as_processeq
  • false transforms: boolean
field:"process.entry_leader.same_as_process" kind:eq value:"false"
process.namein
  • bash
  • busybox
  • csh
  • dash
  • fish
  • ksh
  • sh
  • tcsh
  • zsh
field:"process_basename" kind:in

Killall Execution via Python

#
Source
github.com/elastic/protections-artifacts

Detects when Python executes the Killall binary in order to kill a process.

MITRE ATT&CK Coverage

TacticTechniques
Defense Impairment

Telemetry Coverage

Rule Body

[rule]
description = "Detects when Python executes the Killall binary in order to kill a process."
id = "3e176b0d-3dfd-44ae-8b75-9569463edde5"
license = "Elastic License v2"
name = "Killall Execution via Python"
os_list = ["macos"]
version = "1.0.3"

query = '''
process where event.type == "start" and event.action == "exec" and process.parent.name like~ "python*" and process.name == "killall"
'''

min_endpoint_version = "8.10.2"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.parent.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.10.2"

Stages and Predicates

Stage 1: process

process where event.type == "start" and event.action == "exec" and process.parent.name like~ "python*" and process.name == "killall"

Indicators

These rows show field, operator, and value matches.

Potential NTLM Relay Attack against a Computer Account

#
Status
production
Severity
high
Time window
5s
Sequence by
source.ip, winlog.computer_name
Author
Elastic
Source
github.com/elastic/detection-rules

Detects potential relay attacks by identifying coercion attempts followed by authentication events using a target server's computer account, originating from a different host. This may indicate that an attacker has captured and relayed the server's computer account hash to execute code on behalf of the compromised system.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2025/06/18"
integration = ["system", "windows"]
maturity = "production"
updated_date = "2026/04/22"

[rule]
author = ["Elastic"]
description = """
Detects potential relay attacks by identifying coercion attempts followed by authentication events using a target
server's computer account, originating from a different host. This may indicate that an attacker has captured and
relayed the server's computer account hash to execute code on behalf of the compromised system.
"""
from = "now-9m"
index = ["logs-system.security*", "logs-windows.forwarded*", "winlogbeat-*"]
language = "eql"
license = "Elastic License v2"
name = "Potential NTLM Relay Attack against a Computer Account"
references = [
    "https://github.com/p0dalirius/windows-coerced-authentication-methods",
    "https://www.thehacker.recipes/a-d/movement/mitm-and-coerced-authentications",
    "https://www.synacktiv.com/publications/ntlm-reflection-is-dead-long-live-ntlm-reflection-an-in-depth-analysis-of-cve-2025",
    "https://github.com/Orange-Cyberdefense/ocd-mindmaps/blob/main/excalimap/mindmap/ad/authenticated.md",
]
risk_score = 73
rule_id = "23e5407a-b696-4433-9297-087645f2726c"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Data Source: Active Directory",
    "Use Case: Active Directory Monitoring",
    "Data Source: Windows Security Event Logs",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
sequence by winlog.computer_name, source.ip with maxspan=5s

/* Filter for an event that indicates coercion against known abused named pipes using an account that is not the host */
[file where host.os.type == "windows" and event.code : "5145" and 
    not startswith~(winlog.computer_name, substring(user.name, 0, -1)) and
    file.name : (
        "Spoolss", "netdfs", "lsarpc", "lsass", "netlogon", "samr", "efsrpc", "FssagentRpc",
        "eventlog", "winreg", "srvsvc", "dnsserver", "dhcpserver", "WinsPipe"
    )]

/* Detects a logon attempt using the NTLM protocol resulting from the coercion coming from the same IP address */
[authentication where host.os.type == "windows" and event.code in ("4624", "4625") and
    endswith~(user.name, "$") and winlog.logon.type : "network" and
    winlog.event_data.AuthenticationPackageName : "NTLM" and

    /* Filter for a machine account that matches the hostname */
    startswith~(winlog.computer_name, substring(user.name, 0, -1)) and

    /* Verify if the Source IP belongs to the host */
    not endswith(string(source.ip), string(host.ip)) and
    source.ip != null and source.ip != "::1" and source.ip != "127.0.0.1"]
'''

note = """## Triage and analysis

### Investigating Potential NTLM Relay Attack against a Computer Account

#### Possible investigation steps

- What source events make up the sequence, and do they support a coercion-to-NTLM path?
  - Focus: open Timeline from the sequence alert and recover member events for the alert `host.id` or `host.name` plus `source.ip`; compare source-event `winlog.computer_name`, 5145 `file.name`, `winlog.event_data.TargetUserName`, `winlog.event_data.AuthenticationPackageName`, and `winlog.logon.type`.
  - Hint: use the recovered 5145 Windows Security source event as the primary pipe evidence. If endpoint file telemetry is available for this host and time window, recover the matching `file.*` evidence before using it for interpretation or remediation.
  - Implication: escalate when a coercion-style pipe such as Spoolss, netdfs, efsrpc, FssagentRpc, lsarpc, netlogon, samr, srvsvc, winreg, dnsserver, or WinsPipe is followed within seconds by a type 3 NTLM machine-account logon from the same source; lower concern when the recovered pair matches a recurring proxy, cluster, backup, or management path with the same pipe and auth pattern; close as a non-hit only when source events break the sequence or do not share the same source and target.

- Did the authentication stage succeed, fail, or show weak NTLM handling?
  - Focus: auth-stage `event.code`, `winlog.event_data.Status`, `winlog.event_data.SubStatus`, `winlog.event_data.LmPackageName`, and `winlog.event_data.AuthenticationPackageName`.
  - Implication: urgent escalation is warranted for a 4624 success, success-after-failure pattern, or NTLMv1/weak `winlog.event_data.LmPackageName`; failure-only 4625 activity still supports attempted coercion when the recovered pipe event and source path hold.

- Does the authenticated machine account belong to the target server?
  - Focus: auth-stage `winlog.event_data.TargetUserName` and `winlog.event_data.TargetDomainName` compared with `winlog.computer_name`, `host.name`, and `host.id`.
  - Implication: target-name alignment plus a dollar-suffixed machine account supports relayed or reflected computer-account use; a different host, alias, or cluster identity is an identity mismatch to resolve before disposition, not a benign conclusion by itself.

- Does the source fit a recognized SMB/RPC infrastructure path for this server?
  - Focus: surrounding Windows Security events for the same target, source, and machine account, checking `winlog.event_data.TargetUserName`, `winlog.event_data.AuthenticationPackageName`, `winlog.event_data.LmPackageName`, `winlog.event_data.Status`, and `winlog.event_data.SubStatus`.
  - Hint: use same-source NTLM authentication events to review repeated machine-account logons, success-after-failure patterns, and weak `LmPackageName` values around the alert. $investigate_2
  - Implication: escalate when the source is rare for this server, targets multiple machine accounts, or drives burst failures followed by success; lower concern only when the same source/server/account/auth pattern recurs as a recognized proxy, load-balancer, cluster, backup, or management path. Missing Windows Security history leaves source fit unresolved, not benign.

- Did the same source perform follow-on Windows Security activity after the relay pair?
  - Focus: post-sequence Windows Security events on the same target and source, especially `event.code` 5145, 4624, or 4625 plus `winlog.event_data.TargetUserName`, `winlog.event_data.Status`, and `winlog.event_data.SubStatus`.
  - Hint: review same-source follow-on Windows Security events for repeated share or pipe access and repeated machine-account logons after the sequence. $investigate_3
  - Implication: escalate when the source keeps accessing shares or pipes or repeats machine-account logons after the relay window; absence of follow-on Windows Security events reduces observed scope but does not prove benign execution did not occur.

- If local evidence is suspicious or unresolved, does related alert scope change urgency?
  - Focus: related source-IP alerts for `source.ip`, especially other coercion, machine-account NTLM, service creation, or remote-execution signals. $investigate_0
  - Hint: if source scope remains unclear, check related target-server alerts for the alert `host.id`. $investigate_1
  - Implication: broaden response when the same source or target shows related relay or execution alerts; keep the case locally scoped when related alerts add no new source, target, or follow-on evidence.

- Based on sequence integrity, auth result, identity, source fit, follow-through, and scope, what disposition is supported?
  - Focus: recovered source events, machine-account identity, NTLM handling, recognized infrastructure fit, follow-on Windows Security events, and related-alert scope.
  - Implication: escalate when the recovered sequence holds and the source is unrecognized, successful, weakly protected, or followed by further access; close only when recovered evidence and supported context bind one exact workflow on this host, with outside confirmation when telemetry cannot prove legitimacy; preserve evidence and escalate when results are mixed or visibility is limited.

### False positive analysis

- Clustered file services, SMB/RPC proxies, backup controllers, or management tiers can legitimately front machine-account NTLM traffic through bounded SMB/RPC paths. Confirm by verifying the same `source.ip`, `winlog.computer_name`, `winlog.event_data.TargetUserName`, `winlog.event_data.AuthenticationPackageName`, `winlog.event_data.LmPackageName`, status pattern, 5145 named-pipe/share object, and lack of suspicious follow-on `event.code` activity all converge on the same workflow. If workflow records are unavailable, require historical recurrence of that exact telemetry pattern before closing.
- Before creating an exception, validate recurrence across prior alerts from this rule for the same `source.ip`, `winlog.computer_name`, machine account, NTLM package/version, and 5145 object family. Build the exception from the minimum confirmed workflow pattern; avoid exceptions on source IP alone, target server alone, or dollar-suffixed machine-account names alone.

### Response and remediation

- If confirmed benign, reverse temporary containment and document the exact `source.ip`, `winlog.computer_name`, `winlog.event_data.TargetUserName`, `winlog.event_data.AuthenticationPackageName`, `winlog.event_data.LmPackageName`, `winlog.event_data.Status` or `winlog.event_data.SubStatus`, and 5145 object pattern that proved the workflow. Create a narrow exception only after recurrence proves the same telemetry pattern.
- If suspicious but unconfirmed, preserve the alert document, Timeline member events, recovered 5145 object, authentication result, NTLM package/version, source and target identifiers, status values, and any follow-on Windows Security records before containment. Use reversible containment first, such as temporarily blocking the recovered source from SMB/RPC access to the affected server or isolating the unexpected source host when its role tolerates isolation.
- If confirmed malicious, keep the preserved evidence set attached to the case, then isolate or block the source host and restrict its SMB/RPC access to the affected `winlog.computer_name`. Eradicate only confirmed follow-on services, tasks, shares, or relay tooling identified during investigation; coordinate disruptive actions on domain controllers, cluster nodes, and production servers with identity and infrastructure owners.
- Rotate the affected computer-account secret only after evidence preservation and service-impact review, then review delegated or administrative credentials that could have been exposed or reused through the relayed session. Reduce NTLM exposure, enforce SMB signing and Extended Protection for Authentication where applicable, and disable unneeded coercion-prone RPC services on the affected tier.
- After containment, audit other servers reached from the same `source.ip` and retain the Windows Security telemetry needed to reconstruct the 5145-to-4624/4625 sequence. Document any reflection-style or marshaled-target variant indicators for future case comparison.
"""

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 Detailed File Share](https://ela.st/audit-detailed-file-share)
"""

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "event.code",
    "host.id",
    "host.name",
    "host.ip",
    "source.ip",
    "winlog.computer_name",
    "file.name",
    "winlog.event_data.TargetUserName",
    "winlog.event_data.TargetDomainName",
    "winlog.event_data.AuthenticationPackageName",
    "winlog.event_data.LmPackageName",
    "winlog.logon.type",
    "winlog.event_data.Status",
    "winlog.event_data.SubStatus",
]

[[transform.investigate]]
label = "Alerts associated with this source IP"
description = ""
providers = [
  [
    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
    { excluded = false, field = "source.ip", queryType = "phrase", value = "{{source.ip}}", valueType = "string" }
  ]
]
relativeFrom = "now-48h/h"
relativeTo = "now"

[[transform.investigate]]
label = "Alerts associated with this target server"
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 = "NTLM authentication events from this source to this target"
description = ""
providers = [
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "source.ip", queryType = "phrase", value = "{{source.ip}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4624", valueType = "string" },
    { excluded = false, field = "winlog.event_data.AuthenticationPackageName", queryType = "phrase", value = "NTLM", valueType = "string" }
  ],
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "source.ip", queryType = "phrase", value = "{{source.ip}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4625", valueType = "string" },
    { excluded = false, field = "winlog.event_data.AuthenticationPackageName", queryType = "phrase", value = "NTLM", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[transform.investigate]]
label = "Follow-on Windows Security events from this source to this target"
description = ""
providers = [
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "source.ip", queryType = "phrase", value = "{{source.ip}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "5145", valueType = "string" }
  ],
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "source.ip", queryType = "phrase", value = "{{source.ip}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4624", valueType = "string" }
  ],
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "source.ip", queryType = "phrase", value = "{{source.ip}}", valueType = "string" },
    { excluded = false, field = "event.code", queryType = "phrase", value = "4625", valueType = "string" }
  ]
]
relativeFrom = "now-1h"
relativeTo = "now"

[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1187"
name = "Forced Authentication"
reference = "https://attack.mitre.org/techniques/T1187/"

[[rule.threat.technique]]
id = "T1557"
name = "Adversary-in-the-Middle"
reference = "https://attack.mitre.org/techniques/T1557/"
[[rule.threat.technique.subtechnique]]
id = "T1557.001"
name = "LLMNR/NBT-NS Poisoning and SMB Relay"
reference = "https://attack.mitre.org/techniques/T1557/001/"

[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 5s, correlated by source.ip, winlog.computer_name.

Stage 1: file

[file where host.os.type == "windows" and event.code : "5145" and
    not startswith~(winlog.computer_name, substring(user.name, 0, -1)) and
    file.name : (
        "Spoolss", "netdfs", "lsarpc", "lsass", "netlogon", "samr", "efsrpc", "FssagentRpc",
        "eventlog", "winreg", "srvsvc", "dnsserver", "dhcpserver", "WinsPipe"
    )]

Stage 2: authentication

[authentication where host.os.type == "windows" and event.code in ("4624", "4625") and
    endswith~(user.name, "$") and winlog.logon.type : "network" and
    winlog.event_data.AuthenticationPackageName : "NTLM" and
    startswith~(winlog.computer_name, substring(user.name, 0, -1)) and
    not endswith(string(source.ip), string(host.ip)) and
    source.ip != null and source.ip != "::1" and source.ip != "127.0.0.1"]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.codein
  • 4624 corpus 6 (elastic 3, kusto 3)
  • 4625 corpus 6 (elastic 3, kusto 3)
field:"EventID" kind:in
event.codewildcard
  • 5145 corpus 19 (splunk 17, elastic 2)
field:"EventID" kind:wildcard value:"5145"
file.namewildcard
  • FssagentRpc corpus 3 (elastic 3)
  • Spoolss corpus 3 (elastic 3)
  • WinsPipe corpus 2 (elastic 2)
  • dhcpserver corpus 2 (elastic 2)
  • dnsserver corpus 2 (elastic 2)
  • efsrpc corpus 3 (elastic 3)
  • eventlog corpus 2 (elastic 2)
  • lsarpc corpus 3 (elastic 3)
  • lsass corpus 3 (elastic 3)
  • netdfs corpus 3 (elastic 3)
  • netlogon corpus 3 (elastic 3)
  • samr corpus 3 (elastic 3)
  • srvsvc corpus 2 (elastic 2)
  • winreg corpus 2 (elastic 2)
field:"file.name" kind:wildcard
source.ipis_not_null
  • (no value, null check)
field:"src_ip" kind:is_not_null
source.ipne
  • 127.0.0.1 corpus 22 (elastic 22)
  • ::1 corpus 20 (elastic 20)
field:"src_ip" kind:ne
user.nameends_with
  • $ corpus 5 (elastic 4, kusto 1)
field:"user" kind:ends_with value:"$"
winlog.computer_namestarts_with
  • substring(user.name, 0, (-1)) (expression)
field:"computer_name" kind:starts_with value:"substring(user.name, 0, (-1))"
winlog.event_data.AuthenticationPackageNamewildcard
  • NTLM corpus 7 (sigma 5, elastic 1, splunk 1)
field:"AuthenticationPackageName" kind:wildcard value:"NTLM"
winlog.logon.typewildcard
  • network corpus 30 (splunk 13, sigma 12, elastic 5)
field:"LogonType" kind:wildcard value:"network"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
winlog.computer_namestarts_withsubstring(user.name, 0, (-1))excludes:winlog.computer_name field:"winlog.computer_name" value:"substring(user.name, 0, (-1))"
source.ipends_withstring(host.ip)excludes:source.ip field:"source.ip" value:"string(host.ip)"

Potential Ransomware Note File

#
Time window
1m
Source
github.com/elastic/protections-artifacts

Identifies the execution of Windows utilities to tamper with system recovery settings and subsequently followed by the creation of a file with a name and file header content similar to common Ransomware notes files. This may indicate a Ransomware attack behavior.

MITRE ATT&CK Coverage

TacticTechniques
Impact

Rule Body

[rule]
description = """
Identifies the execution of Windows utilities to tamper with system recovery settings and subsequently followed by the
creation of a file with a name and file header content similar to common Ransomware notes files. This may indicate a
Ransomware attack behavior.
"""
id = "5dba1130-72df-46f1-b581-18d9c866cb23"
license = "Elastic License v2"
name = "Potential Ransomware Note File"
os_list = ["windows"]
version = "1.0.31"

query = '''
sequence with maxspan=60s
 [process where event.action == "start" and
  (
    (process.pe.original_file_name == "wmic.exe" and process.command_line : "*shadowcopy*" and process.command_line : "*delete*") or
    (process.pe.original_file_name == "VSSADMIN.EXE" and process.command_line : "*shadows*" and process.command_line : ("*delete*", "*resize*")) or
    (process.pe.original_file_name == "bcdedit.exe" and process.command_line : ("*bootstatuspolicy*", "*recoveryenabled*")) or
    (process.pe.original_file_name == "WBADMIN.EXE" and process.command_line : ("*catalog*", "*systemstatebackup*") and process.command_line : "*delete*") or
    (process.pe.original_file_name == "iCACLS.EXE" and process.command_line : ("*/deny*S-1-1-0*", "*?:\\*\" /grant*Everyone:F*"))
  ) and
  not process.parent.executable :
                 ("?:\\Program Files (x86)\\Faronics\\Deep Freeze\\*\\DFServ.exe",
                  "C:\\Program Files\\RecoveryConsole\\BackupFP.exe")]
 [file where event.action == "creation" and file.extension : ("hta", "txt", "readme") and
  ( 
   /* ransom note header file content */
    file.Ext.header_bytes :
           ("416c6c20796f75722066696c65*",
            "2d002d002d003d003d003d0020005700",
            "596f7572206e6574776f726b20686173",
            "54006f00200064006500630072007900",
            "3a3a3a204772656574696e6773203a3a",
            "49742773206e6f74206c61746520746f",
            "5f5f5f5f5f202020202020205f5f205f",
            "546865206e6574776f726b206973204c",
            "415454454e54494f4e210d0a0d0a446f",
            "4f6f6f70732120416c6c20796f757220",
            "2d2d2d2d2d2d2d2d2d2d2d205b205765",
            "2a2d2a414c4c2046494c4553204f4e20",
            "3c68746d6c3e0d0a3c686561643e0d0a",
            "3c21444f43545950452068746d6c3e0d",
            "efbbbf3c21444f43545950452068746d",
            "4c6f636b426974*",
            "486920436f6d70616e792c0d0a0d0a45",
            "2020202020207e2b2020202020202020",
            "41766f734c6f636b6572*") or
       /* ransom file name keywords */      
    file.name : ("*read*me*", "*unlock*", "*@*", "*RECOVER*", "*decrypt*", "*restore*file*", "*FILES_BACK*")
  ) and
  not (process.executable : "?:\\Program Files\\TortoiseSVN\\bin\\TSVNCache.exe" and file.name : "README.txt") and
  not (process.executable : "?:\\Windows\\System32\\svchost.exe" and user.id : ("S-1-5-18", "S-1-5-19", "S-1-5-20")) and
  not process.executable :
              ("?:\\WINDOWS\\System32\\msiexec.exe",
               "?:\\WINDOWS\\Sys*\\Robocopy.exe",
               "?:\\Program Files\\7-Zip\\7z.exe",
               "?:\\Windows\\Installer\\MSI*.tmp",
               "?:\\Program Files\\PaperCut Print Deploy Client\\updater.exe",
               "?:\\Program Files (x86)\\Microsoft Visual Studio\\Installer\\setup.exe",
               "?:\\Windows\\ccmcache\\*\\npp.*.exe",
               "?:\\Windows\\OEM\\VmAgentPackageExtractor\\PackageExtractor.exe",
               "?:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
               "?:\\Program Files (x86)\\Kaseya\\*\\KaUsrTsk.exe",
               "?:\\Program Files (x86)\\Kaseya\\*\\AgentMon.exe",
               "?:\\Program Files (x86)\\Egnyte\\Egnyte WebEdit\\client.exe") and
  not file.path : "?:\\Program Files (x86)\\Titus\\BACKUP\\readme.txt" and 
  not (process.executable : "C:\\WindowsAzure\\GuestAgent_*\\WaAppAgent.exe" and file.path : "C:\\WINDOW~1\\GUESTA~*\\FindVolume\\DATALOSS_WARNING_README.txt") and 
  not (process.executable : "C:\\ProWin22\\32bit\\ProSeriesBackgroundUpdater.exe" and file.path : "C:\\ProWin22\\bgupdate\\working\\32bit\\taxdataconversion\\README.txt")
  ]
'''

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

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1485"
name = "Data Destruction"
reference = "https://attack.mitre.org/techniques/T1485/"


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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

[process where event.action == "start" and
  (
    (process.pe.original_file_name == "wmic.exe" and process.command_line : "*shadowcopy*" and process.command_line : "*delete*") or
    (process.pe.original_file_name == "VSSADMIN.EXE" and process.command_line : "*shadows*" and process.command_line : ("*delete*", "*resize*")) or
    (process.pe.original_file_name == "bcdedit.exe" and process.command_line : ("*bootstatuspolicy*", "*recoveryenabled*")) or
    (process.pe.original_file_name == "WBADMIN.EXE" and process.command_line : ("*catalog*", "*systemstatebackup*") and process.command_line : "*delete*") or
    (process.pe.original_file_name == "iCACLS.EXE" and process.command_line : ("*/deny*S-1-1-0*", "*?:\\*\" /grant*Everyone:F*"))
  ) and
  not process.parent.executable :
                 ("?:\\Program Files (x86)\\Faronics\\Deep Freeze\\*\\DFServ.exe",
                  "C:\\Program Files\\RecoveryConsole\\BackupFP.exe")]

Stage 2: file

[file where event.action == "creation" and file.extension : ("hta", "txt", "readme") and
  (
    file.Ext.header_bytes :
           ("416c6c20796f75722066696c65*",
            "2d002d002d003d003d003d0020005700",
            "596f7572206e6574776f726b20686173",
            "54006f00200064006500630072007900",
            "3a3a3a204772656574696e6773203a3a",
            "49742773206e6f74206c61746520746f",
            "5f5f5f5f5f202020202020205f5f205f",
            "546865206e6574776f726b206973204c",
            "415454454e54494f4e210d0a0d0a446f",
            "4f6f6f70732120416c6c20796f757220",
            "2d2d2d2d2d2d2d2d2d2d2d205b205765",
            "2a2d2a414c4c2046494c4553204f4e20",
            "3c68746d6c3e0d0a3c686561643e0d0a",
            "3c21444f43545950452068746d6c3e0d",
            "efbbbf3c21444f43545950452068746d",
            "4c6f636b426974*",
            "486920436f6d70616e792c0d0a0d0a45",
            "2020202020207e2b2020202020202020",
            "41766f734c6f636b6572*") or
    file.name : ("*read*me*", "*unlock*", "*@*", "*RECOVER*", "*decrypt*", "*restore*file*", "*FILES_BACK*")
  ) and
  not (process.executable : "?:\\Program Files\\TortoiseSVN\\bin\\TSVNCache.exe" and file.name : "README.txt") and
  not (process.executable : "?:\\Windows\\System32\\svchost.exe" and user.id : ("S-1-5-18", "S-1-5-19", "S-1-5-20")) and
  not process.executable :
              ("?:\\WINDOWS\\System32\\msiexec.exe",
               "?:\\WINDOWS\\Sys*\\Robocopy.exe",
               "?:\\Program Files\\7-Zip\\7z.exe",
               "?:\\Windows\\Installer\\MSI*.tmp",
               "?:\\Program Files\\PaperCut Print Deploy Client\\updater.exe",
               "?:\\Program Files (x86)\\Microsoft Visual Studio\\Installer\\setup.exe",
               "?:\\Windows\\ccmcache\\*\\npp.*.exe",
               "?:\\Windows\\OEM\\VmAgentPackageExtractor\\PackageExtractor.exe",
               "?:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
               "?:\\Program Files (x86)\\Kaseya\\*\\KaUsrTsk.exe",
               "?:\\Program Files (x86)\\Kaseya\\*\\AgentMon.exe",
               "?:\\Program Files (x86)\\Egnyte\\Egnyte WebEdit\\client.exe") and
  not file.path : "?:\\Program Files (x86)\\Titus\\BACKUP\\readme.txt" and
  not (process.executable : "C:\\WindowsAzure\\GuestAgent_*\\WaAppAgent.exe" and file.path : "C:\\WINDOW~1\\GUESTA~*\\FindVolume\\DATALOSS_WARNING_README.txt") and
  not (process.executable : "C:\\ProWin22\\32bit\\ProSeriesBackgroundUpdater.exe" and file.path : "C:\\ProWin22\\bgupdate\\working\\32bit\\taxdataconversion\\README.txt")
  ]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • creation corpus 50 (elastic 50)
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq
file.Ext.header_byteswildcard
  • 2020202020207e2b2020202020202020
  • 2a2d2a414c4c2046494c4553204f4e20
  • 2d002d002d003d003d003d0020005700
  • 2d2d2d2d2d2d2d2d2d2d2d205b205765
  • 3a3a3a204772656574696e6773203a3a
  • 3c21444f43545950452068746d6c3e0d
  • 3c68746d6c3e0d0a3c686561643e0d0a
  • 415454454e54494f4e210d0a0d0a446f
  • 416c6c20796f75722066696c65*
  • 41766f734c6f636b6572*
  • 486920436f6d70616e792c0d0a0d0a45
  • 49742773206e6f74206c61746520746f
  • 4c6f636b426974*
  • 4f6f6f70732120416c6c20796f757220
  • 54006f00200064006500630072007900
  • 546865206e6574776f726b206973204c
  • 596f7572206e6574776f726b20686173
  • 5f5f5f5f5f202020202020205f5f205f
  • efbbbf3c21444f43545950452068746d
field:"file.Ext.header_bytes" kind:wildcard
file.extensionwildcard
  • hta corpus 20 (elastic 20)
  • readme
  • txt corpus 3 (elastic 3)
field:"file.extension" kind:wildcard
file.namewildcard
  • *@* corpus 3 (elastic 3)
  • *FILES_BACK* corpus 3 (elastic 3)
  • *RECOVER* corpus 3 (elastic 3)
  • *decrypt* corpus 3 (elastic 3)
  • *read*me* corpus 3 (elastic 3)
  • *restore*file* corpus 3 (elastic 3)
  • *unlock*
field:"file.name" kind:wildcard
process.command_linewildcard
  • */deny*S-1-1-0* corpus 2 (elastic 2)
  • *?:\*" /grant*Everyone:F* corpus 2 (elastic 2)
  • *bootstatuspolicy* corpus 10 (elastic 8, sigma 1, splunk 1)
  • *catalog* corpus 12 (elastic 8, sigma 3, splunk 1)
  • *delete* corpus 30 (sigma 16, elastic 8, splunk 6)
  • *recoveryenabled* corpus 10 (elastic 8, sigma 1, splunk 1)
  • *resize* corpus 9 (elastic 5, sigma 3, splunk 1)
  • *shadowcopy* corpus 13 (elastic 7, sigma 3, splunk 3)
  • *shadows* corpus 11 (elastic 8, sigma 3)
  • *systemstatebackup* corpus 8 (elastic 8)
field:"CommandLine" kind:wildcard
process.pe.original_file_nameeq
  • VSSADMIN.EXE corpus 3 (elastic 3)
  • WBADMIN.EXE corpus 3 (elastic 3)
  • bcdedit.exe corpus 4 (elastic 4)
  • iCACLS.EXE corpus 4 (elastic 4)
  • wmic.exe corpus 6 (elastic 6)
field:"OriginalFileName" kind:eq

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.parent.executablewildcard?:\Program Files (x86)\Faronics\Deep Freeze\*\DFServ.exe, C:\Program Files\RecoveryConsole\BackupFP.exeexcludes:process.parent.executable field:"process.parent.executable" value:"?:\Program Files (x86)\Faronics\Deep Freeze\*\DFServ.exe" field:"process.parent.executable" value:"C:\Program Files\RecoveryConsole\BackupFP.exe"
file.nameeqREADME.txtexcludes:file.name field:"file.name" value:"README.txt"
process.executableeq?:\Program Files\TortoiseSVN\bin\TSVNCache.exeexcludes:process.executable field:"process.executable" value:"?:\Program Files\TortoiseSVN\bin\TSVNCache.exe"
file.patheqC:\ProWin22\bgupdate\working\32bit\taxdataconversion\README.txtexcludes:file.path field:"file.path" value:"C:\ProWin22\bgupdate\working\32bit\taxdataconversion\README.txt"
process.executableeqC:\ProWin22\32bit\ProSeriesBackgroundUpdater.exeexcludes:process.executable field:"process.executable" value:"C:\ProWin22\32bit\ProSeriesBackgroundUpdater.exe"
file.pathwildcardC:\WINDOW~1\GUESTA~*\FindVolume\DATALOSS_WARNING_README.txtexcludes:file.path field:"file.path" value:"C:\WINDOW~1\GUESTA~*\FindVolume\DATALOSS_WARNING_README.txt"
process.executablewildcardC:\WindowsAzure\GuestAgent_*\WaAppAgent.exeexcludes:process.executable field:"process.executable" value:"C:\WindowsAzure\GuestAgent_*\WaAppAgent.exe"
process.executableeq?:\Windows\System32\svchost.exeexcludes:process.executable field:"process.executable" value:"?:\Windows\System32\svchost.exe"
user.ideqS-1-5-18, S-1-5-19, S-1-5-20excludes:user.id field:"user.id" value:"S-1-5-18" field:"user.id" value:"S-1-5-19" field:"user.id" value:"S-1-5-20"
file.patheq?:\Program Files (x86)\Titus\BACKUP\readme.txtexcludes:file.path field:"file.path" value:"?:\Program Files (x86)\Titus\BACKUP\readme.txt"
process.executablewildcard?:\WINDOWS\System32\msiexec.exe, ?:\WINDOWS\Sys*\Robocopy.exe, ?:\Program Files\7-Zip\7z.exe, ?:\Windows\Installer\MSI*.tmp, ?:\Program Files\PaperCut Print Deploy Client\updater.exe, ?:\Program Files (x86)\Microsoft Visual Studio\Installer\setup.exe, ?:\Windows\ccmcache\*\npp.*.exe, ?:\Windows\OEM\VmAgentPackageExtractor\PackageExtractor.exe, ?:\Program Files\Google\Chrome\Application\chrome.exe, ?:\Program Files (x86)\Kaseya\*\KaUsrTsk.exe, ?:\Program Files (x86)\Kaseya\*\AgentMon.exe, ?:\Program Files (x86)\Egnyte\Egnyte WebEdit\client.exeexcludes:process.executable

Potential SharpRDP Behavior

#
Status
production
Severity
high
Time window
1m
Sequence by
host.id
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies potential behavior of SharpRDP, which is a tool that can be used to perform authenticated command execution against a remote target via Remote Desktop Protocol (RDP) for the purposes of lateral movement.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Identifies potential behavior of SharpRDP, which is a tool that can be used to perform authenticated command execution
against a remote target via Remote Desktop Protocol (RDP) for the purposes of lateral movement.
"""
from = "now-9m"
index = ["logs-endpoint.events.process-*", "logs-endpoint.events.registry-*", "logs-endpoint.events.network-*"]
language = "eql"
license = "Elastic License v2"
name = "Potential SharpRDP Behavior"
references = [
    "https://posts.specterops.io/revisiting-remote-desktop-lateral-movement-8fb905cb46c3",
    "https://github.com/sbousseaden/EVTX-ATTACK-SAMPLES/blob/master/Lateral%20Movement/LM_sysmon_3_12_13_1_SharpRDP.evtx",
    "https://www.elastic.co/security-labs/hunting-for-lateral-movement-using-event-query-language",
]
risk_score = 73
rule_id = "8c81e506-6e82-4884-9b9a-75d3d252f967"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Lateral Movement",
    "Data Source: Elastic Defend",
    "Resources: Investigation Guide",
]
type = "eql"

query = '''
/* Incoming RDP followed by a new RunMRU string value set to cmd, powershell, taskmgr or tsclient, followed by process execution within 1m */

sequence by host.id with maxspan=1m
  [network where host.os.type == "windows" and event.type == "start" and process.name : "svchost.exe" and destination.port == 3389 and
   network.direction : ("incoming", "ingress") and network.transport == "tcp" and
   source.ip != "127.0.0.1" and source.ip != "::1"
  ]

  [registry where host.os.type == "windows" and event.type == "change" and process.name : "explorer.exe" and
   registry.path : ("HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU\\*") and
   registry.data.strings : ("cmd.exe*", "powershell.exe*", "taskmgr*", "\\\\tsclient\\*.exe\\*")
  ]

  [process where host.os.type == "windows" and event.type == "start" and
   (process.parent.name : ("cmd.exe", "powershell.exe", "taskmgr.exe") or process.args : ("\\\\tsclient\\*.exe")) and
   not process.name : "conhost.exe"
   ]
'''

note = """## Triage and analysis

### Investigating Potential SharpRDP Behavior

#### Possible investigation steps

- Do Timeline source events form one target-side SharpRDP chain?
  - Focus: same-`host.id` events: inbound `source.ip`, RunMRU `registry.data.strings`, child `process.parent.name`, and child `process.command_line`.
  - Hint: record the RunMRU time and child `process.entity_id`; the sequence alert may not preserve stage-specific process or registry fields.
  - Implication: suspicious when non-loopback RDP to port 3389 is followed by a RunMRU shell, Task Manager, or "\\\\tsclient\\" command and child execution; lower suspicion only when all recovered members fit one recognized interactive RDP maintenance action. Missing member events are unresolved, not benign.
- Which RunMRU method launched execution?
  - Focus: RunMRU `registry.path`, `registry.data.strings`, child `process.parent.name`, and child `process.command_line`.
  - Implication: escalate when the RunMRU data selects a shell, Task Manager, or "\\\\tsclient\\" mapped-drive payload and the child process matches that method; normal Run-dialog use is lower risk only when it launches a bounded support utility or installer without shell staging.
- Does the source and user context fit legitimate RDP use on this target?
  - Focus: inbound `source.ip`, launched-process `user.id`, and `user.name`.
  - Implication: escalate when an unusual source uses an end-user or privileged account to start shells, Task Manager, or mapped-drive binaries over RDP; treat a recognized source-user pairing as context only until the RunMRU command and child identity also match the exact RDP task.
- What ran on the target, and does its identity fit the expected RDP workflow?
  - Focus: child `process.executable`, `process.command_line`, `process.code_signature.subject_name`, and `process.code_signature.trusted`.
  - Implication: escalate when the command stages scripts, remote-admin tooling, credential access, or unsigned/user-writable payloads; lower suspicion only when binary identity and command line match the same bounded support or deployment workflow. A trusted signer does not clear suspicious command intent.
- Did the launched child or its descendants create follow-on activity?
  - Focus: same-host endpoint events scoped to recovered child `process.entity_id`: descendant `process.parent.entity_id`, persistence `registry.path`, DNS-event `dns.question.name`, and connection-event `destination.ip`.
  - Hint: query process and registry events tied to the child ID; review DNS and connection events separately because `dns.question.name` and `destination.ip` live on different network event subtypes.
  - Implication: escalate when descendants, registry changes, DNS lookups, or outbound connections show staging, persistence, command-and-control, or more lateral movement; absence of process-scoped DNS or connection telemetry narrows the case only when other evidence is clean. Missing network telemetry is unresolved, not benign.
- Do related target-host alerts change scope?
  - Focus: related RDP, remote-service, credential, and execution alerts for the same `host.id`. $investigate_0
  - Hint: if recovered `source.ip` maps to an enrolled internal asset, follow up on outbound RDP to `destination.port` 3389 from a non-standard RDP client; missing source-host telemetry is unresolved, not benign.
  - Implication: broaden scope when target-host alerts or caveated source-host follow-up show lateral movement beyond one recovered session; keep local only when the suspicious pattern stays confined to this target and the recovered source workflow is otherwise clean.
- Using RDP source, RunMRU command, child lineage and identity, user context, follow-on process/registry/network evidence, and related alerts, escalate RDP-driven command execution or "\\\\tsclient\\" payload launch without a coherent benign workflow; close only when all categories align to one exact recognized RDP workflow and no contradictory host or source evidence remains; preserve artifacts and escalate when evidence is mixed or visibility is incomplete.

### False positive analysis

- Helpdesk or administrator RDP support can trigger when an operator uses Win+R, Task Manager, or a mapped drive to launch a diagnostic or installer. Confirm `source.ip`, `host.id`, `user.id`, `registry.data.strings`, `process.parent.name`, and `process.executable`/`process.command_line` match one task with no suspicious descendant activity. Without telemetry proof, require operator or ticket confirmation; do not close from historical pattern alone.
- TSClient drive-redirection deployment can explain `\\\\tsclient\\` execution only when a known installer or utility launches with stable `process.hash.sha256` or `process.code_signature.subject_name`, matching `process.parent.name`, `source.ip`, and `host.id`. Do not close if registry, DNS, connection, or descendant evidence contradicts it.
- Before creating an exception, anchor on: `source.ip`, `host.id`, `user.id`, exact `registry.data.strings`, `process.parent.name`, and `process.executable` or `process.hash.sha256`. Avoid exceptions on `destination.port`, `process.name`, or RunMRU path alone.

### Response and remediation

- If confirmed benign, reverse any temporary containment and document the exact `source.ip`, `user.id`, `registry.data.strings`, `process.executable`, and `host.id` that established the confirmed workflow. Create an exception only after the exact activity is confirmed and the exception can be pinned to the narrow workflow pattern.
- If suspicious but unconfirmed, export the Timeline source events, capture the launched child process record and parent command line, save the RunMRU value data, and collect staged payloads, persistence key/value snapshots, DNS names, and connection destinations before containment or cleanup.
- If suspicious but unconfirmed, after preservation apply reversible containment: end the active RDP session, temporarily restrict new RDP connections from the recovered `source.ip`, or increase monitoring on the affected `host.id`. Escalate to host isolation only when follow-on activity shows broader abuse and the host role can tolerate isolation.
- If confirmed malicious, isolate the host when feasible, suspend or block the RDP access path or account that established the session, and terminate the launched child process plus suspicious descendants only after preserving the process and command evidence.
- Review other hosts and users tied to the same `source.ip`, `user.id`, or distinctive `process.command_line` pattern before deleting artifacts or resetting credentials so scoping completes before evidence is destroyed.
- Remove staged payloads, persistence changes, or follow-on tooling identified during the investigation, then reset or reissue credentials only when the process, user, and source evidence shows likely account misuse or credential exposure.
- Post-incident hardening: restrict RDP access to controlled jump hosts, limit drive redirection where it is not required, retain process plus registry plus network telemetry on RDP targets, and document any adjacent detection gaps for the detection engineering team.
"""

setup = """## Setup

This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.

Setup instructions: https://ela.st/install-elastic-defend
"""

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "host.name",
    "host.id",
    "host.os.type",
]

[transform]

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

[[rule.threat.technique.subtechnique]]
id = "T1021.001"
name = "Remote Desktop Protocol"
reference = "https://attack.mitre.org/techniques/T1021/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.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"

[[rule.threat.technique.subtechnique]]
id = "T1059.003"
name = "Windows Command Shell"
reference = "https://attack.mitre.org/techniques/T1059/003/"

[rule.threat.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.

Stage 1: network

[network where host.os.type == "windows" and event.type == "start" and process.name : "svchost.exe" and destination.port == 3389 and
   network.direction : ("incoming", "ingress") and network.transport == "tcp" and
   source.ip != "127.0.0.1" and source.ip != "::1"
  ]

Stage 2: registry

[registry where host.os.type == "windows" and event.type == "change" and process.name : "explorer.exe" and
   registry.path : ("HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU\\*") and
   registry.data.strings : ("cmd.exe*", "powershell.exe*", "taskmgr*", "\\\\tsclient\\*.exe\\*")
  ]

Stage 3: process

[process where host.os.type == "windows" and event.type == "start" and
   (process.parent.name : ("cmd.exe", "powershell.exe", "taskmgr.exe") or process.args : ("\\\\tsclient\\*.exe")) and
   not process.name : "conhost.exe"
   ]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
destination.porteq
  • 3389 transforms: number corpus 3 (elastic 3)
field:"DestinationPort" kind:eq value:"3389"
event.typeeq
  • change corpus 89 (elastic 89)
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq
network.directionwildcard
  • incoming corpus 10 (elastic 10)
  • ingress corpus 12 (elastic 12)
field:"Initiated" kind:wildcard
network.transporteq
  • tcp corpus 16 (elastic 16)
field:"Protocol" kind:eq value:"tcp"
process.argswildcard
  • \\tsclient\*.exe
field:"process.args" kind:wildcard value:"\\tsclient\*.exe"
process.namewildcard
  • explorer.exe corpus 21 (elastic 19, splunk 2)
  • svchost.exe corpus 21 (elastic 20, splunk 1)
field:"process_basename" kind:wildcard
process.parent.namewildcard
  • cmd.exe corpus 37 (elastic 32, splunk 4, kusto 1)
  • powershell.exe corpus 37 (elastic 35, splunk 1, kusto 1)
  • taskmgr.exe
field:"parent_process_basename" kind:wildcard
registry.data.stringswildcard
  • \\tsclient\*.exe\*
  • cmd.exe*
  • powershell.exe*
  • taskmgr*
field:"Details" kind:wildcard
registry.pathwildcard
  • HKEY_USERS\*\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU\*
field:"TargetObject" kind:wildcard value:"HKEY_USERS\*\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU\*"
source.ipne
  • 127.0.0.1 corpus 22 (elastic 22)
  • ::1 corpus 20 (elastic 20)
field:"src_ip" kind:ne

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.nameeqconhost.exeexcludes:process.name field:"process.name" value:"conhost.exe"

Potential Shellcode Injection via a WebShell

#
Source
github.com/elastic/protections-artifacts

Identifies the call of code injection related Windows API with suspicious parameters that align with shellcode execution and where the call stack is pointing to an IIS Web application as the source of the injection.

MITRE ATT&CK Coverage

TacticTechniques
Stealth

Rule Body

[rule]
description = """
Identifies the call of code injection related Windows API with suspicious parameters that align with shellcode execution
and where the call stack is pointing to an IIS Web application as the source of the injection.
"""
id = "38da66fc-171f-49f6-9144-bac4abb2f47b"
license = "Elastic License v2"
name = "Potential Shellcode Injection via a WebShell"
os_list = ["windows"]
version = "1.0.7"

query = '''
api where process.name : "w3wp.exe" and
(
 (process.Ext.api.name in ("MapViewOfFile", "MapViewOfFile2", "VirtualAlloc", "VirtualAllocEx", "VirtualProtect", "VirtualProtectEx", "WriteProcessMemory") and
  _arraysearch(process.thread.Ext.call_stack, $entry, $entry.protection_provenance like "app_web_*.dll" and $entry.symbol_info == "Unbacked")) or

 (process.Ext.api.behaviors in ("shellcode", "allocate_shellcode", "execute_shellcode") and
  process.thread.Ext.call_stack_final_user_module.name == "Unbacked" and process.Ext.api.metadata.target_address_name == "Unbacked" and
  process.parent.executable : "C:\\Windows\\System32\\svchost.exe" and
  process.Ext.api.name in ("MapViewOfFile", "MapViewOfFile2", "VirtualAlloc", "VirtualAllocEx", "VirtualProtect", "VirtualProtectEx", "WriteProcessMemory", "connect") and
  (process.thread.Ext.call_stack_final_user_module.protection_provenance_path like "c:\\windows\\microsoft.net\\framework*\\clr.dll" or
   process.thread.Ext.call_stack_final_user_module.protection_provenance == "clr.dll") and
   process.Ext.api.parameters.size != 5 and process.Ext.api.parameters.size != 10 and process.Ext.api.parameters.size != 40 and
   process.Ext.api.behaviors != "hook_api" and
   process.thread.Ext.call_stack_summary in
                ("ntdll.dll|kernelbase.dll|Unbacked",
                 "ntdll.dll|Unbacked",
                 "ntdll.dll|mswsock.dll|ws2_32.dll|Unbacked",
                 "ntdll.dll|kernelbase.dll|kernel32.dll|Unbacked"))
 ) and
 not _arraysearch(process.thread.Ext.call_stack, $entry,
                    $entry.callsite_trailing_bytes like "41c6470c01833d*88bc641c6470c01488b559049895710488d65c85b5e5f415c415d415e415f5dc3001910")
'''

min_endpoint_version = "8.14.2"
[[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 = "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.14.2"

Stages and Predicates

Stage 1: api

api where process.name : "w3wp.exe" and
(
 (process.Ext.api.name in ("MapViewOfFile", "MapViewOfFile2", "VirtualAlloc", "VirtualAllocEx", "VirtualProtect", "VirtualProtectEx", "WriteProcessMemory") and
  _arraysearch(process.thread.Ext.call_stack, $entry, $entry.protection_provenance like "app_web_*.dll" and $entry.symbol_info == "Unbacked")) or

 (process.Ext.api.behaviors in ("shellcode", "allocate_shellcode", "execute_shellcode") and
  process.thread.Ext.call_stack_final_user_module.name == "Unbacked" and process.Ext.api.metadata.target_address_name == "Unbacked" and
  process.parent.executable : "C:\\Windows\\System32\\svchost.exe" and
  process.Ext.api.name in ("MapViewOfFile", "MapViewOfFile2", "VirtualAlloc", "VirtualAllocEx", "VirtualProtect", "VirtualProtectEx", "WriteProcessMemory", "connect") and
  (process.thread.Ext.call_stack_final_user_module.protection_provenance_path like "c:\\windows\\microsoft.net\\framework*\\clr.dll" or
   process.thread.Ext.call_stack_final_user_module.protection_provenance == "clr.dll") and
   process.Ext.api.parameters.size != 5 and process.Ext.api.parameters.size != 10 and process.Ext.api.parameters.size != 40 and
   process.Ext.api.behaviors != "hook_api" and
   process.thread.Ext.call_stack_summary in
                ("ntdll.dll|kernelbase.dll|Unbacked",
                 "ntdll.dll|Unbacked",
                 "ntdll.dll|mswsock.dll|ws2_32.dll|Unbacked",
                 "ntdll.dll|kernelbase.dll|kernel32.dll|Unbacked"))
 ) and
 not _arraysearch(process.thread.Ext.call_stack, $entry,
                    $entry.callsite_trailing_bytes like "41c6470c01833d*88bc641c6470c01488b559049895710488d65c85b5e5f415c415d415e415f5dc3001910")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
process.Ext.api.behaviorsin
  • allocate_shellcode corpus 15 (elastic 15)
  • execute_shellcode corpus 10 (elastic 10)
  • shellcode corpus 15 (elastic 15)
field:"process.Ext.api.behaviors" kind:in
process.Ext.api.behaviorsne
  • hook_api
field:"process.Ext.api.behaviors" kind:ne value:"hook_api"
process.Ext.api.metadata.target_address_nameeq
  • Unbacked corpus 8 (elastic 8)
field:"process.Ext.api.metadata.target_address_name" kind:eq value:"Unbacked"
process.Ext.api.namein
  • MapViewOfFile corpus 24 (elastic 24)
  • MapViewOfFile2 corpus 24 (elastic 24)
  • VirtualAlloc corpus 27 (elastic 27)
  • VirtualAllocEx corpus 22 (elastic 22)
  • VirtualProtect corpus 35 (elastic 35)
  • VirtualProtectEx corpus 29 (elastic 29)
  • WriteProcessMemory corpus 23 (elastic 23)
  • connect corpus 8 (elastic 8)
field:"process.Ext.api.name" kind:in
process.Ext.api.parameters.sizene
  • 10 transforms: number
  • 40 transforms: number
  • 5 transforms: number
field:"process.Ext.api.parameters.size" kind:ne
process.namewildcard
  • w3wp.exe corpus 3 (elastic 3)
field:"process_basename" kind:wildcard value:"w3wp.exe"
process.parent.executablewildcard
  • C:\Windows\System32\svchost.exe corpus 5 (sigma 3, elastic 2)
field:"ParentImage" kind:wildcard value:"C:\Windows\System32\svchost.exe"
process.thread.Ext.call_stack_final_user_module.nameeq
  • Unbacked corpus 21 (elastic 21)
field:"process.thread.Ext.call_stack_final_user_module.name" kind:eq value:"Unbacked"
process.thread.Ext.call_stack_final_user_module.protection_provenanceeq
  • clr.dll corpus 2 (elastic 2)
field:"process.thread.Ext.call_stack_final_user_module.protection_provenance" kind:eq value:"clr.dll"
process.thread.Ext.call_stack_final_user_module.protection_provenance_pathwildcard
  • c:\windows\microsoft.net\framework*\clr.dll corpus 3 (elastic 3)
field:"process.thread.Ext.call_stack_final_user_module.protection_provenance_path" kind:wildcard value:"c:\windows\microsoft.net\framework*\clr.dll"
process.thread.Ext.call_stack_summaryin
  • ntdll.dll|Unbacked corpus 8 (elastic 8)
  • ntdll.dll|kernelbase.dll|Unbacked corpus 11 (elastic 11)
  • ntdll.dll|kernelbase.dll|kernel32.dll|Unbacked corpus 5 (elastic 5)
  • ntdll.dll|mswsock.dll|ws2_32.dll|Unbacked
field:"process.thread.Ext.call_stack_summary" kind:in

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.thread.Ext.call_stackarray_any(no value, null check)excludes:process.thread.Ext.call_stack

Process Discovery Using Built-in Tools

#
Status
production
Kind
building block (feeds higher-level correlation rules; not a standalone alert)
Severity
low
Time window
9m
Author
Elastic
Source
github.com/elastic/detection-rules

This rule identifies the execution of commands that can be used to enumerate running processes. Adversaries may enumerate processes to identify installed applications and security solutions.

MITRE ATT&CK Coverage

TacticTechniques
Discovery

Telemetry Coverage

Rule Body

[metadata]
bypass_bbr_timing = true
creation_date = "2023/07/13"
integration = ["endpoint", "windows", "system"]
maturity = "production"
updated_date = "2025/12/17"

[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
This rule identifies the execution of commands that can be used to enumerate running processes. Adversaries may
enumerate processes to identify installed applications and security solutions.
"""
from = "now-9m"
index = [
    "logs-endpoint.events.process-*",
    "logs-system.security*",
    "logs-windows.*",
    "winlogbeat-*",
]
language = "eql"
license = "Elastic License v2"
name = "Process Discovery Using Built-in Tools"
risk_score = 21
rule_id = "4982ac3e-d0ee-4818-b95d-d9522d689259"
severity = "low"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Discovery",
    "Rule Type: BBR",
    "Data Source: Elastic Defend",
    "Data Source: Windows Security Event Logs",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "windows" and event.type == "start" and process.args != null and 
  not user.id in ("S-1-5-18", "S-1-5-19", "S-1-5-20") and process.parent.executable != null and
  (
   process.name :("PsList.exe", "qprocess.exe") or

   (process.name : "powershell.exe" and process.args : ("*get-process*", "*Win32_Process*") and not process.parent.name in ("openaev-agent.exe", "cmd.exe", "Miro.exe", "Granola.exe", "Wispr Flow.exe")) or

   (process.name : "wmic.exe" and process.args : ("process", "*Win32_Process*") and not process.parent.name in ("Code.exe", "node.exe", "javaw.exe", "java.exe", "asus_framework.exe", "Evernote.exe", "RingCentral.exe", "Avaya Cloud.exe", "Arduino IDE.exe")) or

   (process.name : "tasklist.exe" and process.args_count == 1 and process.parent.args != "tasklist | findstr consent.exe") or

   (process.name : "query.exe" and process.args : ("process", "imagename*", "csv", "/fi"))
  ) and
  not process.working_directory like ("?:\\Program Files*", "D:\\*", "E:\\*") and
  not process.parent.executable like ("?:\\Program Files (x86)\\*.exe", "?:\\Program Files\\*.exe")
'''


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


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

Stages and Predicates

Stage 1: process

process where host.os.type == "windows" and event.type == "start" and process.args != null and 
  not user.id in ("S-1-5-18", "S-1-5-19", "S-1-5-20") and process.parent.executable != null and
  (
   process.name :("PsList.exe", "qprocess.exe") or

   (process.name : "powershell.exe" and process.args : ("*get-process*", "*Win32_Process*") and not process.parent.name in ("openaev-agent.exe", "cmd.exe", "Miro.exe", "Granola.exe", "Wispr Flow.exe")) or

   (process.name : "wmic.exe" and process.args : ("process", "*Win32_Process*") and not process.parent.name in ("Code.exe", "node.exe", "javaw.exe", "java.exe", "asus_framework.exe", "Evernote.exe", "RingCentral.exe", "Avaya Cloud.exe", "Arduino IDE.exe")) or

   (process.name : "tasklist.exe" and process.args_count == 1 and process.parent.args != "tasklist | findstr consent.exe") or

   (process.name : "query.exe" and process.args : ("process", "imagename*", "csv", "/fi"))
  ) and
  not process.working_directory like ("?:\\Program Files*", "D:\\*", "E:\\*") and
  not process.parent.executable like ("?:\\Program Files (x86)\\*.exe", "?:\\Program Files\\*.exe")

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.argsis_not_null
  • (no value, null check)
field:"process.args" kind:is_not_null
process.argswildcard
  • *Win32_Process*
  • *Win32_Process*
  • *get-process*
  • /fi
  • csv
  • imagename*
  • process
field:"process.args" kind:wildcard
process.args_counteq
  • 1 transforms: number corpus 50 (elastic 50)
field:"process.args_count" kind:eq value:"1"
process.namewildcard
  • PsList.exe
  • powershell.exe corpus 187 (elastic 140, splunk 44, kusto 3)
  • qprocess.exe corpus 8 (elastic 8)
  • query.exe corpus 5 (splunk 3, elastic 2)
  • tasklist.exe corpus 11 (elastic 11)
  • wmic.exe corpus 66 (elastic 39, splunk 27)
field:"process_basename" kind:wildcard
process.parent.argsne
  • tasklist | findstr consent.exe
field:"process.parent.args" kind:ne value:"tasklist | findstr consent.exe"
process.parent.executableis_not_null
  • (no value, null check)
field:"ParentImage" kind:is_not_null

Exclusions

The rule actively suppresses these predicates.

Successful AMQP Multi-Queue Purge Burst

#
Status
production
Severity
high
Time window
9m
Group by
client.ip, server.ip
Author
Elastic
Source
github.com/elastic/detection-rules

Identifies multiple successful AMQP queue purge operations issued by the same client to the same broker within a short period. The AMQP queue.purge method removes all messages from a queue that are not awaiting acknowledgment. Purging several distinct queues can indicate deliberate message destruction or disruption after broker credentials are compromised.

Known False Positives

  • Authorized administrators or automation may purge multiple queues during maintenance, testing, disaster recovery, or application resets. Confirm the client, authenticated RabbitMQ user, affected queues, and change window before escalating. Add exceptions for verified administrative sources rather than reducing the queue-cardinality threshold.

MITRE ATT&CK Coverage

TacticTechniques
Impact

Rule Body

[metadata]
creation_date = "2026/07/30"
integration = ["network_traffic"]
maturity = "production"
updated_date = "2026/07/30"

[rule]
author = ["Elastic"]
description = """
Identifies multiple successful AMQP queue purge operations issued by the same client to the same broker within a short
period. The AMQP queue.purge method removes all messages from a queue that are not awaiting acknowledgment. Purging
several distinct queues can indicate deliberate message destruction or disruption after broker credentials are
compromised.
"""
false_positives = [
    """
    Authorized administrators or automation may purge multiple queues during maintenance, testing, disaster recovery, or
    application resets. Confirm the client, authenticated RabbitMQ user, affected queues, and change window before
    escalating. Add exceptions for verified administrative sources rather than reducing the queue-cardinality threshold.
    """,
]
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Successful AMQP Multi-Queue Purge Burst"
note = """## Triage and analysis

### Investigating Successful AMQP Multi-Queue Purge Burst

The AMQP `queue.purge` method removes every ready message from the selected queue. This rule requires successful purge responses for at least three distinct queues from one client-to-broker pair, reducing noise from isolated administrative operations while identifying activity capable of causing broad message loss and application disruption.

### Possible investigation steps

- Review `client.ip`, `server.ip`, `Esql.purge_count`, `Esql.queue_count`, `Esql.queues`, `Esql.first_purge`, and `Esql.last_purge` to determine the scope and timing of the activity.
- Search the underlying `logs-network_traffic.amqp-*` events and confirm that each transaction has `network_traffic.amqp.method: "queue.purge"`, `network_traffic.amqp.no-wait: false`, and `network_traffic.status: "OK"`. Together, these values indicate that Packetbeat observed the broker's `queue.purge-ok` response.
- Use RabbitMQ audit and application logs to identify the authenticated user associated with the client connection. AMQP message properties are not authoritative authentication identities.
- Determine whether the source is approved administration or maintenance automation and whether a documented change authorized purging all affected queues.
- Assess message loss and application impact. Review queue-depth metrics, dead-letter queues, publisher errors, consumer lag, and service availability around the alert.
- Correlate the client and account with `queue.delete`, `exchange.delete`, binding changes, unusual consumers, authentication anomalies, and endpoint alerts.

### False positive analysis

- Queue maintenance, integration testing, disaster-recovery exercises, and application reset workflows may intentionally purge several queues.
- Treat confirmed recurring activity as a benign true positive and scope exceptions to approved client-to-broker pairs or queue names. Broadly excluding `queue.purge` would conceal the destructive behavior this rule is intended to detect.

### Response and remediation

- Revoke or restrict unauthorized RabbitMQ credentials and block the client if the purge was not approved.
- Preserve broker, network, and application evidence before restarting affected services.
- Restore or replay messages from upstream systems, backups, or dead-letter infrastructure where possible.
- Review RabbitMQ permissions and remove unnecessary queue-configuration rights from application accounts.
- Investigate the client host and associated account for credential theft and additional destructive activity.
"""
references = [
    "https://www.rabbitmq.com/amqp-0-9-1-reference",
    "https://attack.mitre.org/techniques/T1485/",
]
risk_score = 73
rule_id = "286614ee-8b72-4ea5-a22d-e0d2ae59d0a9"
setup = """## Setup

This rule requires the Elastic Network Packet Capture integration with the AMQP protocol analyzer enabled and cleartext
AMQP 0.9.1 visibility. AMQP header and method-argument parsing must remain enabled so the method, queue, and transaction
status are populated. AMQP over TLS is opaque to passive capture. RabbitMQ audit logs are required to map the observed
client connection to an authenticated broker identity.
"""
severity = "high"
tags = [
    "Domain: Network",
    "Use Case: Network Security Monitoring",
    "Use Case: Threat Detection",
    "Tactic: Impact",
    "Data Source: Network Packet Capture",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
FROM logs-network_traffic.amqp-*
| WHERE
    data_stream.dataset == "network_traffic.amqp" AND
    network_traffic.amqp.method == "queue.purge" AND
    network_traffic.amqp.`no-wait` == false AND
    network_traffic.status == "OK" AND
    client.ip IS NOT NULL AND
    server.ip IS NOT NULL AND
    network_traffic.amqp.queue IS NOT NULL
| STATS
    Esql.purge_count = COUNT(*),
    Esql.queue_count = COUNT_DISTINCT(network_traffic.amqp.queue),
    Esql.queues = VALUES(network_traffic.amqp.queue),
    Esql.first_purge = MIN(@timestamp),
    Esql.last_purge = MAX(@timestamp)
  BY client.ip, server.ip
| WHERE Esql.purge_count >= 3 AND Esql.queue_count >= 3
| SORT Esql.queue_count DESC, Esql.purge_count DESC
| KEEP client.ip, server.ip, Esql.purge_count, Esql.queue_count, Esql.queues, Esql.first_purge, Esql.last_purge
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1485"
name = "Data Destruction"
reference = "https://attack.mitre.org/techniques/T1485/"


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

Stages and Predicates

Stage 1: from

FROM logs-network_traffic.amqp-*

Stage 2: where

| WHERE
    data_stream.dataset == "network_traffic.amqp" AND
    network_traffic.amqp.method == "queue.purge" AND
    network_traffic.amqp.`no-wait` == false AND
    network_traffic.status == "OK" AND
    client.ip IS NOT NULL AND
    server.ip IS NOT NULL AND
    network_traffic.amqp.queue IS NOT NULL

Stage 3: stats

| STATS
    Esql.purge_count = COUNT(*),
    Esql.queue_count = COUNT_DISTINCT(network_traffic.amqp.queue),
    Esql.queues = VALUES(network_traffic.amqp.queue),
    Esql.first_purge = MIN(@timestamp),
    Esql.last_purge = MAX(@timestamp)
  BY client.ip, server.ip

Stage 4: where

| WHERE Esql.purge_count >= 3 AND Esql.queue_count >= 3

Stage 5: sort

| SORT Esql.queue_count DESC, Esql.purge_count DESC

Stage 6: keep

| KEEP client.ip, server.ip, Esql.purge_count, Esql.queue_count, Esql.queues, Esql.first_purge, Esql.last_purge

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

FieldSource
client.ipKEEP client.ip
server.ipKEEP server.ip
Esql.purge_countKEEP Esql.purge_count
Esql.queue_countKEEP Esql.queue_count
Esql.queuesKEEP Esql.queues
Esql.first_purgeKEEP Esql.first_purge
Esql.last_purgeKEEP Esql.last_purge

Suspicious Antimalware Scan Interface DLL

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

Identifies the creation of the Antimalware Scan Interface (AMSI) DLL in an unusual location. This may indicate an attempt to bypass AMSI by loading a rogue AMSI module instead of the legit one.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2023/01/17"
integration = ["windows", "endpoint", "sentinel_one_cloud_funnel", "m365_defender", "crowdstrike"]
maturity = "production"
updated_date = "2026/04/27"

[rule]
author = ["Elastic"]
description = """
Identifies the creation of the Antimalware Scan Interface (AMSI) DLL in an unusual location. This may indicate an
attempt to bypass AMSI by loading a rogue AMSI module instead of the legit one.
"""
from = "now-9m"
index = [
    "winlogbeat-*",
    "logs-endpoint.events.file-*",
    "logs-windows.sysmon_operational-*",
    "endgame-*",
    "logs-sentinel_one_cloud_funnel.*",
    "logs-m365_defender.event-*",
    "logs-crowdstrike.fdr*",
]
language = "eql"
license = "Elastic License v2"
name = "Suspicious Antimalware Scan Interface DLL"
references = ["https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell"]
risk_score = 73
rule_id = "fa488440-04cc-41d7-9279-539387bf2a17"
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Defense Evasion",
    "Data Source: Elastic Endgame",
    "Resources: Investigation Guide",
    "Data Source: Elastic Defend",
    "Data Source: Sysmon",
    "Data Source: SentinelOne",
    "Data Source: Microsoft Defender XDR",
    "Data Source: Crowdstrike",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
file where host.os.type == "windows" and event.type != "deletion" and file.path != null and
  file.name : ("amsi.dll", "amsi") and 
  event.action != "A process changed a file creation time" and 
  not file.path : (
    "?:\\$SysReset\\CloudImage\\Package_for_RollupFix*\\amsi.dll",
    "?:\\Windows\\system32\\amsi.dll",
    "?:\\Windows\\Syswow64\\amsi.dll",
    "?:\\$WINDOWS.~BT\\*\\amsi.dll",
    "?:\\Windows\\CbsTemp\\*\\amsi.dll",
    "?:\\Windows\\SystemTemp\\*\\amsi.dll",
    "?:\\Windows\\SoftwareDistribution\\Download\\*",
    "?:\\Windows\\WinSxS\\*\\amsi.dll", 
    "?:\\Windows\\servicing\\*\\amsi.dll",
    "\\\\?\\Volume{*}\\Windows\\WinSxS\\*\\amsi.dll", 
    "\\\\?\\Volume{*}\\Windows\\system32\\amsi.dll", 
    "\\\\?\\Volume{*}\\Windows\\syswow64\\amsi.dll",

    /* Crowdstrike specific exclusion as it uses NT Object paths */
    "\\Device\\HarddiskVolume*\\Windows\\system32\\amsi.dll", 
    "\\Device\\HarddiskVolume*\\Windows\\syswow64\\amsi.dll", 
    "\\Device\\HarddiskVolume*\\Windows\\WinSxS\\*\\amsi.dll",
    "\\Device\\HarddiskVolume*\\$SysReset\\CloudImage\\Package_for_RollupFix*\\amsi.dll",
    "\\Device\\HarddiskVolume*\\$WINDOWS.~BT\\*\\amsi.dll", 
    "\\Device\\HarddiskVolume*\\Windows\\SoftwareDistribution\\Download\\*\\amsi.dll", 
    "\\Device\\HarddiskVolume*\\Windows\\CbsTemp\\*\\amsi.dll",
    "\\Device\\HarddiskVolume*\\Windows\\SystemTemp\\*\\amsi.dll", 
    "\\Device\\HarddiskVolume*\\Windows\\servicing\\*\\amsi.dll"
  ) 
'''

note = """## Triage and analysis

### Investigating Suspicious Antimalware Scan Interface DLL
#### Possible investigation steps

- Does the alert show a rogue AMSI DLL in a path a consumer process could reach?
  - Why: AMSI DLL hijack works when amsi.dll is placed where a copied or launched AMSI-aware process searches first; copied PowerShell beside the DLL is a distinctive public-tooling pattern.
  - Focus: `file.path`, `event.action`, and `file.size`, checking writable application, archive extraction, temp, user profile, or working directories outside Windows system and servicing paths.
  - Implication: escalate when the DLL lands beside or inside a reachable search-order path for PowerShell, pwsh, wscript, cscript, mshta, Office, or another AMSI-aware consumer; lower concern only when the path is a lab or package-test directory unreachable by a copied consumer and content evidence fits that test.

- Did the writer and parent context fit that DLL placement?
  - Focus: `process.executable`, `process.command_line`, `process.hash.sha256`, `process.parent.command_line`, `user.id`, and `host.id`.
  - Implication: escalate when the writer is user-writable, script- or shell-launched, newly seen by hash, or started through ad hoc remote administration; lower concern only when writer identity, parent command line, account, and host match one recognized validation workflow. Writer identity alone never clears the placement.

- Did the same writer stage the full DLL-hijack pattern?
  - Focus: file events on the same `host.id` and `process.entity_id`, especially `file.path`, `event.action`, and `file.size`. $investigate_0
  - Implication: escalate when the writer also drops copied powershell.exe, pwsh.exe, a script host, loader script, or renamed DLL beside the new amsi.dll; lower concern only when all artifacts stay inside one controlled validation directory and no consumer starts from it.

- Did a process load or reuse the created DLL path?
  - Focus: with library-load telemetry, pivot from `host.id` plus `file.path` to events where `dll.path` equals the created path, then read loader `process.executable`, `process.command_line`, and `@timestamp`; missing library-load telemetry leaves execution unresolved, not benign. $investigate_1
  - Hint: with only file telemetry, treat later writes or touches of the same `file.path` as reuse clues, not module-load proof.
  - Implication: escalate when PowerShell, pwsh, wscript, cscript, mshta, Office, or another AMSI-aware process loads or reuses the path after creation; unresolved load evidence keeps the case at staging unless other local evidence corroborates abuse.

- Did process execution show use of the hijack directory or another AMSI-bypass path?
  - Focus: process starts on the same `host.id` and `user.id`, especially `process.executable`, `process.command_line`, and `process.parent.command_line`. $investigate_2
  - Implication: escalate when copied PowerShell or a script host starts from the DLL directory, a consumer process uses that directory as its working directory, or command lines show PowerShell v2 launch; lower concern only when execution stays limited to the same controlled validation workflow.

- If local evidence is suspicious or unresolved, is the scope still limited to this host?
  - Focus: related alerts for `host.id`; use `user.id` only when the writer maps to one stable identity, then compare `file.path`, `process.hash.sha256`, and `process.command_line` patterns. $investigate_4
  - Hint: use the user-scoped alert view only after the writer identity is stable enough to test account-level spread. $investigate_3
  - Implication: broaden response when the same host or user shows additional AMSI, suspicious library-load, script-control, persistence, or payload-staging alerts; keep scope local when this is a single bounded placement with no corroborating chain.

- Escalate when suspicious placement has any meaningful corroborator: copied consumer staging, load or reuse, suspicious lineage, execution from the DLL directory, or related evasion alerts. Close only when placement, writer, staging/load result, execution context, and outside validation all bind to authorized testing; preserve artifacts and escalate when evidence is mixed, missing, or contradictory.

### False positive analysis

- Authorized malware-research, red-team, defensive-validation, or package testing that intentionally exercises AMSI search-order behavior is the credible benign path. Confirm `file.path` stays in a lab-only or test-package location; `process.executable`, `process.command_line`, `process.hash.sha256`, `user.id`, and `host.id` map to that workflow; no copied script host launches outside the test; and available load evidence comes from the expected harness. If schedules or inventories are unavailable, require current telemetry to prove the same lab or test harness; use recurrence only for exception design, not closure. If path, writer, load target, or execution context diverges, do not close as benign.
- Before creating an exception, validate the same `process.executable`, `process.hash.sha256`, parent workflow, `file.path`, `user.id`, and `host.id` recur across prior alerts from this rule. Build the exception from that workflow pattern. Avoid exceptions on amsi.dll alone, a directory fragment alone, or the host alone.

### Response and remediation

- If confirmed benign, reverse temporary containment and record which evidence proved the workflow: `file.path`, writer identity, `process.parent.command_line`, account and host scope, staging pattern, and any available load or harness evidence. Create an exception only after that workflow recurs across prior alerts from this rule.
- If suspicious but unconfirmed, preserve the created `file.path`, writer `process.entity_id`, `process.command_line`, parent lineage, sibling staged files, load or reuse evidence when available, and related-alert context before containment. Apply reversible containment tied to the findings, and avoid deleting the DLL until load or reuse is understood.
- If confirmed malicious, isolate the endpoint or contain the responsible account according to the confirmed writer, copied consumer, and execution evidence. Before termination or cleanup, record the writer process details, DLL path, copied consumer executable, load evidence when available, and sibling scripts or payloads; weigh host criticality before isolation.
- Remove the rogue DLL, copied PowerShell or script-host binaries, loader scripts, and sibling payloads found during the investigation, then restore the affected application or working directory from known-good content and verify the legitimate system AMSI locations remain intact.
- If a target process loaded the rogue DLL, capture module and process evidence before restart or termination, then reverse any companion AMSI weakening found through process command lines or staged scripts.
- After containment, scope the same writer identity, DLL path pattern, copied consumer pattern, parent workflow, and companion AMSI-bypass behavior across other hosts, and retain the supporting file, process, and library-load evidence when available.
"""

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

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "event.action",
    "host.name",
    "host.id",
    "user.name",
    "user.id",
    "user.domain",
    "process.entity_id",
    "process.pid",
    "process.executable",
    "process.command_line",
    "file.path",
    "file.name",
    "file.extension",
    "file.size",
]

[transform]

[[transform.investigate]]
label = "File events for the writer process"
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-24h/h"
relativeTo = "now"

[[transform.investigate]]
label = "Events for the created DLL path"
description = ""
providers = [
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "file.path", queryType = "phrase", value = "{{file.path}}", valueType = "string" }
  ],
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "dll.path", queryType = "phrase", value = "{{file.path}}", valueType = "string" }
  ]
]
relativeFrom = "now-24h/h"
relativeTo = "now"

[[transform.investigate]]
label = "Process events for the same host and user"
description = ""
providers = [
  [
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.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"

[[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.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"
[[rule.threat.technique.subtechnique]]
id = "T1574.001"
name = "DLL"
reference = "https://attack.mitre.org/techniques/T1574/001/"

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

Stages and Predicates

Stage 1: file

file where host.os.type == "windows" and event.type != "deletion" and file.path != null and
  file.name : ("amsi.dll", "amsi") and
  event.action != "A process changed a file creation time" and
  not file.path : (
    "?:\\$SysReset\\CloudImage\\Package_for_RollupFix*\\amsi.dll",
    "?:\\Windows\\system32\\amsi.dll",
    "?:\\Windows\\Syswow64\\amsi.dll",
    "?:\\$WINDOWS.~BT\\*\\amsi.dll",
    "?:\\Windows\\CbsTemp\\*\\amsi.dll",
    "?:\\Windows\\SystemTemp\\*\\amsi.dll",
    "?:\\Windows\\SoftwareDistribution\\Download\\*",
    "?:\\Windows\\WinSxS\\*\\amsi.dll",
    "?:\\Windows\\servicing\\*\\amsi.dll",
    "\\\\?\\Volume{*}\\Windows\\WinSxS\\*\\amsi.dll",
    "\\\\?\\Volume{*}\\Windows\\system32\\amsi.dll",
    "\\\\?\\Volume{*}\\Windows\\syswow64\\amsi.dll",
    "\\Device\\HarddiskVolume*\\Windows\\system32\\amsi.dll",
    "\\Device\\HarddiskVolume*\\Windows\\syswow64\\amsi.dll",
    "\\Device\\HarddiskVolume*\\Windows\\WinSxS\\*\\amsi.dll",
    "\\Device\\HarddiskVolume*\\$SysReset\\CloudImage\\Package_for_RollupFix*\\amsi.dll",
    "\\Device\\HarddiskVolume*\\$WINDOWS.~BT\\*\\amsi.dll",
    "\\Device\\HarddiskVolume*\\Windows\\SoftwareDistribution\\Download\\*\\amsi.dll",
    "\\Device\\HarddiskVolume*\\Windows\\CbsTemp\\*\\amsi.dll",
    "\\Device\\HarddiskVolume*\\Windows\\SystemTemp\\*\\amsi.dll",
    "\\Device\\HarddiskVolume*\\Windows\\servicing\\*\\amsi.dll"
  )

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
file.pathwildcard?:\$SysReset\CloudImage\Package_for_RollupFix*\amsi.dll, ?:\Windows\system32\amsi.dll, ?:\Windows\Syswow64\amsi.dll, ?:\$WINDOWS.~BT\*\amsi.dll, ?:\Windows\CbsTemp\*\amsi.dll, ?:\Windows\SystemTemp\*\amsi.dll, ?:\Windows\SoftwareDistribution\Download\*, ?:\Windows\WinSxS\*\amsi.dll, ?:\Windows\servicing\*\amsi.dll, \\?\Volume{*}\Windows\WinSxS\*\amsi.dll, \\?\Volume{*}\Windows\system32\amsi.dll, \\?\Volume{*}\Windows\syswow64\amsi.dll, \Device\HarddiskVolume*\Windows\system32\amsi.dll, \Device\HarddiskVolume*\Windows\syswow64\amsi.dll, \Device\HarddiskVolume*\Windows\WinSxS\*\amsi.dll, \Device\HarddiskVolume*\$SysReset\CloudImage\Package_for_RollupFix*\amsi.dll, \Device\HarddiskVolume*\$WINDOWS.~BT\*\amsi.dll, \Device\HarddiskVolume*\Windows\SoftwareDistribution\Download\*\amsi.dll, \Device\HarddiskVolume*\Windows\CbsTemp\*\amsi.dll, \Device\HarddiskVolume*\Windows\SystemTemp\*\amsi.dll, \Device\HarddiskVolume*\Windows\servicing\*\amsi.dllexcludes:file.path

Suspicious File Overwrite and Modification via Echo

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

Detects the abnormal use of the echo command via a shell to write text into a file located in a suspicious location. Threat actors have used this as a method for creating second stage payloads on systems after initial access has been achieved.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[rule]
description = """
Detects the abnormal use of the echo command via a shell to write text into a file located in a suspicious location.
Threat actors have used this as a method for creating second stage payloads on systems after initial access has been
achieved.
"""
id = "cd3a06dc-58c3-4d57-a03a-0d8991f237e7"
license = "Elastic License v2"
name = "Suspicious File Overwrite and Modification via Echo"
os_list = ["macos"]
version = "1.0.22"

query = '''
sequence by process.entity_id with maxspan=20s
[process where event.type == "start" and event.action == "exec" and 
    process.name in ("bash", "sh", "zsh") and
    process.args == "-c" and
    process.args like~ ("echo* > /.*", 
                        "echo* > /usr/local/bin/*", 
                        "echo* > ~/.*", 
                        "echo* > /tmp/*", 
                        "echo* > /var/root/*", 
                        "echo* > /private/tmp/*", 
                        "echo* > /var/tmp/*", 
                        "echo* > /var/folders/*", 
                        "echo* > /Library/*", 
                        "echo* > /Users/*", 
                        "echo* > ~/*") and 
    process.args_count <= 3 and 
    process.Ext.effective_parent.name == null and 
    not process.parent.executable like ("/Library/Developer/*", "/Applications/Xcode.app/Contents/*")]
[file where event.action == "modification" and process.name in ("sh", "zsh", "bash") and
    not file.path like~ ("/private/tmp/docker-desktop-privileged*/exitcode.txt", "/Users/*/Library/Logs/zoom.us/crashlog/usage.txt")]
'''

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

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.004"
name = "Unix Shell"
reference = "https://attack.mitre.org/techniques/T1059/004/"



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1027"
name = "Obfuscated Files or Information"
reference = "https://attack.mitre.org/techniques/T1027/"


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

[internal]
min_endpoint_version = "8.5.0"

Stages and Predicates

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

Stage 1: process

[process where event.type == "start" and event.action == "exec" and 
    process.name in ("bash", "sh", "zsh") and
    process.args == "-c" and
    process.args like~ ("echo* > /.*", 
                        "echo* > /usr/local/bin/*", 
                        "echo* > ~/.*", 
                        "echo* > /tmp/*", 
                        "echo* > /var/root/*", 
                        "echo* > /private/tmp/*", 
                        "echo* > /var/tmp/*", 
                        "echo* > /var/folders/*", 
                        "echo* > /Library/*", 
                        "echo* > /Users/*", 
                        "echo* > ~/*") and 
    process.args_count <= 3 and 
    process.Ext.effective_parent.name == null and 
    not process.parent.executable like ("/Library/Developer/*", "/Applications/Xcode.app/Contents/*")]

Stage 2: file

[file where event.action == "modification" and process.name in ("sh", "zsh", "bash") and
    not file.path like~ ("/private/tmp/docker-desktop-privileged*/exitcode.txt", "/Users/*/Library/Logs/zoom.us/crashlog/usage.txt")]

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"
process.Ext.effective_parent.nameis_null
  • (no value, null check)
field:"process.Ext.effective_parent.name" kind:is_null
process.argseq
  • -c corpus 91 (elastic 91)
field:"process.args" kind:eq value:"-c"
process.argswildcard
  • echo* > /.*
  • echo* > /Library/*
  • echo* > /Users/*
  • echo* > /private/tmp/*
  • echo* > /tmp/*
  • echo* > /usr/local/bin/*
  • echo* > /var/folders/*
  • echo* > /var/root/*
  • echo* > /var/tmp/*
  • echo* > ~/*
  • echo* > ~/.*
field:"process.args" kind:wildcard
process.args_countle
  • 3 transforms: number corpus 9 (elastic 9)
field:"process.args_count" kind:le value:"3"
process.namein
  • bash corpus 181 (elastic 181)
  • sh corpus 180 (elastic 180)
  • zsh corpus 180 (elastic 180)
field:"process_basename" kind:in

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.parent.executablestarts_with/Library/Developer/, /Applications/Xcode.app/Contents/excludes:process.parent.executable field:"process.parent.executable" value:"/Library/Developer/" field:"process.parent.executable" value:"/Applications/Xcode.app/Contents/"
file.pathwildcard/private/tmp/docker-desktop-privileged*/exitcode.txt, /Users/*/Library/Logs/zoom.us/crashlog/usage.txtexcludes:file.path field:"file.path" value:"/private/tmp/docker-desktop-privileged*/exitcode.txt" field:"file.path" value:"/Users/*/Library/Logs/zoom.us/crashlog/usage.txt"

Suspicious Usage of bpf_probe_write_user Helper

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

This rule monitors the syslog log file for messages related to instances of a program using the "bpf_probe_write_user" helper. The "bpf_probe_write_user" helper is used to write data to user space from a BPF program. Unauthorized use of this helper can be indicative of an eBPF rootkit or other malicious activity.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2025/01/28"
integration = ["system"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
This rule monitors the syslog log file for messages related to instances of a program using the "bpf_probe_write_user" helper.
The "bpf_probe_write_user" helper is used to write data to user space from a BPF program. Unauthorized use of this helper can
be indicative of an eBPF rootkit or other malicious activity.
"""
from = "now-9m"
index = ["logs-system.syslog-*"]
language = "kuery"
license = "Elastic License v2"
name = "Suspicious Usage of bpf_probe_write_user Helper"
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 Usage of bpf_probe_write_user Helper

The `bpf_probe_write_user` helper is a function within the eBPF (extended Berkeley Packet Filter) framework, allowing BPF programs to write data to user space. While useful for legitimate monitoring and debugging, adversaries can exploit it to manipulate user space memory, potentially deploying rootkits or evading defenses. The detection rule monitors syslog entries for kernel processes invoking this helper, flagging potential unauthorized use indicative of malicious activity.

### Possible investigation steps

- Review the syslog entries for the specific message "bpf_probe_write_user" to identify the exact time and context of the event.
- Correlate the timestamp of the alert with other logs and system activities to identify any unusual behavior or patterns around the same time.
- Investigate the process details associated with the kernel at the time of the alert to determine if there are any anomalies or unauthorized modifications.
- Check for any recent changes or installations on the system that could have introduced unauthorized BPF programs.
- Assess the system for signs of persistence mechanisms or defense evasion tactics, as indicated by the MITRE ATT&CK framework references.
- Conduct a thorough review of user accounts and permissions to ensure no unauthorized access or privilege escalation has occurred.
- If suspicious activity is confirmed, isolate the affected system and perform a comprehensive forensic analysis to understand the scope and impact of the potential compromise.

### False positive analysis

- Legitimate monitoring tools may use the bpf_probe_write_user helper for debugging purposes. Identify and whitelist these tools by verifying their source and ensuring they are part of authorized software packages.
- Kernel developers and system administrators might use this helper during system diagnostics or performance tuning. Establish a baseline of expected usage patterns and create exceptions for known maintenance activities.
- Automated scripts or system processes that perform regular system checks could trigger this rule. Review the scripts and processes to confirm their legitimacy and exclude them from alerts if they are verified as safe.
- Security software or intrusion detection systems might utilize this helper as part of their normal operations. Coordinate with your security team to recognize these activities and adjust the rule to prevent unnecessary alerts.

### Response and remediation

- Immediately isolate the affected system from the network to prevent further unauthorized access or data manipulation.
- Terminate any suspicious processes associated with the `bpf_probe_write_user` helper to halt potential malicious activity.
- Conduct a thorough review of recent system changes and installed software to identify unauthorized modifications or installations.
- Restore affected systems from a known good backup to ensure the integrity of user space memory and system files.
- Implement stricter access controls and monitoring on systems with eBPF capabilities to prevent unauthorized use of the `bpf_probe_write_user` helper.
- Escalate the incident to the security operations team for further analysis and to determine if additional systems are affected.
- Update detection mechanisms to include additional indicators of compromise related to eBPF rootkits and similar threats, enhancing future threat detection capabilities.
"""
risk_score = 73
rule_id = "c37ffc64-da75-447e-ad1c-cbc64727b3b8"
setup = """## Setup

This rule requires data coming in from one of the following integrations:
- Filebeat

### Filebeat Setup
Filebeat is a lightweight shipper for forwarding and centralizing log data. Installed as an agent on your servers, Filebeat monitors the log files or locations that you specify, collects log events, and forwards them either to Elasticsearch or Logstash for indexing.

#### The following steps should be executed in order to add the Filebeat for the 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/filebeat/current/setup-repositories.html).
- To run Filebeat on Docker follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/filebeat/current/running-on-docker.html).
- To run Filebeat on Kubernetes follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/filebeat/current/running-on-kubernetes.html).
- For quick start information for Filebeat refer to the [helper guide](https://www.elastic.co/guide/en/beats/filebeat/8.11/filebeat-installation-configuration.html).
- For complete Setup and Run Filebeat information refer to the [helper guide](https://www.elastic.co/guide/en/beats/filebeat/current/setting-up-and-running.html).

#### Rule Specific Setup Note
- This rule requires the Filebeat System Module to be enabled.
- The system module collects and parses logs created by the system logging service of common Unix/Linux based distributions.
- To run the system module of Filebeat on Linux follow the setup instructions in the [helper guide](https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-module-system.html).
"""
severity = "high"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Persistence",
    "Tactic: Defense Evasion",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
host.os.type:linux and data_stream.dataset:"system.syslog" and process.name:kernel and message:"bpf_probe_write_user"
'''

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

[[rule.threat.technique]]
id = "T1547"
name = "Boot or Logon Autostart Execution"
reference = "https://attack.mitre.org/techniques/T1547/"

[[rule.threat.technique.subtechnique]]
id = "T1547.006"
name = "Kernel Modules and Extensions"
reference = "https://attack.mitre.org/techniques/T1547/006/"

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

[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1014"
name = "Rootkit"
reference = "https://attack.mitre.org/techniques/T1014/"

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

Stages and Predicates

Stage 1: query

host.os.type:linux and data_stream.dataset:"system.syslog" and process.name:kernel and message:"bpf_probe_write_user"

Indicators

These rows show field, operator, and value matches.

Suspicious User Keychain DB Access by Unsigned Binary

#
Source
github.com/elastic/protections-artifacts

Detects when an unsigned binary executing from a volume mount or temporary execution path attempts to access the user's keychain file.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[rule]
description = """
Detects when an unsigned binary executing from a volume mount or temporary execution path attempts to access the user's
keychain file.
"""
id = "f2887252-f1ac-4a3d-b551-0efe53852823"
license = "Elastic License v2"
name = "Suspicious User Keychain DB Access by Unsigned Binary"
os_list = ["macos"]
reference = ["https://objective-see.org/blog/blog_0x7A.html"]
version = "1.0.4"

query = '''
file where event.action == "open" and process.executable like ("/Volumes/*", "/private/var/folders/*.app/*") and 
 file.path like~ "/Users/*/Library/Keychains/login.keychain-db" and file.name like "login.keychain-db" and 
 process.code_signature.exists == false
'''

min_endpoint_version = "8.10.2"
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 = "T1555"
name = "Credentials from Password Stores"
reference = "https://attack.mitre.org/techniques/T1555/"
[[threat.technique.subtechnique]]
id = "T1555.001"
name = "Keychain"
reference = "https://attack.mitre.org/techniques/T1555/001/"



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

[internal]
min_endpoint_version = "8.10.2"

Stages and Predicates

Stage 1: file

file where event.action == "open" and process.executable like ("/Volumes/*", "/private/var/folders/*.app/*") and 
 file.path like~ "/Users/*/Library/Keychains/login.keychain-db" and file.name like "login.keychain-db" and 
 process.code_signature.exists == false

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • open corpus 49 (elastic 49)
field:"EventType" kind:eq value:"open"
file.namewildcard
  • login.keychain-db corpus 5 (elastic 5)
field:"file.name" kind:wildcard value:"login.keychain-db"
file.pathwildcard
  • /Users/*/Library/Keychains/login.keychain-db
field:"TargetFilename" kind:wildcard value:"/Users/*/Library/Keychains/login.keychain-db"
process.code_signature.existseq
  • false transforms: boolean corpus 118 (elastic 118)
field:"process.code_signature.exists" kind:eq value:"false"
process.executablewildcard
  • /Volumes/* corpus 2 (elastic 2)
  • /private/var/folders/*.app/*
field:"Image" kind:wildcard

UAC Bypass via Windows Firewall Snap-In Hijack

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

Identifies attempts to bypass User Account Control (UAC) by hijacking the Microsoft Management Console (MMC) Windows Firewall snap-in. Attackers bypass UAC to stealthily execute code with elevated permissions.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2020/10/14"
integration = ["endpoint", "windows", "m365_defender", "sentinel_one_cloud_funnel"]
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 attempts to bypass User Account Control (UAC) by hijacking the Microsoft Management Console (MMC) Windows
Firewall snap-in. Attackers bypass UAC to stealthily execute code with elevated permissions.
"""
from = "now-9m"
index = [
    "winlogbeat-*",
    "logs-endpoint.events.process-*",
    "logs-windows.sysmon_operational-*",
    "endgame-*",
    "logs-m365_defender.event-*",
    "logs-sentinel_one_cloud_funnel.*",
]
language = "eql"
license = "Elastic License v2"
name = "UAC Bypass via Windows Firewall Snap-In Hijack"
note = """## Triage and analysis

### Investigating UAC Bypass via Windows Firewall Snap-In Hijack

Windows User Account Control (UAC) allows a program to elevate its privileges (tracked as low to high integrity levels) to perform a task under administrator-level permissions, possibly by prompting the user for confirmation. UAC can deny an operation under high-integrity enforcement, or allow the user to perform the action if they are in the local administrators group and enter an administrator password when prompted.

For more information about the UAC and how it works, check the [official Microsoft docs page](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works).

This rule identifies attempts to bypass User Account Control (UAC) by hijacking the Microsoft Management Console (MMC) Windows Firewall snap-in. Attackers bypass UAC to stealthily execute code with elevated permissions.

> **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.
- Investigate other alerts associated with the user/host during the past 48 hours.
- Inspect the host for suspicious or abnormal behavior in the alert timeframe.
- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications, and any spawned child processes.
- Examine the host for derived artifacts that indicate suspicious activities:
  - Analyze any suspicious spawned processes 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 is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.

### Response and remediation

- Initiate the incident response process based on the outcome of the triage.
- Isolate the involved host to prevent further post-compromise behavior.
- If the triage identified malware, search the environment for additional compromised hosts.
  - Implement temporary network rules, procedures, and segmentation to contain the malware.
  - Stop suspicious processes.
  - Immediately block the identified indicators of compromise (IoCs).
  - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
- Remove and block malicious artifacts identified during triage.
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
"""

setup = """## Setup

This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.

Setup instructions: https://ela.st/install-elastic-defend

### Additional data sources

This rule also supports the following third-party data sources. For setup instructions, refer to the links below:

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

references = ["https://github.com/AzAgarampur/byeintegrity-uac"]
risk_score = 47
rule_id = "1178ae09-5aff-460a-9f2f-455cd0ac4d8e"
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Privilege Escalation",
    "Tactic: Defense Evasion",
    "Resources: Investigation Guide",
    "Data Source: Elastic Endgame",
    "Data Source: Elastic Defend",
    "Data Source: Sysmon",
    "Data Source: Microsoft Defender XDR",
    "Data Source: SentinelOne",
]
timestamp_override = "event.ingested"
type = "eql"

query = '''
process where host.os.type == "windows" and event.type == "start" and
 process.parent.name == "mmc.exe" and
 /* process.Ext.token.integrity_level_name == "high" can be added in future for tuning */
 /* args of the Windows Firewall SnapIn */
  process.parent.args == "WF.msc" and process.name != "WerFault.exe"
'''


[[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.002"
name = "Bypass User Account Control"
reference = "https://attack.mitre.org/techniques/T1548/002/"

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

[[rule.threat.technique.subtechnique]]
id = "T1218.014"
name = "MMC"
reference = "https://attack.mitre.org/techniques/T1218/014/"

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

Stages and Predicates

Stage 1: process

process where host.os.type == "windows" and event.type == "start" and
 process.parent.name == "mmc.exe" and
  process.parent.args == "WF.msc" and process.name != "WerFault.exe"

Indicators

These rows show field, operator, and value matches.

Untrusted DLL Loaded by a Persistent Program

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

Identifies the load of an untrusted DLL by a persistent trusted binary. This behavior may indicate that an existing persistent program is sideloading a malicious DLL.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the load of an untrusted DLL by a persistent trusted binary. This behavior may indicate that an existing
persistent program is sideloading a malicious DLL.
"""
id = "29007eb1-40d9-47fa-82c0-d862db0586b4"
license = "Elastic License v2"
name = "Untrusted DLL Loaded by a Persistent Program"
os_list = ["windows"]
version = "1.0.29"

query = '''
sequence by process.entity_id with maxspan=1m
 [process where event.action == "start" and
  (
    /* programs started shortly after user logon like startup items */
   (process.parent.executable : "?:\\Windows\\Explorer.exe" and process.Ext.session_info.relative_logon_time <= 100) or

   /* scheduled tasks */
   (process.parent.name : "svchost.exe" and process.parent.args : "Schedule") or

    /* services */
    process.parent.executable : "?:\\Windows\\System32\\services.exe"
   ) and
  not (process.executable :
             ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe", "?:\\Windows\\Explorer.exe",
              "?:\\Windows\\SysWOW64\\*", "?:\\Windows\\System32\\*", "?:\\Windows\\splwow64.exe", "?:\\Windows\\Microsoft.NET\\*") and
              not process.name : ("rundll32.exe", "regsvr32.exe")) and
  process.executable : "C:\\*"]
[library where

   (dll.Ext.relative_file_creation_time < 5000 or dll.Ext.relative_file_name_modify_time < 5000 ) and dll.name : "*.dll" and

   process.code_signature.status :"trusted" and not dll.code_signature.status : ("trusted", "errorCode_endpoint*") and
   dll.hash.sha256 != null and
   not (dll.path : ("?:\\Windows\\Installer\\*",
                   "?:\\Windows\\System32\\DriverStore\\FileRepository\\*",
                   "?:\\Windows\\SysWOW64\\DriverStore\\FileRepository\\*",
                   "?:\\Program Files\\*", "?:\\Program Files (x86)\\*",
                   "?:\\Windows\\assembly\\*",
                   "?:\\Users\\*\\AppData\\Local\\Microsoft\\Windows\\INetCache\\IE\\*") and not process.name : ("regsvr32.exe", "rundll32.exe")) and
   not process.executable : ("?:\\Windows\\SysWOW64\\msiexec.exe", "?:\\Windows\\System32\\msiexec.exe") and
   not dll.hash.sha256 :
             ("8dc562cda7217a3a52db898243de3e2ed68b80e62ddcb8619545ed0b4e7f65a8",
              "06cad1e73c3e0976d3b85df7299891a6bf3fadd166972af431e74673305ea12a",
              "5b175330539eb0911e1cce8c94892fdf728ad67fc593866a7efe80e68b92d86a",
              "2120b986bed79dba90c3fa91f0d1e577e500e9674d9a329307872bfc9eb7db95",
              "c923980eab8e1a02608fa5e01f7658fd4a036180fe2c292cbf886e8a7813e9e6",
              "d6dd5739fc1a02f7cc284b8957d7412800ded255f2c5b5a736f3a2742c046de6",
              "35e5768a738ff9d172bc75261a31dba48b7718c5c71fabffbba7fb1ed5427cb6", 
              "917aa103ee56f1a7929b24b06678aadf15809601bd07ac711c2f1dafb3ecb909", 
              "05fdd60cb09e1d43c0a0097f7ff683d81dfaad2653637686b1668a7d2acc6df9", 
              "fc2b6d0f9e4af39e3892ddbdc08ac13640042112e6188482a7c1fb94454e8f52",
              "63588b11dfee771e6114188883bee4310872a7ebfb8b4c45db8307f9e1791e55",
              "76f19b52423774932831dcba0596989ec56213f9b217a0432fbc122f99704a2a",
              "26dad78da7bfb24d2046f3aa86f6fe779844fb3681baaeeca08404f4ab9fdbf0",
              "33e70c386def674726997fc0a8df13febc54c5aa3338dd20f0b72bc1aa1d9a90",
              "a5a8987d32bde392688bf8edba95b6ba2b6489d9caf7a039ae5b3494db7d0bee",
              "b83d2753d39343fb75f1ce3b81664569a5558fd097ca8d75a43c7adee544ed1f",
              "87adacbb25035066422d22c327516dc1916624b8967dca1bfa271b94e2a7af97",
              "c64d6ce488c9f9b00cda6cdfd2de2a6fa30b40315ac818247d237a925059d7ea",
              "19be195104c5b277f91b05664b192a3be17173bab68d7300098dc7db16538398",
              "d2e14ef693f6a663c2ad657c75b048e4d6febd85b860c652be8711b95ee129aa",
              "b515718a183a845b043c80e6c2647f4ec3620bdf231b7dc5662c96d06ded9290",
              "35bcddf8c134e26faad82ddf7c29c8d043a730b11c1014c66731998be041bd76",
              "7b873201c26858d889cf891464e77b1f3fc478d025e56b75f07ff2b3f64eb209",
              "0cde7b49bc46cc5d2e25e760709431c3ade1c5bf9e1bc5acec239760aff03ccf",
              "ac7c6f8091f06f99ebc9aedd0e6e5d60509e174746510c5c2f6466e9f29d547a",
              "6e0063b9bbf38556325669d975707499add784bd47c7d053b75eb4f076685d1c", 
              "51b82e3994b6ac4279914579bb75d06121e211d24b54a9ce5ad64101778f6fbb", 
              "a6f2eaba3d776ee23976579c83486057b457d2ea17d2555fe2841b7d178237e4", 
              "483e1f8314839fe1280db4c4c74a20d66868535856a8a64da542fee09adeac12", 
              "75b1359a24ea27a8798e0a0ef43ea9ad93e5cdfaf3872d40cb8292a0c8c2c3da", 
              "7bc542b772dd5fe2efdd84b6262eeadf4c03976af4860c9431027f7a26ba20dd", 
              "9c5e11214b88feeefa0649ec267951ec193fd67a3cc0ea08efe83c2542f0465f", 
              "2250edf8968f04eefc1b10502a7a6f5a70461127e892c9f8cdb460d16065b01b", 
              "e2908dec495cc6e621358eb7c5d41403f25eb4bdbf3802866eadea378422d412", 
              "adfe16ce618fd1be24fe5764934f118d4b7d248eb838bc9dedca5114d8f94199") and
   not dll.pe.imphash :
              ("c1c7505e1e6e929ebb6b9100e55b050a",
               "6ed82d3226365ffafff2c57c1935d352",
               "4c12041ee3b1492f5ec25875e818c034",
               "d41d8cd98f00b204e9800998ecf8427e",
               "14338d2168d869b1b53d66354179e8c5",
               "2708b225750647f95ffa2ede70f97f32",
               "dae02f32a21e03ce65412f6e56942daa") and
   not (process.executable :
             ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe", "?:\\Windows\\Explorer.exe",
              "?:\\Windows\\SysWOW64\\*", "?:\\Windows\\System32\\*", "?:\\Windows\\splwow64.exe", "?:\\Windows\\Microsoft.NET\\*") and
              not process.name : ("rundll32.exe", "regsvr32.exe")) and
   not (dll.name : "*.tmp" and not process.name : ("regsvr32.exe", "rundll32.exe")) and

   /* DLL loaded from the process.executable current directory */
   (endswith~(substring(dll.path, 0, length(dll.path) - (length(dll.name) + 1)), substring(process.executable, 0, length(process.executable) - (length(process.name) + 1))) and
    not process.name : ("regsvr32.exe", "rundll32.exe")) and

    not (process.code_signature.subject_name:
                        ("Johannes Schindelin",
                         "Datto Inc",
                         "IFS World Operations AB",
                         "RingCentral, Inc.", "Net Health Systems, Inc.",
                         "Mobatek",
                         "Red Gate Software Ltd",
                         "Signal Messenger, LLC",
                         "KYLIN INC.",
                         "Cricut, Inc.",
                         "Clevercontrol LLC",
                         "VNG CORPORATION",
                         "Connectwise, LLC",
                         "PreVeil, Inc",
                         "RICOH COMPANY,LTD.",
                         "ONELAUNCH TECHNOLOGIES INC.",
                         "Overjet, Inc.",
                         "BANDAI NAMCO Online Inc.",
                         "Jade Software Corporation Limited",
                         "Freshworks Inc",
                         "8bit Solutions LLC",
                         "Canon Electronics Inc.",
                         "OPERIS SAS",
                         "TD Ameritrade",
                         "INTEGRATED COMPUTER SYSTEMS, INC.",
                         "KYOCERA Document Solutions Inc.",
                         "Conexant Systems LLC",
                         "Lenovo",
                         "Paessler AG",
                         "Rainberry Inc",
                         "Fibocom Wireless Inc.",
                         "Fiserv",
                         "Rocket.Chat Technologies Corp.",
                         "Solarwinds Worldwide, LLC",
                         "Milsoft Utility Solutions, Inc.",
                         "Talkdesk, Inc.",
                         "Amazon.com Services LLC",
                         "Canva",
                         "Wondershare Technology Group Co.,Ltd",
                         "Jade Software Corporation Ltd",
                         "Ivanti, Inc.",
                         "The Reynolds and Reynolds Company",
                         "Brother Industries, Ltd.",
                         "FrontApp, Inc.",
                         "The Neat Company, Inc.",
                         "Environmental Systems Research Institute, Inc.",
                         "CANON INC.",
                         "Micro Focus International plc",
                         "Mattermost, Inc.",
                         "PFU Limited",
                         "Poised Inc",
                         "Loom, Inc.",
                         "NUUO Inc.",
                         "Tencent Technology(Shenzhen) Company Limited",
                         "TEDDYSOFT OOD",
                         "The MathWorks, Inc.",
                         "Exclaimer Ltd") and process.code_signature.trusted == true)]
'''

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"
[[threat.technique.subtechnique]]
id = "T1574.001"
name = "DLL"
reference = "https://attack.mitre.org/techniques/T1574/001/"



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

[internal]
min_endpoint_version = "8.10.0"

Stages and Predicates

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

Stage 1: process

[process where event.action == "start" and
  (
   (process.parent.executable : "?:\\Windows\\Explorer.exe" and process.Ext.session_info.relative_logon_time <= 100) or
   (process.parent.name : "svchost.exe" and process.parent.args : "Schedule") or
    process.parent.executable : "?:\\Windows\\System32\\services.exe"
   ) and
  not (process.executable :
             ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe", "?:\\Windows\\Explorer.exe",
              "?:\\Windows\\SysWOW64\\*", "?:\\Windows\\System32\\*", "?:\\Windows\\splwow64.exe", "?:\\Windows\\Microsoft.NET\\*") and
              not process.name : ("rundll32.exe", "regsvr32.exe")) and
  process.executable : "C:\\*"]

Stage 2: library

[library where
   (dll.Ext.relative_file_creation_time < 5000 or dll.Ext.relative_file_name_modify_time < 5000 ) and dll.name : "*.dll" and
   process.code_signature.status :"trusted" and not dll.code_signature.status : ("trusted", "errorCode_endpoint*") and
   dll.hash.sha256 != null and
   not (dll.path : ("?:\\Windows\\Installer\\*",
                   "?:\\Windows\\System32\\DriverStore\\FileRepository\\*",
                   "?:\\Windows\\SysWOW64\\DriverStore\\FileRepository\\*",
                   "?:\\Program Files\\*", "?:\\Program Files (x86)\\*",
                   "?:\\Windows\\assembly\\*",
                   "?:\\Users\\*\\AppData\\Local\\Microsoft\\Windows\\INetCache\\IE\\*") and not process.name : ("regsvr32.exe", "rundll32.exe")) and
   not process.executable : ("?:\\Windows\\SysWOW64\\msiexec.exe", "?:\\Windows\\System32\\msiexec.exe") and
   not dll.hash.sha256 :
             ("8dc562cda7217a3a52db898243de3e2ed68b80e62ddcb8619545ed0b4e7f65a8",
              "06cad1e73c3e0976d3b85df7299891a6bf3fadd166972af431e74673305ea12a",
              "5b175330539eb0911e1cce8c94892fdf728ad67fc593866a7efe80e68b92d86a",
              "2120b986bed79dba90c3fa91f0d1e577e500e9674d9a329307872bfc9eb7db95",
              "c923980eab8e1a02608fa5e01f7658fd4a036180fe2c292cbf886e8a7813e9e6",
              "d6dd5739fc1a02f7cc284b8957d7412800ded255f2c5b5a736f3a2742c046de6",
              "35e5768a738ff9d172bc75261a31dba48b7718c5c71fabffbba7fb1ed5427cb6",
              "917aa103ee56f1a7929b24b06678aadf15809601bd07ac711c2f1dafb3ecb909",
              "05fdd60cb09e1d43c0a0097f7ff683d81dfaad2653637686b1668a7d2acc6df9",
              "fc2b6d0f9e4af39e3892ddbdc08ac13640042112e6188482a7c1fb94454e8f52",
              "63588b11dfee771e6114188883bee4310872a7ebfb8b4c45db8307f9e1791e55",
              "76f19b52423774932831dcba0596989ec56213f9b217a0432fbc122f99704a2a",
              "26dad78da7bfb24d2046f3aa86f6fe779844fb3681baaeeca08404f4ab9fdbf0",
              "33e70c386def674726997fc0a8df13febc54c5aa3338dd20f0b72bc1aa1d9a90",
              "a5a8987d32bde392688bf8edba95b6ba2b6489d9caf7a039ae5b3494db7d0bee",
              "b83d2753d39343fb75f1ce3b81664569a5558fd097ca8d75a43c7adee544ed1f",
              "87adacbb25035066422d22c327516dc1916624b8967dca1bfa271b94e2a7af97",
              "c64d6ce488c9f9b00cda6cdfd2de2a6fa30b40315ac818247d237a925059d7ea",
              "19be195104c5b277f91b05664b192a3be17173bab68d7300098dc7db16538398",
              "d2e14ef693f6a663c2ad657c75b048e4d6febd85b860c652be8711b95ee129aa",
              "b515718a183a845b043c80e6c2647f4ec3620bdf231b7dc5662c96d06ded9290",
              "35bcddf8c134e26faad82ddf7c29c8d043a730b11c1014c66731998be041bd76",
              "7b873201c26858d889cf891464e77b1f3fc478d025e56b75f07ff2b3f64eb209",
              "0cde7b49bc46cc5d2e25e760709431c3ade1c5bf9e1bc5acec239760aff03ccf",
              "ac7c6f8091f06f99ebc9aedd0e6e5d60509e174746510c5c2f6466e9f29d547a",
              "6e0063b9bbf38556325669d975707499add784bd47c7d053b75eb4f076685d1c",
              "51b82e3994b6ac4279914579bb75d06121e211d24b54a9ce5ad64101778f6fbb",
              "a6f2eaba3d776ee23976579c83486057b457d2ea17d2555fe2841b7d178237e4",
              "483e1f8314839fe1280db4c4c74a20d66868535856a8a64da542fee09adeac12",
              "75b1359a24ea27a8798e0a0ef43ea9ad93e5cdfaf3872d40cb8292a0c8c2c3da",
              "7bc542b772dd5fe2efdd84b6262eeadf4c03976af4860c9431027f7a26ba20dd",
              "9c5e11214b88feeefa0649ec267951ec193fd67a3cc0ea08efe83c2542f0465f",
              "2250edf8968f04eefc1b10502a7a6f5a70461127e892c9f8cdb460d16065b01b",
              "e2908dec495cc6e621358eb7c5d41403f25eb4bdbf3802866eadea378422d412",
              "adfe16ce618fd1be24fe5764934f118d4b7d248eb838bc9dedca5114d8f94199") and
   not dll.pe.imphash :
              ("c1c7505e1e6e929ebb6b9100e55b050a",
               "6ed82d3226365ffafff2c57c1935d352",
               "4c12041ee3b1492f5ec25875e818c034",
               "d41d8cd98f00b204e9800998ecf8427e",
               "14338d2168d869b1b53d66354179e8c5",
               "2708b225750647f95ffa2ede70f97f32",
               "dae02f32a21e03ce65412f6e56942daa") and
   not (process.executable :
             ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe", "?:\\Windows\\Explorer.exe",
              "?:\\Windows\\SysWOW64\\*", "?:\\Windows\\System32\\*", "?:\\Windows\\splwow64.exe", "?:\\Windows\\Microsoft.NET\\*") and
              not process.name : ("rundll32.exe", "regsvr32.exe")) and
   not (dll.name : "*.tmp" and not process.name : ("regsvr32.exe", "rundll32.exe")) and
   (endswith~(substring(dll.path, 0, length(dll.path) - (length(dll.name) + 1)), substring(process.executable, 0, length(process.executable) - (length(process.name) + 1))) and
    not process.name : ("regsvr32.exe", "rundll32.exe")) and
    not (process.code_signature.subject_name:
                        ("Johannes Schindelin",
                         "Datto Inc",
                         "IFS World Operations AB",
                         "RingCentral, Inc.", "Net Health Systems, Inc.",
                         "Mobatek",
                         "Red Gate Software Ltd",
                         "Signal Messenger, LLC",
                         "KYLIN INC.",
                         "Cricut, Inc.",
                         "Clevercontrol LLC",
                         "VNG CORPORATION",
                         "Connectwise, LLC",
                         "PreVeil, Inc",
                         "RICOH COMPANY,LTD.",
                         "ONELAUNCH TECHNOLOGIES INC.",
                         "Overjet, Inc.",
                         "BANDAI NAMCO Online Inc.",
                         "Jade Software Corporation Limited",
                         "Freshworks Inc",
                         "8bit Solutions LLC",
                         "Canon Electronics Inc.",
                         "OPERIS SAS",
                         "TD Ameritrade",
                         "INTEGRATED COMPUTER SYSTEMS, INC.",
                         "KYOCERA Document Solutions Inc.",
                         "Conexant Systems LLC",
                         "Lenovo",
                         "Paessler AG",
                         "Rainberry Inc",
                         "Fibocom Wireless Inc.",
                         "Fiserv",
                         "Rocket.Chat Technologies Corp.",
                         "Solarwinds Worldwide, LLC",
                         "Milsoft Utility Solutions, Inc.",
                         "Talkdesk, Inc.",
                         "Amazon.com Services LLC",
                         "Canva",
                         "Wondershare Technology Group Co.,Ltd",
                         "Jade Software Corporation Ltd",
                         "Ivanti, Inc.",
                         "The Reynolds and Reynolds Company",
                         "Brother Industries, Ltd.",
                         "FrontApp, Inc.",
                         "The Neat Company, Inc.",
                         "Environmental Systems Research Institute, Inc.",
                         "CANON INC.",
                         "Micro Focus International plc",
                         "Mattermost, Inc.",
                         "PFU Limited",
                         "Poised Inc",
                         "Loom, Inc.",
                         "NUUO Inc.",
                         "Tencent Technology(Shenzhen) Company Limited",
                         "TEDDYSOFT OOD",
                         "The MathWorks, Inc.",
                         "Exclaimer Ltd") and process.code_signature.trusted == true)]

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
dll.Ext.relative_file_creation_timelt
  • 5000 transforms: number corpus 6 (elastic 6)
field:"dll.Ext.relative_file_creation_time" kind:lt value:"5000"
dll.Ext.relative_file_name_modify_timelt
  • 5000 transforms: number corpus 6 (elastic 6)
field:"dll.Ext.relative_file_name_modify_time" kind:lt value:"5000"
dll.hash.sha256is_not_null
  • (no value, null check)
field:"Hashes" kind:is_not_null
dll.namewildcard
  • *.dll corpus 2 (elastic 2)
field:"dll.name" kind:wildcard value:"*.dll"
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
process.Ext.session_info.relative_logon_timele
  • 100 transforms: number
field:"process.Ext.session_info.relative_logon_time" kind:le value:"100"
process.code_signature.statuswildcard
  • trusted corpus 6 (elastic 6)
field:"SignatureStatus" kind:wildcard value:"trusted"
process.executablewildcard
  • C:\* corpus 16 (elastic 16)
field:"Image" kind:wildcard value:"C:\*"
process.namewildcard
  • regsvr32.exe corpus 74 (elastic 69, splunk 5)
  • rundll32.exe corpus 123 (elastic 100, splunk 23)
field:"process_basename" kind:wildcard
process.parent.argswildcard
  • Schedule corpus 4 (elastic 4)
field:"process.parent.args" kind:wildcard value:"Schedule"
process.parent.executablewildcard
  • ?:\Windows\Explorer.exe corpus 5 (elastic 5)
  • ?:\Windows\System32\services.exe corpus 3 (elastic 3)
field:"ParentImage" kind:wildcard
process.parent.namewildcard
  • svchost.exe corpus 15 (elastic 10, splunk 5)
field:"parent_process_basename" kind:wildcard value:"svchost.exe"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.nameeqrundll32.exe, regsvr32.exeexcludes:process.name field:"process.name" value:"rundll32.exe" field:"process.name" value:"regsvr32.exe"
process.executablewildcard?:\Program Files\*.exe, ?:\Program Files (x86)\*.exe, ?:\Windows\Explorer.exe, ?:\Windows\SysWOW64\*, ?:\Windows\System32\*, ?:\Windows\splwow64.exe, ?:\Windows\Microsoft.NET\*excludes:process.executable
process.nameeqregsvr32.exe, rundll32.exeexcludes:process.name field:"process.name" value:"regsvr32.exe" field:"process.name" value:"rundll32.exe"
dll.nameends_with.tmpexcludes:dll.name field:"dll.name" value:".tmp"
dll.pathwildcard?:\Windows\Installer\*, ?:\Windows\System32\DriverStore\FileRepository\*, ?:\Windows\SysWOW64\DriverStore\FileRepository\*, ?:\Program Files\*, ?:\Program Files (x86)\*, ?:\Windows\assembly\*, ?:\Users\*\AppData\Local\Microsoft\Windows\INetCache\IE\*excludes:dll.path
process.code_signature.subject_nameeqJohannes Schindelin, Datto Inc, IFS World Operations AB, RingCentral, Inc., Net Health Systems, Inc., Mobatek, Red Gate Software Ltd, Signal Messenger, LLC, KYLIN INC., Cricut, Inc., Clevercontrol LLC, VNG CORPORATION, Connectwise, LLC, PreVeil, Inc, RICOH COMPANY,LTD., ONELAUNCH TECHNOLOGIES INC., Overjet, Inc., BANDAI NAMCO Online Inc., Jade Software Corporation Limited, Freshworks Inc, 8bit Solutions LLC, Canon Electronics Inc., OPERIS SAS, TD Ameritrade, INTEGRATED COMPUTER SYSTEMS, INC., KYOCERA Document Solutions Inc., Conexant Systems LLC, Lenovo, Paessler AG, Rainberry Inc, Fibocom Wireless Inc., Fiserv, Rocket.Chat Technologies Corp., Solarwinds Worldwide, LLC, Milsoft Utility Solutions, Inc., Talkdesk, Inc., Amazon.com Services LLC, Canva, Wondershare Technology Group Co.,Ltd, Jade Software Corporation Ltd, Ivanti, Inc., The Reynolds and Reynolds Company, Brother Industries, Ltd., FrontApp, Inc., The Neat Company, Inc., Environmental Systems Research Institute, Inc., CANON INC., Micro Focus International plc, Mattermost, Inc., PFU Limited, Poised Inc, Loom, Inc., NUUO Inc., Tencent Technology(Shenzhen) Company Limited, TEDDYSOFT OOD, The MathWorks, Inc., Exclaimer Ltdexcludes:process.code_signature.subject_name
process.code_signature.trustedeqtrueexcludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true"
dll.code_signature.statuswildcardtrusted, errorCode_endpoint*excludes:dll.code_signature.status field:"dll.code_signature.status" value:"trusted" field:"dll.code_signature.status" value:"errorCode_endpoint*"
dll.hash.sha256eq8dc562cda7217a3a52db898243de3e2ed68b80e62ddcb8619545ed0b4e7f65a8, 06cad1e73c3e0976d3b85df7299891a6bf3fadd166972af431e74673305ea12a, 5b175330539eb0911e1cce8c94892fdf728ad67fc593866a7efe80e68b92d86a, 2120b986bed79dba90c3fa91f0d1e577e500e9674d9a329307872bfc9eb7db95, c923980eab8e1a02608fa5e01f7658fd4a036180fe2c292cbf886e8a7813e9e6, d6dd5739fc1a02f7cc284b8957d7412800ded255f2c5b5a736f3a2742c046de6, 35e5768a738ff9d172bc75261a31dba48b7718c5c71fabffbba7fb1ed5427cb6, 917aa103ee56f1a7929b24b06678aadf15809601bd07ac711c2f1dafb3ecb909, 05fdd60cb09e1d43c0a0097f7ff683d81dfaad2653637686b1668a7d2acc6df9, fc2b6d0f9e4af39e3892ddbdc08ac13640042112e6188482a7c1fb94454e8f52, 63588b11dfee771e6114188883bee4310872a7ebfb8b4c45db8307f9e1791e55, 76f19b52423774932831dcba0596989ec56213f9b217a0432fbc122f99704a2a, 26dad78da7bfb24d2046f3aa86f6fe779844fb3681baaeeca08404f4ab9fdbf0, 33e70c386def674726997fc0a8df13febc54c5aa3338dd20f0b72bc1aa1d9a90, a5a8987d32bde392688bf8edba95b6ba2b6489d9caf7a039ae5b3494db7d0bee, b83d2753d39343fb75f1ce3b81664569a5558fd097ca8d75a43c7adee544ed1f, 87adacbb25035066422d22c327516dc1916624b8967dca1bfa271b94e2a7af97, c64d6ce488c9f9b00cda6cdfd2de2a6fa30b40315ac818247d237a925059d7ea, 19be195104c5b277f91b05664b192a3be17173bab68d7300098dc7db16538398, d2e14ef693f6a663c2ad657c75b048e4d6febd85b860c652be8711b95ee129aa, b515718a183a845b043c80e6c2647f4ec3620bdf231b7dc5662c96d06ded9290, 35bcddf8c134e26faad82ddf7c29c8d043a730b11c1014c66731998be041bd76, 7b873201c26858d889cf891464e77b1f3fc478d025e56b75f07ff2b3f64eb209, 0cde7b49bc46cc5d2e25e760709431c3ade1c5bf9e1bc5acec239760aff03ccf, ac7c6f8091f06f99ebc9aedd0e6e5d60509e174746510c5c2f6466e9f29d547a, 6e0063b9bbf38556325669d975707499add784bd47c7d053b75eb4f076685d1c, 51b82e3994b6ac4279914579bb75d06121e211d24b54a9ce5ad64101778f6fbb, a6f2eaba3d776ee23976579c83486057b457d2ea17d2555fe2841b7d178237e4, 483e1f8314839fe1280db4c4c74a20d66868535856a8a64da542fee09adeac12, 75b1359a24ea27a8798e0a0ef43ea9ad93e5cdfaf3872d40cb8292a0c8c2c3da, 7bc542b772dd5fe2efdd84b6262eeadf4c03976af4860c9431027f7a26ba20dd, 9c5e11214b88feeefa0649ec267951ec193fd67a3cc0ea08efe83c2542f0465f, 2250edf8968f04eefc1b10502a7a6f5a70461127e892c9f8cdb460d16065b01b, e2908dec495cc6e621358eb7c5d41403f25eb4bdbf3802866eadea378422d412, adfe16ce618fd1be24fe5764934f118d4b7d248eb838bc9dedca5114d8f94199excludes:dll.hash.sha256
dll.pe.imphasheqc1c7505e1e6e929ebb6b9100e55b050a, 6ed82d3226365ffafff2c57c1935d352, 4c12041ee3b1492f5ec25875e818c034, d41d8cd98f00b204e9800998ecf8427e, 14338d2168d869b1b53d66354179e8c5, 2708b225750647f95ffa2ede70f97f32, dae02f32a21e03ce65412f6e56942daaexcludes:dll.pe.imphash
process.executableeq?:\Windows\SysWOW64\msiexec.exe, ?:\Windows\System32\msiexec.exeexcludes:process.executable field:"process.executable" value:"?:\Windows\SysWOW64\msiexec.exe" field:"process.executable" value:"?:\Windows\System32\msiexec.exe"

Yum Package Manager Plugin File Creation

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

Detects file creation events in the plugin directories for the Yum package manager. In Linux, Yum (Yellowdog Updater, Modified) is a command-line utility used for handling packages on (by default) Fedora-based systems, providing functions for installing, updating, upgrading, and removing software along with managing package repositories. Attackers can backdoor Yum to gain persistence by injecting malicious code into plugins that Yum runs, thereby ensuring continued unauthorized access or control each time Yum is used for package management.

MITRE ATT&CK Coverage

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Detects file creation events in the plugin directories for the Yum package manager. In Linux, Yum (Yellowdog Updater,
Modified) is a command-line utility used for handling packages on (by default) Fedora-based systems, providing functions
for installing, updating, upgrading, and removing software along with managing package repositories. Attackers can
backdoor Yum to gain persistence by injecting malicious code into plugins that Yum runs, thereby ensuring continued
unauthorized access or control each time Yum is used for package management.
"""
from = "now-9m"
index = ["logs-endpoint.events.file*"]
language = "eql"
license = "Elastic License v2"
name = "Yum Package Manager Plugin 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 Yum Package Manager Plugin File Creation

The Yum package manager is integral to managing software on Fedora-based Linux systems, utilizing plugins to extend its functionality. Adversaries may exploit this by inserting malicious code into these plugins, ensuring persistent access whenever Yum is executed. The detection rule identifies suspicious file creation in plugin directories, excluding legitimate processes and temporary files, to flag potential unauthorized modifications.

### Possible investigation steps

- Review the file creation event details, focusing on the file path to confirm if it matches the plugin directories "/usr/lib/yum-plugins/*" or "/etc/yum/pluginconf.d/*".
- Identify the process responsible for the file creation by examining the process.executable field, ensuring it is not one of the legitimate processes listed in the exclusion criteria.
- Check the file extension and name to ensure it is not a temporary or excluded file type, such as those with extensions "swp", "swpx", "swx", or names starting with ".ansible".
- Investigate the origin and legitimacy of the process by correlating with other system logs or using threat intelligence to determine if the process is known to be associated with malicious activity.
- Assess the file content for any signs of malicious code or unauthorized modifications, especially if the file is a script or configuration file.
- Determine if there have been any recent changes or updates to the system that could explain the file creation, such as legitimate software installations or updates.

### False positive analysis

- Legitimate software updates or installations may trigger file creation events in Yum plugin directories. To handle these, users can create exceptions for known package management processes like rpm, dnf, and yum, which are already included in the rule's exclusion list.
- Temporary files created by text editors or system processes, such as those with extensions like swp, swpx, or swx, can be safely excluded as they are typically non-threatening. Ensure these extensions are part of the exclusion criteria.
- Automation tools like Ansible may generate temporary files in the plugin directories. Users can exclude file names starting with .ansible or .ansible_tmp to prevent false positives from these operations.
- Processes running from specific directories like /nix/store or /var/lib/dpkg are often part of legitimate system operations. Users should verify these paths and include them in the exclusion list if they are part of regular system behavior.
- System maintenance scripts or tools like sed and perl may create temporary files during their execution. Users can exclude these specific process names and file patterns to reduce false alerts.

### Response and remediation

- Isolate the affected system from the network to prevent further unauthorized access or lateral movement by the adversary.
- Terminate any suspicious processes that may be running as a result of the malicious plugin modification to halt any ongoing malicious activity.
- Restore the compromised plugin files from a known good backup to ensure the integrity of the Yum package manager's functionality.
- Conduct a thorough review of user accounts and permissions on the affected system to identify and remove any unauthorized access or privilege escalations.
- Implement file integrity monitoring on the Yum plugin directories to detect any future unauthorized modifications promptly.
- Escalate the incident to the security operations team for further investigation and to determine if additional systems may be affected.
- Update and patch the system to the latest security standards to mitigate any vulnerabilities that may have been exploited by the adversary."""
references = [
    "https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/linux/local/yum_package_manager_persistence.rb",
    "https://www.elastic.co/security-labs/sequel-on-persistence-mechanisms",
]
risk_score = 47
rule_id = "0b15bcad-aff1-4250-a5be-5d1b7eb56d07"
setup = """## Setup

This rule requires data coming in from Elastic Defend.

### Elastic Defend Integration Setup
Elastic Defend is integrated into the Elastic Agent using Fleet. Upon configuration, the integration allows the Elastic Agent to monitor events on your host and send data to the Elastic Security app.

#### Prerequisite Requirements:
- Fleet is required for Elastic Defend.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).

#### The following steps should be executed in order to add the Elastic Defend integration on a Linux System:
- Go to the Kibana home page and click "Add integrations".
- In the query bar, search for "Elastic Defend" and select the integration to see more details about it.
- Click "Add Elastic Defend".
- Configure the integration name and optionally add a description.
- Select the type of environment you want to protect, either "Traditional Endpoints" or "Cloud Workloads".
- Select a configuration preset. Each preset comes with different default settings for Elastic Agent, you can further customize these later by configuring the Elastic Defend integration policy. [Helper guide](https://www.elastic.co/guide/en/security/current/configure-endpoint-integration-policy.html).
- We suggest selecting "Complete EDR (Endpoint Detection and Response)" as a configuration setting, that provides "All events; all preventions"
- Enter a name for the agent policy in "New agent policy name". If other agent policies already exist, you can click the "Existing hosts" tab and select an existing policy instead.
For more details on Elastic Agent configuration settings, refer to the [helper guide](https://www.elastic.co/guide/en/fleet/8.10/agent-policy.html).
- Click "Save and Continue".
- To complete the integration, select "Add Elastic Agent to your hosts" and continue to the next section to install the Elastic Agent on your hosts.
For more details on Elastic Defend refer to the [helper guide](https://www.elastic.co/guide/en/security/current/install-endpoint.html).
"""
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Persistence",
    "Tactic: Defense Evasion",
    "Data Source: Elastic Defend",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
file where host.os.type == "linux" and event.action in ("rename", "creation") and
file.path : ("/usr/lib/yum-plugins/*", "/etc/yum/pluginconf.d/*") and not (
  process.executable in (
    "/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", "/sbin/apk", "/usr/sbin/apk",
    "/usr/local/sbin/apk", "/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/lib/snapd/snapd", "/usr/local/bin/dockerd",
    "/usr/libexec/netplan/generate", "./usr/bin/podman"
  ) or
  process.name in ("yumBackend.py", "crio", "dockerd") or
  file.extension in ("swp", "swpx", "swx") or
  file.Ext.original.name like ".ansible*" or
  file.name like ".ansible_tmp*" or
  process.executable : (
    "/nix/store/*", "/var/lib/dpkg/*", "/tmp/vmis.*", "/snap/*", "/dev/fd/*", "/usr/lib/*", "/usr/libexec/*",
    "/etc/kernel/*"

  ) or
  process.executable == null or
  (process.name == "sed" and file.name : "sed*") or
  (process.name == "perl" and file.name : "e2scrub_all.tmp*")
)
'''

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

[[rule.threat.technique]]
id = "T1543"
name = "Create or Modify System Process"
reference = "https://attack.mitre.org/techniques/T1543/"

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

[[rule.threat.technique.subtechnique]]
id = "T1546.016"
name = "Installer Packages"
reference = "https://attack.mitre.org/techniques/T1546/016/"

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

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

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

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

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

Stages and Predicates

Stage 1: file

file where host.os.type == "linux" and event.action in ("rename", "creation") and
file.path : ("/usr/lib/yum-plugins/*", "/etc/yum/pluginconf.d/*") and not (
  process.executable in (
    "/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", "/sbin/apk", "/usr/sbin/apk",
    "/usr/local/sbin/apk", "/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/lib/snapd/snapd", "/usr/local/bin/dockerd",
    "/usr/libexec/netplan/generate", "./usr/bin/podman"
  ) or
  process.name in ("yumBackend.py", "crio", "dockerd") or
  file.extension in ("swp", "swpx", "swx") or
  file.Ext.original.name like ".ansible*" or
  file.name like ".ansible_tmp*" or
  process.executable : (
    "/nix/store/*", "/var/lib/dpkg/*", "/tmp/vmis.*", "/snap/*", "/dev/fd/*", "/usr/lib/*", "/usr/libexec/*",
    "/etc/kernel/*"

  ) or
  process.executable == null or
  (process.name == "sed" and file.name : "sed*") or
  (process.name == "perl" and file.name : "e2scrub_all.tmp*")
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actionin
  • creation
  • rename
field:"EventType" kind:in
file.pathwildcard
  • /etc/yum/pluginconf.d/*
  • /usr/lib/yum-plugins/*
field:"TargetFilename" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
file.namestarts_withe2scrub_all.tmpexcludes:file.name field:"file.name" value:"e2scrub_all.tmp"
process.nameeqperlexcludes:process.name field:"process.name" value:"perl"
file.namestarts_withsedexcludes:file.name field:"file.name" value:"sed"
process.nameeqsedexcludes:process.name field:"process.name" value:"sed"
file.Ext.original.namestarts_with.ansibleexcludes:file.Ext.original.name field:"file.Ext.original.name" value:".ansible"
file.extensioninswp, swpx, swxexcludes:file.extension field:"file.extension" value:"swp" field:"file.extension" value:"swpx" field:"file.extension" value:"swx"
file.namestarts_with.ansible_tmpexcludes:file.name field:"file.name" value:".ansible_tmp"
process.executablein./usr/bin/podman, /bin/autossl_check, /bin/chef-client, /bin/dnf, /bin/dnf-automatic, /bin/dockerd, /bin/microdnf, /bin/podman, /bin/puppet, /bin/rpm, /bin/snapd, /bin/yum, /opt/puppetlabs/puppet/bin/puppet, /proc/self/exe, /sbin/apk, /usr/bin/autossl_check, /usr/bin/chef-client, /usr/bin/dnf, /usr/bin/dnf-automatic, /usr/bin/dockerd, /usr/bin/microdnf, /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/dockerd, /usr/local/sbin/apk, /usr/sbin/apk, /usr/sbin/dockerdexcludes:process.executable
process.executableis_null(no value, null check)excludes:process.executable
process.executablestarts_with/nix/store/, /var/lib/dpkg/, /tmp/vmis., /snap/, /dev/fd/, /usr/lib/, /usr/libexec/, /etc/kernel/excludes:process.executable
process.nameincrio, dockerd, yumBackend.pyexcludes:process.name field:"process.name" value:"crio" field:"process.name" value:"dockerd" field:"process.name" value:"yumBackend.py"

Back to all Elastic rules