Detection rules › Elastic

Elastic rules: 2w

Attempt to Modify an Okta Network Zone

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

Detects attempts to modify an Okta network zone. Okta network zones can be configured to limit or restrict access to a network based on IP addresses or geolocations. An adversary may attempt to modify, delete, or deactivate an Okta network zone in order to remove or weaken an organization's security controls.

Known False Positives

  • Consider adding exceptions to this rule to filter false positives if Oyour organization's Okta network zones are regularly modified.

MITRE ATT&CK Coverage

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2020/05/21"
integration = ["okta"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
Detects attempts to modify an Okta network zone. Okta network zones can be configured to limit or restrict access to a
network based on IP addresses or geolocations. An adversary may attempt to modify, delete, or deactivate an Okta network
zone in order to remove or weaken an organization's security controls.
"""
false_positives = [
    """
    Consider adding exceptions to this rule to filter false positives if Oyour organization's Okta network zones are
    regularly modified.
    """,
]
index = ["filebeat-*", "logs-okta*"]
language = "kuery"
license = "Elastic License v2"
name = "Attempt to Modify an Okta Network Zone"
note = """## Triage and analysis

### Investigating Attempt to Modify an Okta Network Zone

The modification of an Okta network zone is a critical event as it could potentially allow an adversary to gain unrestricted access to your network. This rule detects attempts to modify, delete, or deactivate an Okta network zone, which may suggest an attempt to remove or weaken an organization's security controls.

#### Possible investigation steps:

- Identify the actor related to the alert by reviewing `okta.actor.id`, `okta.actor.type`, `okta.actor.alternate_id`, or `okta.actor.display_name` fields in the alert.
- Review the `okta.client.user_agent.raw_user_agent` field to understand the device and software used by the actor.
- Examine the `okta.outcome.reason` field for additional context around the modification attempt.
- Check the `okta.outcome.result` field to confirm the network zone modification attempt.
- Check if there are multiple network zone modification attempts from the same actor or IP address (`okta.client.ip`).
- Check for successful logins immediately following the modification attempt.
- Verify whether the actor's activity aligns with typical behavior or if any unusual activity took place around the time of the modification attempt.

### False positive analysis:

- Check if there were issues with the Okta system at the time of the modification attempt. This could indicate a system error rather than a genuine threat activity.
- Check the geographical location (`okta.request.ip_chain.geographical_context`) and time of the modification attempt. If these match the actor's normal behavior, it might be a false positive.
- Verify the actor's administrative rights to ensure they are correctly configured.

### Response and remediation:

- If unauthorized modification is confirmed, initiate the incident response process.
- Immediately lock the affected actor account and require a password change.
- Consider resetting MFA tokens for the actor and require re-enrollment.
- Check if the compromised account was used to access or alter any sensitive data or systems.
- If a specific modification technique was used, ensure your systems are patched or configured to prevent such techniques.
- Assess the criticality of affected services and servers.
- Work with your IT team to minimize the impact on users and maintain business continuity.
- If multiple accounts are affected, consider a broader reset or audit of MFA tokens.
- Implement security best practices [outlined](https://www.okta.com/blog/2019/10/9-admin-best-practices-to-keep-your-org-secure/) by Okta.
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).

## Setup

The Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
references = [
    "https://help.okta.com/en/prod/Content/Topics/Security/network/network-zones.htm",
    "https://developer.okta.com/docs/reference/api/system-log/",
    "https://developer.okta.com/docs/reference/api/event-types/",
    "https://www.elastic.co/security-labs/testing-okta-visibility-and-detection-dorothy",
    "https://www.elastic.co/security-labs/monitoring-okta-threats-with-elastic-security",
    "https://www.elastic.co/security-labs/starter-guide-to-understanding-okta",
]
risk_score = 47
rule_id = "e48236ca-b67a-4b4e-840c-fdc7782bc0c3"
severity = "medium"
tags = [
    "Use Case: Identity and Access Audit",
    "Data Source: Okta",
    "Use Case: Network Security Monitoring",
    "Tactic: Defense Evasion",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:okta.system and event.action:(zone.update or network_zone.rule.disabled or zone.remove_blacklist)
'''


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

[[rule.threat.technique]]
id = "T1484"
name = "Domain or Tenant Policy Modification"
reference = "https://attack.mitre.org/techniques/T1484/"

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

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

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

Stages and Predicates

Stage 1: query

data_stream.dataset:okta.system and event.action:(zone.update or network_zone.rule.disabled or zone.remove_blacklist)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data_stream.dataseteq
  • okta.system corpus 35 (elastic 35)
field:"data_stream.dataset" kind:eq value:"okta.system"
event.actionin
  • network_zone.rule.disabled
  • zone.remove_blacklist
  • zone.update
field:"EventType" kind:in

Container Runtime CLI Execution with Suspicious Arguments

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

Detects execution of container runtime CLI tools (ctr, crictl, nerdctl) with arguments indicating container creation, command execution inside existing containers, image manipulation, or host filesystem mounting. These tools interact directly with the container runtime socket, bypassing the Kubernetes API server, RBAC authorization, admission webhooks, pod security standards, and Kubernetes audit logging entirely. Attackers with host-level access may use these tools to create privileged ghost containers, exec into other pods to steal service account tokens and secrets, pull attacker-controlled images, and destroy evidence, all while remaining invisible to Kubernetes-level monitoring.

Known False Positives

  • Platform automation, node bootstrap, and legitimate break-glass admin sessions may use these CLIs with overlapping arguments. Tune by parent process, user, or host role (worker vs bastion).

MITRE ATT&CK Coverage

TacticTechniques
Execution
Privilege Escalation

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Detects execution of container runtime CLI tools (ctr, crictl, nerdctl) with arguments indicating container creation,
command execution inside existing containers, image manipulation, or host filesystem mounting. These tools interact
directly with the container runtime socket, bypassing the Kubernetes API server, RBAC authorization, admission webhooks,
pod security standards, and Kubernetes audit logging entirely. Attackers with host-level access may use these tools to
create privileged ghost containers, exec into other pods to steal service account tokens and secrets, pull
attacker-controlled images, and destroy evidence, all while remaining invisible to Kubernetes-level monitoring.
"""
false_positives = [
    """
    Platform automation, node bootstrap, and legitimate break-glass admin sessions may use these CLIs with overlapping
    arguments. Tune by parent process, user, or host role (worker vs bastion).
    """,
]
from = "now-9m"
index = ["auditbeat-*", "logs-auditd_manager.auditd-*", "logs-endpoint.events.process*"]
language = "eql"
license = "Elastic License v2"
name = "Container Runtime CLI Execution with Suspicious Arguments"
note = """## Triage and analysis

### Investigating Container Runtime CLI Execution with Suspicious Arguments

Review the full argv list and working directory. Confirm whether the session is interactive, whether the image or bundle
referenced is trusted, and whether bind mounts or privileged flags target host paths such as `/`, `/etc`, or Docker
sockets.

### Possible investigation steps

- Reconstruct the container ID or snapshot key passed to `tasks`, `snapshots`, or `content` subcommands.
- Correlate with file, network, and Kubernetes audit activity for pulls from unusual registries or subsequent pod
  changes.
- Check whether the parent should legitimately be kubelet, containerd, or systemd on that host class.

### Response and remediation

- If unauthorized, isolate the node, revoke credentials available to the session, and hunt for new privileged
  workloads or image imports.
"""
references = [
    "https://attack.mitre.org/techniques/T1609/",
    "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/containerd-ctr-privilege-escalation",
]
risk_score = 47
rule_id = "86b3a245-03de-49a5-ab57-ae44d8f064da"
setup = """## Setup

Requires process execution telemetry with arguments from **Elastic Defend** (`logs-endpoint.events.process*`) and/or
**Auditd Manager** / Auditbeat (`logs-auditd_manager.auditd-*`, `auditbeat-*`).

Ensure exec-related auditing captures full argv for `ctr`, `crictl`, and `nerdctl`. See
https://docs.elastic.co/integrations/auditd_manager
"""
severity = "medium"
tags = [
    "Data Source: Auditd Manager",
    "Data Source: Elastic Defend",
    "Domain: Container",
    "Domain: Endpoint",
    "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 in ("exec", "executed") and
(
  (
    process.name in ("ctr", "crictl", "nerdctl") and
    (
      (process.args == "tasks" and process.args == "exec") or
      (process.args == "run" and process.args in ("--privileged", "--rm", "--mount", "--net-host", "--pid-host")) or
      (process.args == "snapshots" and process.args == "mount")
    )
  ) or
  (
    (process.executable like ("/dev/shm/*", "/tmp/*", "/var/tmp/*") or process.name : ".*") and
    process.args like ("*containerd.sock*", "k8s.io")
  )
) and
not process.parent.executable in (
  "/usr/bin/kubelet", "/usr/local/bin/kubelet",
  "/usr/bin/containerd", "/usr/sbin/containerd",
  "/lib/systemd/systemd", "/usr/lib/systemd/systemd", "/sbin/init"
)
'''

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

[[rule.threat.technique]]
id = "T1609"
name = "Container Administration Command"
reference = "https://attack.mitre.org/techniques/T1609/"

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

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

[[rule.threat.technique]]
id = "T1611"
name = "Escape to Host"
reference = "https://attack.mitre.org/techniques/T1611/"

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

Stages and Predicates

Stage 1: process

process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "executed") and
(
  (
    process.name in ("ctr", "crictl", "nerdctl") and
    (
      (process.args == "tasks" and process.args == "exec") or
      (process.args == "run" and process.args in ("--privileged", "--rm", "--mount", "--net-host", "--pid-host")) or
      (process.args == "snapshots" and process.args == "mount")
    )
  ) or
  (
    (process.executable like ("/dev/shm/*", "/tmp/*", "/var/tmp/*") or process.name : ".*") and
    process.args like ("*containerd.sock*", "k8s.io")
  )
) and
not process.parent.executable in (
  "/usr/bin/kubelet", "/usr/local/bin/kubelet",
  "/usr/bin/containerd", "/usr/sbin/containerd",
  "/lib/systemd/systemd", "/usr/lib/systemd/systemd", "/sbin/init"
)

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.parent.executablein/lib/systemd/systemd, /sbin/init, /usr/bin/containerd, /usr/bin/kubelet, /usr/lib/systemd/systemd, /usr/local/bin/kubelet, /usr/sbin/containerdexcludes:process.parent.executable

Direct Interactive Kubernetes API Request by Unusual Utilities

#
Status
production
Severity
low
Time window
1s
Sequence by
kubernetes.audit.user.extra.authentication.kubernetes.io/pod-name, orchestrator.resource.name
Author
Elastic
Source
github.com/elastic/detection-rules

This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct interactive Kubernetes API requests via unusual utilities. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster.

Known False Positives

  • There is a potential for false positives if the direct interactive Kubernetes API requests are used for legitimate purposes, such as debugging or troubleshooting. It is important to investigate any alerts generated by this rule to determine if they are indicative of malicious activity or part of legitimate container activity.
  • There is a risk of false positives if there are several containers named the same, as the rule may correlate the request to the wrong container.

MITRE ATT&CK Coverage

Telemetry Coverage

PlatformRecord / event type
Kubernetesget-clusterrolebindings: get clusterrolebindings
Kuberneteslist-clusterrolebindings: list clusterrolebindings
Kuberneteswatch-clusterrolebindings: watch clusterrolebindings
Kubernetescreate-clusterrolebindings: create clusterrolebindings
Kubernetesupdate-clusterrolebindings: update clusterrolebindings
Kubernetespatch-clusterrolebindings: patch clusterrolebindings
Kubernetesget-clusterroles: get clusterroles
Kuberneteslist-clusterroles: list clusterroles
Kuberneteswatch-clusterroles: watch clusterroles
Kubernetescreate-clusterroles: create clusterroles
Kubernetesupdate-clusterroles: update clusterroles
Kubernetespatch-clusterroles: patch clusterroles
Kubernetesget-configmaps: get configmaps
Kuberneteslist-configmaps: list configmaps
Kuberneteswatch-configmaps: watch configmaps
Kubernetescreate-configmaps: create configmaps
Kubernetesupdate-configmaps: update configmaps
Kubernetespatch-configmaps: patch configmaps
Kubernetesget-cronjobs: get cronjobs
Kuberneteslist-cronjobs: list cronjobs
Kuberneteswatch-cronjobs: watch cronjobs
Kubernetescreate-cronjobs: create cronjobs
Kubernetesupdate-cronjobs: update cronjobs
Kubernetespatch-cronjobs: patch cronjobs
Kubernetesget-daemonsets: get daemonsets
Kuberneteslist-daemonsets: list daemonsets
Kuberneteswatch-daemonsets: watch daemonsets
Kubernetescreate-daemonsets: create daemonsets
Kubernetesupdate-daemonsets: update daemonsets
Kubernetespatch-daemonsets: patch daemonsets
Kubernetesget-deployments: get deployments
Kuberneteslist-deployments: list deployments
Kuberneteswatch-deployments: watch deployments
Kubernetescreate-deployments: create deployments
Kubernetesupdate-deployments: update deployments
Kubernetespatch-deployments: patch deployments
Kubernetesget-jobs: get jobs
Kuberneteslist-jobs: list jobs
Kuberneteswatch-jobs: watch jobs
Kubernetescreate-jobs: create jobs
Kubernetesupdate-jobs: update jobs
Kubernetespatch-jobs: patch jobs
Kubernetesget-namespaces: get namespaces
Kuberneteslist-namespaces: list namespaces
Kuberneteswatch-namespaces: watch namespaces
Kubernetescreate-namespaces: create namespaces
Kubernetesupdate-namespaces: update namespaces
Kubernetespatch-namespaces: patch namespaces
Kubernetesget-nodes: get nodes
Kuberneteslist-nodes: list nodes
Kuberneteswatch-nodes: watch nodes
Kubernetescreate-nodes: create nodes
Kubernetesupdate-nodes: update nodes
Kubernetespatch-nodes: patch nodes
Kubernetesget-pods: get pods
Kuberneteslist-pods: list pods
Kuberneteswatch-pods: watch pods
Kubernetescreate-pods: create pods
Kubernetesupdate-pods: update pods
Kubernetespatch-pods: patch pods
Kubernetesget-pods-attach: get pods/attach
Kubernetescreate-pods-attach: create pods/attach
Kubernetesget-pods-exec: get pods/exec
Kubernetescreate-pods-exec: create pods/exec
Kubernetesget-pods-log: get pods/log
Kubernetesget-pods-portforward: get pods/portforward
Kubernetescreate-pods-portforward: create pods/portforward
Kubernetesget-rolebindings: get rolebindings
Kuberneteslist-rolebindings: list rolebindings
Kuberneteswatch-rolebindings: watch rolebindings
Kubernetescreate-rolebindings: create rolebindings
Kubernetesupdate-rolebindings: update rolebindings
Kubernetespatch-rolebindings: patch rolebindings
Kubernetesget-roles: get roles
Kuberneteslist-roles: list roles
Kuberneteswatch-roles: watch roles
Kubernetescreate-roles: create roles
Kubernetesupdate-roles: update roles
Kubernetespatch-roles: patch roles
Kubernetesget-secrets: get secrets
Kuberneteslist-secrets: list secrets
Kuberneteswatch-secrets: watch secrets
Kubernetescreate-secrets: create secrets
Kubernetesupdate-secrets: update secrets
Kubernetespatch-secrets: patch secrets
Kubernetescreate-selfsubjectaccessreviews: create selfsubjectaccessreviews
Kubernetescreate-selfsubjectrulesreviews: create selfsubjectrulesreviews
Kubernetesget-serviceaccounts: get serviceaccounts
Kuberneteslist-serviceaccounts: list serviceaccounts
Kuberneteswatch-serviceaccounts: watch serviceaccounts
Kubernetescreate-serviceaccounts: create serviceaccounts
Kubernetesupdate-serviceaccounts: update serviceaccounts
Kubernetespatch-serviceaccounts: patch serviceaccounts
Kubernetesget-statefulsets: get statefulsets
Kuberneteslist-statefulsets: list statefulsets
Kuberneteswatch-statefulsets: watch statefulsets
Kubernetescreate-statefulsets: create statefulsets
Kubernetesupdate-statefulsets: update statefulsets
Kubernetespatch-statefulsets: patch statefulsets
Kubernetescreate-subjectaccessreviews: create subjectaccessreviews

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2026/01/21"
integration = ["cloud_defend", "kubernetes"]
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/04/10"

[rule]
author = ["Elastic"]
description = """
This rule leverages a combination of Defend for Containers and Kubernetes audit logs to detect the execution of direct
interactive Kubernetes API requests via unusual utilities. An adversary may need to execute direct interactive Kubernetes
API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often
used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move
laterally within the cluster.
"""
false_positives = [
    """
    There is a potential for false positives if the direct interactive Kubernetes API requests are used for legitimate purposes,
    such as debugging or troubleshooting. It is important to investigate any alerts generated by this rule to determine
    if they are indicative of malicious activity or part of legitimate container activity.
    """,
    """
    There is a risk of false positives if there are several containers named the same, as the rule may correlate the request
    to the wrong container.
    """,
]
from = "now-6m"
index = ["logs-cloud_defend.process*", "logs-kubernetes.audit_logs-*"]
interval = "5m"
language = "eql"
license = "Elastic License v2"
name = "Direct Interactive Kubernetes API Request by Unusual Utilities"
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 Direct Interactive Kubernetes API Request by Unusual Utilities

This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.

### Possible investigation steps

- Identify the implicated pod, container image, and executing service account, then quickly review its RBAC bindings and effective permissions to determine blast radius.
- Inspect the container’s interactive session context by pulling recent command lines, shell history, environment variables, and mounted service account tokens, and look for custom scripts or binaries issuing HTTP requests.
- Correlate nearby Kubernetes audit entries tied to the same principal and pod to map accessed resources and verbs, noting any exec/attach/portforward or sensitive object interactions across namespaces.
- Review network activity from the pod to the API server and any in-pod proxies, including DNS lookups and outbound connections, to spot nonstandard clients or tunneling behavior.
- If suspicious, isolate the pod or node, capture runtime artifacts (e.g., process memory or HTTP client traffic), revoke and rotate the service account credentials, and verify image provenance and integrity.

### False positive analysis

- An operator interactively attaches to a pod and uses a Python REPL or bash with /dev/tcp to call the in-cluster API for routine troubleshooting (e.g., list pods, read ConfigMaps, or run selfsubjectaccessreviews), producing normal audit entries that match the rule signature.
- A correlation artifact arises when two namespaces have pods with the same name: one pod starts an interactive shell while another independently performs get/list/watch calls, and the 1-second sequence keyed only on pod-name links the unrelated events.

### Response and remediation

- Immediately isolate the implicated pod that issued direct API calls using a nonstandard utility by applying a deny-all egress NetworkPolicy in its namespace (including to kubernetes.default.svc:443), terminating the interactive session, and scaling its owning Deployment/Job/StatefulSet to zero replicas.
- Before teardown, capture a runtime snapshot of the container and node including the binary or script used to query the API (e.g., files under /tmp or /dev/tcp usage), shell history, environment, and the mounted service account token and CA bundle at /var/run/secrets/kubernetes.io/serviceaccount/.
- Revoke access by removing the service account’s RoleBindings/ClusterRoleBindings, deleting all pods that mount that service account to force token rotation, rotating any Secrets and ConfigMaps that were read or created during the window, and deleting any unauthorized Jobs, CronJobs, or Deployments created by the same principal.
- Restore workloads from a known-good image digest, re-enable the Deployment only after image scan and integrity checks pass, and monitor subsequent Kubernetes audit logs for pods/exec, portforward, and access to secrets across the affected namespaces.
- Escalate to incident response leadership and consider cluster-wide containment if audit logs show create/patch of ClusterRoleBindings, access to secrets outside the workload’s namespace, or use of pods/exec to pivot into other nodes or system namespaces such as kube-system.
- Harden access by enforcing least-privilege RBAC that denies pods/exec and attach for application service accounts, setting automountServiceAccountToken: false on workloads that do not need it, restricting egress to the API server with NetworkPolicies, and requiring just-in-time break-glass roles for interactive access.
"""
risk_score = 21
rule_id = "02275e05-57a1-46ab-a443-7fb444da6b28"
severity = "low"
tags = [
    "Data Source: Elastic Defend for Containers",
    "Data Source: Kubernetes",
    "Domain: Container",
    "Domain: Kubernetes",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Execution",
    "Tactic: Discovery",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "eql"
query = '''
sequence with maxspan=1s
  [process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and process.interactive == true and
  container.id like "*" and
  /* Covered by the rule "Direct Interactive Kubernetes API Request by Common Utilities" */
  not (
     process.name in ("wget", "curl", "openssl", "socat", "ncat", "kubectl") or
     (
       /* Account for tools that execute utilities as a subprocess, in this case the target utility name will appear as a process arg */
       process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox") and
       process.args in (
         "wget", "/bin/wget", "/usr/bin/wget", "/usr/local/bin/wget",
         "ssl_client", "/bin/ssl_client", "/usr/bin/ssl_client", "/usr/local/bin/ssl_client",
         "curl", "/bin/curl", "/usr/bin/curl", "/usr/local/bin/curl",
         "openssl", "/bin/openssl", "/usr/bin/openssl", "/usr/local/bin/openssl",
         "socat", "/bin/socat", "/usr/bin/socat", "/usr/local/bin/socat",
         "ncat", "/bin/ncat", "/usr/bin/ncat", "/usr/local/bin/ncat",
         "kubectl", "/bin/kubectl", "/usr/bin/kubectl", "/usr/local/bin/kubectl"
       ) and
       /* default exclusion list to not FP on default multi-process commands */
       not process.args in (
         "which", "/bin/which", "/usr/bin/which", "/usr/local/bin/which",
         "man", "/bin/man", "/usr/bin/man", "/usr/local/bin/man",
         "chmod", "/bin/chmod", "/usr/bin/chmod", "/usr/local/bin/chmod",
         "chown", "/bin/chown", "/usr/bin/chown", "/usr/local/bin/chown"
       )
     ) or
     /* General exclusions for utilities that are not typically used for Kubernetes API requests */
     process.name in (
       "sleep", "head", "tail", "apk", "apt", "apt-get", "dnf", "microdnf", "yum", "zypper", "tdnf",
       "pacman", "rpm", "dpkg"
     )
   )] by orchestrator.resource.name
  [any where
     data_stream.dataset == "kubernetes.audit_logs" and
     kubernetes.audit.stage in ("ResponseStarted","ResponseComplete") and
     kubernetes.audit.verb in ("get", "list", "watch", "create", "patch", "update") and
     (
       kubernetes.audit.objectRef.resource in (
         "pods", "secrets", "serviceaccounts", "configmaps",
         "roles", "rolebindings", "clusterroles", "clusterrolebindings",
         "deployments", "daemonsets", "statefulsets", "jobs", "cronjobs",
         "nodes", "namespaces",
         "selfsubjectaccessreviews", "selfsubjectrulesreviews", "subjectaccessreviews"
       )
       or (
         kubernetes.audit.objectRef.resource == "pods" and
         kubernetes.audit.objectRef.subresource in ("exec", "attach", "portforward", "log")
       )
     )
  ] by `kubernetes.audit.user.extra.authentication.kubernetes.io/pod-name`
'''

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

[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"

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

[[rule.threat.technique]]
id = "T1609"
name = "Container Administration Command"
reference = "https://attack.mitre.org/techniques/T1609/"

[[rule.threat.technique]]
id = "T1610"
name = "Deploy Container"
reference = "https://attack.mitre.org/techniques/T1610/"

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

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

[[rule.threat.technique]]
id = "T1069"
name = "Permission Groups Discovery"
reference = "https://attack.mitre.org/techniques/T1069/"

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

[[rule.threat.technique]]
id = "T1613"
name = "Container and Resource Discovery"
reference = "https://attack.mitre.org/techniques/T1613/"

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

Stages and Predicates

Ordered sequence: each step below must occur in order within 1s, correlated by kubernetes.audit.user.extra.authentication.kubernetes.io/pod-name, orchestrator.resource.name.

Stage 1: process

[process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and process.interactive == true and
  container.id like "*" and
  not (
     process.name in ("wget", "curl", "openssl", "socat", "ncat", "kubectl") or
     (
       process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox") and
       process.args in (
         "wget", "/bin/wget", "/usr/bin/wget", "/usr/local/bin/wget",
         "ssl_client", "/bin/ssl_client", "/usr/bin/ssl_client", "/usr/local/bin/ssl_client",
         "curl", "/bin/curl", "/usr/bin/curl", "/usr/local/bin/curl",
         "openssl", "/bin/openssl", "/usr/bin/openssl", "/usr/local/bin/openssl",
         "socat", "/bin/socat", "/usr/bin/socat", "/usr/local/bin/socat",
         "ncat", "/bin/ncat", "/usr/bin/ncat", "/usr/local/bin/ncat",
         "kubectl", "/bin/kubectl", "/usr/bin/kubectl", "/usr/local/bin/kubectl"
       ) and
       not process.args in (
         "which", "/bin/which", "/usr/bin/which", "/usr/local/bin/which",
         "man", "/bin/man", "/usr/bin/man", "/usr/local/bin/man",
         "chmod", "/bin/chmod", "/usr/bin/chmod", "/usr/local/bin/chmod",
         "chown", "/bin/chown", "/usr/bin/chown", "/usr/local/bin/chown"
       )
     ) or
     process.name in (
       "sleep", "head", "tail", "apk", "apt", "apt-get", "dnf", "microdnf", "yum", "zypper", "tdnf",
       "pacman", "rpm", "dpkg"
     )
   )] by orchestrator.resource.name

Stage 2: any

[any where
     data_stream.dataset == "kubernetes.audit_logs" and
     kubernetes.audit.stage in ("ResponseStarted","ResponseComplete") and
     kubernetes.audit.verb in ("get", "list", "watch", "create", "patch", "update") and
     (
       kubernetes.audit.objectRef.resource in (
         "pods", "secrets", "serviceaccounts", "configmaps",
         "roles", "rolebindings", "clusterroles", "clusterrolebindings",
         "deployments", "daemonsets", "statefulsets", "jobs", "cronjobs",
         "nodes", "namespaces",
         "selfsubjectaccessreviews", "selfsubjectrulesreviews", "subjectaccessreviews"
       )
       or (
         kubernetes.audit.objectRef.resource == "pods" and
         kubernetes.audit.objectRef.subresource in ("exec", "attach", "portforward", "log")
       )
     )
  ] by `kubernetes.audit.user.extra.authentication.kubernetes.io/pod-name`

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
container.idwildcard
  • * corpus 26 (elastic 26)
field:"container.id" kind:wildcard value:"*"
data_stream.dataseteq
  • kubernetes.audit_logs corpus 10 (elastic 10)
field:"data_stream.dataset" kind:eq value:"kubernetes.audit_logs"
event.actioneq
  • exec corpus 547 (elastic 547)
field:"EventType" kind:eq value:"exec"
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
kubernetes.audit.objectRef.resourceeq
  • pods corpus 2 (elastic 2)
field:"kubernetes.audit.objectRef.resource" kind:eq value:"pods"
kubernetes.audit.objectRef.resourcein
  • clusterrolebindings corpus 2 (elastic 2)
  • clusterroles corpus 5 (elastic 5)
  • configmaps corpus 3 (elastic 3)
  • cronjobs corpus 2 (elastic 2)
  • daemonsets corpus 2 (elastic 2)
  • deployments corpus 2 (elastic 2)
  • jobs
  • namespaces corpus 2 (elastic 2)
  • nodes corpus 2 (elastic 2)
  • pods corpus 2 (elastic 2)
  • rolebindings corpus 2 (elastic 2)
  • roles corpus 5 (elastic 5)
  • secrets corpus 2 (elastic 2)
  • selfsubjectaccessreviews
  • selfsubjectrulesreviews
  • serviceaccounts corpus 2 (elastic 2)
  • statefulsets
  • subjectaccessreviews
field:"kubernetes.audit.objectRef.resource" kind:in
kubernetes.audit.objectRef.subresourcein
  • attach
  • exec
  • log
  • portforward
field:"kubernetes.audit.objectRef.subresource" kind:in
kubernetes.audit.stagein
  • ResponseComplete corpus 5 (elastic 5)
  • ResponseStarted corpus 5 (elastic 5)
field:"kubernetes.audit.stage" kind:in
kubernetes.audit.verbin
  • create corpus 7 (elastic 7)
  • get corpus 5 (elastic 5)
  • list corpus 4 (elastic 4)
  • patch corpus 7 (elastic 7)
  • update corpus 7 (elastic 7)
  • watch corpus 2 (elastic 2)
field:"kubernetes.audit.verb" kind:in
process.argsin
  • /bin/chmod corpus 2 (elastic 2)
  • /bin/chown
  • /bin/man
  • /bin/which corpus 2 (elastic 2)
  • /usr/bin/chmod corpus 2 (elastic 2)
  • /usr/bin/chown
  • /usr/bin/man
  • /usr/bin/which corpus 2 (elastic 2)
  • /usr/local/bin/chmod corpus 2 (elastic 2)
  • /usr/local/bin/chown
  • /usr/local/bin/man
  • /usr/local/bin/which corpus 2 (elastic 2)
  • chmod corpus 2 (elastic 2)
  • chown
  • man
  • which corpus 2 (elastic 2)
field:"process.args" kind:in
process.interactiveeq
  • true transforms: boolean corpus 17 (elastic 17)
field:"process.interactive" kind:eq value:"true"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argsin/bin/chmod, /bin/chown, /bin/man, /bin/which, /usr/bin/chmod, /usr/bin/chown, /usr/bin/man, /usr/bin/which, /usr/local/bin/chmod, /usr/local/bin/chown, /usr/local/bin/man, /usr/local/bin/which, chmod, chown, man, whichexcludes:process.args
process.argsin/bin/curl, /bin/kubectl, /bin/ncat, /bin/openssl, /bin/socat, /bin/ssl_client, /bin/wget, /usr/bin/curl, /usr/bin/kubectl, /usr/bin/ncat, /usr/bin/openssl, /usr/bin/socat, /usr/bin/ssl_client, /usr/bin/wget, /usr/local/bin/curl, /usr/local/bin/kubectl, /usr/local/bin/ncat, /usr/local/bin/openssl, /usr/local/bin/socat, /usr/local/bin/ssl_client, /usr/local/bin/wget, curl, kubectl, ncat, openssl, socat, ssl_client, wgetexcludes:process.args
process.nameinbash, busybox, csh, dash, fish, ksh, sh, tcsh, zshexcludes:process.name
process.nameinapk, apt, apt-get, dnf, dpkg, head, microdnf, pacman, rpm, sleep, tail, tdnf, yum, zypperexcludes:process.name
process.nameincurl, kubectl, ncat, openssl, socat, wgetexcludes:process.name

Distributed File System Shares Enumeration via LDAP

#
Source
github.com/elastic/protections-artifacts

Identifies attempts to enumerate Distributed File System Shares using LDAP queries. Adversaries often query DFS links to learn about every central file share across the org without scanning the network. DFS shares might contain sensitive data (backups, GPO scripts, credentials, installer packages) or access controlled areas if permissions are misconfigured.

MITRE ATT&CK Coverage

TacticTechniques
Discovery

Rule Body

[rule]
description = """
Identifies attempts to enumerate Distributed File System Shares using LDAP queries. Adversaries often query DFS links to
learn about every central file share across the org without scanning the network. DFS shares might contain sensitive
data (backups, GPO scripts, credentials, installer packages) or access controlled areas if permissions are
misconfigured.
"""
id = "559c64c5-47f9-44b1-9261-4295eff8491f"
license = "Elastic License v2"
name = "Distributed File System Shares Enumeration via LDAP"
os_list = ["windows"]
reference = ["https://attack.mitre.org/techniques/T1087/002/"]
version = "1.0.3"

query = '''
api where process.Ext.api.name == "ldap_search" and
 process.Ext.api.parameters.search_filter : ("(&(objectClass=msDFS-Linkv2))", "(objectClass=msDFS-Linkv2)", "objectClass=msDFS-Linkv2") and
 process.Ext.api.parameters.attribute_list : "msdfs-linkpathv2" and process.Ext.api.parameters.attribute_list : "msDFS-TargetListv2"
'''

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1135"
name = "Network Share Discovery"
reference = "https://attack.mitre.org/techniques/T1135/"


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

[internal]
min_endpoint_version = "9.1.0"

Stages and Predicates

Stage 1: api

api where process.Ext.api.name == "ldap_search" and
 process.Ext.api.parameters.search_filter : ("(&(objectClass=msDFS-Linkv2))", "(objectClass=msDFS-Linkv2)", "objectClass=msDFS-Linkv2") and
 process.Ext.api.parameters.attribute_list : "msdfs-linkpathv2" and process.Ext.api.parameters.attribute_list : "msDFS-TargetListv2"

Indicators

These rows show field, operator, and value matches.

DLL Loaded via a CallBack Function

#
Source
github.com/elastic/protections-artifacts

Identifies attempts to load a DLL indirectly using thread pool callback functions. This may be the result of an evasion attempt to obscure the call origin.

MITRE ATT&CK Coverage

TacticTechniques
Stealth

Rule Body

[rule]
description = """
Identifies attempts to load a DLL indirectly using thread pool callback functions. This may be the result of an evasion
attempt to obscure the call origin.
"""
id = "716a3414-52cc-4165-97af-ec713dfac674"
license = "Elastic License v2"
name = "DLL Loaded via a CallBack Function"
os_list = ["windows"]
reference = ["https://www.elastic.co/security-labs/doubling-down-etw-callstacks"]
version = "1.0.1"

query = '''
library where
   process.thread.Ext.call_stack_summary == "ntdll.dll|kernel32.dll|ntdll.dll" and
   _arraysearch(process.thread.Ext.call_stack, $entry,
                $entry.symbol_info : ("?:\\Windows\\Sys*\\ntdll.dll!TpReleaseCleanupGroupMembers*",
                                      "?:\\Windows\\Sys*\\ntdll.dll!RtlDeregisterWaitEx*",
                                      "?:\\Windows\\Sys*\\ntdll.dll!TppWorkpExecuteCallback*",
                                      "?:\\Windows\\Sys*\\ntdll.dll!TppWorkerThread*")) and
   _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : "?:\\Windows\\Sys*\\ntdll.dll!LdrLoadDll*")
'''

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

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

Stages and Predicates

Stage 1: library

library where
   process.thread.Ext.call_stack_summary == "ntdll.dll|kernel32.dll|ntdll.dll" and
   _arraysearch(process.thread.Ext.call_stack, $entry,
                $entry.symbol_info : ("?:\\Windows\\Sys*\\ntdll.dll!TpReleaseCleanupGroupMembers*",
                                      "?:\\Windows\\Sys*\\ntdll.dll!RtlDeregisterWaitEx*",
                                      "?:\\Windows\\Sys*\\ntdll.dll!TppWorkpExecuteCallback*",
                                      "?:\\Windows\\Sys*\\ntdll.dll!TppWorkerThread*")) and
   _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : "?:\\Windows\\Sys*\\ntdll.dll!LdrLoadDll*")

Indicators

These rows show field, operator, and value matches.

Execution via a Suspicious WMI Client

#
Source
github.com/elastic/protections-artifacts

Identifies the execution of a process via Windows Management Instrumentation (WMI) and with an unusual effective parent. Adversaries may abuse Windows Management Instrumentation (WMI) to execute malicious commands and payloads.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the execution of a process via Windows Management Instrumentation (WMI) and with an unusual effective parent.
Adversaries may abuse Windows Management Instrumentation (WMI) to execute malicious commands and payloads.
"""
id = "b0a0d293-f85e-4994-97e6-95541c0bc181"
license = "Elastic License v2"
name = "Execution via a Suspicious WMI Client"
os_list = ["windows"]
reference = ["https://www.elastic.co/security-labs/spring-cleaning-with-latrodectus"]
version = "1.0.33"

query = '''
process where event.action == "start" and
  process.parent.name :"WmiPrvSE.exe" and
   (
    process.Ext.effective_parent.name : ("excel.exe", "powerpnt.exe", "winword.exe", "mshta.exe",
                                         "wscript.exe", "rundll32.exe", "regsvr32.exe",
                                         "msbuild.exe", "InstallUtil.exe") or
    process.Ext.effective_parent.executable : ("?:\\Users\\Public\\*", "?:\\ProgramData\\*", "?:\\Users\\*\\AppData\\*", "?:\\Windows\\Microsoft.NET\\*")
    ) and 
  not (user.id : "S-1-5-18" and process.name : "powershell.exe") and
  not process.hash.sha256 : 
             ("0e692d9d3342fdcab1ce3d61aed0520989a94371e5898edb266c92f1fe11c97f", 
              "8ee339af3ce1287066881147557dc3b57d1835cbba56b2457663068ed25b7840", 
              "f27cb78f44fc8f70606be883bbed705bd1dd2c2f8a84a596e5f4924e19068f22") and
  not (process.name : "powershell.exe" and process.args : "C:\\Windows\\TEMP\\RestartHealthService.ps1" and
       process.args : "60" and process.args : "1" and
       not process.Ext.effective_parent.name : ("excel.exe", "powerpnt.exe", "winword.exe")) and

  not (process.code_signature.subject_name : ("Immense Networks LLC", "Synology Inc.", "Xerox Corporation", "Beijing Qihu Technology Co., Ltd.") and
       process.code_signature.trusted == true) and

  not (process.args : "?:\\Windows\\TEMP\\RestartHealthService.js" and process.args : "60" and user.id : "S-1-5-18" and
       process.Ext.effective_parent.name : "cscript.exe") and

  /* ansible */
  not (process.name : "powershell.exe" and
       process.command_line : "*CgAgACAAIAAgAHQAcgBhAHAAIAB7AAoAIAAgACAAIAAgACAAIAAgACQAdwByAGEAcABwAGUAcgBfAHAAYQB0AGgAIAA9ACAAIgAkACgAJABlAG4AdgA6AFQARQBNAFAAKQBcAGEAbgBzAGkAYgBsAGUALQBhAHMAeQBuAGMALQB3AHIAYQBwAHAAZQByAC0AZ*") and

  not (process.name : "powershell.exe" and
       process.command_line : ("powershell.exe -WindowStyle \"Hidden\" -Command \"Enable-PSRemoting -Force\"",
                               "powershell.exe -WindowStyle \"Hidden\" -Command \"Set-WSManQuickConfig -Force\"",
                               "powershell.exe -WindowStyle \"Hidden\" -Command \"WinRM QuickConfig -Quiet -Force\"")) and
  not process.executable :
             ("?:\\Windows\\System32\\WerFault.exe",
              "?:\\Windows\\SysWOW64\\WerFault.exe",
              "?:\\Windows\\System32\\typeperf.exe",
              "?:\\Program Files*\\Adobe\\Acrobat DC\\Acrobat\\AcroTray.exe",
              "?:\\Program Files*\\Google\\Chrome\\Application\\chrome.exe",
              "?:\\Program Files*\\Mozilla Firefox\\firefox.exe",
              "\\Device\\Mup\\*.exe") and
  not (process.name : "cmd.exe" and
       process.args : ("\\\\*\\netlogon\\logon.cmd",
                       "?:\\ProgramData\\Package Cache\" %a in (cybereasonsensor.exe)*",
                       "(x86)\\EOG\\iFileMenu\\iFileMenu.bat"))
'''

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

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1566"
name = "Phishing"
reference = "https://attack.mitre.org/techniques/T1566/"
[[threat.technique.subtechnique]]
id = "T1566.001"
name = "Spearphishing Attachment"
reference = "https://attack.mitre.org/techniques/T1566/001/"



[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1047"
name = "Windows Management Instrumentation"
reference = "https://attack.mitre.org/techniques/T1047/"


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

[[threat.technique.subtechnique]]
id = "T1218.005"
name = "Mshta"
reference = "https://attack.mitre.org/techniques/T1218/005/"

[[threat.technique.subtechnique]]
id = "T1218.009"
name = "Regsvcs/Regasm"
reference = "https://attack.mitre.org/techniques/T1218/009/"

[[threat.technique.subtechnique]]
id = "T1218.010"
name = "Regsvr32"
reference = "https://attack.mitre.org/techniques/T1218/010/"

[[threat.technique.subtechnique]]
id = "T1218.011"
name = "Rundll32"
reference = "https://attack.mitre.org/techniques/T1218/011/"



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

[internal]
min_endpoint_version = "8.4.0"

Stages and Predicates

Stage 1: process

process where event.action == "start" and
  process.parent.name :"WmiPrvSE.exe" and
   (
    process.Ext.effective_parent.name : ("excel.exe", "powerpnt.exe", "winword.exe", "mshta.exe",
                                         "wscript.exe", "rundll32.exe", "regsvr32.exe",
                                         "msbuild.exe", "InstallUtil.exe") or
    process.Ext.effective_parent.executable : ("?:\\Users\\Public\\*", "?:\\ProgramData\\*", "?:\\Users\\*\\AppData\\*", "?:\\Windows\\Microsoft.NET\\*")
    ) and
  not (user.id : "S-1-5-18" and process.name : "powershell.exe") and
  not process.hash.sha256 :
             ("0e692d9d3342fdcab1ce3d61aed0520989a94371e5898edb266c92f1fe11c97f",
              "8ee339af3ce1287066881147557dc3b57d1835cbba56b2457663068ed25b7840",
              "f27cb78f44fc8f70606be883bbed705bd1dd2c2f8a84a596e5f4924e19068f22") and
  not (process.name : "powershell.exe" and process.args : "C:\\Windows\\TEMP\\RestartHealthService.ps1" and
       process.args : "60" and process.args : "1" and
       not process.Ext.effective_parent.name : ("excel.exe", "powerpnt.exe", "winword.exe")) and
  not (process.code_signature.subject_name : ("Immense Networks LLC", "Synology Inc.", "Xerox Corporation", "Beijing Qihu Technology Co., Ltd.") and
       process.code_signature.trusted == true) and
  not (process.args : "?:\\Windows\\TEMP\\RestartHealthService.js" and process.args : "60" and user.id : "S-1-5-18" and
       process.Ext.effective_parent.name : "cscript.exe") and
  not (process.name : "powershell.exe" and
       process.command_line : "*CgAgACAAIAAgAHQAcgBhAHAAIAB7AAoAIAAgACAAIAAgACAAIAAgACQAdwByAGEAcABwAGUAcgBfAHAAYQB0AGgAIAA9ACAAIgAkACgAJABlAG4AdgA6AFQARQBNAFAAKQBcAGEAbgBzAGkAYgBsAGUALQBhAHMAeQBuAGMALQB3AHIAYQBwAHAAZQByAC0AZ*") and
  not (process.name : "powershell.exe" and
       process.command_line : ("powershell.exe -WindowStyle \"Hidden\" -Command \"Enable-PSRemoting -Force\"",
                               "powershell.exe -WindowStyle \"Hidden\" -Command \"Set-WSManQuickConfig -Force\"",
                               "powershell.exe -WindowStyle \"Hidden\" -Command \"WinRM QuickConfig -Quiet -Force\"")) and
  not process.executable :
             ("?:\\Windows\\System32\\WerFault.exe",
              "?:\\Windows\\SysWOW64\\WerFault.exe",
              "?:\\Windows\\System32\\typeperf.exe",
              "?:\\Program Files*\\Adobe\\Acrobat DC\\Acrobat\\AcroTray.exe",
              "?:\\Program Files*\\Google\\Chrome\\Application\\chrome.exe",
              "?:\\Program Files*\\Mozilla Firefox\\firefox.exe",
              "\\Device\\Mup\\*.exe") and
  not (process.name : "cmd.exe" and
       process.args : ("\\\\*\\netlogon\\logon.cmd",
                       "?:\\ProgramData\\Package Cache\" %a in (cybereasonsensor.exe)*",
                       "(x86)\\EOG\\iFileMenu\\iFileMenu.bat"))

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • start corpus 388 (elastic 388)
field:"EventType" kind:eq value:"start"
process.Ext.effective_parent.executablewildcard
  • ?:\ProgramData\*
  • ?:\Users\*\AppData\*
  • ?:\Users\Public\*
  • ?:\Windows\Microsoft.NET\*
field:"process.Ext.effective_parent.executable" kind:wildcard
process.Ext.effective_parent.namewildcard
  • InstallUtil.exe corpus 2 (elastic 2)
  • excel.exe corpus 2 (elastic 2)
  • msbuild.exe corpus 2 (elastic 2)
  • mshta.exe corpus 2 (elastic 2)
  • powerpnt.exe corpus 2 (elastic 2)
  • regsvr32.exe corpus 2 (elastic 2)
  • rundll32.exe corpus 2 (elastic 2)
  • winword.exe corpus 2 (elastic 2)
  • wscript.exe corpus 2 (elastic 2)
field:"process.Ext.effective_parent.name" kind:wildcard
process.parent.namewildcard
  • WmiPrvSE.exe corpus 24 (elastic 19, splunk 5)
field:"parent_process_basename" kind:wildcard value:"WmiPrvSE.exe"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.Ext.effective_parent.nameeqexcel.exe, powerpnt.exe, winword.exeexcludes:process.Ext.effective_parent.name field:"process.Ext.effective_parent.name" value:"excel.exe" field:"process.Ext.effective_parent.name" value:"powerpnt.exe" field:"process.Ext.effective_parent.name" value:"winword.exe"
process.argseq1excludes:process.args field:"process.args" value:"1"
process.argseq60excludes:process.args field:"process.args" value:"60"
process.argseqC:\Windows\TEMP\RestartHealthService.ps1excludes:process.args field:"process.args" value:"C:\Windows\TEMP\RestartHealthService.ps1"
process.nameeqpowershell.exeexcludes:process.name field:"process.name" value:"powershell.exe"
process.Ext.effective_parent.nameeqcscript.exeexcludes:process.Ext.effective_parent.name field:"process.Ext.effective_parent.name" value:"cscript.exe"
process.argseq?:\Windows\TEMP\RestartHealthService.jsexcludes:process.args field:"process.args" value:"?:\Windows\TEMP\RestartHealthService.js"
user.ideqS-1-5-18excludes:user.id field:"user.id" value:"S-1-5-18"
process.argswildcard\\*\netlogon\logon.cmd, ?:\ProgramData\Package Cache" %a in (cybereasonsensor.exe)*, (x86)\EOG\iFileMenu\iFileMenu.batexcludes:process.args
process.nameeqcmd.exeexcludes:process.name field:"process.name" value:"cmd.exe"
process.code_signature.subject_nameeqImmense Networks LLC, Synology Inc., Xerox Corporation, Beijing Qihu Technology Co., Ltd.excludes:process.code_signature.subject_name
process.code_signature.trustedeqtrueexcludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true"
process.command_lineeqpowershell.exe -WindowStyle "Hidden" -Command "Enable-PSRemoting -Force", powershell.exe -WindowStyle "Hidden" -Command "Set-WSManQuickConfig -Force", powershell.exe -WindowStyle "Hidden" -Command "WinRM QuickConfig -Quiet -Force"excludes:process.command_line
process.command_linematchCgAgACAAIAAgAHQAcgBhAHAAIAB7AAoAIAAgACAAIAAgACAAIAAgACQAdwByAGEAcABwAGUAcgBfAHAAYQB0AGgAIAA9ACAAIgAkACgAJABlAG4AdgA6AFQARQBNAFAAKQBcAGEAbgBzAGkAYgBsAGUALQBhAHMAeQBuAGMALQB3AHIAYQBwAHAAZQByAC0AZexcludes:process.command_line field:"process.command_line" value:"CgAgACAAIAAgAHQAcgBhAHAAIAB7AAoAIAAgACAAIAAgACAAIAAgACQAdwByAGEAcABwAGUAcgBfAHAAYQB0AGgAIAA9ACAAIgAkACgAJABlAG4AdgA6AFQARQBNAFAAKQBcAGEAbgBzAGkAYgBsAGUALQBhAHMAeQBuAGMALQB3AHIAYQBwAHAAZQByAC0AZ"
process.executablewildcard?:\Windows\System32\WerFault.exe, ?:\Windows\SysWOW64\WerFault.exe, ?:\Windows\System32\typeperf.exe, ?:\Program Files*\Adobe\Acrobat DC\Acrobat\AcroTray.exe, ?:\Program Files*\Google\Chrome\Application\chrome.exe, ?:\Program Files*\Mozilla Firefox\firefox.exe, \Device\Mup\*.exeexcludes:process.executable
process.hash.sha256eq0e692d9d3342fdcab1ce3d61aed0520989a94371e5898edb266c92f1fe11c97f, 8ee339af3ce1287066881147557dc3b57d1835cbba56b2457663068ed25b7840, f27cb78f44fc8f70606be883bbed705bd1dd2c2f8a84a596e5f4924e19068f22excludes:process.hash.sha256 field:"process.hash.sha256" value:"0e692d9d3342fdcab1ce3d61aed0520989a94371e5898edb266c92f1fe11c97f" field:"process.hash.sha256" value:"8ee339af3ce1287066881147557dc3b57d1835cbba56b2457663068ed25b7840" field:"process.hash.sha256" value:"f27cb78f44fc8f70606be883bbed705bd1dd2c2f8a84a596e5f4924e19068f22"

First Occurrence GitHub Event for a Personal Access Token (PAT)

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

Detects a first occurrence event for a personal access token (PAT) not seen in the last 14 days.

MITRE ATT&CK Coverage

Rule Body

[metadata]
bypass_bbr_timing = true
creation_date = "2023/10/11"
integration = ["github"]
maturity = "production"
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
building_block_type = "default"
description = "Detects a first occurrence event for a personal access token (PAT) not seen in the last 14 days.\n"
from = "now-9m"
index = ["logs-github.audit-*"]
language = "kuery"
license = "Elastic License v2"
name = "First Occurrence GitHub Event for a Personal Access Token (PAT)"
risk_score = 21
rule_id = "ce08b55a-f67d-4804-92b5-617b0fe5a5b5"
severity = "low"
tags = [
    "Domain: Cloud",
    "Use Case: Threat Detection",
    "Use Case: UEBA",
    "Tactic: Execution",
    "Rule Type: BBR",
    "Data Source: Github",
]
timestamp_override = "event.ingested"
type = "new_terms"

query = '''
event.dataset:"github.audit" and event.category:"configuration" and
event.action:* and github.hashed_token:* and 
github.programmatic_access_type:("OAuth access token" or "Fine-grained personal access token")
'''


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

[[rule.threat.technique]]
id = "T1648"
name = "Serverless Execution"
reference = "https://attack.mitre.org/techniques/T1648/"

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

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

[[rule.threat.technique]]
id = "T1550"
name = "Use Alternate Authentication Material"
reference = "https://attack.mitre.org/techniques/T1550/"

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

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

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

[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"

[[rule.threat.technique.subtechnique]]
id = "T1098.001"
name = "Additional Cloud Credentials"
reference = "https://attack.mitre.org/techniques/T1098/001/"

[rule.threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[rule.new_terms]
field = "new_terms_fields"
value = ["github.hashed_token", "event.action"]
[[rule.new_terms.history_window_start]]
field = "history_window_start"
value = "now-5d"


Stages and Predicates

Stage 1: new_terms

event.dataset:"github.audit" and event.category:"configuration" and
event.action:* and github.hashed_token:* and 
github.programmatic_access_type:("OAuth access token" or "Fine-grained personal access token")

Indicators

These rows show field, operator, and value matches.

GKE Secret Access from Node or Denied Service Account

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

Detects GKE Secrets API activity that should not occur in normal cluster operation: a node identity (system:node:*) performing secrets get or list, or a pod service account failing a secrets get. Kubelet and node credentials are not expected to call the Secrets API for enumeration or direct reads, and a denied service-account secret get could indicate stolen-token probing or over-privileged tooling reaching beyond its RBAC.

Known False Positives

  • Rare node maintenance or diagnostic tooling may touch the Secrets API; validate against change windows and approved node management paths.
  • Misconfigured workloads can generate repeated denied secret gets during startup; confirm RBAC intent before treating as compromise.

MITRE ATT&CK Coverage

TacticTechniques
Credential Access

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

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

[rule]
author = ["Elastic"]
description = """
Detects GKE Secrets API activity that should not occur in normal cluster operation: a node identity
(system:node:*) performing secrets get or list, or a pod service account failing a secrets get.
Kubelet and node credentials are not expected to call the Secrets API for enumeration or direct reads,
and a denied service-account secret get could indicate stolen-token probing or over-privileged tooling
reaching beyond its RBAC.
"""
false_positives = [
    """
    Rare node maintenance or diagnostic tooling may touch the Secrets API; validate against change windows
    and approved node management paths.
    """,
    """
    Misconfigured workloads can generate repeated denied secret gets during startup; confirm RBAC intent
    before treating as compromise.
    """,
]
from = "now-6m"
index = ["logs-gcp.audit-*"]
language = "kuery"
license = "Elastic License v2"
name = "GKE Secret Access from Node or Denied Service Account"
note = """## Triage and analysis

### Investigating GKE Secret Access from Node or Denied Service Account

This rule fires on two high-confidence patterns in GKE audit logs:

- `system:node:*` successfully or unsuccessfully calling `secrets.get` or `secrets.list`
- `system:serviceaccount:*` receiving `event.outcome:failure` on `secrets.get`

Treat node-originated Secrets API calls as priority. For denied service-account gets, determine whether
the identity is probing secrets outside its Role/ClusterRole or using an unexpected client from a
compromised token.

### Possible investigation steps

- Resolve `client.user.email` to the node or workload and review RBAC bindings for secret `get`/`list` scope.
- Inspect `gcp.audit.resource_name`, `source.ip`, and `user_agent.original` for anomalous clients or
  cross-namespace targets.
- Correlate with successful secret reads, pod exec, token creation, or RoleBinding changes in the same window.
- For node events, confirm whether kubelet, CSI, or maintenance tooling on that node should ever call the
  Secrets API.

### False positive analysis

- Node diagnostics or custom CSI helpers may rarely issue Secrets API calls; allowlist only after confirming
  the path is approved.
- Broken RBAC on a newly deployed workload can produce repeated denied gets until permissions are fixed.

### Response and remediation

- If malicious, revoke the node or service-account credentials, isolate the host or workload, rotate exposed
  secrets, and tighten RBAC to least privilege for the affected identity.
"""
setup = "The GCP Fleet integration with GKE audit logs enabled is required to be compatible with this rule."
references = [
    "https://kubernetes.io/docs/reference/access-authn-authz/authentication/#service-account-tokens",
]
risk_score = 47
rule_id = "bedab6b4-f195-45d1-8f97-7d300eb79671"
severity = "medium"
tags = [
    "Domain: Cloud",
    "Domain: Kubernetes",
    "Data Source: GCP",
    "Data Source: Google Cloud Platform",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:gcp.audit and service.name:k8s.io and
source.ip:(* and not (127.0.0.1 or "::1")) and
(
  (
    client.user.email:system\:node\:* and
    event.action:(io.k8s.core.v1.secrets.get or io.k8s.core.v1.secrets.list)
  ) or (
    client.user.email:system\:serviceaccount\:* and
    event.action:io.k8s.core.v1.secrets.get and
    event.outcome:failure
  )
)
'''

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

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

[[rule.threat.technique.subtechnique]]
id = "T1552.007"
name = "Container API"
reference = "https://attack.mitre.org/techniques/T1552/007/"

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

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

Stages and Predicates

Stage 1: query

data_stream.dataset:gcp.audit and service.name:k8s.io and
source.ip:(* and not (127.0.0.1 or "::1")) and
(
  (
    client.user.email:system\:node\:* and
    event.action:(io.k8s.core.v1.secrets.get or io.k8s.core.v1.secrets.list)
  ) or (
    client.user.email:system\:serviceaccount\:* and
    event.action:io.k8s.core.v1.secrets.get and
    event.outcome:failure
  )
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
client.user.emailwildcard
  • system:node:*
  • system:serviceaccount:* corpus 3 (elastic 3)
field:"client.user.email" kind:wildcard
data_stream.dataseteq
  • gcp.audit corpus 60 (elastic 60)
field:"data_stream.dataset" kind:eq value:"gcp.audit"
event.actioneq
  • io.k8s.core.v1.secrets.get corpus 2 (elastic 2)
field:"EventType" kind:eq value:"io.k8s.core.v1.secrets.get"
event.actionin
  • io.k8s.core.v1.secrets.get corpus 3 (elastic 3)
  • io.k8s.core.v1.secrets.list corpus 3 (elastic 3)
field:"EventType" kind:in
event.outcomeeq
  • failure corpus 14 (elastic 14)
field:"event.outcome" kind:eq value:"failure"
service.nameeq
  • k8s.io corpus 28 (elastic 28)
field:"ServiceName" kind:eq value:"k8s.io"
source.ipis_not_null
  • (no value, null check)
field:"src_ip" kind:is_not_null

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
source.ipin127.0.0.1, ::1excludes:source.ip field:"source.ip" value:"127.0.0.1" field:"source.ip" value:"::1"

Kubernetes Admission Webhook Created or Modified

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

Detects creation, modification, or deletion of Kubernetes MutatingWebhookConfigurations or ValidatingWebhookConfigurations by non-system identities. Admission webhooks intercept every API request matching their rules before persistence, giving an attacker powerful capabilities: injecting malicious sidecars into every new pod via a mutating webhook, blocking security tooling deployments via a validating webhook, or silently exfiltrating pod specifications to an external server. Webhook manipulation is a stealthy persistence and defense evasion technique because the webhook configuration itself looks benign in kubectl output while actively modifying or intercepting all matching Kubernetes API traffic.

Known False Positives

  • Cluster operators and GitOps automation may legitimately install or upgrade admission controllers (e.g. cert-manager, Gatekeeper, Kyverno, service mesh components). Validate change tickets and approved controllers before tuning.

MITRE ATT&CK Coverage

TacticTechniques
Persistence
Defense Impairment

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2026/05/05"
integration = ["kubernetes"]
maturity = "production"
updated_date = "2026/05/26"

[rule]
author = ["Elastic"]
description = """
Detects creation, modification, or deletion of Kubernetes MutatingWebhookConfigurations or ValidatingWebhookConfigurations 
by non-system identities. Admission webhooks intercept every API request matching their rules before persistence, giving an 
attacker powerful capabilities: injecting malicious sidecars into every new pod via a mutating webhook, blocking security 
tooling deployments via a validating webhook, or silently exfiltrating pod specifications to an external server. 
Webhook manipulation is a stealthy persistence and defense evasion technique because the webhook configuration itself looks 
benign in kubectl output while actively modifying or intercepting all matching Kubernetes API traffic.
"""
false_positives = [
  """
  Cluster operators and GitOps automation may legitimately install or upgrade admission controllers (e.g. cert-manager,
  Gatekeeper, Kyverno, service mesh components). Validate change tickets and approved controllers before tuning.
  """,
]
from = "now-9m"
index = ["logs-kubernetes.audit_logs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Kubernetes Admission Webhook Created or Modified"
note = """## Triage and analysis

### Investigating Kubernetes Admission Webhook Created or Modified

Admission webhooks can mutate or validate resources before they are persisted. A malicious webhook can inject sidecars,
alter securityContext, block defensive workloads, or exfiltrate pod specs. This rule alerts on allowed changes to
MutatingWebhookConfiguration and ValidatingWebhookConfiguration objects by identities outside common system patterns.

### Possible investigation steps

- Confirm the webhook resource and operation:
  - kubernetes.audit.objectRef.resource and kubernetes.audit.verb
  - kubernetes.audit.objectRef.name (the webhook configuration name)
- Attribute the actor and access path:
  - user.name (human vs service account vs node identity)
  - source.ip and user_agent.original
  - In cloud-managed clusters, map the identity to IAM/Entra principal data present in kubernetes.audit.user.extra.*.
- Extract the webhook destination and review for external exfiltration:
  - kubernetes.audit.requestObject.webhooks.clientConfig.url (suspicious when pointing to the public internet)
  - kubernetes.audit.requestObject.webhooks.clientConfig.service.* (in-cluster service; still validate namespace/name)
- Review impact-driving webhook settings:
  - failurePolicy (e.g., Ignore can make malicious webhooks stealthier by avoiding obvious outages)
  - namespaceSelector / objectSelector targeting (e.g., excluding kube-system while targeting everything else)
  - rules.operations and rules.resources (e.g., CREATE pods is consistent with broad sidecar injection)
  - sideEffects, timeoutSeconds, matchPolicy, reinvocationPolicy
- Scope blast radius and follow-on activity:
  - Hunt for pods created/updated after the webhook change that include unexpected containers, initContainers, env vars,
    volume mounts, or securityContext changes.
  - Check for concurrent RBAC changes, token creation, or secret access from the same identity and source IP.

### False positive analysis

- GitOps upgrades or controller installs can legitimately change admission webhooks. Validate the change against:
  - approved Helm/Git commits, change tickets, and expected controller namespaces
  - known controller identities (cert-manager, Gatekeeper, Kyverno, service mesh controllers)

### Response and remediation

- If unauthorized, revert or delete the webhook configuration from a known-good source (GitOps/Helm), then block the
  actor identity and rotate any credentials it used.
- If the webhook targeted pod creation, assume workload impact: identify affected namespaces/workloads, redeploy from
  trusted manifests/images, and validate that new pods are no longer being mutated.
- If an external clientConfig.url was used, treat it as potential data exfiltration and review egress/DNS logs for the
  destination around the alert window.
"""
risk_score = 47
rule_id = "4f8f7c08-ffb5-443f-86c6-0884c964df7b"
severity = "medium"
tags = [
  "Data Source: Kubernetes",
  "Domain: Kubernetes",
  "Use Case: Threat Detection",
  "Tactic: Persistence",
  "Tactic: Defense Evasion",
  "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
kubernetes.audit.objectRef.resource:("mutatingwebhookconfigurations" or "validatingwebhookconfigurations") and
kubernetes.audit.verb:("create" or "update" or "patch" or "delete") and
kubernetes.audit.annotations.authorization_k8s_io/decision:"allow" and 
user.name:(* and not 
  (system\:kube-controller-manager or
  system\:kube-scheduler or
  system\:serviceaccount\:kube-system\:* or
  eks\:* or aksService or masterclient or nodeclient or
  system\:serviceaccount\:gke-managed-system\:* or
  system\:serviceaccount\:cert-manager\:* or
  system\:serviceaccount\:gatekeeper-system\:* or
  system\:serviceaccount\:kyverno\:* or
  system\:serviceaccount\:*\:*-operator)
) and
kubernetes.audit.objectRef.name:(* and not (pod-identity-webhook or vpc-resource-mutating-webhook or eks-* or gke-*)) and 
not (kubernetes.audit.user.groups:"system:serviceaccounts:flux-system" and kubernetes.audit.objectRef.name:"k8tz")
'''

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

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

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

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

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

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

Stages and Predicates

Stage 1: query

kubernetes.audit.objectRef.resource:("mutatingwebhookconfigurations" or "validatingwebhookconfigurations") and
kubernetes.audit.verb:("create" or "update" or "patch" or "delete") and
kubernetes.audit.annotations.authorization_k8s_io/decision:"allow" and 
user.name:(* and not 
  (system\:kube-controller-manager or
  system\:kube-scheduler or
  system\:serviceaccount\:kube-system\:* or
  eks\:* or aksService or masterclient or nodeclient or
  system\:serviceaccount\:gke-managed-system\:* or
  system\:serviceaccount\:cert-manager\:* or
  system\:serviceaccount\:gatekeeper-system\:* or
  system\:serviceaccount\:kyverno\:* or
  system\:serviceaccount\:*\:*-operator)
) and
kubernetes.audit.objectRef.name:(* and not (pod-identity-webhook or vpc-resource-mutating-webhook or eks-* or gke-*)) and 
not (kubernetes.audit.user.groups:"system:serviceaccounts:flux-system" and kubernetes.audit.objectRef.name:"k8tz")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
kubernetes.audit.annotations.authorization_k8s_io/decisioneq
  • allow corpus 21 (elastic 21)
field:"kubernetes.audit.annotations.authorization_k8s_io/decision" kind:eq value:"allow"
kubernetes.audit.objectRef.nameis_not_null
  • (no value, null check)
field:"kubernetes.audit.objectRef.name" kind:is_not_null
kubernetes.audit.objectRef.resourcein
  • mutatingwebhookconfigurations
  • validatingwebhookconfigurations
field:"kubernetes.audit.objectRef.resource" kind:in
kubernetes.audit.verbin
  • create corpus 10 (elastic 10)
  • delete corpus 5 (elastic 5)
  • patch corpus 13 (elastic 13)
  • update corpus 12 (elastic 12)
field:"kubernetes.audit.verb" kind:in
user.nameis_not_null
  • (no value, null check)
field:"user" kind:is_not_null

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
kubernetes.audit.objectRef.nameeqk8tzexcludes:kubernetes.audit.objectRef.name field:"kubernetes.audit.objectRef.name" value:"k8tz"
kubernetes.audit.user.groupseqsystem:serviceaccounts:flux-systemexcludes:kubernetes.audit.user.groups field:"kubernetes.audit.user.groups" value:"system:serviceaccounts:flux-system"
kubernetes.audit.objectRef.nameeqpod-identity-webhookexcludes:kubernetes.audit.objectRef.name field:"kubernetes.audit.objectRef.name" value:"pod-identity-webhook"
kubernetes.audit.objectRef.nameeqvpc-resource-mutating-webhookexcludes:kubernetes.audit.objectRef.name field:"kubernetes.audit.objectRef.name" value:"vpc-resource-mutating-webhook"
kubernetes.audit.objectRef.namestarts_witheks-excludes:kubernetes.audit.objectRef.name field:"kubernetes.audit.objectRef.name" value:"eks-"
kubernetes.audit.objectRef.namestarts_withgke-excludes:kubernetes.audit.objectRef.name field:"kubernetes.audit.objectRef.name" value:"gke-"
user.nameeqaksServiceexcludes:user.name field:"user.name" value:"aksService"
user.nameeqmasterclientexcludes:user.name field:"user.name" value:"masterclient"
user.nameeqnodeclientexcludes:user.name field:"user.name" value:"nodeclient"
user.nameeqsystem:kube-controller-managerexcludes:user.name field:"user.name" value:"system:kube-controller-manager"
user.nameeqsystem:kube-schedulerexcludes:user.name field:"user.name" value:"system:kube-scheduler"
user.namestarts_witheks:excludes:user.name field:"user.name" value:"eks:"
user.namestarts_withsystem:serviceaccount:cert-manager:excludes:user.name field:"user.name" value:"system:serviceaccount:cert-manager:"
user.namestarts_withsystem:serviceaccount:gatekeeper-system:excludes:user.name field:"user.name" value:"system:serviceaccount:gatekeeper-system:"
user.namestarts_withsystem:serviceaccount:gke-managed-system:excludes:user.name field:"user.name" value:"system:serviceaccount:gke-managed-system:"
user.namestarts_withsystem:serviceaccount:kube-system:excludes:user.name field:"user.name" value:"system:serviceaccount:kube-system:"
user.namestarts_withsystem:serviceaccount:kyverno:excludes:user.name field:"user.name" value:"system:serviceaccount:kyverno:"
user.namewildcardsystem:serviceaccount:*:*-operatorexcludes:user.name field:"user.name" value:"system:serviceaccount:*:*-operator"

Kubernetes Pod Created with a Sensitive hostPath Volume

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

This rule detects when a pod is created with a sensitive volume of type hostPath. A hostPath volume type mounts a sensitive file or folder from the node to the container. If the container gets compromised, the attacker can use this mount for gaining access to the node. There are many ways a container with unrestricted access to the host filesystem can escalate privileges, including reading data from other containers, and accessing tokens of more privileged pods.

Known False Positives

  • An administrator may need to attach a hostPath volume for a legitimate reason. This alert should be investigated for legitimacy by determining if the kuberenetes.audit.requestObject.spec.volumes.hostPath.path triggered is one needed by its target container/pod. For example, when the fleet managed elastic agent is deployed as a daemonset it creates several hostPath volume mounts, some of which are sensitive host directories like /proc, /etc/kubernetes, and /var/log. Add exceptions for trusted container images using the query field "kubernetes.audit.requestObject.spec.container.image"

MITRE ATT&CK Coverage

TacticTechniques
Execution
Privilege Escalation

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

[metadata]
creation_date = "2022/07/11"
integration = ["kubernetes"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
This rule detects when a pod is created with a sensitive volume of type hostPath. A hostPath volume type mounts a
sensitive file or folder from the node to the container. If the container gets compromised, the attacker can use this
mount for gaining access to the node. There are many ways a container with unrestricted access to the host filesystem
can escalate privileges, including reading data from other containers, and accessing tokens of more privileged pods.
"""
false_positives = [
    """
    An administrator may need to attach a hostPath volume for a legitimate reason. This alert should be investigated for
    legitimacy by determining if the kuberenetes.audit.requestObject.spec.volumes.hostPath.path triggered is one needed
    by its target container/pod. For example, when the fleet managed elastic agent is deployed as a daemonset it creates
    several hostPath volume mounts, some of which are sensitive host directories like /proc, /etc/kubernetes, and
    /var/log. Add exceptions for trusted container images using the query field
    "kubernetes.audit.requestObject.spec.container.image"
    """,
]
index = ["logs-kubernetes.audit_logs-*"]
language = "kuery"
license = "Elastic License v2"
name = "Kubernetes Pod Created with a Sensitive hostPath Volume"
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 Kubernetes Pod Created with a Sensitive hostPath Volume

Kubernetes allows containers to access host filesystems via hostPath volumes, which can be crucial for certain applications. However, if a container is compromised, adversaries can exploit these mounts to access sensitive host data or escalate privileges. The detection rule identifies when pods are created or modified with hostPath volumes pointing to critical directories, signaling potential misuse or security risks.

### Possible investigation steps

- Review the Kubernetes audit logs to identify the specific pod creation or modification event that triggered the alert, focusing on the event.dataset field with the value "kubernetes.audit_logs".
- Examine the kubernetes.audit.requestObject.spec.volumes.hostPath.path field to determine which sensitive hostPath was mounted and assess the potential risk associated with that specific path.
- Check the kubernetes.audit.annotations.authorization_k8s_io/decision field to confirm that the action was allowed, and verify the legitimacy of the authorization decision.
- Investigate the kubernetes.audit.requestObject.spec.containers.image field to identify the container image used, ensuring it is not a known or suspected malicious image, and cross-reference with any known vulnerabilities or security advisories.
- Analyze the context of the pod creation or modification by reviewing the kubernetes.audit.verb field to understand whether the action was a create, update, or patch operation, and correlate this with recent changes or deployments in the environment.
- Assess the potential impact on the cluster by identifying other pods or services that might be affected by the compromised pod, especially those with elevated privileges or access to sensitive data.

### False positive analysis

- Development environments often use hostPath volumes for testing purposes, which can trigger this rule. To manage this, create exceptions for specific namespaces or labels associated with development workloads.
- Monitoring tools or agents may require access to certain host paths for legitimate reasons. Identify these tools and exclude their specific container images from the rule, similar to the exclusion of the elastic-agent image.
- Backup or logging applications might need access to host directories to perform their functions. Review these applications and consider excluding their specific hostPath configurations if they are deemed non-threatening.
- Some system maintenance tasks might temporarily use hostPath volumes. Document these tasks and schedule them during known maintenance windows, then create temporary exceptions during these periods.
- Custom scripts or automation tools that interact with Kubernetes may inadvertently trigger this rule. Audit these scripts and tools, and if they are safe, exclude their specific actions or paths from the rule.

### Response and remediation

- Immediately isolate the affected pod to prevent further access to sensitive host data. This can be done by cordoning the node or deleting the pod if necessary.
- Review and revoke any credentials or tokens that may have been exposed through the compromised pod to prevent unauthorized access to other resources.
- Conduct a thorough analysis of the container image and application code to identify any vulnerabilities or malicious code that may have led to the compromise.
- Patch or update the container image and application code to address any identified vulnerabilities, and redeploy the application with the updated image.
- Implement network policies to restrict pod-to-pod and pod-to-node communication, limiting the potential impact of a compromised pod.
- Enhance monitoring and logging for Kubernetes audit logs to ensure timely detection of similar threats in the future, focusing on unauthorized access attempts and privilege escalation activities.
- Escalate the incident to the security operations team for further investigation and to assess the need for additional security measures or incident response actions.

## Setup

The Kubernetes Fleet integration with Audit Logs enabled or similarly structured data is required to be compatible with this rule."""
references = [
    "https://blog.appsecco.com/kubernetes-namespace-breakout-using-insecure-host-path-volume-part-1-b382f2a6e216",
    "https://kubernetes.io/docs/concepts/storage/volumes/#hostpath",
]
risk_score = 47
rule_id = "2abda169-416b-4bb3-9a6b-f8d239fd78ba"
severity = "medium"
tags = [
    "Data Source: Kubernetes",
    "Domain: Kubernetes",
    "Use Case: Threat Detection",
    "Tactic: Execution",
    "Tactic: Privilege Escalation",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
data_stream.dataset : "kubernetes.audit_logs" and kubernetes.audit.annotations.authorization_k8s_io/decision:"allow" and
kubernetes.audit.objectRef.resource:"pods" and kubernetes.audit.verb:("create" or "update" or "patch") and
kubernetes.audit.requestObject.spec.volumes.hostPath.path: (
  "/" or "/proc" or "/root" or "/var" or "/var/run" or "/var/run/docker.sock" or "/var/run/crio/crio.sock" or
  "/var/run/cri-dockerd.sock" or "/var/lib/kubelet" or "/var/lib/kubelet/pki" or "/var/lib/docker/overlay2" or
  "/etc" or "/etc/kubernetes" or "/etc/kubernetes/manifests" or "/etc/kubernetes/pki" or "/home/admin"
) and
not kubernetes.audit.requestObject.spec.containers.image: (
  docker.elastic.co/beats/elastic-agent* or *elastic/elastic-agent* or docker.elastic.co/elastic-agent/elastic-agent* or
  *elastic-agent\:dev* or *cloudops-azure-devops-agent* or rancher/mirrored-longhornio-longhorn-instance-manager* or
  quay.io/calico* or ghcr.io/aquasecurity* or rancher/system-agent* or rancher/mirrored-longhornio-csi-node-driver-registrar* or
  rancher/mirrored-longhornio-livenessprobe* or quay.io/prometheus/node-exporter* or *eks/observability/cloudwatch-agent* or
  amazon/aws-efs-csi-driver* or public.ecr.aws/eks-distro/kubernetes-csi* or quay.io/cilium/cilium* or openebs/node-disk-manager* or
  openebs/cstor-csi-driver* or registry.k8s.io/sig-storage/csi-node-driver-registrar* or *.amazonaws.com/eks/csi-node-driver-registrar* or
  *.amazonaws.com/eks/livenessprobe* or *.amazonaws.com/eks/aws-efs-csi-driver* or mcr.microsoft.com/oss/v2/kubernetes-csi* or
  rancher/mirrored-cilium-cilium* or jenkins/inbound-agent* or gcr.io/datadoghq/agent* or rancher/mirrored-longhornio-longhorn-share-manager* or
  */sysdig/*
)
'''

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

[[rule.threat.technique]]
id = "T1611"
name = "Escape to Host"
reference = "https://attack.mitre.org/techniques/T1611/"

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

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

Stages and Predicates

Stage 1: query

data_stream.dataset : "kubernetes.audit_logs" and kubernetes.audit.annotations.authorization_k8s_io/decision:"allow" and
kubernetes.audit.objectRef.resource:"pods" and kubernetes.audit.verb:("create" or "update" or "patch") and
kubernetes.audit.requestObject.spec.volumes.hostPath.path: (
  "/" or "/proc" or "/root" or "/var" or "/var/run" or "/var/run/docker.sock" or "/var/run/crio/crio.sock" or
  "/var/run/cri-dockerd.sock" or "/var/lib/kubelet" or "/var/lib/kubelet/pki" or "/var/lib/docker/overlay2" or
  "/etc" or "/etc/kubernetes" or "/etc/kubernetes/manifests" or "/etc/kubernetes/pki" or "/home/admin"
) and
not kubernetes.audit.requestObject.spec.containers.image: (
  docker.elastic.co/beats/elastic-agent* or *elastic/elastic-agent* or docker.elastic.co/elastic-agent/elastic-agent* or
  *elastic-agent\:dev* or *cloudops-azure-devops-agent* or rancher/mirrored-longhornio-longhorn-instance-manager* or
  quay.io/calico* or ghcr.io/aquasecurity* or rancher/system-agent* or rancher/mirrored-longhornio-csi-node-driver-registrar* or
  rancher/mirrored-longhornio-livenessprobe* or quay.io/prometheus/node-exporter* or *eks/observability/cloudwatch-agent* or
  amazon/aws-efs-csi-driver* or public.ecr.aws/eks-distro/kubernetes-csi* or quay.io/cilium/cilium* or openebs/node-disk-manager* or
  openebs/cstor-csi-driver* or registry.k8s.io/sig-storage/csi-node-driver-registrar* or *.amazonaws.com/eks/csi-node-driver-registrar* or
  *.amazonaws.com/eks/livenessprobe* or *.amazonaws.com/eks/aws-efs-csi-driver* or mcr.microsoft.com/oss/v2/kubernetes-csi* or
  rancher/mirrored-cilium-cilium* or jenkins/inbound-agent* or gcr.io/datadoghq/agent* or rancher/mirrored-longhornio-longhorn-share-manager* or
  */sysdig/*
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data_stream.dataseteq
  • kubernetes.audit_logs corpus 24 (elastic 24)
field:"data_stream.dataset" kind:eq value:"kubernetes.audit_logs"
kubernetes.audit.annotations.authorization_k8s_io/decisioneq
  • allow corpus 21 (elastic 21)
field:"kubernetes.audit.annotations.authorization_k8s_io/decision" kind:eq value:"allow"
kubernetes.audit.objectRef.resourceeq
  • pods corpus 9 (elastic 9)
field:"kubernetes.audit.objectRef.resource" kind:eq value:"pods"
kubernetes.audit.requestObject.spec.volumes.hostPath.pathin
  • /
  • /etc
  • /etc/kubernetes
  • /etc/kubernetes/manifests
  • /etc/kubernetes/pki
  • /home/admin
  • /proc
  • /root
  • /var
  • /var/lib/docker/overlay2
  • /var/lib/kubelet
  • /var/lib/kubelet/pki
  • /var/run
  • /var/run/cri-dockerd.sock
  • /var/run/crio/crio.sock
  • /var/run/docker.sock
field:"kubernetes.audit.requestObject.spec.volumes.hostPath.path" kind:in
kubernetes.audit.verbin
  • create corpus 10 (elastic 10)
  • patch corpus 13 (elastic 13)
  • update corpus 12 (elastic 12)
field:"kubernetes.audit.verb" kind:in

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
kubernetes.audit.requestObject.spec.containers.imagematch.amazonaws.com/eks/aws-efs-csi-driverexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:".amazonaws.com/eks/aws-efs-csi-driver"
kubernetes.audit.requestObject.spec.containers.imagematch.amazonaws.com/eks/csi-node-driver-registrarexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:".amazonaws.com/eks/csi-node-driver-registrar"
kubernetes.audit.requestObject.spec.containers.imagematch.amazonaws.com/eks/livenessprobeexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:".amazonaws.com/eks/livenessprobe"
kubernetes.audit.requestObject.spec.containers.imagematch/sysdig/excludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"/sysdig/"
kubernetes.audit.requestObject.spec.containers.imagematchcloudops-azure-devops-agentexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"cloudops-azure-devops-agent"
kubernetes.audit.requestObject.spec.containers.imagematcheks/observability/cloudwatch-agentexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"eks/observability/cloudwatch-agent"
kubernetes.audit.requestObject.spec.containers.imagematchelastic-agent:devexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"elastic-agent:dev"
kubernetes.audit.requestObject.spec.containers.imagematchelastic/elastic-agentexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"elastic/elastic-agent"
kubernetes.audit.requestObject.spec.containers.imagestarts_withamazon/aws-efs-csi-driverexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"amazon/aws-efs-csi-driver"
kubernetes.audit.requestObject.spec.containers.imagestarts_withdocker.elastic.co/beats/elastic-agentexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"docker.elastic.co/beats/elastic-agent"
kubernetes.audit.requestObject.spec.containers.imagestarts_withdocker.elastic.co/elastic-agent/elastic-agentexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"docker.elastic.co/elastic-agent/elastic-agent"
kubernetes.audit.requestObject.spec.containers.imagestarts_withgcr.io/datadoghq/agentexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"gcr.io/datadoghq/agent"
kubernetes.audit.requestObject.spec.containers.imagestarts_withghcr.io/aquasecurityexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"ghcr.io/aquasecurity"
kubernetes.audit.requestObject.spec.containers.imagestarts_withjenkins/inbound-agentexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"jenkins/inbound-agent"
kubernetes.audit.requestObject.spec.containers.imagestarts_withmcr.microsoft.com/oss/v2/kubernetes-csiexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"mcr.microsoft.com/oss/v2/kubernetes-csi"
kubernetes.audit.requestObject.spec.containers.imagestarts_withopenebs/cstor-csi-driverexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"openebs/cstor-csi-driver"
kubernetes.audit.requestObject.spec.containers.imagestarts_withopenebs/node-disk-managerexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"openebs/node-disk-manager"
kubernetes.audit.requestObject.spec.containers.imagestarts_withpublic.ecr.aws/eks-distro/kubernetes-csiexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"public.ecr.aws/eks-distro/kubernetes-csi"
kubernetes.audit.requestObject.spec.containers.imagestarts_withquay.io/calicoexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"quay.io/calico"
kubernetes.audit.requestObject.spec.containers.imagestarts_withquay.io/cilium/ciliumexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"quay.io/cilium/cilium"
kubernetes.audit.requestObject.spec.containers.imagestarts_withquay.io/prometheus/node-exporterexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"quay.io/prometheus/node-exporter"
kubernetes.audit.requestObject.spec.containers.imagestarts_withrancher/mirrored-cilium-ciliumexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"rancher/mirrored-cilium-cilium"
kubernetes.audit.requestObject.spec.containers.imagestarts_withrancher/mirrored-longhornio-csi-node-driver-registrarexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"rancher/mirrored-longhornio-csi-node-driver-registrar"
kubernetes.audit.requestObject.spec.containers.imagestarts_withrancher/mirrored-longhornio-livenessprobeexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"rancher/mirrored-longhornio-livenessprobe"
kubernetes.audit.requestObject.spec.containers.imagestarts_withrancher/mirrored-longhornio-longhorn-instance-managerexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"rancher/mirrored-longhornio-longhorn-instance-manager"
kubernetes.audit.requestObject.spec.containers.imagestarts_withrancher/mirrored-longhornio-longhorn-share-managerexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"rancher/mirrored-longhornio-longhorn-share-manager"
kubernetes.audit.requestObject.spec.containers.imagestarts_withrancher/system-agentexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"rancher/system-agent"
kubernetes.audit.requestObject.spec.containers.imagestarts_withregistry.k8s.io/sig-storage/csi-node-driver-registrarexcludes:kubernetes.audit.requestObject.spec.containers.image field:"kubernetes.audit.requestObject.spec.containers.image" value:"registry.k8s.io/sig-storage/csi-node-driver-registrar"

Loadable Kernel Module Loaded via Unusual Parent

#
Source
github.com/elastic/protections-artifacts

This rule monitors for the loading of kernel modules by unusual parent processes. Loadable kernel modules (LKMs) are pieces of code that can be loaded into the kernel at runtime to extend its functionality. These are commonly abused by rootkits or other malicious software to hide their presence or to gain elevated privileges. These LKMs are commonly loaded through expected parent processes.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
This rule monitors for the loading of kernel modules by unusual parent processes. Loadable kernel modules (LKMs) are
pieces of code that can be loaded into the kernel at runtime to extend its functionality. These are commonly abused by
rootkits or other malicious software to hide their presence or to gain elevated privileges. These LKMs are commonly
loaded through expected parent processes.
"""
id = "7365ad8d-5aad-4720-a262-16367be025c0"
license = "Elastic License v2"
name = "Loadable Kernel Module Loaded via Unusual Parent"
os_list = ["linux"]
reference = ["https://www.elastic.co/security-labs/continuation-on-persistence-mechanisms"]
version = "1.0.10"

query = '''
process where event.type == "start" and event.action == "load_module" and (
  process.parent.executable like (
    "/tmp/*", "/var/tmp/*", "/dev/shm/*", "./*", "/run/*", "/var/run/*", "/boot/*", "/sys/*", "/lost+found/*",
    "/proc/*", "/var/mail/*", "/var/www/*", "/home/*", "/root/*" 
  ) or
  process.parent.name like~ (
    // Hidden processes
    ".*",
    // Suspicious file formats
    "*.elf", "*.sh", "*.py", "*.rb", "*.pl", "*.lua*", "*.php*", "*.js",
    // Scheduled tasks
    "cron", "crond"
  ) or
  (
    process.parent.name like ("python*", "perl*", "ruby*", "lua*", "php*", "node", "java") and
    not (
      (
        process.executable == "/usr/bin/kmod" and
        process.args in ("/sbin/modprobe", "modprobe", "/usr/bin/modprobe", "/usr/sbin/modprobe") and
        process.args_count <= 2
      ) or
      process.executable == "/sbin/iscsiadm"
    )
  )
) and
not (
  process.parent.command_line in (
    "/usr/bin/python3 -m kcarectl.__main__ --smart-update",
    "/usr/bin/python3 -m kcarectl.__main__ -q --auto-update",
    "/usr/bin/perl /usr/sbin/csf -r",
    "pvestatd",
    "/usr/bin/python3 -sP /usr/bin/firewalld --nofork --nopid",
    "/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid",
    "/usr/bin/python3 -sP /usr/sbin/firewalld --nofork --nopid",
    "/usr/bin/python3 -m kcarectl.__main__ --unload",
    "python2 /usr/bin/kcarectl -q --auto-update"
  ) or
  process.parent.args in ("/usr/share/ksplice/ksplice-apply", "/usr/bin/waydroid", "/usr/sbin/blksnap-loader") or
  process.parent.args like "/home/*/.ansible/tmp/ansible-tmp-*/AnsiballZ_command.py" or
  process.args == "ip6_tables" or
  (process.name == "systemd" and process.parent.name == "runc" and process.parent.command_line == "runc init") or
  (
    process.parent.executable like "/usr/bin/python*" and
    process.command_line in ("/usr/sbin/modprobe br_netfilter", "/usr/sbin/modprobe overlay")
  ) or
  process.parent.executable like (
    "/run/containerd/io.containerd.runtime.v2.task/k8s.io/*", "./runc", "/opt/puppetlabs/puppet/bin/ruby",
    "/home/*/work/check-hardware/coco-detect/target/debug/coco-detect"
  )
)
'''

min_endpoint_version = "9.1.4"
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 = "T1547"
name = "Boot or Logon Autostart Execution"
reference = "https://attack.mitre.org/techniques/T1547/"
[[threat.technique.subtechnique]]
id = "T1547.006"
name = "Kernel Modules and Extensions"
reference = "https://attack.mitre.org/techniques/T1547/006/"



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


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

[internal]
min_endpoint_version = "9.1.4"

Stages and Predicates

Stage 1: process

process where event.type == "start" and event.action == "load_module" and (
  process.parent.executable like (
    "/tmp/*", "/var/tmp/*", "/dev/shm/*", "./*", "/run/*", "/var/run/*", "/boot/*", "/sys/*", "/lost+found/*",
    "/proc/*", "/var/mail/*", "/var/www/*", "/home/*", "/root/*"
  ) or
  process.parent.name like~ (
    ".*",
    "*.elf", "*.sh", "*.py", "*.rb", "*.pl", "*.lua*", "*.php*", "*.js",
    "cron", "crond"
  ) or
  (
    process.parent.name like ("python*", "perl*", "ruby*", "lua*", "php*", "node", "java") and
    not (
      (
        process.executable == "/usr/bin/kmod" and
        process.args in ("/sbin/modprobe", "modprobe", "/usr/bin/modprobe", "/usr/sbin/modprobe") and
        process.args_count <= 2
      ) or
      process.executable == "/sbin/iscsiadm"
    )
  )
) and
not (
  process.parent.command_line in (
    "/usr/bin/python3 -m kcarectl.__main__ --smart-update",
    "/usr/bin/python3 -m kcarectl.__main__ -q --auto-update",
    "/usr/bin/perl /usr/sbin/csf -r",
    "pvestatd",
    "/usr/bin/python3 -sP /usr/bin/firewalld --nofork --nopid",
    "/usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid",
    "/usr/bin/python3 -sP /usr/sbin/firewalld --nofork --nopid",
    "/usr/bin/python3 -m kcarectl.__main__ --unload",
    "python2 /usr/bin/kcarectl -q --auto-update"
  ) or
  process.parent.args in ("/usr/share/ksplice/ksplice-apply", "/usr/bin/waydroid", "/usr/sbin/blksnap-loader") or
  process.parent.args like "/home/*/.ansible/tmp/ansible-tmp-*/AnsiballZ_command.py" or
  process.args == "ip6_tables" or
  (process.name == "systemd" and process.parent.name == "runc" and process.parent.command_line == "runc init") or
  (
    process.parent.executable like "/usr/bin/python*" and
    process.command_line in ("/usr/sbin/modprobe br_netfilter", "/usr/sbin/modprobe overlay")
  ) or
  process.parent.executable like (
    "/run/containerd/io.containerd.runtime.v2.task/k8s.io/*", "./runc", "/opt/puppetlabs/puppet/bin/ruby",
    "/home/*/work/check-hardware/coco-detect/target/debug/coco-detect"
  )
)

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • load_module
field:"EventType" kind:eq value:"load_module"
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
process.parent.executablewildcard
  • ./*
  • /boot/*
  • /dev/shm/*
  • /home/*
  • /lost+found/*
  • /proc/*
  • /root/*
  • /run/*
  • /sys/*
  • /tmp/*
  • /var/mail/*
  • /var/run/*
  • /var/tmp/*
  • /var/www/*
field:"ParentImage" kind:wildcard
process.parent.namewildcard
  • *.elf
  • *.js
  • *.lua*
  • *.php*
  • *.pl
  • *.py
  • *.rb
  • *.sh
  • .*
  • cron
  • crond
  • java
  • lua*
  • node
  • perl*
  • php*
  • python*
  • ruby*
field:"parent_process_basename" kind:wildcard

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.command_linein/usr/sbin/modprobe br_netfilter, /usr/sbin/modprobe overlayexcludes:process.command_line field:"process.command_line" value:"/usr/sbin/modprobe br_netfilter" field:"process.command_line" value:"/usr/sbin/modprobe overlay"
process.parent.executablestarts_with/usr/bin/pythonexcludes:process.parent.executable field:"process.parent.executable" value:"/usr/bin/python"
process.nameeqsystemdexcludes:process.name field:"process.name" value:"systemd"
process.parent.command_lineeqrunc initexcludes:process.parent.command_line field:"process.parent.command_line" value:"runc init"
process.parent.nameeqruncexcludes:process.parent.name field:"process.parent.name" value:"runc"
process.argseqip6_tablesexcludes:process.args field:"process.args" value:"ip6_tables"
process.parent.argsin/usr/bin/waydroid, /usr/sbin/blksnap-loader, /usr/share/ksplice/ksplice-applyexcludes:process.parent.args field:"process.parent.args" value:"/usr/bin/waydroid" field:"process.parent.args" value:"/usr/sbin/blksnap-loader" field:"process.parent.args" value:"/usr/share/ksplice/ksplice-apply"
process.parent.argswildcard/home/*/.ansible/tmp/ansible-tmp-*/AnsiballZ_command.pyexcludes:process.parent.args field:"process.parent.args" value:"/home/*/.ansible/tmp/ansible-tmp-*/AnsiballZ_command.py"
process.parent.command_linein/usr/bin/perl /usr/sbin/csf -r, /usr/bin/python3 -m kcarectl.__main__ --smart-update, /usr/bin/python3 -m kcarectl.__main__ --unload, /usr/bin/python3 -m kcarectl.__main__ -q --auto-update, /usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid, /usr/bin/python3 -sP /usr/bin/firewalld --nofork --nopid, /usr/bin/python3 -sP /usr/sbin/firewalld --nofork --nopid, pvestatd, python2 /usr/bin/kcarectl -q --auto-updateexcludes:process.parent.command_line
process.parent.executablewildcard/run/containerd/io.containerd.runtime.v2.task/k8s.io/*, ./runc, /opt/puppetlabs/puppet/bin/ruby, /home/*/work/check-hardware/coco-detect/target/debug/coco-detectexcludes:process.parent.executable

Multi-Value Secret Searching via Find

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

Identifies the execution of the find command with a multi-value search pattern to collect sensitive information. This is a common technique used by attackers to collect sensitive information from the system.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the execution of the find command with a multi-value search pattern to collect sensitive information. This is
a common technique used by attackers to collect sensitive information from the system.
"""
id = "18405ccf-5443-4577-8b25-629aac642002"
license = "Elastic License v2"
name = "Multi-Value Secret Searching via Find"
os_list = ["linux"]
reference = [
    "https://socket.dev/blog/10-npm-typosquatted-packages-deploy-credential-harvester",
    "https://futuresearch.ai/blog/litellm-pypi-supply-chain-attack/",
    "https://www.virustotal.com/gui/file/71e35aef03099cd1f2d6446734273025a163597de93912df321ef118bf135238",
]
version = "1.0.2"

query = '''
sequence by process.parent.entity_id with maxspan=10s
  [process where event.type == "start" and event.action == "exec" and process.name == "find" and 
  process.args == "-type" and process.args == "f" and process.command_line like~ (
    "*password*", "*passwd*", "*pwd*", "*secret*", "*token*", "*apikey*", "*api.key*", "*access_key*",
    "*private_key*", "*client_secret*", "*credential*", "*auth*", "*bearer*",
    "*begin private*", "*begin openssh private*", "*begin rsa private*", "*begin dsa private*", "*begin ec private*",
    "*id_rsa*", "*id_dsa*", "*id_ecdsa*", "*id_ed25519*", "*ssh-rsa*", "*ghp_*", "*github_pat*", "*xoxb-*",
    "*hooks.slack.com*", "*discord.com/api/webhooks*", "*/.aws/*", "*/.env *", "*/.azure/*",
    "*azure_client_id*", "*azure_tenant_id*", "*azure_client_secret*", "*azure_federated_token_file*",
    "*identity_endpoint*", "*identity_header*", "*msi_endpoint*", "*msi_secret*", "*/var/run/secrets/azure/*",
    "*/.config/gcloud/*", "*application_default_credentials.json*", "*type: service_account*", "*client_email*",
    "*/var/run/secrets/google/*", "*google_application_credentials*", "*/run/secrets/kubernetes.io/serviceaccount/*"
  ) and process.parent.executable != null and
  not (
    (process.args == "-L" and process.args == "-xdev") or
    process.parent.args like (
      "/etc/cron.daily/plesk-rrd-cleaner", "/war-deployment/ops.servers/backup.sh", "/home/*/tools/unyo/mulpay_deletelog.sh",
      "/usr/local/psa/admin/sbin/spamtrain", "plz-out/bin/pipeline/authn/authn.bin.sh", "/usr/bin/makepkg"
    ) or
    process.command_line in (
      "find /etc/zerum-stacks/lynx/wdr_proxy/.htpasswd -type f",
      "find /run/credentials/getty@tty4.service -xdev -type f ( -perm -0002 -a ! -perm -1000 )",
      "find /run/credentials/getty@tty3.service -xdev -type f ( -perm -0002 -a ! -perm -1000 )",
      "find /run/snapd/ns/authd-msentraid.mnt -xdev -type f -perm -002 -exec chmod o-w {} ;"
    ) or
    process.command_line like "find /var/tmp/portage/*" or
    process.parent.executable in ("/usr/bin/make", "/usr/bin/sw-engine", "/usr/local/bin/build_rpm", "/opt/puppetlabs/puppet/bin/ruby") or
    process.working_directory like (
      "/opt/rapid7/ir_agent/components/endpoint_broker/common", "/__w/Modular-Teepee/Modular-Teepee",
      "/build*", "/opt/netconfs/home/*", "/tmp/plz_sandbox"
    ) or
    process.args like (
      "/run/credentials/systemd-*.service", "/var/lib/sannav/docker/containers/*/mounts/secrets", "/snap/authd-msentraid/*",
      "/home/*/.cache/yay/1password/pkg/1password/*", "/var/tmp/dracut.*/initramfs"
    ) or
    (process.parent.name == "bash" and process.parent.command_line like "*XDG_CONFIG_HOME*" and process.working_directory == "/tmp/plz_sandbox") or
    (
      process.parent.executable == "/usr/bin/xargs" and
      process.parent.command_line == "xargs -I {} find {} -xdev -type f ( -perm -0002 -a ! -perm -1000 )"
    )
  )] as event0
  [process where event.type == "start" and event.action == "exec" and process.name == "find" and 
  not startswith~(process.command_line, event0.process.command_line) and
  process.args == "-type" and process.args == "f" and process.command_line like~ (
    "*password*", "*passwd*", "*pwd*", "*secret*", "*token*", "*apikey*", "*api.key*", "*access_key*",
    "*private_key*", "*client_secret*", "*credential*", "*auth*", "*bearer*",
    "*begin private*", "*begin openssh private*", "*begin rsa private*", "*begin dsa private*", "*begin ec private*",
    "*id_rsa*", "*id_dsa*", "*id_ecdsa*", "*id_ed25519*", "*ssh-rsa*", "*ghp_*", "*github_pat*", "*xoxb-*",
    "*hooks.slack.com*", "*discord.com/api/webhooks*", "*/.aws/*", "*/.env *", "*/.azure/*",
    "*azure_client_id*", "*azure_tenant_id*", "*azure_client_secret*", "*azure_federated_token_file*",
    "*identity_endpoint*", "*identity_header*", "*msi_endpoint*", "*msi_secret*", "*/var/run/secrets/azure/*",
    "*/.config/gcloud/*", "*application_default_credentials.json*", "*type: service_account*", "*client_email*",
    "*/var/run/secrets/google/*", "*google_application_credentials*", "*/run/secrets/kubernetes.io/serviceaccount/*"
  )] as event1
  [process where event.type == "start" and event.action == "exec" and process.name == "find" and
  not startswith~(process.command_line, event1.process.command_line) and
  process.args == "-type" and process.args == "f" and process.command_line like~ (
    "*password*", "*passwd*", "*pwd*", "*secret*", "*token*", "*apikey*", "*api.key*", "*access_key*",
    "*private_key*", "*client_secret*", "*credential*", "*auth*", "*bearer*",
    "*begin private*", "*begin openssh private*", "*begin rsa private*", "*begin dsa private*", "*begin ec private*",
    "*id_rsa*", "*id_dsa*", "*id_ecdsa*", "*id_ed25519*", "*ssh-rsa*", "*ghp_*", "*github_pat*", "*xoxb-*",
    "*hooks.slack.com*", "*discord.com/api/webhooks*", "*/.aws/*", "*/.env *", "*/.azure/*",
    "*azure_client_id*", "*azure_tenant_id*", "*azure_client_secret*", "*azure_federated_token_file*",
    "*identity_endpoint*", "*identity_header*", "*msi_endpoint*", "*msi_secret*", "*/var/run/secrets/azure/*",
    "*/.config/gcloud/*", "*application_default_credentials.json*", "*type: service_account*", "*client_email*",
    "*/var/run/secrets/google/*", "*google_application_credentials*", "*/run/secrets/kubernetes.io/serviceaccount/*"
  )]
'''

min_endpoint_version = "8.4.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.entity_id"
state = 2

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

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

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1082"
name = "System Information Discovery"
reference = "https://attack.mitre.org/techniques/T1082/"

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


[threat.tactic]
id = "TA0007"
name = "Discovery"
reference = "https://attack.mitre.org/tactics/TA0007/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1074"
name = "Data Staged"
reference = "https://attack.mitre.org/techniques/T1074/"
[[threat.technique.subtechnique]]
id = "T1074.001"
name = "Local Data Staging"
reference = "https://attack.mitre.org/techniques/T1074/001/"


[[threat.technique]]
id = "T1119"
name = "Automated Collection"
reference = "https://attack.mitre.org/techniques/T1119/"


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

[internal]
min_endpoint_version = "8.4.0"

Stages and Predicates

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

Stage 1: process

[process where event.type == "start" and event.action == "exec" and process.name == "find" and 
  process.args == "-type" and process.args == "f" and process.command_line like~ (
    "*password*", "*passwd*", "*pwd*", "*secret*", "*token*", "*apikey*", "*api.key*", "*access_key*",
    "*private_key*", "*client_secret*", "*credential*", "*auth*", "*bearer*",
    "*begin private*", "*begin openssh private*", "*begin rsa private*", "*begin dsa private*", "*begin ec private*",
    "*id_rsa*", "*id_dsa*", "*id_ecdsa*", "*id_ed25519*", "*ssh-rsa*", "*ghp_*", "*github_pat*", "*xoxb-*",
    "*hooks.slack.com*", "*discord.com/api/webhooks*", "*/.aws/*", "*/.env *", "*/.azure/*",
    "*azure_client_id*", "*azure_tenant_id*", "*azure_client_secret*", "*azure_federated_token_file*",
    "*identity_endpoint*", "*identity_header*", "*msi_endpoint*", "*msi_secret*", "*/var/run/secrets/azure/*",
    "*/.config/gcloud/*", "*application_default_credentials.json*", "*type: service_account*", "*client_email*",
    "*/var/run/secrets/google/*", "*google_application_credentials*", "*/run/secrets/kubernetes.io/serviceaccount/*"
  ) and process.parent.executable != null and
  not (
    (process.args == "-L" and process.args == "-xdev") or
    process.parent.args like (
      "/etc/cron.daily/plesk-rrd-cleaner", "/war-deployment/ops.servers/backup.sh", "/home/*/tools/unyo/mulpay_deletelog.sh",
      "/usr/local/psa/admin/sbin/spamtrain", "plz-out/bin/pipeline/authn/authn.bin.sh", "/usr/bin/makepkg"
    ) or
    process.command_line in (
      "find /etc/zerum-stacks/lynx/wdr_proxy/.htpasswd -type f",
      "find /run/credentials/getty@tty4.service -xdev -type f ( -perm -0002 -a ! -perm -1000 )",
      "find /run/credentials/getty@tty3.service -xdev -type f ( -perm -0002 -a ! -perm -1000 )",
      "find /run/snapd/ns/authd-msentraid.mnt -xdev -type f -perm -002 -exec chmod o-w {} ;"
    ) or
    process.command_line like "find /var/tmp/portage/*" or
    process.parent.executable in ("/usr/bin/make", "/usr/bin/sw-engine", "/usr/local/bin/build_rpm", "/opt/puppetlabs/puppet/bin/ruby") or
    process.working_directory like (
      "/opt/rapid7/ir_agent/components/endpoint_broker/common", "/__w/Modular-Teepee/Modular-Teepee",
      "/build*", "/opt/netconfs/home/*", "/tmp/plz_sandbox"
    ) or
    process.args like (
      "/run/credentials/systemd-*.service", "/var/lib/sannav/docker/containers/*/mounts/secrets", "/snap/authd-msentraid/*",
      "/home/*/.cache/yay/1password/pkg/1password/*", "/var/tmp/dracut.*/initramfs"
    ) or
    (process.parent.name == "bash" and process.parent.command_line like "*XDG_CONFIG_HOME*" and process.working_directory == "/tmp/plz_sandbox") or
    (
      process.parent.executable == "/usr/bin/xargs" and
      process.parent.command_line == "xargs -I {} find {} -xdev -type f ( -perm -0002 -a ! -perm -1000 )"
    )
  )] as event0

Stage 2: process

[process where event.type == "start" and event.action == "exec" and process.name == "find" and 
  not startswith~(process.command_line, event0.process.command_line) and
  process.args == "-type" and process.args == "f" and process.command_line like~ (
    "*password*", "*passwd*", "*pwd*", "*secret*", "*token*", "*apikey*", "*api.key*", "*access_key*",
    "*private_key*", "*client_secret*", "*credential*", "*auth*", "*bearer*",
    "*begin private*", "*begin openssh private*", "*begin rsa private*", "*begin dsa private*", "*begin ec private*",
    "*id_rsa*", "*id_dsa*", "*id_ecdsa*", "*id_ed25519*", "*ssh-rsa*", "*ghp_*", "*github_pat*", "*xoxb-*",
    "*hooks.slack.com*", "*discord.com/api/webhooks*", "*/.aws/*", "*/.env *", "*/.azure/*",
    "*azure_client_id*", "*azure_tenant_id*", "*azure_client_secret*", "*azure_federated_token_file*",
    "*identity_endpoint*", "*identity_header*", "*msi_endpoint*", "*msi_secret*", "*/var/run/secrets/azure/*",
    "*/.config/gcloud/*", "*application_default_credentials.json*", "*type: service_account*", "*client_email*",
    "*/var/run/secrets/google/*", "*google_application_credentials*", "*/run/secrets/kubernetes.io/serviceaccount/*"
  )] as event1

Stage 3: process

[process where event.type == "start" and event.action == "exec" and process.name == "find" and
  not startswith~(process.command_line, event1.process.command_line) and
  process.args == "-type" and process.args == "f" and process.command_line like~ (
    "*password*", "*passwd*", "*pwd*", "*secret*", "*token*", "*apikey*", "*api.key*", "*access_key*",
    "*private_key*", "*client_secret*", "*credential*", "*auth*", "*bearer*",
    "*begin private*", "*begin openssh private*", "*begin rsa private*", "*begin dsa private*", "*begin ec private*",
    "*id_rsa*", "*id_dsa*", "*id_ecdsa*", "*id_ed25519*", "*ssh-rsa*", "*ghp_*", "*github_pat*", "*xoxb-*",
    "*hooks.slack.com*", "*discord.com/api/webhooks*", "*/.aws/*", "*/.env *", "*/.azure/*",
    "*azure_client_id*", "*azure_tenant_id*", "*azure_client_secret*", "*azure_federated_token_file*",
    "*identity_endpoint*", "*identity_header*", "*msi_endpoint*", "*msi_secret*", "*/var/run/secrets/azure/*",
    "*/.config/gcloud/*", "*application_default_credentials.json*", "*type: service_account*", "*client_email*",
    "*/var/run/secrets/google/*", "*google_application_credentials*", "*/run/secrets/kubernetes.io/serviceaccount/*"
  )]

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.argseq
  • -type
  • f
field:"process.args" kind:eq
process.command_linewildcard
  • */.aws/*
  • */.azure/*
  • */.config/gcloud/*
  • */.env *
  • */run/secrets/kubernetes.io/serviceaccount/*
  • */var/run/secrets/azure/*
  • */var/run/secrets/google/*
  • *access_key*
  • *api.key*
  • *apikey*
  • *application_default_credentials.json*
  • *auth*
  • *azure_client_id*
  • *azure_client_secret*
  • *azure_federated_token_file*
  • *azure_tenant_id*
  • *bearer*
  • *begin dsa private*
  • *begin ec private*
  • *begin openssh private*
  • *begin private*
  • *begin rsa private*
  • *client_email*
  • *client_secret*
  • *credential*
  • *discord.com/api/webhooks*
  • *ghp_*
  • *github_pat*
  • *google_application_credentials*
  • *hooks.slack.com*
  • *id_dsa*
  • *id_ecdsa*
  • *id_ed25519*
  • *id_rsa*
  • *identity_endpoint*
  • *identity_header*
  • *msi_endpoint*
  • *msi_secret*
  • *passwd*
  • *password*
  • *private_key*
  • *pwd*
  • *secret*
  • *ssh-rsa*
  • *token*
  • *type: service_account*
  • *xoxb-*
field:"CommandLine" kind:wildcard
process.nameeq
  • find
field:"process_basename" kind:eq value:"find"
process.parent.executableis_not_null
  • (no value, null check)
field:"ParentImage" kind:is_not_null

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argseq-Lexcludes:process.args field:"process.args" value:"-L"
process.argseq-xdevexcludes:process.args field:"process.args" value:"-xdev"
process.parent.command_lineeqxargs -I {} find {} -xdev -type f ( -perm -0002 -a ! -perm -1000 )excludes:process.parent.command_line field:"process.parent.command_line" value:"xargs -I {} find {} -xdev -type f ( -perm -0002 -a ! -perm -1000 )"
process.parent.executableeq/usr/bin/xargsexcludes:process.parent.executable field:"process.parent.executable" value:"/usr/bin/xargs"
process.parent.command_linematchXDG_CONFIG_HOMEexcludes:process.parent.command_line field:"process.parent.command_line" value:"XDG_CONFIG_HOME"
process.parent.nameeqbashexcludes:process.parent.name field:"process.parent.name" value:"bash"
process.working_directoryeq/tmp/plz_sandboxexcludes:process.working_directory field:"process.working_directory" value:"/tmp/plz_sandbox"
process.argswildcard/run/credentials/systemd-*.service, /var/lib/sannav/docker/containers/*/mounts/secrets, /snap/authd-msentraid/*, /home/*/.cache/yay/1password/pkg/1password/*, /var/tmp/dracut.*/initramfsexcludes:process.args
process.command_lineinfind /etc/zerum-stacks/lynx/wdr_proxy/.htpasswd -type f, find /run/credentials/getty@tty3.service -xdev -type f ( -perm -0002 -a ! -perm -1000 ), find /run/credentials/getty@tty4.service -xdev -type f ( -perm -0002 -a ! -perm -1000 ), find /run/snapd/ns/authd-msentraid.mnt -xdev -type f -perm -002 -exec chmod o-w {} ;excludes:process.command_line
process.command_linestarts_withfind /var/tmp/portage/excludes:process.command_line field:"process.command_line" value:"find /var/tmp/portage/"
process.parent.argswildcard/etc/cron.daily/plesk-rrd-cleaner, /war-deployment/ops.servers/backup.sh, /home/*/tools/unyo/mulpay_deletelog.sh, /usr/local/psa/admin/sbin/spamtrain, plz-out/bin/pipeline/authn/authn.bin.sh, /usr/bin/makepkgexcludes:process.parent.args
process.parent.executablein/opt/puppetlabs/puppet/bin/ruby, /usr/bin/make, /usr/bin/sw-engine, /usr/local/bin/build_rpmexcludes:process.parent.executable
process.working_directorywildcard/opt/rapid7/ir_agent/components/endpoint_broker/common, /__w/Modular-Teepee/Modular-Teepee, /build*, /opt/netconfs/home/*, /tmp/plz_sandboxexcludes:process.working_directory
process.command_linestarts_withevent0.process.command_lineexcludes:process.command_line field:"process.command_line" value:"event0.process.command_line"
process.command_linestarts_withevent1.process.command_lineexcludes:process.command_line field:"process.command_line" value:"event1.process.command_line"

Permission Theft - Prevented - Elastic Endgame

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

Elastic Endgame prevented Permission Theft. Click the Elastic Endgame icon in the event.module column or the link in the rule.reference column for additional information.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2020/02/18"
maturity = "production"
promotion = true
updated_date = "2026/03/24"

[rule]
author = ["Elastic"]
description = """
Elastic Endgame prevented Permission Theft. Click the Elastic Endgame icon in the event.module column or the link in the
rule.reference column for additional information.
"""
from = "now-2m"
index = ["endgame-*"]
interval = "1m"
language = "kuery"
license = "Elastic License v2"
max_signals = 1000
name = "Permission Theft - Prevented - Elastic Endgame"
risk_score = 47
rule_id = "453f659e-0429-40b1-bfdb-b6957286e04b"
setup = """## Setup

### Additional notes

For information on troubleshooting the maximum alerts warning please refer to this [guide](https://www.elastic.co/guide/en/security/current/alerts-ui-monitor.html#troubleshoot-max-alerts).
"""
severity = "medium"
tags = ["Data Source: Elastic Endgame", "Use Case: Threat Detection", "Tactic: Privilege Escalation", "Resources: Investigation Guide"]
timestamp_override = "event.ingested"
type = "query"

query = '''
event.kind:alert and event.module:endgame and endgame.metadata.type:prevention and (event.action:token_protection_event or endgame.event_subtype_full:token_protection_event)
'''
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 Permission Theft - Prevented - Elastic Endgame

Elastic Endgame is a security solution that prevents unauthorized access by monitoring and blocking attempts to manipulate access tokens, a common privilege escalation tactic. Adversaries exploit token manipulation to gain elevated permissions without detection. The detection rule identifies and alerts on prevention events related to token protection, leveraging specific event types and actions to flag suspicious activities, thus mitigating potential threats.

### Possible investigation steps

- Review the alert details to confirm the event.kind is 'alert' and event.module is 'endgame', ensuring the alert is relevant to Elastic Endgame's token protection.
- Examine the event.action and endgame.event_subtype_full fields to determine if the alert was triggered by a 'token_protection_event', which indicates an attempt to manipulate access tokens.
- Investigate the source and destination of the alert by analyzing associated IP addresses, user accounts, and hostnames to identify potential unauthorized access attempts.
- Check the endgame.metadata.type field to verify that the event type is 'prevention', confirming that the attempted permission theft was successfully blocked.
- Correlate the alert with other recent alerts or logs to identify patterns or repeated attempts that might indicate a persistent threat actor.
- Assess the risk score and severity level to prioritize the investigation and determine if immediate action is required to mitigate potential threats.

### False positive analysis

- Routine administrative tasks involving legitimate token manipulation may trigger alerts. Review the context of the event to determine if it aligns with expected administrative activities.
- Scheduled scripts or automated processes that require token access might be flagged. Identify these processes and consider creating exceptions for known, safe operations.
- Software updates or installations that involve token changes can generate alerts. Verify the source and purpose of the update to ensure it is authorized, and exclude these events if they are part of regular maintenance.
- Security tools or monitoring solutions that interact with tokens for legitimate purposes may cause false positives. Cross-reference with known tool activities and whitelist these actions if they are verified as non-threatening.
- User behavior analytics might misinterpret legitimate user actions as suspicious. Analyze user activity patterns and adjust the detection thresholds or rules to better align with normal user behavior.

### Response and remediation

- Immediately isolate the affected system to prevent further unauthorized access or privilege escalation attempts.
- Revoke any potentially compromised access tokens and force re-authentication for affected accounts to ensure that only legitimate users regain access.
- Conduct a thorough review of recent access logs and token usage to identify any unauthorized access or actions taken by the adversary.
- Apply patches or updates to the affected systems and applications to address any vulnerabilities that may have been exploited for token manipulation.
- Implement enhanced monitoring on the affected systems to detect any further attempts at access token manipulation or privilege escalation.
- Notify the security team and relevant stakeholders about the incident, providing details of the threat and actions taken, and escalate to higher management if the threat level increases.
- Review and update access control policies and token management practices to prevent similar incidents in the future, ensuring that only necessary permissions are granted and regularly audited."""


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

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

[[rule.threat.technique.subtechnique]]
id = "T1134.001"
name = "Token Impersonation/Theft"
reference = "https://attack.mitre.org/techniques/T1134/001/"

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

Stages and Predicates

Stage 1: query

event.kind:alert and event.module:endgame and endgame.metadata.type:prevention and (event.action:token_protection_event or endgame.event_subtype_full:token_protection_event)

Indicators

These rows show field, operator, and value matches.

Potential CertiGhost AD CS Machine Identity Mismatch (CVE-2026-54121)

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

Identifies successful Active Directory Certificate Services (AD CS) certificate issuance events where a machine-account requester differs from the Remote Machine Discovery (RMD) chase target while the event's DNS subject alternative name (SAN) matches that target. This requester-to-target mismatch may indicate CertiGhost (CVE-2026-54121) or similar abuse of AD CS request-context chase processing.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[metadata]
creation_date = "2026/08/12"
integration = ["system"]
maturity = "production"
updated_date = "2026/08/12"

[rule]
author = ["Elastic"]
description = """
Identifies successful Active Directory Certificate Services (AD CS) certificate issuance events where a machine-account
requester differs from the Remote Machine Discovery (RMD) chase target while the event's DNS subject alternative name
(SAN) matches that target. This requester-to-target mismatch may indicate CertiGhost (CVE-2026-54121) or similar abuse
of AD CS request-context chase processing.
"""
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Potential CertiGhost AD CS Machine Identity Mismatch (CVE-2026-54121)"
references = [
    "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-54121",
    "https://gist.github.com/H0j3n/a5ef2609b5f2944ac2390a191a534c26",
    "https://github.com/aniqfakhrul/CVE-2026-54121",
]
risk_score = 73
rule_id = "2985ea6e-5b1e-4845-9a57-95f7f78b35f1"
severity = "high"
tags = [
    "Domain: Endpoint",
    "Domain: Identity",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Tactic: Privilege Escalation",
    "Use Case: Active Directory Monitoring",
    "Use Case: Vulnerability",
    "Data Source: Active Directory",
    "Data Source: Windows Security Event Logs",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
FROM logs-system.security-* METADATA _id, _index, _version
| WHERE event.code == "4887" AND
    winlog.event_data.Requester LIKE "*$" AND
    winlog.event_data.Attributes IS NOT NULL

// Parse Attributes for RMD and CDC, and as a fallback when dedicated template or SAN fields are absent.
// CDC and the effective template are retained for triage purposes
| GROK winlog.event_data.Attributes
    """(?im)^[ \t]*CertificateTemplate[ \t]*:[ \t]*(?<Esql.attributes_certificate_template>[^\r\n]+)\r?$"""
| GROK winlog.event_data.Attributes
    """(?im)^[ \t]*SAN[ \t]*:[ \t]*dns[ \t]*=[ \t]*(?<Esql.attributes_san_value>[^\r\n]+)\r?$"""
| GROK winlog.event_data.SubjectAlternativeName
    """(?im)^[ \t]*DNS[ \t]+Name[ \t]*=[ \t]*(?<Esql.event_san_value>[^\r\n]+)\r?$"""
| GROK winlog.event_data.Attributes
    """(?im)^[ \t]*cdc[ \t]*:[ \t]*(?<Esql.cdc_value>[^\r\n]+)\r?$"""
| GROK winlog.event_data.Attributes
    """(?im)^[ \t]*rmd[ \t]*:[ \t]*(?<Esql.rmd_value>[^\r\n]+)\r?$"""
| EVAL Esql.effective_certificate_template = TRIM(COALESCE(
         winlog.event_data.CertificateTemplate,
         Esql.attributes_certificate_template
       )),
       Esql.san_value = TRIM(COALESCE(Esql.event_san_value, Esql.attributes_san_value)),
       Esql.cdc_value = TRIM(Esql.cdc_value),
       Esql.rmd_value = TRIM(Esql.rmd_value),
       Esql.normalized_requester = TO_LOWER(
         REPLACE(winlog.event_data.Requester, """^.*\\|\$$""", "")
       ),
       Esql.normalized_san_value = TO_LOWER(
         REPLACE(Esql.san_value, """\.$""", "")
       ),
       Esql.normalized_rmd_value = TO_LOWER(
         REPLACE(Esql.rmd_value, """\.$""", "")
       )
// Preserve IP-shaped values; shorten other SAN and RMD values to the first DNS label for machine-account comparison.
| EVAL Esql.san_is_ip_shaped =
          Esql.normalized_san_value RLIKE """[0-9]{1,3}(\.[0-9]{1,3}){3}""" OR Esql.normalized_san_value LIKE "*:*",
       Esql.rmd_is_ip_shaped =
          Esql.normalized_rmd_value RLIKE """[0-9]{1,3}(\.[0-9]{1,3}){3}""" OR Esql.normalized_rmd_value LIKE "*:*"
| EVAL Esql.normalized_san_target = CASE(
         Esql.san_is_ip_shaped,
         Esql.normalized_san_value,
         REPLACE(Esql.normalized_san_value, """\..*$""", "")
       ),
       Esql.normalized_rmd_target = CASE(
         Esql.rmd_is_ip_shaped,
         Esql.normalized_rmd_value,
         REPLACE(Esql.normalized_rmd_value, """\..*$""", "")
       )
| WHERE Esql.normalized_requester IS NOT NULL AND
    Esql.normalized_san_target IS NOT NULL AND
    Esql.normalized_rmd_target IS NOT NULL
| WHERE Esql.normalized_requester != Esql.normalized_rmd_target AND
    Esql.normalized_san_target == Esql.normalized_rmd_target
| KEEP @timestamp, _id, _index, _version, event.code, event.action, event.category, event.type, event.outcome,
    event.created, event.ingested, data_stream.dataset, data_stream.namespace, host.id, host.name,
    winlog.computer_name, winlog.record_id, winlog.event_data.RequestId, winlog.event_data.Requester,
    winlog.event_data.CertificateTemplate, winlog.event_data.Subject, winlog.event_data.SubjectAlternativeName,
    winlog.event_data.Attributes, winlog.event_data.Disposition, winlog.event_data.SubjectKeyIdentifier,
    Esql.effective_certificate_template, Esql.san_value, Esql.cdc_value, Esql.rmd_value,
    Esql.normalized_requester, Esql.normalized_san_target, Esql.normalized_rmd_target
'''

setup = """## Setup

Audit Certification Services must be enabled on enterprise certification authorities so that successful certificate
issuance generates Security event 4887.

The Windows Security integration must retain `winlog.event_data.Attributes`, including the requested SAN and chase
attributes. The rule prefers dedicated certificate-template and subject-alternative-name fields when present and uses
`Attributes` as a fallback. Dropped, truncated, or rewritten attributes create a visibility gap and do not indicate
benign activity.

Setup instructions: https://ela.st/audit-certification-services
"""

note = """## Triage and analysis

### Investigating Potential CertiGhost AD CS Machine Identity Mismatch (CVE-2026-54121)

#### Possible investigation steps

- Does the matched AD CS issuance record validate the identity mismatch?
  - Focus: `event.code`, `winlog.event_data.RequestId`, `winlog.event_data.Requester`, `Esql.san_value`, `Esql.rmd_value`
  - Hint: Reopen the Windows Security 4887 record on the same CA host and request ID. Compare the parsed SAN and RMD with the complete `winlog.event_data.Attributes` and dedicated SAN field; additional SAN values or disagreement keep the case unresolved. $investigate_0
  - Implication: Event 4887 proves successful issuance, and the alert establishes that the requester differs from the RMD target while the parsed SAN matches that target. This is an operational anti-pattern. Close as benign only when CA records and test records identify an authorized CertiGhost or AD CS security test matching the exact CA, request ID, requester, target, template, and time.
- What identity and authentication capability did the issued certificate receive?
  - Focus: `Esql.effective_certificate_template`, `winlog.event_data.Subject`, `winlog.event_data.SubjectAlternativeName`, `winlog.event_data.SubjectKeyIdentifier`
  - Hint: Retrieve the issued certificate and CA request/template configuration for the same request ID. Inspect the certificate's actual subject, SAN, EKUs or application policies, validity and revocation state, and the template's subject-name settings and enrollment permissions.
  - Implication: Event 4887 and the template name alone do not establish the complete certificate contents or authentication capability. A certificate that represents the RMD target and permits authentication increases the likelihood and impact of credential abuse. Missing certificate or template configuration is unresolved, not benign.
- What other issuances by the requester appear on the same CA host?
  - Focus: `host.id`, `winlog.event_data.Requester`, `winlog.event_data.RequestId`, `winlog.event_data.Attributes`, `winlog.event_data.SubjectAlternativeName`
  - Hint: Recover 4887 events for the same requester on this CA host. $investigate_1
  - Implication: Repeated successful requests for different SAN/RMD targets expand the potential abuse scope. One isolated request does not reduce the significance of the current mismatch.
- What other CA events reference the same target identity?
  - Focus: `Esql.san_value`, `Esql.rmd_value`, `winlog.event_data.Attributes`, `winlog.event_data.SubjectAlternativeName`, `winlog.event_data.Requester`
  - Hint: Copy the alert's exact SAN and RMD values into a scoped Timeline or Discover search for raw 4886, 4887, and 4888 records on the same CA host. Use contains or wildcard matching against `winlog.event_data.Attributes` and `winlog.event_data.SubjectAlternativeName`; derived `Esql.*` fields exist only on the alert.
  - Implication: Requests for the same target from additional unexpected accounts expand the affected scope. The absence of other matching events does not clear the current issuance.
- Did the CA connect to the CDC value during certificate processing?
  - Focus: `host.id`, `Esql.cdc_value`, `destination.ip`, `destination.port`, `process.name`
  - Hint: When the CDC value is an IP address, search network events from the CA host around issuance for that `destination.ip`. For a hostname, resolve it from collected DNS or asset evidence before comparing destination IPs. Review LDAP or LDAPS from `certsrv.exe` and SMB from `System` without requiring either process for all callback traffic.
  - Implication: CA-host LDAP or SMB traffic to the CDC value supports request-context chase activity, but neither the CDC attribute nor a connection alone proves exploitation. Missing DNS or CA network telemetry is unresolved, not benign.
- Does surrounding activity show requester creation or target-certificate use?
  - Focus: `event.code`, `winlog.event_data.Requester`, `Esql.normalized_rmd_target`, `winlog.event_data.TargetUserName`, `winlog.event_data.PreAuthType`
  - Hint: After validating the issuance, inspect account-management events where `winlog.event_data.TargetUserName` matches the requester account name without its domain prefix. Inspect successful 4768 events with `winlog.event_data.PreAuthType` equal to `16`. For DNS-shaped RMD values, compare `winlog.event_data.TargetUserName` with the normalized RMD target plus `$`; for IP-shaped values, first resolve the associated computer account from AD, asset, or CA evidence. Treat later authentication as corroboration unless identity and certificate evidence establish the relationship.
  - Implication: Requester creation or change followed by target PKINIT strengthens the exploitation hypothesis. Missing account-management or domain-controller authentication telemetry is unresolved, not benign.

Escalate when the mismatch is not an authorized test, the issued certificate can authenticate as the target, or callback and follow-on evidence corroborate abuse. Close only when CA, certificate, and test records establish the exact authorized scope; preserve and escalate when evidence or visibility is mixed or incomplete.

### False positive analysis

The detected requester-to-target relationship is an operational anti-pattern and did not appear in the self-aligned enrollment controls. Authorized CertiGhost or AD CS security testing is the only currently validated benign explanation. Treat other claimed cross-identity enrollment workflows as unresolved until the 4887 source event, CA request record, issued certificate, template configuration, requester, target, CA, and time scope align without contradictions.

Do not close on recurrence, absence of related alerts, or the requester account name alone. ES|QL fields created by the query cannot be used in rule exceptions. If an exception is required for recurring authorized testing, combine narrowly scoped source fields such as the CA `host.id`, `winlog.event_data.Requester`, and the exact `winlog.event_data.Attributes` pattern. Avoid exceptions based only on a host, requester, or template.

### Response and remediation

- Preserve the 4887 source record, CA request and database records, issued certificate and identifiers, template configuration, and relevant authentication and network evidence before disruptive action.
- Identify affected certification authorities and apply the Microsoft security update or mitigation for CVE-2026-54121. Review request history for the requester and target to identify additional certificates requiring action.
- If malicious activity is confirmed, revoke the affected certificate and verify that revocation information is distributed. Disable or remove an attacker-controlled requester account after preserving evidence. Rotate the target machine credentials and invalidate affected authentication material when certificate use or impersonation is established.
- Isolate an endpoint only when host evidence attributes compromise to that system. The requester account may not map to a managed endpoint, and the target identity alone does not prove that the target endpoint was compromised.
- Record confirmed certificate identifiers, affected principals, CA configuration gaps, and telemetry gaps for the responsible response, PKI, identity, and detection owners.
"""
[rule.investigation_fields]
field_names = [
    "@timestamp",
    "event.code",
    "host.id",
    "host.name",
    "winlog.computer_name",
    "winlog.record_id",
    "winlog.event_data.RequestId",
    "winlog.event_data.Requester",
    "winlog.event_data.CertificateTemplate",
    "winlog.event_data.Subject",
    "winlog.event_data.SubjectAlternativeName",
    "winlog.event_data.Attributes",
    "winlog.event_data.Disposition",
    "winlog.event_data.SubjectKeyIdentifier",
    "Esql.effective_certificate_template",
    "Esql.san_value",
    "Esql.rmd_value",
    "Esql.cdc_value",
    "Esql.normalized_requester",
    "Esql.normalized_san_target",
    "Esql.normalized_rmd_target",
]

[[transform.investigate]]
label = "Matched certificate issuance"
description = "Finds the Windows Security 4887 certificate issuance record on the same CA host and request ID."
providers = [[
    { excluded = false, field = "event.code", queryType = "phrase", value = "4887", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "winlog.event_data.RequestId", queryType = "phrase", value = "{{winlog.event_data.RequestId}}", valueType = "string" },
]]
relativeFrom = "now-24h"
relativeTo = "now"

[[transform.investigate]]
label = "Same requester issuances"
description = "Finds successful certificate issuance events for the same requester on the same CA host."
providers = [[
    { excluded = false, field = "event.code", queryType = "phrase", value = "4887", valueType = "string" },
    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
    { excluded = false, field = "winlog.event_data.Requester", queryType = "phrase", value = "{{winlog.event_data.Requester}}", valueType = "string" },
]]
relativeFrom = "now-7d"
relativeTo = "now"


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1649"
name = "Steal or Forge Authentication Certificates"
reference = "https://attack.mitre.org/techniques/T1649/"

[[rule.threat.technique]]
id = "T1212"
name = "Exploitation for Credential Access"
reference = "https://attack.mitre.org/techniques/T1212/"


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


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

Stages and Predicates

Stage 1: from

FROM logs-system.security-* METADATA _id, _index, _version

Stage 2: where

| WHERE event.code == "4887" AND
    winlog.event_data.Requester LIKE "*$" AND
    winlog.event_data.Attributes IS NOT NULL

Stage 3: grok

| GROK winlog.event_data.Attributes
    """(?im)^[ \t]*CertificateTemplate[ \t]*:[ \t]*(?<Esql.attributes_certificate_template>[^\r\n]+)\r?$"""

Stage 4: grok

| GROK winlog.event_data.Attributes
    """(?im)^[ \t]*SAN[ \t]*:[ \t]*dns[ \t]*=[ \t]*(?<Esql.attributes_san_value>[^\r\n]+)\r?$"""

Stage 5: grok

| GROK winlog.event_data.SubjectAlternativeName
    """(?im)^[ \t]*DNS[ \t]+Name[ \t]*=[ \t]*(?<Esql.event_san_value>[^\r\n]+)\r?$"""

Stage 6: grok

| GROK winlog.event_data.Attributes
    """(?im)^[ \t]*cdc[ \t]*:[ \t]*(?<Esql.cdc_value>[^\r\n]+)\r?$"""

Stage 7: grok

| GROK winlog.event_data.Attributes
    """(?im)^[ \t]*rmd[ \t]*:[ \t]*(?<Esql.rmd_value>[^\r\n]+)\r?$"""

Stage 8: eval

| EVAL Esql.effective_certificate_template = TRIM(COALESCE(
         winlog.event_data.CertificateTemplate,
         Esql.attributes_certificate_template
       )),
       Esql.san_value = TRIM(COALESCE(Esql.event_san_value, Esql.attributes_san_value)),
       Esql.cdc_value = TRIM(Esql.cdc_value),
       Esql.rmd_value = TRIM(Esql.rmd_value),
       Esql.normalized_requester = TO_LOWER(
         REPLACE(winlog.event_data.Requester, """^.*\\|\$$""", "")
       ),
       Esql.normalized_san_value = TO_LOWER(
         REPLACE(Esql.san_value, """\.$""", "")
       ),
       Esql.normalized_rmd_value = TO_LOWER(
         REPLACE(Esql.rmd_value, """\.$""", "")
       )

Stage 9: eval

| EVAL Esql.san_is_ip_shaped =
          Esql.normalized_san_value RLIKE """[0-9]{1,3}(\.[0-9]{1,3}){3}""" OR Esql.normalized_san_value LIKE "*:*",
       Esql.rmd_is_ip_shaped =
          Esql.normalized_rmd_value RLIKE """[0-9]{1,3}(\.[0-9]{1,3}){3}""" OR Esql.normalized_rmd_value LIKE "*:*"

Stage 10: eval

| EVAL Esql.normalized_san_target = CASE(
         Esql.san_is_ip_shaped,
         Esql.normalized_san_value,
         REPLACE(Esql.normalized_san_value, """\..*$""", "")
       ),
       Esql.normalized_rmd_target = CASE(
         Esql.rmd_is_ip_shaped,
         Esql.normalized_rmd_value,
         REPLACE(Esql.normalized_rmd_value, """\..*$""", "")
       )
Esql.normalized_rmd_target =
ifEsql.rmd_is_ip_shapedEsql.normalized_rmd_value
elseREPLACE(Esql.normalized_rmd_value, """\..*$""", "")
Esql.normalized_san_target =
ifEsql.san_is_ip_shapedEsql.normalized_san_value
elseREPLACE(Esql.normalized_san_value, """\..*$""", "")

Stage 11: where

| WHERE Esql.normalized_requester IS NOT NULL AND
    Esql.normalized_san_target IS NOT NULL AND
    Esql.normalized_rmd_target IS NOT NULL

Stage 12: where

| WHERE Esql.normalized_requester != Esql.normalized_rmd_target AND
    Esql.normalized_san_target == Esql.normalized_rmd_target

Stage 13: keep

| KEEP @timestamp, _id, _index, _version, event.code, event.action, event.category, event.type, event.outcome,
    event.created, event.ingested, data_stream.dataset, data_stream.namespace, host.id, host.name,
    winlog.computer_name, winlog.record_id, winlog.event_data.RequestId, winlog.event_data.Requester,
    winlog.event_data.CertificateTemplate, winlog.event_data.Subject, winlog.event_data.SubjectAlternativeName,
    winlog.event_data.Attributes, winlog.event_data.Disposition, winlog.event_data.SubjectKeyIdentifier,
    Esql.effective_certificate_template, Esql.san_value, Esql.cdc_value, Esql.rmd_value,
    Esql.normalized_requester, Esql.normalized_san_target, Esql.normalized_rmd_target

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

FieldSource
@timestampKEEP @timestamp
_idKEEP _id
_indexKEEP _index
_versionKEEP _version
event.codeKEEP event.code
event.actionKEEP event.action
event.categoryKEEP event.category
event.typeKEEP event.type
event.outcomeKEEP event.outcome
event.createdKEEP event.created
event.ingestedKEEP event.ingested
data_stream.datasetKEEP data_stream.dataset
data_stream.namespaceKEEP data_stream.namespace
host.idKEEP host.id
host.nameKEEP host.name
winlog.computer_nameKEEP winlog.computer_name
winlog.record_idKEEP winlog.record_id
winlog.event_data.RequestIdKEEP winlog.event_data.RequestId
winlog.event_data.RequesterKEEP winlog.event_data.Requester
winlog.event_data.CertificateTemplateKEEP winlog.event_data.CertificateTemplate
winlog.event_data.SubjectKEEP winlog.event_data.Subject
winlog.event_data.SubjectAlternativeNameKEEP winlog.event_data.SubjectAlternativeName
winlog.event_data.AttributesKEEP winlog.event_data.Attributes
winlog.event_data.DispositionKEEP winlog.event_data.Disposition
winlog.event_data.SubjectKeyIdentifierKEEP winlog.event_data.SubjectKeyIdentifier
Esql.effective_certificate_templateKEEP Esql.effective_certificate_template
Esql.san_valueKEEP Esql.san_value
Esql.cdc_valueKEEP Esql.cdc_value
Esql.rmd_valueKEEP Esql.rmd_value
Esql.normalized_requesterKEEP Esql.normalized_requester
Esql.normalized_san_targetKEEP Esql.normalized_san_target
Esql.normalized_rmd_targetKEEP Esql.normalized_rmd_target

Potential DLL Hijacking via Environment Paths

#
Source
github.com/elastic/protections-artifacts

Identifies attempts to load an unsigned DLL from Microsoft default environment paths and by a Microsoft signed binary. This may indicate an attempt to elevate privilege or persist via DLL Search Order Hijacking.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies attempts to load an unsigned DLL from Microsoft default environment paths and by a Microsoft signed binary.
This may indicate an attempt to elevate privilege or persist via DLL Search Order Hijacking.
"""
id = "971ff66d-a0fe-4fdc-aa74-3cb1a19336f4"
license = "Elastic License v2"
name = "Potential DLL Hijacking via Environment Paths"
os_list = ["windows"]
version = "1.0.23"

query = '''
library where

 dll.Ext.relative_file_creation_time <= 900 and

 process.code_signature.status : "trusted" and process.code_signature.subject_name : "Microsoft *" and

 not dll.code_signature.status : ("trusted", "errorCode_endpoint*") and

 dll.path :
   ("?:\\Users\\*\\AppData\\Local\\Microsoft\\WindowsApps\\*.dll",
    "?:\\Windows\\System32\\WindowsPowerShell\\v1.0\\*.dll",
    "?:\\Windows\\System32\\wbem\\*.dll",
    "?:\\Windows\\system32\\OpenSSH\\*.dll",
    "?:\\Python??\\*",
    "?:\\Program Files (x86)\\Common Files\\Oracle\\Java\\javapath\\*.dll",
    "?:\\Program Files\\Microsoft SQL Server\\*\\Tools\\Binn\\*.dll",
    "?:\\Program Files (x86)\\Microsoft SQL Server\\*\\Tools\\Binn\\*.dll",
    "?:\\Program Files\\dotnet\\*",
    "?:\\Program Files\\Windows NT\\*",
    "?:\\Program Files (x86)\\Windows NT\\*") and

 /* not subdirs */
 not dll.path :
       ("?:\\Users\\*\\AppData\\Local\\Microsoft\\WindowsApps\\*\\*.dll",
        "?:\\Windows\\System32\\WindowsPowerShell\\v1.0\\*\\*.dll",
        "?:\\Windows\\System32\\wbem\\*\\*.dll",
        "?:\\Windows\\system32\\OpenSSH\\*\\*.dll",
        "?:\\Python??\\*\\*",
        "?:\\Program Files (x86)\\Common Files\\Oracle\\Java\\javapath\\*\\*.dll",
        "?:\\Program Files\\Microsoft SQL Server\\*\\Tools\\Binn\\*\\*.dll",
        "?:\\Program Files (x86)\\Microsoft SQL Server\\*\\Tools\\Binn\\*\\*.dll",
        "?:\\Program Files\\dotnet\\*\\*", 
        "?:\\Windows\\Microsoft.NET\\Framework*\\Temporary ASP.NET Files\\*",
        "?:\\Windows\\Sys*\\wbem\\wbemsvc.dll",
        "?:\\Windows\\Sys*\\wbem\\wbemprox.dll",
        "?:\\Windows\\Sys*\\wbem\\wmiutils.dll",
        "?:\\Windows\\Sys*\\wbem\\mofd.dll",
        "?:\\Windows\\Sys*\\wbem\\esscli.dll",
        "?:\\Windows\\Sys*\\wbem\\cimwin32.dll",
        "?:\\Windows\\System32\\wbem\\MDMSettingsProv.dll") and

 /* not DLL loaded from the process.executable current directory - except windir and subdirs */
 not (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 dll.path : ("?:\\Windows\\*.dll", "?:\\Program Files*\\Windows NT\\*")) and
 /* https://github.com/valinet/ExplorerPatcher/wiki/Antivirus-false-positives */
 not (process.name : "explorer.exe" and dll.pe.imphash : "caebca4526b1331e2458f507d6ef4838" and
      dll.pe.original_file_name : "ExplorerPatcher.dll") and 
 not (dll.pe.original_file_name : "Radeon Settings Host Service" and dll.path : "?:\\Windows\\System32\\amdihk64.dll") and 
 not dll.path regex~ """(c:\\windows\\system32\\hp[a-z0-9\-\_\.]+\.dll|c:\\windows\\syswow64\\hp[a-z0-9\-\_\.]+\.dll)""" and 
 not process.executable : 
               ("?:\\Windows\\SysWOW64\\regsvr32.exe", 
                "?:\\Windows\\system32\\regsvr32.exe", 
                "?:\\Windows\\SysWOW64\\rundll32.exe", 
                "?:\\Windows\\system32\\rundll32.exe",
                "?:\\Windows\\SysWOW64\\msiexec.exe", 
                "?:\\Windows\\system32\\msiexec.exe", 
                "?:\\Windows\\System32\\spoolsv.exe") and 
 not dll.hash.sha256 : 
              ("fc96ee3fad0edf3f26b6ba118a4fad919eefefa478996f3cee9c28e274c8130f", 
               "2392414a18bfdd146cb55d4e865809f2dac35f857b9bff20a939da94876fb9eb", 
               "a1fe9948e692b1fa2ebba3c3d6fb2b88f7d97b418398369ad3865418c4e3cb88", 
               "90a88986c8c5f30fb153ec803feda6572b2c2630a6c9578fcc017800692694d5", 
               "db9cdc52afb49ae408f5f7e6f3213615a25c16ad6ea56f7caf51c62ea548e8e5", 
               "da2d6ff6aa7b28aa5d8e1b9c1f1af9221b929741761a72b965911c97c338fa8f", 
               "a1628b28eb62fada7cd068557c2df466097f05d2de828c34c3d0eb6705c05821", 
               "da2d6ff6aa7b28aa5d8e1b9c1f1af9221b929741761a72b965911c97c338fa8f", 
               "e416f3765be8358eb2fe789c8f9033bbbeda952ce6a36a350d403e2f07b963f8",
               "ca70262f22d519dc152f9d93db7fe704b2c57517b137d557effca6ba65e4de70")
'''

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

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

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



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

[internal]
min_endpoint_version = "8.10.0"

Stages and Predicates

Stage 1: library

library where
 dll.Ext.relative_file_creation_time <= 900 and
 process.code_signature.status : "trusted" and process.code_signature.subject_name : "Microsoft *" and
 not dll.code_signature.status : ("trusted", "errorCode_endpoint*") and
 dll.path :
   ("?:\\Users\\*\\AppData\\Local\\Microsoft\\WindowsApps\\*.dll",
    "?:\\Windows\\System32\\WindowsPowerShell\\v1.0\\*.dll",
    "?:\\Windows\\System32\\wbem\\*.dll",
    "?:\\Windows\\system32\\OpenSSH\\*.dll",
    "?:\\Python??\\*",
    "?:\\Program Files (x86)\\Common Files\\Oracle\\Java\\javapath\\*.dll",
    "?:\\Program Files\\Microsoft SQL Server\\*\\Tools\\Binn\\*.dll",
    "?:\\Program Files (x86)\\Microsoft SQL Server\\*\\Tools\\Binn\\*.dll",
    "?:\\Program Files\\dotnet\\*",
    "?:\\Program Files\\Windows NT\\*",
    "?:\\Program Files (x86)\\Windows NT\\*") and
 not dll.path :
       ("?:\\Users\\*\\AppData\\Local\\Microsoft\\WindowsApps\\*\\*.dll",
        "?:\\Windows\\System32\\WindowsPowerShell\\v1.0\\*\\*.dll",
        "?:\\Windows\\System32\\wbem\\*\\*.dll",
        "?:\\Windows\\system32\\OpenSSH\\*\\*.dll",
        "?:\\Python??\\*\\*",
        "?:\\Program Files (x86)\\Common Files\\Oracle\\Java\\javapath\\*\\*.dll",
        "?:\\Program Files\\Microsoft SQL Server\\*\\Tools\\Binn\\*\\*.dll",
        "?:\\Program Files (x86)\\Microsoft SQL Server\\*\\Tools\\Binn\\*\\*.dll",
        "?:\\Program Files\\dotnet\\*\\*",
        "?:\\Windows\\Microsoft.NET\\Framework*\\Temporary ASP.NET Files\\*",
        "?:\\Windows\\Sys*\\wbem\\wbemsvc.dll",
        "?:\\Windows\\Sys*\\wbem\\wbemprox.dll",
        "?:\\Windows\\Sys*\\wbem\\wmiutils.dll",
        "?:\\Windows\\Sys*\\wbem\\mofd.dll",
        "?:\\Windows\\Sys*\\wbem\\esscli.dll",
        "?:\\Windows\\Sys*\\wbem\\cimwin32.dll",
        "?:\\Windows\\System32\\wbem\\MDMSettingsProv.dll") and
 not (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 dll.path : ("?:\\Windows\\*.dll", "?:\\Program Files*\\Windows NT\\*")) and
 not (process.name : "explorer.exe" and dll.pe.imphash : "caebca4526b1331e2458f507d6ef4838" and
      dll.pe.original_file_name : "ExplorerPatcher.dll") and
 not (dll.pe.original_file_name : "Radeon Settings Host Service" and dll.path : "?:\\Windows\\System32\\amdihk64.dll") and
 not dll.path regex~ """(c:\\windows\\system32\\hp[a-z0-9\-\_\.]+\.dll|c:\\windows\\syswow64\\hp[a-z0-9\-\_\.]+\.dll)""" and
 not process.executable :
               ("?:\\Windows\\SysWOW64\\regsvr32.exe",
                "?:\\Windows\\system32\\regsvr32.exe",
                "?:\\Windows\\SysWOW64\\rundll32.exe",
                "?:\\Windows\\system32\\rundll32.exe",
                "?:\\Windows\\SysWOW64\\msiexec.exe",
                "?:\\Windows\\system32\\msiexec.exe",
                "?:\\Windows\\System32\\spoolsv.exe") and
 not dll.hash.sha256 :
              ("fc96ee3fad0edf3f26b6ba118a4fad919eefefa478996f3cee9c28e274c8130f",
               "2392414a18bfdd146cb55d4e865809f2dac35f857b9bff20a939da94876fb9eb",
               "a1fe9948e692b1fa2ebba3c3d6fb2b88f7d97b418398369ad3865418c4e3cb88",
               "90a88986c8c5f30fb153ec803feda6572b2c2630a6c9578fcc017800692694d5",
               "db9cdc52afb49ae408f5f7e6f3213615a25c16ad6ea56f7caf51c62ea548e8e5",
               "da2d6ff6aa7b28aa5d8e1b9c1f1af9221b929741761a72b965911c97c338fa8f",
               "a1628b28eb62fada7cd068557c2df466097f05d2de828c34c3d0eb6705c05821",
               "da2d6ff6aa7b28aa5d8e1b9c1f1af9221b929741761a72b965911c97c338fa8f",
               "e416f3765be8358eb2fe789c8f9033bbbeda952ce6a36a350d403e2f07b963f8",
               "ca70262f22d519dc152f9d93db7fe704b2c57517b137d557effca6ba65e4de70")

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
dll.Ext.relative_file_creation_timele
  • 900 transforms: number corpus 9 (elastic 9)
field:"dll.Ext.relative_file_creation_time" kind:le value:"900"
dll.pathwildcard
  • ?:\Program Files (x86)\Common Files\Oracle\Java\javapath\*.dll
  • ?:\Program Files (x86)\Microsoft SQL Server\*\Tools\Binn\*.dll
  • ?:\Program Files (x86)\Windows NT\*
  • ?:\Program Files*\Windows NT\*
  • ?:\Program Files\Microsoft SQL Server\*\Tools\Binn\*.dll
  • ?:\Program Files\Windows NT\*
  • ?:\Program Files\dotnet\*
  • ?:\Python??\*
  • ?:\Users\*\AppData\Local\Microsoft\WindowsApps\*.dll
  • ?:\Windows\*.dll
  • ?:\Windows\System32\WindowsPowerShell\v1.0\*.dll
  • ?:\Windows\System32\wbem\*.dll
  • ?:\Windows\system32\OpenSSH\*.dll
field:"ImageLoaded" kind:wildcard
process.code_signature.statuswildcard
  • trusted corpus 6 (elastic 6)
field:"SignatureStatus" kind:wildcard value:"trusted"
process.code_signature.subject_namewildcard
  • Microsoft * corpus 10 (elastic 10)
field:"Signature" kind:wildcard value:"Microsoft *"

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
dll.pathwildcard?:\Windows\*.dll, ?:\Program Files*\Windows NT\*excludes:dll.path field:"dll.path" value:"?:\Windows\*.dll" field:"dll.path" value:"?:\Program Files*\Windows NT\*"
dll.patheq?:\Windows\System32\amdihk64.dllexcludes:dll.path field:"dll.path" value:"?:\Windows\System32\amdihk64.dll"
dll.pe.original_file_nameeqRadeon Settings Host Serviceexcludes:dll.pe.original_file_name field:"dll.pe.original_file_name" value:"Radeon Settings Host Service"
dll.pe.imphasheqcaebca4526b1331e2458f507d6ef4838excludes:dll.pe.imphash field:"dll.pe.imphash" value:"caebca4526b1331e2458f507d6ef4838"
dll.pe.original_file_nameeqExplorerPatcher.dllexcludes:dll.pe.original_file_name field:"dll.pe.original_file_name" value:"ExplorerPatcher.dll"
process.nameeqexplorer.exeexcludes:process.name field:"process.name" value:"explorer.exe"
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.sha256eqfc96ee3fad0edf3f26b6ba118a4fad919eefefa478996f3cee9c28e274c8130f, 2392414a18bfdd146cb55d4e865809f2dac35f857b9bff20a939da94876fb9eb, a1fe9948e692b1fa2ebba3c3d6fb2b88f7d97b418398369ad3865418c4e3cb88, 90a88986c8c5f30fb153ec803feda6572b2c2630a6c9578fcc017800692694d5, db9cdc52afb49ae408f5f7e6f3213615a25c16ad6ea56f7caf51c62ea548e8e5, da2d6ff6aa7b28aa5d8e1b9c1f1af9221b929741761a72b965911c97c338fa8f, a1628b28eb62fada7cd068557c2df466097f05d2de828c34c3d0eb6705c05821, da2d6ff6aa7b28aa5d8e1b9c1f1af9221b929741761a72b965911c97c338fa8f, e416f3765be8358eb2fe789c8f9033bbbeda952ce6a36a350d403e2f07b963f8, ca70262f22d519dc152f9d93db7fe704b2c57517b137d557effca6ba65e4de70excludes:dll.hash.sha256
dll.pathregex_match(c:\windows\system32\hp[a-z0-9\-\_.]+.dll|c:\windows\syswow64\hp[a-z0-9\-\_.]+.dll)excludes:dll.path field:"dll.path" value:"(c:\windows\system32\hp[a-z0-9\-\_.]+.dll|c:\windows\syswow64\hp[a-z0-9\-\_.]+.dll)"
dll.pathwildcard?:\Users\*\AppData\Local\Microsoft\WindowsApps\*\*.dll, ?:\Windows\System32\WindowsPowerShell\v1.0\*\*.dll, ?:\Windows\System32\wbem\*\*.dll, ?:\Windows\system32\OpenSSH\*\*.dll, ?:\Python??\*\*, ?:\Program Files (x86)\Common Files\Oracle\Java\javapath\*\*.dll, ?:\Program Files\Microsoft SQL Server\*\Tools\Binn\*\*.dll, ?:\Program Files (x86)\Microsoft SQL Server\*\Tools\Binn\*\*.dll, ?:\Program Files\dotnet\*\*, ?:\Windows\Microsoft.NET\Framework*\Temporary ASP.NET Files\*, ?:\Windows\Sys*\wbem\wbemsvc.dll, ?:\Windows\Sys*\wbem\wbemprox.dll, ?:\Windows\Sys*\wbem\wmiutils.dll, ?:\Windows\Sys*\wbem\mofd.dll, ?:\Windows\Sys*\wbem\esscli.dll, ?:\Windows\Sys*\wbem\cimwin32.dll, ?:\Windows\System32\wbem\MDMSettingsProv.dllexcludes:dll.path
process.executableeq?:\Windows\SysWOW64\regsvr32.exe, ?:\Windows\system32\regsvr32.exe, ?:\Windows\SysWOW64\rundll32.exe, ?:\Windows\system32\rundll32.exe, ?:\Windows\SysWOW64\msiexec.exe, ?:\Windows\system32\msiexec.exe, ?:\Windows\System32\spoolsv.exeexcludes:process.executable

Potential Lateral Movement via SMBExec

#
Source
github.com/elastic/protections-artifacts

Identifies suspicious service execution via Windows Command Shell which may indicate lateral movement attempt via known offensive testing tool like SMBExec.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies suspicious service execution via Windows Command Shell which may indicate lateral movement attempt via known
offensive testing tool like SMBExec.
"""
id = "c6a9046e-7ca3-460b-9707-f17e6dfabcb6"
license = "Elastic License v2"
name = "Potential Lateral Movement via SMBExec"
os_list = ["windows"]
reference = [
    "https://github.com/SecureAuthCorp/impacket/blob/master/examples/smbexec.py#L277",
    "https://www.elastic.co/security-labs/unmasking-financial-services-intrusion-ref0657",
]
version = "1.0.28"

query = '''
process where event.action == "start" and
 (
   ((process.name : "cmd.exe" or process.pe.original_file_name == "Cmd.Exe") and process.parent.name : "services.exe" and
     process.command_line : "*/Q*echo*.bat*del*.bat*") or

   /* descendant of SMBExec */
   (descendant of
    [process where event.action == "start" and (process.name : "cmd.exe" or process.pe.original_file_name == "Cmd.Exe") and
     process.parent.name : "services.exe" and process.command_line : "*/Q*echo*.bat*del*.bat*"] and
     not process.executable : ("?:\\Windows\\system32\\cmd.exe", "?:\\Windows\\System32\\conhost.exe"))
  )
'''

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

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



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


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

[internal]
min_endpoint_version = "7.15.0"

Stages and Predicates

Stage 1: process

process where event.action == "start" and
 (
   ((process.name : "cmd.exe" or process.pe.original_file_name == "Cmd.Exe") and process.parent.name : "services.exe" and
     process.command_line : "*/Q*echo*.bat*del*.bat*") or
   (descendant of
    [process where event.action == "start" and (process.name : "cmd.exe" or process.pe.original_file_name == "Cmd.Exe") and
     process.parent.name : "services.exe" and process.command_line : "*/Q*echo*.bat*del*.bat*"] and
     not process.executable : ("?:\\Windows\\system32\\cmd.exe", "?:\\Windows\\System32\\conhost.exe"))
  )

Indicators

These rows show field, operator, and value matches.

Potential Linux Credential Dumping via Mimipenguin

#
Source
github.com/elastic/protections-artifacts

Identifies the execution of the mimipenguin exploit script which is linux adaptation of Windows tool mimikatz. Mimipenguin exploit script is used to dump clear text passwords from a currently logged-in user. The tool exploits a known vulnerability CVE-2018-20781. Malicious actors can exploit the cleartext credentials in memory by dumping the process and extracting lines that have a high probability of containing cleartext passwords.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
Identifies the execution of the mimipenguin exploit script which is linux adaptation of Windows tool mimikatz.
Mimipenguin exploit script is used to dump clear text passwords from a currently logged-in user. The tool exploits a
known vulnerability CVE-2018-20781. Malicious actors can exploit the cleartext credentials in memory by dumping the
process and extracting lines that have a high probability of containing cleartext passwords.
"""
id = "ff106396-2a52-40a2-97be-3e933bc0adbc"
license = "Elastic License v2"
name = "Potential Linux Credential Dumping via Mimipenguin"
os_list = ["linux"]
reference = [
    "https://github.com/huntergregal/mimipenguin",
    "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-20781",
]
version = "1.0.2"

query = '''
process where event.type == "start" and event.action == "exec" and process.name like "python*" and
process.parent.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and
process.command_line like """python* -c from __future__ import print_function; import crypt; print(crypt.crypt("*", "$$$"))"""
'''

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

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

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1003"
name = "OS Credential Dumping"
reference = "https://attack.mitre.org/techniques/T1003/"
[[threat.technique.subtechnique]]
id = "T1003.008"
name = "/etc/passwd and /etc/shadow"
reference = "https://attack.mitre.org/techniques/T1003/008/"



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

[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 like "python*" and
process.parent.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish") and
process.command_line like """python* -c from __future__ import print_function; import crypt; print(crypt.crypt("*", "$$$"))"""

Indicators

These rows show field, operator, and value matches.

Potential Remote Code Execution via Mail Server

#
Source
github.com/elastic/protections-artifacts

This rule detects potential remote code execution attempts via commonly used mail server applications, by monitoring for unusual child processes and command line arguments.

MITRE ATT&CK Coverage

Rule Body

[rule]
description = """
This rule detects potential remote code execution attempts via commonly used mail server applications, by monitoring for
unusual child processes and command line arguments.
"""
id = "318e6a4f-fb72-4010-a625-d41bae9e349a"
license = "Elastic License v2"
name = "Potential Remote Code Execution via Mail Server"
os_list = ["linux"]
version = "1.0.7"

query = '''
process where event.type == "start" and event.action == "exec" and process.parent.interactive == false and
(
  process.parent.name in ("exim4", "postfix", "smtpd", "sendmail", "dovecot", "amavisd-new", "amavisd", "spamd") or
  (
    process.parent.name == "master" and
    process.parent.executable like "/*/postfix*master"
  )
) and
not (
  (process.parent.name == "exim4" and process.args like "/usr/lib/nagios/plugins/check_file_age*") or
  (process.parent.name in ("amavisd-new", "amavisd") and process.command_line == "/usr/bin/gzip -d") or
  (process.parent.name == "dovecot" and process.command_line == "gzip") or
  (process.parent.name == "amavisd" and process.name == "amavisd")
) and
(
  process.name in (
    "scp", "gzip", "bzip2", "xz", "tar", "getcap", "capsh", "find", "nohup", "setsid", "timeout", "disown",
    "mkfifo", "printenv", "env", "chpasswd", "echo"
  ) or
  (
    process.name == "touch" and
    not process.args like (
      "/home/*/.esmtp_queue/*/lock", "/root/.esmtp_queue/*/lock", "/prod/prod/data/prodstage/possum/error/"
    )
  ) or
  process.name like ".*" or
  (
    process.name in ("whoami", "id", "hostname", "uname", "ps", "netstat", "ss", "ip", "ifconfig") and
    process.interactive == true and process.parent.interactive == false
  ) or
  process.executable like ("/dev/shm/*", "/tmp/*", "/var/tmp/*", "/root/*", "./*") or
  (
    process.executable like ("/bin/python*", "/usr/bin/python*", "/usr/local/bin/python*") and (
      process.args == "-c" or
      (
        process.args_count <= 2 and
        process.args like ("/tmp/*", "/var/tmp/*", "/dev/shm/*", "/var/www/*", "/root/*", "/home/*/*", "./*.py") and
        process.args like "*.py*"
      )
    ) and
    not process.args in ("--version", "app.py")
  ) or
  (
    process.executable like (
      "/bin/perl*", "/usr/bin/perl*", "/usr/local/bin/perl*",
      "/bin/ruby*", "/usr/bin/ruby*", "/usr/local/bin/ruby*",
      "/bin/lua*", "/usr/bin/lua*", "/usr/local/bin/lua*",
      "/bin/node", "/usr/bin/node", "/usr/local/bin/node"
    ) and
    (process.args like "-e*" or process.args_count <= 2)
  ) or
  (
    process.executable like ("/bin/php*", "/usr/bin/php*", "/usr/local/bin/php*") and
    (process.args like "-r*" or process.args_count <= 2) and
    not (
      process.args like "var_export*" or
      process.command_line in ("php -r echo get_current_user().PHP_EOL;", "php -r echo date('T');")
    ) 
  ) or
  (
    process.name in ("nc", "ncat", "netcat", "netcat.openbsd", "netcat.traditional", "nc.openbsd", "nc.traditional") and (
      process.command_line regex ".*[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}.*" or
      process.command_line like "*http*"
    ) and
    not process.args in ("localhost", "127.0.0.1", "-z", "-zv") 
  ) or
  (
    process.name == "socat" and
    process.command_line like~ ("*exec*", "*tty*", "*fork*", "*file*", "*open*") and
    process.command_line like~ ("*tcp*", "*udp*", "*openssl*")
  ) or
  (
    process.name == "openssl" and (
      process.command_line like ("*s_server*", "*s_client*") or
      (process.args == "enc" and process.args in ("-d", "-base64", "-a", "-A"))
    )
  ) or
  (
    process.name in ("curl", "wget") and process.args like~ ("-o", "--output*", "-o-") and (
      process.command_line regex ".*[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}.*" or
      process.command_line like "*http*"
    ) and
    process.command_line like ("* /tmp/*", "* /var/tmp/*", "* /dev/shm/*", "* /var/www/*", "* ~/*", "* /home/*", "* /run/*", "* /var/run/*")
  ) or
  (
    process.name in ("base64", "basez", "base64plain", "base64url", "base64mime", "base64pem", "basenc", "base32", "base16") and
    process.args like~ "-*d*"
  ) or
  (
    process.name == "xxd" and process.args like~ ("-*r*", "-*p*")
  ) or
  (process.name == "sudo" and process.args == "-l") or
  (
    process.executable like ("/bin/chmod", "/usr/bin/chmod", "/usr/local/bin/chmod") and
    process.args like ("+x", "a+x", "0777", "755", "777", "+s", "u+s", "g+s")
  ) or
  (
    process.executable like ("/bin/cat", "/usr/bin/cat", "/usr/local/bin/cat") and
    process.args like (
      "/etc/passwd", "/etc/shadow", "/etc/hostname", "/etc/hosts", "*ssh*", "/proc/self/environ",
      "*.env*", "*../../../*", "*/secrets/kubernetes.io/serviceaccount/*", "*/.docker/config.json*",
      "*/.npmrc*", "*.aws/credentials*", "*/.aws/config*"
    )
  ) or
  (
    process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox") and
    process.args in ("-c", "-cl", "-lc") and (
      process.command_line like (
        /* Suspicious Paths */
        "* /tmp/* ", "* /var/tmp/* ", "* /dev/shm/*", "* /var/www/*", "* /run/*", "* /var/run/*",

        /* Interpreter Execution */
        "*python* -c*", "*php* -r*", "*perl* -e*", "*ruby* -e*", "*lua* -e*", "*node * -e *",

        /* Encoding, Decoding & Piping */
        "*|sh", "*| sh *", "*| sh ", "*|bash*", "*| bash*", "*|zsh*",  "*| zsh*", "*|dash*",  "*| dash*",
        "*|python*", "*| python*", "*|php*", "*| php*", "*|perl*", "*| perl*", "*|ruby*", "*| ruby*",
        "*|node*", "*| node*", "*|lua*",  "*| lua*", "*|busybox*", "*| busybox*", "*|*base64 -d*", "*|*base64 --decode*",
        "*|*base64 --decode*", "*|*openssl base64 -d*", "*xxd *", "*| openssl*enc * -d *", "*b64decode -r*",

        /* Reverse Shells */
        "*netcat *", "* nc *", "*ncat *", "*/dev/tcp*", "*/dev/udp/*", "*socat *", "*openssl*s_client *", "*stty*raw*-echo*",

        /* File Access */
        "*>*/etc/cron*", "*/etc/ssh*", "*/home/*/.ssh/*", "*/root/.ssh*", "*~/.ssh/*", "*/etc/shadow*", "*/etc/passwd*", "*chpasswd*",

        /* Helpers */
        "*nohup*", "*setsid *", "*timeout *sh -c *", "*disown*", "*env *sh *-c*",

        /* Miscellaneous */
        "*chattr *", "*busybox *",  "*#!*", "*chmod +x *", "*chmod 777*", 
        
        /* Decompression */
        "*gzip -*d *", "*bzip2 -*d *", "*xz -*d *", "*tar -*x*",
         
         /* Path Traversal */
         "*../../../*etc/*", "*/.../*", "*../../../*home/*/*", "*../../../*root/*"
      ) or
      (
        process.command_line like ("*wget *", "*curl *") and
        (
          process.command_line regex ".*[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}(:[0-9]{1,5})?/.*" or
          process.command_line like ("*http*", "*ftp*")
        ) and
        (
          (
            process.command_line regex~ """.*curl.* \-[a-zA-Z]*[oO]( .+|\-.*)?""" or
            process.command_line like~ ("*curl* --output*", "*curl* --remote-name*")
          ) or
          (
            (
              process.command_line regex~ """.*wget.* \-[a-zA-Z]*O.*""" or
              process.command_line like~ "*wget* --output-document*"
            ) and
          not process.command_line like """*--output-document "-"*"""
          ) or
          process.command_line like ("*|*sh*", "*|*python*", "*|*php*", "*|*perl*", "*|*ruby*", "*|*node*", "*|*lua*", "*|*busybox*") or
          (
            process.command_line like ("*curl *>> /*", "*curl *>>/*", "*curl *> /*", "*curl *>/*", "*wget *>> /*", "*wget *>>/*", "*wget *> /*", "*wget *>/*") and
            not process.command_line like ("*> /dev/null*", "*>/dev/null*", "*curl*/etc/cobra/*/uploads/whatsapp/*")
          )
        ) and
        not process.command_line like ("*-O /dev/null*", "*-o /dev/null*")
      )
    )
  )
) and
not (
  process.executable like ("/tmp/newroot/*", "/opt/lxc/*", "/var/snap/lxd/*") or
  process.parent.command_line == "runc init" or
  process.command_line in ("pickup -l -t unix -u", "pickup -l -t unix -u -c") or
  (
    process.parent.executable == "/etc/init.d/postfix" and process.command_line == "/bin/echo -n postfix is running"
  ) or
  (
    process.parent.executable == "/usr/libexec/postfix/master" and
    process.command_line like (
      "/usr/bin/hostname", "ps -eo pid,args", "uname -m", "/usr/bin/perl -w /root/check_megaraid_sas",
      "gzip /prod/prod/data/prodstage/pos/save/*"
    )
  ) or
  (
    process.parent.executable == "/usr/sbin/dovecot" and
    process.command_line like "*/usr/local/cpanel/3rdparty/wp-toolkit/plib/vendor/wp-cli/wpt-wp-cli.php*"
  ) or
  (
    process.parent.executable in ("/usr/sbin/sendmail", "/etc/init.d/sendmail") and
    process.name == "touch"
  ) or
  process.entry_leader.executable == "/usr/local/qualys/cloud-agent/bin/qualys-cloud-agent" or
  (process.parent.executable == "/tmp/usr/sbin/sendmail" and process.executable like ("/tmp/usr/bin/*", "/tmp/bin/*"))
)
'''

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

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


[threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[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 = "T1554"
name = "Compromise Host Software Binary"
reference = "https://attack.mitre.org/techniques/T1554/"


[threat.tactic]
id = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1210"
name = "Exploitation of Remote Services"
reference = "https://attack.mitre.org/techniques/T1210/"


[threat.tactic]
id = "TA0008"
name = "Lateral Movement"
reference = "https://attack.mitre.org/tactics/TA0008/"
[[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 = "8.3.0"

Stages and Predicates

Stage 1: process

process where event.type == "start" and event.action == "exec" and process.parent.interactive == false and
(
  process.parent.name in ("exim4", "postfix", "smtpd", "sendmail", "dovecot", "amavisd-new", "amavisd", "spamd") or
  (
    process.parent.name == "master" and
    process.parent.executable like "/*/postfix*master"
  )
) and
not (
  (process.parent.name == "exim4" and process.args like "/usr/lib/nagios/plugins/check_file_age*") or
  (process.parent.name in ("amavisd-new", "amavisd") and process.command_line == "/usr/bin/gzip -d") or
  (process.parent.name == "dovecot" and process.command_line == "gzip") or
  (process.parent.name == "amavisd" and process.name == "amavisd")
) and
(
  process.name in (
    "scp", "gzip", "bzip2", "xz", "tar", "getcap", "capsh", "find", "nohup", "setsid", "timeout", "disown",
    "mkfifo", "printenv", "env", "chpasswd", "echo"
  ) or
  (
    process.name == "touch" and
    not process.args like (
      "/home/*/.esmtp_queue/*/lock", "/root/.esmtp_queue/*/lock", "/prod/prod/data/prodstage/possum/error/"
    )
  ) or
  process.name like ".*" or
  (
    process.name in ("whoami", "id", "hostname", "uname", "ps", "netstat", "ss", "ip", "ifconfig") and
    process.interactive == true and process.parent.interactive == false
  ) or
  process.executable like ("/dev/shm/*", "/tmp/*", "/var/tmp/*", "/root/*", "./*") or
  (
    process.executable like ("/bin/python*", "/usr/bin/python*", "/usr/local/bin/python*") and (
      process.args == "-c" or
      (
        process.args_count <= 2 and
        process.args like ("/tmp/*", "/var/tmp/*", "/dev/shm/*", "/var/www/*", "/root/*", "/home/*/*", "./*.py") and
        process.args like "*.py*"
      )
    ) and
    not process.args in ("--version", "app.py")
  ) or
  (
    process.executable like (
      "/bin/perl*", "/usr/bin/perl*", "/usr/local/bin/perl*",
      "/bin/ruby*", "/usr/bin/ruby*", "/usr/local/bin/ruby*",
      "/bin/lua*", "/usr/bin/lua*", "/usr/local/bin/lua*",
      "/bin/node", "/usr/bin/node", "/usr/local/bin/node"
    ) and
    (process.args like "-e*" or process.args_count <= 2)
  ) or
  (
    process.executable like ("/bin/php*", "/usr/bin/php*", "/usr/local/bin/php*") and
    (process.args like "-r*" or process.args_count <= 2) and
    not (
      process.args like "var_export*" or
      process.command_line in ("php -r echo get_current_user().PHP_EOL;", "php -r echo date('T');")
    )
  ) or
  (
    process.name in ("nc", "ncat", "netcat", "netcat.openbsd", "netcat.traditional", "nc.openbsd", "nc.traditional") and (
      process.command_line regex ".*[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}.*" or
      process.command_line like "*http*"
    ) and
    not process.args in ("localhost", "127.0.0.1", "-z", "-zv")
  ) or
  (
    process.name == "socat" and
    process.command_line like~ ("*exec*", "*tty*", "*fork*", "*file*", "*open*") and
    process.command_line like~ ("*tcp*", "*udp*", "*openssl*")
  ) or
  (
    process.name == "openssl" and (
      process.command_line like ("*s_server*", "*s_client*") or
      (process.args == "enc" and process.args in ("-d", "-base64", "-a", "-A"))
    )
  ) or
  (
    process.name in ("curl", "wget") and process.args like~ ("-o", "--output*", "-o-") and (
      process.command_line regex ".*[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}.*" or
      process.command_line like "*http*"
    ) and
    process.command_line like ("* /tmp/*", "* /var/tmp/*", "* /dev/shm/*", "* /var/www/*", "* ~/*", "* /home/*", "* /run/*", "* /var/run/*")
  ) or
  (
    process.name in ("base64", "basez", "base64plain", "base64url", "base64mime", "base64pem", "basenc", "base32", "base16") and
    process.args like~ "-*d*"
  ) or
  (
    process.name == "xxd" and process.args like~ ("-*r*", "-*p*")
  ) or
  (process.name == "sudo" and process.args == "-l") or
  (
    process.executable like ("/bin/chmod", "/usr/bin/chmod", "/usr/local/bin/chmod") and
    process.args like ("+x", "a+x", "0777", "755", "777", "+s", "u+s", "g+s")
  ) or
  (
    process.executable like ("/bin/cat", "/usr/bin/cat", "/usr/local/bin/cat") and
    process.args like (
      "/etc/passwd", "/etc/shadow", "/etc/hostname", "/etc/hosts", "*ssh*", "/proc/self/environ",
      "*.env*", "*../../../*", "*/secrets/kubernetes.io/serviceaccount/*", "*/.docker/config.json*",
      "*/.npmrc*", "*.aws/credentials*", "*/.aws/config*"
    )
  ) or
  (
    process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox") and
    process.args in ("-c", "-cl", "-lc") and (
      process.command_line like (
        "* /tmp/* ", "* /var/tmp/* ", "* /dev/shm/*", "* /var/www/*", "* /run/*", "* /var/run/*",
        "*python* -c*", "*php* -r*", "*perl* -e*", "*ruby* -e*", "*lua* -e*", "*node * -e *",
        "*|sh", "*| sh *", "*| sh ", "*|bash*", "*| bash*", "*|zsh*",  "*| zsh*", "*|dash*",  "*| dash*",
        "*|python*", "*| python*", "*|php*", "*| php*", "*|perl*", "*| perl*", "*|ruby*", "*| ruby*",
        "*|node*", "*| node*", "*|lua*",  "*| lua*", "*|busybox*", "*| busybox*", "*|*base64 -d*", "*|*base64 --decode*",
        "*|*base64 --decode*", "*|*openssl base64 -d*", "*xxd *", "*| openssl*enc * -d *", "*b64decode -r*",
        "*netcat *", "* nc *", "*ncat *", "*/dev/tcp*", "*/dev/udp/*", "*socat *", "*openssl*s_client *", "*stty*raw*-echo*",
        "*>*/etc/cron*", "*/etc/ssh*", "*/home/*/.ssh/*", "*/root/.ssh*", "*~/.ssh/*", "*/etc/shadow*", "*/etc/passwd*", "*chpasswd*",
        "*nohup*", "*setsid *", "*timeout *sh -c *", "*disown*", "*env *sh *-c*",
        "*chattr *", "*busybox *",  "*#!*", "*chmod +x *", "*chmod 777*",
        "*gzip -*d *", "*bzip2 -*d *", "*xz -*d *", "*tar -*x*",
         "*../../../*etc/*", "*/.../*", "*../../../*home/*/*", "*../../../*root/*"
      ) or
      (
        process.command_line like ("*wget *", "*curl *") and
        (
          process.command_line regex ".*[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}(:[0-9]{1,5})?/.*" or
          process.command_line like ("*http*", "*ftp*")
        ) and
        (
          (
            process.command_line regex~ """.*curl.* \-[a-zA-Z]*[oO]( .+|\-.*)?""" or
            process.command_line like~ ("*curl* --output*", "*curl* --remote-name*")
          ) or
          (
            (
              process.command_line regex~ """.*wget.* \-[a-zA-Z]*O.*""" or
              process.command_line like~ "*wget* --output-document*"
            ) and
          not process.command_line like """*--output-document "-"*"""
          ) or
          process.command_line like ("*|*sh*", "*|*python*", "*|*php*", "*|*perl*", "*|*ruby*", "*|*node*", "*|*lua*", "*|*busybox*") or
          (
            process.command_line like ("*curl *>> /*", "*curl *>>/*", "*curl *> /*", "*curl *>/*", "*wget *>> /*", "*wget *>>/*", "*wget *> /*", "*wget *>/*") and
            not process.command_line like ("*> /dev/null*", "*>/dev/null*", "*curl*/etc/cobra/*/uploads/whatsapp/*")
          )
        ) and
        not process.command_line like ("*-O /dev/null*", "*-o /dev/null*")
      )
    )
  )
) and
not (
  process.executable like ("/tmp/newroot/*", "/opt/lxc/*", "/var/snap/lxd/*") or
  process.parent.command_line == "runc init" or
  process.command_line in ("pickup -l -t unix -u", "pickup -l -t unix -u -c") or
  (
    process.parent.executable == "/etc/init.d/postfix" and process.command_line == "/bin/echo -n postfix is running"
  ) or
  (
    process.parent.executable == "/usr/libexec/postfix/master" and
    process.command_line like (
      "/usr/bin/hostname", "ps -eo pid,args", "uname -m", "/usr/bin/perl -w /root/check_megaraid_sas",
      "gzip /prod/prod/data/prodstage/pos/save/*"
    )
  ) or
  (
    process.parent.executable == "/usr/sbin/dovecot" and
    process.command_line like "*/usr/local/cpanel/3rdparty/wp-toolkit/plib/vendor/wp-cli/wpt-wp-cli.php*"
  ) or
  (
    process.parent.executable in ("/usr/sbin/sendmail", "/etc/init.d/sendmail") and
    process.name == "touch"
  ) or
  process.entry_leader.executable == "/usr/local/qualys/cloud-agent/bin/qualys-cloud-agent" or
  (process.parent.executable == "/tmp/usr/sbin/sendmail" and process.executable like ("/tmp/usr/bin/*", "/tmp/bin/*"))
)

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.argseq
  • -c
  • -l
  • enc
field:"process.args" kind:eq
process.argsin
  • -A
  • -a
  • -base64
  • -c
  • -cl
  • -d
  • -lc
field:"process.args" kind:in
process.argswildcard
  • *../../../*
  • *.aws/credentials*
  • *.env*
  • *.py*
  • */.aws/config*
  • */.docker/config.json*
  • */.npmrc*
  • */secrets/kubernetes.io/serviceaccount/*
  • *ssh*
  • +s
  • +x
  • -*d*
  • -*p*
  • -*r*
  • --output*
  • -e*
  • -o
  • -o-
  • -r*
  • ./*.py
  • /dev/shm/*
  • /etc/hostname
  • /etc/hosts
  • /etc/passwd
  • /etc/shadow
  • /home/*/*
  • /proc/self/environ
  • /root/*
  • /tmp/*
  • /var/tmp/*
  • /var/www/*
  • 0777
  • 755
  • 777
  • a+x
  • g+s
  • u+s
field:"process.args" kind:wildcard
process.args_countle
  • 2 transforms: number
field:"process.args_count" kind:le value:"2"
process.command_lineregex_match
  • .*[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}(:[0-9]{1,5})?/.*
  • .*[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.*
  • .*curl.* \-[a-zA-Z]*[oO]( .+|\-.*)?
  • .*wget.* \-[a-zA-Z]*O.*
field:"CommandLine" kind:regex_match
process.command_linewildcard
  • * /dev/shm/*
  • * /dev/shm/*
  • * /home/*
  • * /run/*
  • * /run/*
  • * /tmp/*
  • * /tmp/*
  • * /var/run/*
  • * /var/run/*
  • * /var/tmp/*
  • * /var/tmp/*
  • * /var/www/*
  • * /var/www/*
  • * nc *
  • * ~/*
  • *#!*
  • *../../../*etc/*
  • *../../../*home/*/*
  • *../../../*root/*
  • */.../*
  • */dev/tcp*
  • */dev/udp/*
  • */etc/passwd*
  • */etc/shadow*
  • */etc/ssh*
  • */home/*/.ssh/*
  • */root/.ssh*
  • *>*/etc/cron*
  • *b64decode -r*
  • *busybox *
  • *bzip2 -*d *
  • *chattr *
  • *chmod +x *
  • *chmod 777*
  • *chpasswd*
  • *curl *
  • *curl *> /*
  • *curl *>/*
  • *curl *>> /*
  • *curl *>>/*
  • +76 more values (see full rule source)
field:"CommandLine" kind:wildcard
process.executablewildcard
  • ./*
  • /bin/cat
  • /bin/chmod
  • /bin/lua*
  • /bin/node
  • /bin/perl*
  • /bin/php*
  • /bin/python*
  • /bin/ruby*
  • /dev/shm/*
  • /root/*
  • /tmp/*
  • /usr/bin/cat
  • /usr/bin/chmod
  • /usr/bin/lua*
  • /usr/bin/node
  • /usr/bin/perl*
  • /usr/bin/php*
  • /usr/bin/python*
  • /usr/bin/ruby*
  • /usr/local/bin/cat
  • /usr/local/bin/chmod
  • /usr/local/bin/lua*
  • /usr/local/bin/node
  • /usr/local/bin/perl*
  • /usr/local/bin/php*
  • /usr/local/bin/python*
  • /usr/local/bin/ruby*
  • /var/tmp/*
field:"Image" kind:wildcard
process.interactiveeq
  • true transforms: boolean
field:"process.interactive" kind:eq value:"true"
process.nameeq
  • openssl
  • socat
  • sudo
  • touch
  • xxd
field:"process_basename" kind:eq
process.namein
  • base16
  • base32
  • base64
  • base64mime
  • base64pem
  • base64plain
  • base64url
  • basenc
  • basez
  • bash
  • busybox
  • bzip2
  • capsh
  • chpasswd
  • csh
  • curl
  • dash
  • disown
  • echo
  • env
  • find
  • fish
  • getcap
  • gzip
  • hostname
  • id
  • ifconfig
  • ip
  • ksh
  • mkfifo
  • nc
  • nc.openbsd
  • nc.traditional
  • ncat
  • netcat
  • netcat.openbsd
  • netcat.traditional
  • netstat
  • nohup
  • printenv
  • ps
  • scp
  • setsid
  • sh
  • ss
  • tar
  • tcsh
  • timeout
  • uname
  • wget
  • whoami
  • xz
  • zsh
field:"process_basename" kind:in
process.namewildcard
  • .*
field:"process_basename" kind:wildcard value:".*"
process.parent.executablewildcard
  • /*/postfix*master
field:"ParentImage" kind:wildcard value:"/*/postfix*master"
process.parent.interactiveeq
  • false transforms: boolean
field:"process.parent.interactive" kind:eq value:"false"
process.parent.nameeq
  • master
field:"parent_process_basename" kind:eq value:"master"
process.parent.namein
  • amavisd
  • amavisd-new
  • dovecot
  • exim4
  • postfix
  • sendmail
  • smtpd
  • spamd
field:"parent_process_basename" kind:in

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.argsstarts_with/usr/lib/nagios/plugins/check_file_ageexcludes:process.args field:"process.args" value:"/usr/lib/nagios/plugins/check_file_age"
process.parent.nameeqexim4excludes:process.parent.name field:"process.parent.name" value:"exim4"
process.command_lineeq/usr/bin/gzip -dexcludes:process.command_line field:"process.command_line" value:"/usr/bin/gzip -d"
process.parent.nameinamavisd, amavisd-newexcludes:process.parent.name field:"process.parent.name" value:"amavisd" field:"process.parent.name" value:"amavisd-new"
process.command_lineeqgzipexcludes:process.command_line field:"process.command_line" value:"gzip"
process.parent.nameeqdovecotexcludes:process.parent.name field:"process.parent.name" value:"dovecot"
process.nameeqamavisdexcludes:process.name field:"process.name" value:"amavisd"
process.parent.nameeqamavisdexcludes:process.parent.name field:"process.parent.name" value:"amavisd"
process.command_lineeq/bin/echo -n postfix is runningexcludes:process.command_line field:"process.command_line" value:"/bin/echo -n postfix is running"
process.parent.executableeq/etc/init.d/postfixexcludes:process.parent.executable field:"process.parent.executable" value:"/etc/init.d/postfix"
process.command_linematch/usr/local/cpanel/3rdparty/wp-toolkit/plib/vendor/wp-cli/wpt-wp-cli.phpexcludes:process.command_line field:"process.command_line" value:"/usr/local/cpanel/3rdparty/wp-toolkit/plib/vendor/wp-cli/wpt-wp-cli.php"
process.parent.executableeq/usr/sbin/dovecotexcludes:process.parent.executable field:"process.parent.executable" value:"/usr/sbin/dovecot"
process.command_linewildcard/usr/bin/hostname, ps -eo pid,args, uname -m, /usr/bin/perl -w /root/check_megaraid_sas, gzip /prod/prod/data/prodstage/pos/save/*excludes:process.command_line
process.parent.executableeq/usr/libexec/postfix/masterexcludes:process.parent.executable field:"process.parent.executable" value:"/usr/libexec/postfix/master"
process.executablestarts_with/tmp/usr/bin/, /tmp/bin/excludes:process.executable field:"process.executable" value:"/tmp/usr/bin/" field:"process.executable" value:"/tmp/bin/"
process.parent.executableeq/tmp/usr/sbin/sendmailexcludes:process.parent.executable field:"process.parent.executable" value:"/tmp/usr/sbin/sendmail"
process.nameeqtouchexcludes:process.name field:"process.name" value:"touch"
process.parent.executablein/etc/init.d/sendmail, /usr/sbin/sendmailexcludes:process.parent.executable field:"process.parent.executable" value:"/etc/init.d/sendmail" field:"process.parent.executable" value:"/usr/sbin/sendmail"
process.command_lineinpickup -l -t unix -u, pickup -l -t unix -u -cexcludes:process.command_line field:"process.command_line" value:"pickup -l -t unix -u" field:"process.command_line" value:"pickup -l -t unix -u -c"
process.entry_leader.executableeq/usr/local/qualys/cloud-agent/bin/qualys-cloud-agentexcludes:process.entry_leader.executable field:"process.entry_leader.executable" value:"/usr/local/qualys/cloud-agent/bin/qualys-cloud-agent"
process.executablestarts_with/tmp/newroot/, /opt/lxc/, /var/snap/lxd/excludes:process.executable field:"process.executable" value:"/tmp/newroot/" field:"process.executable" value:"/opt/lxc/" field:"process.executable" value:"/var/snap/lxd/"
process.parent.command_lineeqrunc initexcludes:process.parent.command_line field:"process.parent.command_line" value:"runc init"

Potential Spike in Web Server Error Logs

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

This rule detects unusual spikes in error logs from web servers, which may indicate reconnaissance activities such as vulnerability scanning or fuzzing attempts by adversaries. These activities often generate a high volume of error responses as they probe for weaknesses in web applications. Error response codes may potentially indicate server-side issues that could be exploited.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2025/11/19"
integration = ["nginx", "apache", "apache_tomcat", "iis"]
maturity = "production"
updated_date = "2026/04/10"

[rule]
author = ["Elastic"]
description = """
This rule detects unusual spikes in error logs from web servers, which may indicate reconnaissance activities such
as vulnerability scanning or fuzzing attempts by adversaries. These activities often generate a high volume of error
responses as they probe for weaknesses in web applications. Error response codes may potentially indicate server-side
issues that could be exploited.
"""
from = "now-11m"
interval = "10m"
language = "esql"
license = "Elastic License v2"
name = "Potential Spike in Web Server Error Logs"
note = """ ## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating Potential Spike in Web Server Error Logs

This detection flags spikes of web server error responses across HTTP/TLS and common server platforms, signaling active scanning or fuzzing that can expose misconfigurations or exploitable paths. A typical pattern is an automated scanner sweeping endpoints like /admin/, /debug/, /.env, /.git, and backup archives while mutating query parameters, producing repeated 404/403 and occasional 500 responses across multiple applications within minutes.

### Possible investigation steps

- Pivot on the noisy client IP(s) to build a minute-by-minute timeline across affected hosts showing request rate, status codes, methods, and top paths to distinguish automated scanning from a localized application failure.
- Enrich the client with ASN, geolocation, hosting/Tor/proxy reputation, historical sightings, and maintenance windows to quickly decide if it matches a known external scanner or an internal scheduled test.
- Aggregate the most requested URIs and verbs and look for telltale patterns such as /.env, /.git, backup archives, admin consoles, or unusual verbs like PROPFIND/TRACE, then correlate any 5xx bursts with application and server error logs and recent deploys or config changes.
- Hunt for follow-on success from the same client by checking for subsequent 200/302s to sensitive paths, authentication events and session creation, or evidence of file writes and suspicious child processes on the web hosts.
- If traffic traverses a CDN/WAF/load balancer, pivot to those logs to recover true client IPs, review rule matches and throttling, and determine whether similar patterns occurred across multiple edges or regions.

### False positive analysis

- Internal QA or integration tests that systematically crawl application routes after a deployment can generate bursts of 404/403 and occasional 500s from a single client IP, closely resembling active scanning.
- A transient backend outage or misconfiguration (broken asset paths or auth flows) can cause legitimate traffic to return many errors aggregated under a shared egress IP (NAT), pushing per-IP counts above the threshold without adversary activity.

### Response and remediation

- Immediately block or throttle the noisy client IPs at the WAF/CDN and load balancer by enabling per-IP rate limits and signatures for scanner patterns such as repeated hits to /.env, /.git, /admin, backup archives, or unusual verbs like PROPFIND/TRACE.
- If errors include concentrated 5xx responses from one web host, drain that node from service behind the load balancer, capture its web and application error logs, and roll back the most recent deploy or config change until error rates normalize.
- Remove risky exposures uncovered by the scan by denying access to environment files and VCS directories (.env, .git), disabling directory listing, locking down admin consoles, and rejecting unsupported HTTP methods at the web server.
- Escalate to Incident Response if the same client shifts from errors to successful access on sensitive endpoints (200/302 to /admin, /login, or API keys), if you observe file writes under the webroot or suspicious child processes, or if multiple unrelated clients show the same pattern across regions.
- Recover service by redeploying known-good builds, re-enabling health checks, running smoke tests against top routes, and restoring normal WAF/CDN policies while keeping a temporary blocklist for the offending IPs.
- Harden long term by tuning WAF/CDN to auto-throttle bursty 404/403/500 patterns, disabling TRACE/OPTIONS where unused, minimizing verbose error pages, and ensuring logs capture the true client IP via X-Forwarded-For or True-Client-IP headers.
"""
risk_score = 21
rule_id = "6631a759-4559-4c33-a392-13f146c8bcc4"
severity = "low"
tags = [
    "Domain: Web",
    "Use Case: Threat Detection",
    "Tactic: Reconnaissance",
    "Data Source: Nginx",
    "Data Source: Apache",
    "Data Source: Apache Tomcat",
    "Data Source: IIS",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-nginx.error-*, logs-apache_tomcat.error-*, logs-apache.error-*, logs-iis.error-*
| keep
    @timestamp,
    event.type,
    data_stream.dataset,
    source.ip,
    agent.id,
    host.name,
    data_stream.namespace

| where source.ip is not null
| stats
    Esql.event_count = count(),
    Esql.host_name_values = values(host.name),
    Esql.agent_id_values = values(agent.id),
    Esql.data_stream_dataset_values = values(data_stream.dataset),
    Esql.data_stream_namespace_values = values(data_stream.namespace)
    by source.ip, agent.id
| where
    Esql.event_count > 50
'''

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

[[rule.threat.technique]]
id = "T1595"
name = "Active Scanning"
reference = "https://attack.mitre.org/techniques/T1595/"

[[rule.threat.technique.subtechnique]]
id = "T1595.002"
name = "Vulnerability Scanning"
reference = "https://attack.mitre.org/techniques/T1595/002/"

[[rule.threat.technique.subtechnique]]
id = "T1595.003"
name = "Wordlist Scanning"
reference = "https://attack.mitre.org/techniques/T1595/003/"

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

Stages and Predicates

Stage 1: from

from logs-nginx.error-*, logs-apache_tomcat.error-*, logs-apache.error-*, logs-iis.error-*

Stage 2: keep

| keep
    @timestamp,
    event.type,
    data_stream.dataset,
    source.ip,
    agent.id,
    host.name,
    data_stream.namespace

Stage 3: where

| where source.ip is not null

Stage 4: stats

| stats
    Esql.event_count = count(),
    Esql.host_name_values = values(host.name),
    Esql.agent_id_values = values(agent.id),
    Esql.data_stream_dataset_values = values(data_stream.dataset),
    Esql.data_stream_namespace_values = values(data_stream.namespace)
    by source.ip, agent.id

Stage 5: where

| where
    Esql.event_count > 50

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

FieldSource
Esql.event_countSTATS Esql.event_count = count()
Esql.host_name_valuesSTATS Esql.host_name_values = values(host.name)
Esql.agent_id_valuesSTATS Esql.agent_id_values = values(agent.id)
Esql.data_stream_dataset_valuesSTATS Esql.data_stream_dataset_values = values(data_stream.dataset)
Esql.data_stream_namespace_valuesSTATS Esql.data_stream_namespace_values = values(data_stream.namespace)
source.ipSTATS BY
agent.idSTATS BY

PowerShell Suspicious Script with Clipboard Retrieval Capabilities

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

Detects PowerShell script block content that retrieves clipboard data using Get-Clipboard or Windows clipboard APIs. Adversaries can collect copied credentials, tokens, or other sensitive data from the clipboard.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2023/01/12"
integration = ["windows"]
maturity = "production"
updated_date = "2026/01/26"

[rule]
author = ["Elastic"]
description = """
Detects PowerShell script block content that retrieves clipboard data using Get-Clipboard or Windows clipboard APIs.
Adversaries can collect copied credentials, tokens, or other sensitive data from the clipboard.
"""
from = "now-9m"
index = ["winlogbeat-*", "logs-windows.powershell*"]
language = "kuery"
license = "Elastic License v2"
name = "PowerShell Suspicious Script with Clipboard Retrieval Capabilities"
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 PowerShell Suspicious Script with Clipboard Retrieval Capabilities

This alert indicates PowerShell script block content associated with clipboard access. The matched script may use the Get-Clipboard cmdlet or Windows clipboard APIs (for example, Windows.Forms.Clipboard or related UI components) to retrieve user-copied data. Clipboard collection is often opportunistic and may be used to capture credentials, tokens, and other sensitive information copied during normal workflows.

#### Key alert fields to review

- `user.name`, `user.domain`, `user.id`: Account execution context for correlation, prioritization, and scoping.
- `host.name`, `host.id`: Host execution context for correlation, prioritization, and scoping.
- `powershell.file.script_block_text`: Script block content that matched the detection logic.
- `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`: Script block metadata to pivot to other fragments or reconstruct full script content when split across multiple events.
- `file.path`, `file.directory`, `file.name`: File-origin context when the script block is sourced from an on-disk file.
- `powershell.file.script_block_length`: Script block length (size) context.

#### Possible investigation steps

- Review `powershell.file.script_block_text` to understand the clipboard access technique and usage pattern:
  - Get-Clipboard usage versus .NET/UI based access (for example, Windows.Forms.Clipboard, Windows.Clipboard, TextBox.Paste, or methods such as GetText).
  - Whether clipboard access appears to be a one-time action or part of repeated/polled collection logic (for example, loops, timers, or repeated calls in the same script).
- Reconstruct the complete script when content is split across multiple events:
  - Pivot on `powershell.file.script_block_id` and order related events by `powershell.sequence` to rebuild the full script up to `powershell.total`.
  - Use `powershell.file.script_block_length` as context for unusually large scripts, which may indicate additional functionality beyond clipboard retrieval.
- Evaluate intent by reviewing surrounding logic in `powershell.file.script_block_text`:
  - Where clipboard contents are stored (variables, arrays, buffers) and whether the script transforms data after retrieval (for example, encoding, compression, string manipulation, or obfuscation).
  - Any indications of staging or transfer behavior following clipboard access (for example, writing data to disk or preparing network requests).
- Validate provenance and expected use:
  - Use `user.name`, `user.domain`, and `user.id` to determine whether the execution context is expected to run PowerShell that interacts with the clipboard.
  - Use `host.name` and `host.id` to determine whether the affected host is a typical endpoint for interactive clipboard use or an unusual target for clipboard collection.
  - If `file.path`, `file.directory`, or `file.name` are present, assess whether the script source is expected for the user and host, and whether it is located in a user-writable or temporary location.
- Determine execution context and whether the activity is user-driven or automated:
  - Correlate activity for the same `host.id` and `user.id` with process execution telemetry (if available) to identify the PowerShell host and its parent process, and whether execution was interactive or automated.
  - If authentication telemetry is available, correlate nearby logon activity for the same user and host to identify newly established sessions or unusual remote access preceding the alert.
- Scope and prevalence:
  - Search for other script block events with similar clipboard-related strings in `powershell.file.script_block_text` for the same `user.id` and `host.id`, and then across other hosts to identify reuse.
  - Look for reuse of the same `file.name` or `file.path` across hosts, which can indicate shared tooling or broader distribution.
- Assess impact and potential exposure:
  - If the script suggests repeated clipboard reads or immediate staging/transfer behavior, treat clipboard contents handled by the affected user on the host during the timeframe as potentially exposed and prioritize investigation accordingly.

### False positive analysis

- Clipboard retrieval can be legitimate in user productivity scripts, developer/test utilities, and administrative automation that transforms or inserts copied content into other workflows.
- Benign activity is more likely when the script source (`file.path`/`file.name`) aligns with known internal tooling, the user context is expected, and the script block text shows clear user-facing intent without follow-on staging or transfer behavior.
- False positives are less likely when clipboard access is repeated or automated, appears on atypical hosts for interactive use, or is coupled with suspicious handling of the retrieved data (for example, encoding, buffering, or writing to unexpected locations).

### Response and remediation

- If the activity is confirmed benign, document the script, expected users/hosts, and the business justification. Ensure the script source is maintained under change control to detect unauthorized modifications.
- If suspicious or malicious activity is suspected:
  - Contain the affected host to prevent further collection and preserve evidence.
  - Preserve relevant artifacts, including all related script block events for the `powershell.file.script_block_id` and any referenced script file from `file.path` (if present).
  - Investigate for downstream handling of clipboard data (staging or transfer) using available endpoint, file, network, and authentication telemetry scoped to `host.id` and `user.id`.
  - Assess potential credential or token exposure for the affected user and initiate credential hygiene actions appropriate to your environment.
  - Remove or remediate the execution source (malicious scripts or unauthorized automation) and investigate for persistence mechanisms that could re-run the clipboard collection.
  - Expand scoping by hunting for the same clipboard retrieval patterns in `powershell.file.script_block_text`, and for reuse of the same `file.name`/`file.path` across other hosts.
  - Capture lessons learned and update monitoring and access controls to reduce future abuse of PowerShell-based collection techniques while preserving required operational use cases.
"""
references = [
    "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-clipboard",
    "https://github.com/EmpireProject/Empire/blob/master/data/module_source/collection/Get-ClipboardContents.ps1",
]
risk_score = 47
rule_id = "92984446-aefb-4d5e-ad12-598042ca80ba"
setup = """## Setup

PowerShell Script Block Logging must be enabled to generate the events used by this rule (e.g., 4104).
Setup instructions: https://ela.st/powershell-logging-setup
"""
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Windows",
    "Use Case: Threat Detection",
    "Tactic: Collection",
    "Data Source: PowerShell Logs",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
event.category:process and host.os.type:windows and
(
  (
    powershell.file.script_block_text : (
      "Windows.Clipboard" or
      "Windows.Forms.Clipboard" or
      "Windows.Forms.TextBox"
    ) and
    powershell.file.script_block_text : (
      "]::GetText" or
      ".Paste()"
    )
  ) or
  powershell.file.script_block_text : "Get-Clipboard"
) and
  not powershell.file.script_block_text : (
    "sentinelbreakpoints" and "Set-PSBreakpoint" and "PowerSploitIndicators"
  ) and
  not user.id : "S-1-5-18" and
  not (
    file.path : *WindowsPowerShell\\Modules\\*.ps1 and
    file.name : ("Convert-ExcelRangeToImage.ps1" or "Read-Clipboard.ps1")
  ) and
  not powershell.file.script_block_text : (
    "Set-Alias -Name \"gcb\" -Value \"Get-Clipboard\"" or
    "[Windows.Clipboard]::SetText($colorizedText" or
    "EEFCB906-B326-4E99-9F54-8B4BB6EF3C6D"
  )
'''


[[rule.filters]]

[rule.filters.meta]
negate = true
[rule.filters.query.wildcard."file.path"]
case_insensitive = true
value = "?:\\\\program?files\\\\powershell\\\\?\\\\Modules\\\\*.psd1"
[[rule.filters]]

[rule.filters.meta]
negate = true
[rule.filters.query.wildcard."file.path"]
case_insensitive = true
value = "?:\\\\Windows\\\\system32\\\\WindowsPowerShell\\\\v1.0\\\\Modules\\\\*.psd1"
[[rule.filters]]

[rule.filters.meta]
negate = true
[rule.filters.query.wildcard."file.path"]
case_insensitive = true
value = "?:\\\\Program?Files\\\\WindowsPowerShell\\\\Modules\\\\*.ps?1"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1115"
name = "Clipboard Data"
reference = "https://attack.mitre.org/techniques/T1115/"


[rule.threat.tactic]
id = "TA0009"
name = "Collection"
reference = "https://attack.mitre.org/tactics/TA0009/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[rule.threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"



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

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "user.name",
    "user.id",
    "user.domain",
    "powershell.file.script_block_text",
    "powershell.file.script_block_id",
    "powershell.sequence",
    "powershell.total",
    "file.path",
    "file.directory",
    "file.name",
    "process.pid",
    "host.name",
    "host.id",
    "powershell.file.script_block_length"
]

Stages and Predicates

Stage 1: query

event.category:process and host.os.type:windows and
(
  (
    powershell.file.script_block_text : (
      "Windows.Clipboard" or
      "Windows.Forms.Clipboard" or
      "Windows.Forms.TextBox"
    ) and
    powershell.file.script_block_text : (
      "]::GetText" or
      ".Paste()"
    )
  ) or
  powershell.file.script_block_text : "Get-Clipboard"
) and
  not powershell.file.script_block_text : (
    "sentinelbreakpoints" and "Set-PSBreakpoint" and "PowerSploitIndicators"
  ) and
  not user.id : "S-1-5-18" and
  not (
    file.path : *WindowsPowerShell\\Modules\\*.ps1 and
    file.name : ("Convert-ExcelRangeToImage.ps1" or "Read-Clipboard.ps1")
  ) and
  not powershell.file.script_block_text : (
    "Set-Alias -Name \"gcb\" -Value \"Get-Clipboard\"" or
    "[Windows.Clipboard]::SetText($colorizedText" or
    "EEFCB906-B326-4E99-9F54-8B4BB6EF3C6D"
  )

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.categoryeq
  • process corpus 105 (elastic 105)
field:"event.category" kind:eq value:"process"
powershell.file.script_block_texteq
  • Get-Clipboard
field:"ScriptBlockText" kind:eq value:"Get-Clipboard"
powershell.file.script_block_textin
  • .Paste()
  • Windows.Clipboard
  • Windows.Forms.Clipboard
  • Windows.Forms.TextBox
  • ]::GetText
field:"ScriptBlockText" kind:in

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
file.nameinConvert-ExcelRangeToImage.ps1, Read-Clipboard.ps1excludes:file.name field:"file.name" value:"Convert-ExcelRangeToImage.ps1" field:"file.name" value:"Read-Clipboard.ps1"
file.pathwildcard*WindowsPowerShell\Modules\*.ps1excludes:file.path field:"file.path" value:"*WindowsPowerShell\Modules\*.ps1"
powershell.file.script_block_texteqPowerSploitIndicatorsexcludes:powershell.file.script_block_text field:"powershell.file.script_block_text" value:"PowerSploitIndicators"
powershell.file.script_block_texteqSet-PSBreakpointexcludes:powershell.file.script_block_text field:"powershell.file.script_block_text" value:"Set-PSBreakpoint"
powershell.file.script_block_texteqsentinelbreakpointsexcludes:powershell.file.script_block_text field:"powershell.file.script_block_text" value:"sentinelbreakpoints"
powershell.file.script_block_textinEEFCB906-B326-4E99-9F54-8B4BB6EF3C6D, Set-Alias -Name "gcb" -Value "Get-Clipboard", [Windows.Clipboard]::SetText($colorizedTextexcludes:powershell.file.script_block_text
user.ideqS-1-5-18excludes:user.id field:"user.id" value:"S-1-5-18"

Temporary Binary Execution via Osascript

#
Source
github.com/elastic/protections-artifacts

Detects when a binary is executed from a temporary directory via osascript. Threat actors have been see leveraging applescript to automate post execution tasks, such as downloading and executing a binary from a temporary directory.

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

[rule]
description = """
Detects when a binary is executed from a temporary directory via osascript. Threat actors have been see leveraging
applescript to automate post execution tasks, such as downloading and executing a binary from a temporary directory.
"""
id = "a75b6762-fc64-4c96-b3b8-48ed000d997b"
license = "Elastic License v2"
name = "Temporary Binary Execution via Osascript"
os_list = ["macos"]
reference = ["https://x.com/MsftSecIntel/status/1891410993265123662"]
version = "1.0.3"

query = '''
process where event.type == "start" and event.action == "exec" and process.executable like ("/tmp/*", "/private/tmp/*") and 
 process.parent.name == "osascript"
'''

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

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

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



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

[internal]
min_endpoint_version = "8.11.0"

Stages and Predicates

Stage 1: process

process where event.type == "start" and event.action == "exec" and process.executable like ("/tmp/*", "/private/tmp/*") and 
 process.parent.name == "osascript"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
event.actioneq
  • exec corpus 547 (elastic 547)
field:"EventType" kind:eq value:"exec"
event.typeeq
  • start corpus 1036 (elastic 1036)
field:"event.type" kind:eq value:"start"
process.executablewildcard
  • /private/tmp/* corpus 3 (elastic 3)
  • /tmp/* corpus 32 (elastic 32)
field:"Image" kind:wildcard
process.parent.nameeq
  • osascript corpus 11 (elastic 11)
field:"parent_process_basename" kind:eq value:"osascript"

Unusual GCP Event for a User

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

A machine learning job detected an GCP Audit event that, while not inherently suspicious or abnormal, is being made by a user context that does not normally use the event action. This can be the result of compromised credentials or keys as someone uses a valid account to persist, move laterally, or exfiltrate data.

Known False Positives

  • New or unusual user event activity can be due to manual troubleshooting or reconfiguration; changes in cloud automation scripts or workflows; adoption of new services; or changes in the way services are used.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2025/10/06"
integration = ["gcp"]
maturity = "production"
min_stack_comments = "New job added"
min_stack_version = "9.4.0"
updated_date = "2026/04/01"

[rule]
anomaly_threshold = 75
author = ["Elastic"]
description = """
A machine learning job detected an GCP Audit event that, while not inherently suspicious or abnormal, is being made by a
user context that does not normally use the event action. This can be the result of compromised credentials or keys as
someone uses a valid account to persist, move laterally, or exfiltrate data.
"""
false_positives = [
    """
    New or unusual user event activity can be due to manual troubleshooting or reconfiguration; changes in cloud
    automation scripts or workflows; adoption of new services; or changes in the way services are used.
    """,
]
from = "now-2h"
interval = "15m"
license = "Elastic License v2"
machine_learning_job_id = "gcp_audit_rare_method_for_a_user_email_ea"
name = "Unusual GCP Event for a User"
setup = """## Setup

This rule requires the installation of associated Machine Learning jobs, as well as data coming in from GCP.

### Anomaly Detection Setup

Once the rule is enabled, the associated Machine Learning job will start automatically. You can view the Machine Learning job linked under the "Definition" panel of the detection rule. If the job does not start due to an error, the issue must be resolved for the job to commence successfully. For more details on setting up anomaly detection jobs, refer to the [helper guide](https://www.elastic.co/guide/en/kibana/current/xpack-ml-anomalies.html).

### GCP Audit logs Integration Setup
The Google Cloud Platform (GCP) Audit logs integration allows you to collect logs and metrics from Google Cloud Platform (GCP) with Elastic Agent.

#### The following steps should be executed in order to add the Elastic Agent System "Google Cloud Platform (GCP) Audit logs" integration to your system:
- Go to the Kibana home page and click “Add integrations”.
- In the query bar, search for “Google Cloud Platform (GCP) Audit logs” and select the integration to see more details about it.
- Click “Add Google Cloud Platform (GCP) Audit logs".
- Configure the integration.
- Click “Save and Continue”.
- For more details on the integration refer to the [helper guide](https://www.elastic.co/docs/current/integrations/gcp).
"""
references = ["https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html"]
risk_score = 21
rule_id = "2e08f34c-691c-497e-87de-5d794a1b2a53"
severity = "low"
tags = [
    "Domain: Cloud",
    "Data Source: GCP",
    "Data Source: GCP Audit Logs",
    "Data Source: Google Cloud Platform",
    "Rule Type: ML",
    "Rule Type: Machine Learning",
    "Resources: Investigation Guide",
]
type = "machine_learning"

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

[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"

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

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

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

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

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

[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 = "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 = "TA0003"
name = "Persistence"
reference = "https://attack.mitre.org/tactics/TA0003/"

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

[[rule.threat.technique]]
id = "T1041"
name = "Exfiltration Over C2 Channel"
reference = "https://attack.mitre.org/techniques/T1041/"

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

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

[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"

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

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

Unusual Group Name Accessed by a User

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

A machine learning job has detected a user accessing an uncommon group name for privileged operations, indicating potential privileged access activity. This indicates that a user has accessed a group name that is unusual for their typical operations, particularly for actions requiring elevated privileges. This could point to an attempt to manipulate group memberships or escalate privileges on a system.

MITRE ATT&CK Coverage

Rule Body

[metadata]
creation_date = "2025/02/18"
integration = ["pad", "system"]
maturity = "production"
updated_date = "2026/07/27"
min_stack_version = "9.4.0"
min_stack_comments = "Use EA (Entity Analytics) fields"

[rule]
anomaly_threshold = 75
author = ["Elastic"]
description = """
A machine learning job has detected a user accessing an uncommon group name for privileged operations, indicating
potential privileged access activity. This indicates that a user has accessed a group name that is unusual for their
typical operations, particularly for actions requiring elevated privileges. This could point to an attempt to manipulate
group memberships or escalate privileges on a system.
"""
from = "now-1h"
interval = "15m"
license = "Elastic License v2"
machine_learning_job_id = "pad_windows_rare_group_name_by_user_ea"
name = "Unusual Group Name Accessed by a User"
note = """## Triage and analysis

> **Disclaimer**:
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

### Investigating Unusual Group Name Accessed by a User

In IT environments, group names often define access levels and permissions. Adversaries may exploit this by accessing or altering uncommon group names to escalate privileges. The detection rule leverages machine learning to identify deviations from a user's typical access patterns, flagging unusual group name access as a potential indicator of privilege escalation attempts. This proactive approach helps in early detection of unauthorized access activities.

### Possible investigation steps

- Review the alert details to identify the specific user and the unusual group name accessed. Note the timestamp of the access for further context.
- Check the user's historical access patterns to determine if this group name access is indeed anomalous compared to their typical behavior.
- Investigate the permissions and roles associated with the unusual group name to assess the potential impact of the access.
- Examine recent changes to the user's account, such as password resets or modifications to account settings, which might indicate account compromise.
- Correlate this event with other security alerts or logs, such as login attempts from unusual locations or times, to identify potential indicators of compromise.
- Contact the user or their manager to verify if the access was legitimate and authorized, documenting any explanations provided.
- If unauthorized access is suspected, initiate a security incident response process to mitigate any potential threats and prevent further unauthorized access.

### False positive analysis

- Routine administrative tasks may trigger alerts if administrators access uncommon group names for legitimate system maintenance. To manage this, create exceptions for known administrative accounts performing regular tasks.
- Automated scripts or services that require access to various group names for operational purposes might be flagged. Identify these scripts and whitelist their activities to prevent false positives.
- Temporary project groups or newly created groups for specific tasks can appear unusual. Document and monitor these groups, and update the machine learning model to recognize them as non-threatening.
- Cross-departmental collaborations may involve users accessing group names outside their usual scope. Establish a process to review and approve such access, and adjust the detection rule to accommodate these scenarios.
- Changes in user roles or responsibilities can lead to access pattern deviations. Ensure that role changes are communicated to the security team to update access baselines accordingly.

### Response and remediation

- Immediately isolate the affected user account to prevent further unauthorized access or privilege escalation. This can be done by disabling the account or changing its password.
- Review and audit the group membership changes associated with the unusual group name to identify any unauthorized modifications. Revert any unauthorized changes to restore the original group settings.
- Conduct a thorough investigation of the user's recent activities to identify any other suspicious actions or access patterns that may indicate further compromise.
- Notify the security team and relevant stakeholders about the potential privilege escalation attempt to ensure awareness and coordinated response efforts.
- Implement additional monitoring on the affected user account and the unusual group name to detect any further unauthorized access attempts.
- Review and update access control policies to ensure that only authorized users have access to sensitive group names and privileged operations.
- Consider implementing additional security measures, such as multi-factor authentication, for accessing sensitive group names to prevent unauthorized access in the future."""
references = [
    "https://www.elastic.co/guide/en/security/current/prebuilt-ml-jobs.html",
    "https://docs.elastic.co/en/integrations/pad",
]
risk_score = 21
rule_id = "fb5d91d0-3b94-4f91-bf20-b6fbc4b2480a"
setup = """## Setup

The rule requires the Privileged Access Detection integration assets to be installed, as well as Windows logs collected by the System integration.

### Privileged Access Detection Setup
The Privileged Access Detection integration detects privileged access activity by identifying abnormalities in Windows, Linux and Okta events. Anomalies are detected using Elastic's Anomaly Detection feature.

#### Prerequisite Requirements:
- Fleet is required for Privileged Access Detection.
- To configure Fleet Server refer to the [documentation](https://www.elastic.co/guide/en/fleet/current/fleet-server.html).
- Windows events collected by the [System](https://docs.elastic.co/en/integrations/system) integration.
- To add the System integration to an Elastic Agent policy, refer to [this](https://www.elastic.co/guide/en/fleet/current/add-integration-to-policy.html) guide.

#### The following steps should be executed to install assets associated with the Privileged Access Detection integration:
- Go to the Kibana homepage. Under Management, click Integrations.
- In the query bar, search for Privileged Access Detection and select the integration to see more details about it.
- Follow the instructions under the **Installation** section.
- For this rule to work, complete the instructions through **Add preconfigured anomaly detection jobs**.
"""
severity = "low"
tags = [
    "Data Source: Windows Security Event Logs",
    "Use Case: Privileged Access Detection",
    "Rule Type: ML",
    "Rule Type: Machine Learning",
    "Tactic: Privilege Escalation",
    "Resources: Investigation Guide",
]
type = "machine_learning"
[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1068"
name = "Exploitation for Privilege Escalation"
reference = "https://attack.mitre.org/techniques/T1068/"

[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"

[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"

[[rule.threat.technique.subtechnique]]
id = "T1098.007"
name = "Additional Local or Domain Groups"
reference = "https://attack.mitre.org/techniques/T1098/007/"

[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 = "T1069"
name = "Permission Groups Discovery"
reference = "https://attack.mitre.org/techniques/T1069/"

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

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

[[rule.threat.technique]]
id = "T1098"
name = "Account Manipulation"
reference = "https://attack.mitre.org/techniques/T1098/"

[[rule.threat.technique.subtechnique]]
id = "T1098.007"
name = "Additional Local or Domain Groups"
reference = "https://attack.mitre.org/techniques/T1098/007/"

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

Back to all Elastic rules