Detection rules › Elastic
Elastic rules: 2w
Attempt to Modify an Okta Network Zone
#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
| Tactic | Techniques |
|---|---|
| Privilege Escalation | |
| Defense Impairment |
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.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"okta.system" |
event.action | in |
| field:"EventType" kind:in |
Container Runtime CLI Execution with Suspicious Arguments
#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
| Tactic | Techniques |
|---|---|
| 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.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | in |
| field:"EventType" kind:in |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | eq |
| field:"process.args" kind:eq |
process.args | in |
| field:"process.args" kind:in |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.name | in |
| field:"process_basename" kind:in |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:".*" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.parent.executable | in | /lib/systemd/systemd, /sbin/init, /usr/bin/containerd, /usr/bin/kubelet, /usr/lib/systemd/systemd, /usr/local/bin/kubelet, /usr/sbin/containerd | excludes:process.parent.executable |
Direct Interactive Kubernetes API Request by Unusual Utilities
#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
Rules Detecting the Same Action
These rules filter on the same operation.
- Amazon EKS Kubernetes Pod scan detection (Splunk)
- Azure AKS Attempted User Exec into Pod (Elastic)
- Azure AKS CoreDNS or Kube-DNS Configuration Modified (Elastic)
- Azure AKS Ephemeral Container Added to Pod (Elastic)
- Azure AKS Secret get or list with Suspicious User Agent (Elastic)
- Azure AKS Service Account Token Created via TokenRequest API (Elastic)
- Azure AKS Suspicious Self-Subject Review by Service Account or Node Identity (Elastic)
- Container With A hostPath Mount Created (Sigma)
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.
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | in | /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, which | excludes:process.args |
process.args | in | /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, wget | excludes:process.args |
process.name | in | bash, busybox, csh, dash, fish, ksh, sh, tcsh, zsh | excludes:process.name |
process.name | in | apk, apt, apt-get, dnf, dpkg, head, microdnf, pacman, rpm, sleep, tail, tdnf, yum, zypper | excludes:process.name |
process.name | in | curl, kubectl, ncat, openssl, socat, wget | excludes:process.name |
DLL Loaded via a CallBack Function
#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
| Tactic | Techniques |
|---|---|
| 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.
| Field | Kind | Values | Search |
|---|---|---|---|
process.thread.Ext.call_stack_summary | eq |
| field:"process.thread.Ext.call_stack_summary" kind:eq value:"ntdll.dll|kernel32.dll|ntdll.dll" |
Execution via a Suspicious WMI Client
#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
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Execution | |
| Stealth |
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.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.Ext.effective_parent.executable | wildcard |
| field:"process.Ext.effective_parent.executable" kind:wildcard |
process.Ext.effective_parent.name | wildcard |
| field:"process.Ext.effective_parent.name" kind:wildcard |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard value:"WmiPrvSE.exe" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.Ext.effective_parent.name | eq | excel.exe, powerpnt.exe, winword.exe | excludes: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.args | eq | 1 | excludes:process.args field:"process.args" value:"1" |
process.args | eq | 60 | excludes:process.args field:"process.args" value:"60" |
process.args | eq | C:\Windows\TEMP\RestartHealthService.ps1 | excludes:process.args field:"process.args" value:"C:\Windows\TEMP\RestartHealthService.ps1" |
process.name | eq | powershell.exe | excludes:process.name field:"process.name" value:"powershell.exe" |
process.Ext.effective_parent.name | eq | cscript.exe | excludes:process.Ext.effective_parent.name field:"process.Ext.effective_parent.name" value:"cscript.exe" |
process.args | eq | ?:\Windows\TEMP\RestartHealthService.js | excludes:process.args field:"process.args" value:"?:\Windows\TEMP\RestartHealthService.js" |
user.id | eq | S-1-5-18 | excludes:user.id field:"user.id" value:"S-1-5-18" |
process.args | wildcard | \\*\netlogon\logon.cmd, ?:\ProgramData\Package Cache" %a in (cybereasonsensor.exe)*, (x86)\EOG\iFileMenu\iFileMenu.bat | excludes:process.args |
process.name | eq | cmd.exe | excludes:process.name field:"process.name" value:"cmd.exe" |
process.code_signature.subject_name | eq | Immense Networks LLC, Synology Inc., Xerox Corporation, Beijing Qihu Technology Co., Ltd. | excludes:process.code_signature.subject_name |
process.code_signature.trusted | eq | true | excludes:process.code_signature.trusted field:"process.code_signature.trusted" value:"true" |
process.command_line | eq | 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" | excludes:process.command_line |
process.command_line | match | CgAgACAAIAAgAHQAcgBhAHAAIAB7AAoAIAAgACAAIAAgACAAIAAgACQAdwByAGEAcABwAGUAcgBfAHAAYQB0AGgAIAA9ACAAIgAkACgAJABlAG4AdgA6AFQARQBNAFAAKQBcAGEAbgBzAGkAYgBsAGUALQBhAHMAeQBuAGMALQB3AHIAYQBwAHAAZQByAC0AZ | excludes:process.command_line field:"process.command_line" value:"CgAgACAAIAAgAHQAcgBhAHAAIAB7AAoAIAAgACAAIAAgACAAIAAgACQAdwByAGEAcABwAGUAcgBfAHAAYQB0AGgAIAA9ACAAIgAkACgAJABlAG4AdgA6AFQARQBNAFAAKQBcAGEAbgBzAGkAYgBsAGUALQBhAHMAeQBuAGMALQB3AHIAYQBwAHAAZQByAC0AZ" |
process.executable | wildcard | ?:\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 | excludes:process.executable |
process.hash.sha256 | eq | 0e692d9d3342fdcab1ce3d61aed0520989a94371e5898edb266c92f1fe11c97f, 8ee339af3ce1287066881147557dc3b57d1835cbba56b2457663068ed25b7840, f27cb78f44fc8f70606be883bbed705bd1dd2c2f8a84a596e5f4924e19068f22 | excludes: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)
#Detects a first occurrence event for a personal access token (PAT) not seen in the last 14 days.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution | |
| Persistence | |
| Lateral Movement |
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.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | is_not_null | field:"EventType" kind:is_not_null | |
event.category | eq |
| field:"event.category" kind:eq value:"configuration" |
event.dataset | eq |
| field:"event.dataset" kind:eq value:"github.audit" |
github.hashed_token | is_not_null | field:"github.hashed_token" kind:is_not_null | |
github.programmatic_access_type | in |
| field:"github.programmatic_access_type" kind:in |
GKE Secret Access from Node or Denied Service Account
#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
| Tactic | Techniques |
|---|---|
| Credential Access |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Kubernetes | get-secrets: get secrets |
| Kubernetes | list-secrets: list secrets |
Rules Detecting the Same Action
These rules filter on the same operation.
- Azure AKS Secret get or list with Suspicious User Agent (Elastic)
- Direct Interactive Kubernetes API Request by Unusual Utilities (Elastic)
- GKE Rapid Secret GET Activity Against Multiple Objects (Elastic)
- GKE Secret Access via Unusual User Agent (Elastic)
- GKE Secret get or list with Suspicious User Agent (Elastic)
- GKE Secrets List from Unusual Source AS Organization (Elastic)
- GKE Unusual Service Account Secret Access via New User Agent (Elastic)
- Kubernetes Abuse of Secret by Unusual Location (Splunk)
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.
| Field | Kind | Values | Search |
|---|---|---|---|
client.user.email | wildcard |
| field:"client.user.email" kind:wildcard |
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"gcp.audit" |
event.action | eq |
| field:"EventType" kind:eq value:"io.k8s.core.v1.secrets.get" |
event.action | in |
| field:"EventType" kind:in |
event.outcome | eq |
| field:"event.outcome" kind:eq value:"failure" |
service.name | eq |
| field:"ServiceName" kind:eq value:"k8s.io" |
source.ip | is_not_null | field:"src_ip" kind:is_not_null |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
source.ip | in | 127.0.0.1, ::1 | excludes:source.ip field:"source.ip" value:"127.0.0.1" field:"source.ip" value:"::1" |
Kubernetes Admission Webhook Created or Modified
#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
| Tactic | Techniques |
|---|---|
| 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.
| Field | Kind | Values | Search |
|---|---|---|---|
kubernetes.audit.annotations.authorization_k8s_io/decision | eq |
| field:"kubernetes.audit.annotations.authorization_k8s_io/decision" kind:eq value:"allow" |
kubernetes.audit.objectRef.name | is_not_null | field:"kubernetes.audit.objectRef.name" kind:is_not_null | |
kubernetes.audit.objectRef.resource | in |
| field:"kubernetes.audit.objectRef.resource" kind:in |
kubernetes.audit.verb | in |
| field:"kubernetes.audit.verb" kind:in |
user.name | is_not_null | field:"user" kind:is_not_null |
Exclusions
The rule actively suppresses these predicates.
Kubernetes Pod Created with a Sensitive hostPath Volume
#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
| Tactic | Techniques |
|---|---|
| Execution | |
| Privilege Escalation |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Kubernetes | create-pods: create pods |
| Kubernetes | update-pods: update pods |
| Kubernetes | patch-pods: patch pods |
Rules Detecting the Same Action
These rules filter on the same operation.
- Azure AKS Attempted User Exec into Pod (Elastic)
- Azure AKS Ephemeral Container Added to Pod (Elastic)
- Container With A hostPath Mount Created (Sigma)
- Creation Of Pod In System Namespace (Sigma)
- Direct Interactive Kubernetes API Request by Unusual Utilities (Elastic)
- Exec into Pod (Panther)
- GCP Break-glass Container Workload Deployed (Sigma)
- GCP K8s Pod Attached To Node Host Network (Panther)
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.
| Field | Kind | Values | Search |
|---|---|---|---|
data_stream.dataset | eq |
| field:"data_stream.dataset" kind:eq value:"kubernetes.audit_logs" |
kubernetes.audit.annotations.authorization_k8s_io/decision | eq |
| field:"kubernetes.audit.annotations.authorization_k8s_io/decision" kind:eq value:"allow" |
kubernetes.audit.objectRef.resource | eq |
| field:"kubernetes.audit.objectRef.resource" kind:eq value:"pods" |
kubernetes.audit.requestObject.spec.volumes.hostPath.path | in |
| field:"kubernetes.audit.requestObject.spec.volumes.hostPath.path" kind:in |
kubernetes.audit.verb | in |
| field:"kubernetes.audit.verb" kind:in |
Exclusions
The rule actively suppresses these predicates.
Loadable Kernel Module Loaded via Unusual Parent
#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
| Tactic | Techniques |
|---|---|
| Persistence | |
| Stealth |
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.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"load_module" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.parent.executable | wildcard |
| field:"ParentImage" kind:wildcard |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.command_line | in | /usr/sbin/modprobe br_netfilter, /usr/sbin/modprobe overlay | excludes:process.command_line field:"process.command_line" value:"/usr/sbin/modprobe br_netfilter" field:"process.command_line" value:"/usr/sbin/modprobe overlay" |
process.parent.executable | starts_with | /usr/bin/python | excludes:process.parent.executable field:"process.parent.executable" value:"/usr/bin/python" |
process.name | eq | systemd | excludes:process.name field:"process.name" value:"systemd" |
process.parent.command_line | eq | runc init | excludes:process.parent.command_line field:"process.parent.command_line" value:"runc init" |
process.parent.name | eq | runc | excludes:process.parent.name field:"process.parent.name" value:"runc" |
process.args | eq | ip6_tables | excludes:process.args field:"process.args" value:"ip6_tables" |
process.parent.args | in | /usr/bin/waydroid, /usr/sbin/blksnap-loader, /usr/share/ksplice/ksplice-apply | excludes: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.args | wildcard | /home/*/.ansible/tmp/ansible-tmp-*/AnsiballZ_command.py | excludes:process.parent.args field:"process.parent.args" value:"/home/*/.ansible/tmp/ansible-tmp-*/AnsiballZ_command.py" |
process.parent.command_line | in | /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-update | excludes:process.parent.command_line |
process.parent.executable | wildcard | /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 | excludes:process.parent.executable |
Multi-Value Secret Searching via Find
#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
| Tactic | Techniques |
|---|---|
| Discovery | |
| Collection |
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.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | eq |
| field:"process.args" kind:eq |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.name | eq |
| field:"process_basename" kind:eq value:"find" |
process.parent.executable | is_not_null | field:"ParentImage" kind:is_not_null |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.args | eq | -L | excludes:process.args field:"process.args" value:"-L" |
process.args | eq | -xdev | excludes:process.args field:"process.args" value:"-xdev" |
process.parent.command_line | eq | xargs -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.executable | eq | /usr/bin/xargs | excludes:process.parent.executable field:"process.parent.executable" value:"/usr/bin/xargs" |
process.parent.command_line | match | XDG_CONFIG_HOME | excludes:process.parent.command_line field:"process.parent.command_line" value:"XDG_CONFIG_HOME" |
process.parent.name | eq | bash | excludes:process.parent.name field:"process.parent.name" value:"bash" |
process.working_directory | eq | /tmp/plz_sandbox | excludes:process.working_directory field:"process.working_directory" value:"/tmp/plz_sandbox" |
process.args | wildcard | /run/credentials/systemd-*.service, /var/lib/sannav/docker/containers/*/mounts/secrets, /snap/authd-msentraid/*, /home/*/.cache/yay/1password/pkg/1password/*, /var/tmp/dracut.*/initramfs | excludes:process.args |
process.command_line | in | find /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_line | starts_with | find /var/tmp/portage/ | excludes:process.command_line field:"process.command_line" value:"find /var/tmp/portage/" |
process.parent.args | wildcard | /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 | excludes:process.parent.args |
process.parent.executable | in | /opt/puppetlabs/puppet/bin/ruby, /usr/bin/make, /usr/bin/sw-engine, /usr/local/bin/build_rpm | excludes:process.parent.executable |
process.working_directory | wildcard | /opt/rapid7/ir_agent/components/endpoint_broker/common, /__w/Modular-Teepee/Modular-Teepee, /build*, /opt/netconfs/home/*, /tmp/plz_sandbox | excludes:process.working_directory |
process.command_line | starts_with | event0.process.command_line | excludes:process.command_line field:"process.command_line" value:"event0.process.command_line" |
process.command_line | starts_with | event1.process.command_line | excludes:process.command_line field:"process.command_line" value:"event1.process.command_line" |
Permission Theft - Prevented - Elastic Endgame
#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
| Tactic | Techniques |
|---|---|
| Privilege Escalation |
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.
| Field | Kind | Values | Search |
|---|---|---|---|
endgame.event_subtype_full | eq |
| field:"endgame.event_subtype_full" kind:eq value:"token_protection_event" |
endgame.metadata.type | eq |
| field:"endgame.metadata.type" kind:eq value:"prevention" |
event.action | eq |
| field:"EventType" kind:eq value:"token_protection_event" |
event.kind | eq |
| field:"event.kind" kind:eq value:"alert" |
event.module | eq |
| field:"event.module" kind:eq value:"endgame" |
Potential CertiGhost AD CS Machine Identity Mismatch (CVE-2026-54121)
#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
| Tactic | Techniques |
|---|---|
| Privilege Escalation | |
| Credential Access |
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 =Esql.rmd_is_ip_shapedEsql.normalized_rmd_valueREPLACE(Esql.normalized_rmd_value, """\..*$""", "")Esql.normalized_san_target =Esql.san_is_ip_shapedEsql.normalized_san_valueREPLACE(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.
| Field | Source |
|---|---|
@timestamp | KEEP @timestamp |
_id | KEEP _id |
_index | KEEP _index |
_version | KEEP _version |
event.code | KEEP event.code |
event.action | KEEP event.action |
event.category | KEEP event.category |
event.type | KEEP event.type |
event.outcome | KEEP event.outcome |
event.created | KEEP event.created |
event.ingested | KEEP event.ingested |
data_stream.dataset | KEEP data_stream.dataset |
data_stream.namespace | KEEP data_stream.namespace |
host.id | KEEP host.id |
host.name | KEEP host.name |
winlog.computer_name | KEEP winlog.computer_name |
winlog.record_id | KEEP winlog.record_id |
winlog.event_data.RequestId | KEEP winlog.event_data.RequestId |
winlog.event_data.Requester | KEEP winlog.event_data.Requester |
winlog.event_data.CertificateTemplate | KEEP winlog.event_data.CertificateTemplate |
winlog.event_data.Subject | KEEP winlog.event_data.Subject |
winlog.event_data.SubjectAlternativeName | KEEP winlog.event_data.SubjectAlternativeName |
winlog.event_data.Attributes | KEEP winlog.event_data.Attributes |
winlog.event_data.Disposition | KEEP winlog.event_data.Disposition |
winlog.event_data.SubjectKeyIdentifier | KEEP winlog.event_data.SubjectKeyIdentifier |
Esql.effective_certificate_template | KEEP Esql.effective_certificate_template |
Esql.san_value | KEEP Esql.san_value |
Esql.cdc_value | KEEP Esql.cdc_value |
Esql.rmd_value | KEEP Esql.rmd_value |
Esql.normalized_requester | KEEP Esql.normalized_requester |
Esql.normalized_san_target | KEEP Esql.normalized_san_target |
Esql.normalized_rmd_target | KEEP Esql.normalized_rmd_target |
Potential DLL Hijacking via Environment Paths
#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
| Tactic | Techniques |
|---|---|
| Stealth |
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.
| Field | Kind | Values | Search |
|---|---|---|---|
dll.Ext.relative_file_creation_time | le |
| field:"dll.Ext.relative_file_creation_time" kind:le value:"900" |
dll.path | wildcard |
| field:"ImageLoaded" kind:wildcard |
process.code_signature.status | wildcard |
| field:"SignatureStatus" kind:wildcard value:"trusted" |
process.code_signature.subject_name | wildcard |
| field:"Signature" kind:wildcard value:"Microsoft *" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
dll.path | wildcard | ?:\Windows\*.dll, ?:\Program Files*\Windows NT\* | excludes:dll.path field:"dll.path" value:"?:\Windows\*.dll" field:"dll.path" value:"?:\Program Files*\Windows NT\*" |
dll.path | eq | ?:\Windows\System32\amdihk64.dll | excludes:dll.path field:"dll.path" value:"?:\Windows\System32\amdihk64.dll" |
dll.pe.original_file_name | eq | Radeon Settings Host Service | excludes:dll.pe.original_file_name field:"dll.pe.original_file_name" value:"Radeon Settings Host Service" |
dll.pe.imphash | eq | caebca4526b1331e2458f507d6ef4838 | excludes:dll.pe.imphash field:"dll.pe.imphash" value:"caebca4526b1331e2458f507d6ef4838" |
dll.pe.original_file_name | eq | ExplorerPatcher.dll | excludes:dll.pe.original_file_name field:"dll.pe.original_file_name" value:"ExplorerPatcher.dll" |
process.name | eq | explorer.exe | excludes:process.name field:"process.name" value:"explorer.exe" |
dll.code_signature.status | wildcard | trusted, errorCode_endpoint* | excludes:dll.code_signature.status field:"dll.code_signature.status" value:"trusted" field:"dll.code_signature.status" value:"errorCode_endpoint*" |
dll.hash.sha256 | eq | fc96ee3fad0edf3f26b6ba118a4fad919eefefa478996f3cee9c28e274c8130f, 2392414a18bfdd146cb55d4e865809f2dac35f857b9bff20a939da94876fb9eb, a1fe9948e692b1fa2ebba3c3d6fb2b88f7d97b418398369ad3865418c4e3cb88, 90a88986c8c5f30fb153ec803feda6572b2c2630a6c9578fcc017800692694d5, db9cdc52afb49ae408f5f7e6f3213615a25c16ad6ea56f7caf51c62ea548e8e5, da2d6ff6aa7b28aa5d8e1b9c1f1af9221b929741761a72b965911c97c338fa8f, a1628b28eb62fada7cd068557c2df466097f05d2de828c34c3d0eb6705c05821, da2d6ff6aa7b28aa5d8e1b9c1f1af9221b929741761a72b965911c97c338fa8f, e416f3765be8358eb2fe789c8f9033bbbeda952ce6a36a350d403e2f07b963f8, ca70262f22d519dc152f9d93db7fe704b2c57517b137d557effca6ba65e4de70 | excludes:dll.hash.sha256 |
dll.path | regex_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.path | wildcard | ?:\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 | excludes:dll.path |
process.executable | eq | ?:\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 | excludes:process.executable |
Potential Lateral Movement via SMBExec
#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
| Tactic | Techniques |
|---|---|
| Execution | |
| Lateral Movement |
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.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"start" |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard value:"*/Q*echo*.bat*del*.bat*" |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"cmd.exe" |
process.parent.name | wildcard |
| field:"parent_process_basename" kind:wildcard value:"services.exe" |
process.pe.original_file_name | eq |
| field:"OriginalFileName" kind:eq value:"Cmd.Exe" |
Potential Linux Credential Dumping via Mimipenguin
#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
| Tactic | Techniques |
|---|---|
| Credential Access |
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.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:"python*" |
process.parent.name | in |
| field:"parent_process_basename" kind:in |
Potential Remote Code Execution via Mail Server
#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
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Execution | |
| Persistence | |
| Lateral Movement | |
| Command & Control |
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.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.args | eq |
| field:"process.args" kind:eq |
process.args | in |
| field:"process.args" kind:in |
process.args | wildcard |
| field:"process.args" kind:wildcard |
process.args_count | le |
| field:"process.args_count" kind:le value:"2" |
process.command_line | regex_match |
| field:"CommandLine" kind:regex_match |
process.command_line | wildcard |
| field:"CommandLine" kind:wildcard |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.interactive | eq |
| field:"process.interactive" kind:eq value:"true" |
process.name | eq |
| field:"process_basename" kind:eq |
process.name | in |
| field:"process_basename" kind:in |
process.name | wildcard |
| field:"process_basename" kind:wildcard value:".*" |
process.parent.executable | wildcard |
| field:"ParentImage" kind:wildcard value:"/*/postfix*master" |
process.parent.interactive | eq |
| field:"process.parent.interactive" kind:eq value:"false" |
process.parent.name | eq |
| field:"parent_process_basename" kind:eq value:"master" |
process.parent.name | in |
| field:"parent_process_basename" kind:in |
Exclusions
The rule actively suppresses these predicates.
Potential Spike in Web Server Error Logs
#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
| Tactic | Techniques |
|---|---|
| Reconnaissance |
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.
| Field | Kind | Values | Search |
|---|---|---|---|
Esql.event_count | gt |
| field:"Esql.event_count" kind:gt value:"50" |
source.ip | is_not_null | field:"src_ip" kind:is_not_null |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Esql.event_count | STATS Esql.event_count = count() |
Esql.host_name_values | STATS Esql.host_name_values = values(host.name) |
Esql.agent_id_values | STATS Esql.agent_id_values = values(agent.id) |
Esql.data_stream_dataset_values | STATS Esql.data_stream_dataset_values = values(data_stream.dataset) |
Esql.data_stream_namespace_values | STATS Esql.data_stream_namespace_values = values(data_stream.namespace) |
source.ip | STATS BY |
agent.id | STATS BY |
PowerShell Suspicious Script with Clipboard Retrieval Capabilities
#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
| Tactic | Techniques |
|---|---|
| Execution | |
| Collection |
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.
| Field | Kind | Values | Search |
|---|---|---|---|
event.category | eq |
| field:"event.category" kind:eq value:"process" |
powershell.file.script_block_text | eq |
| field:"ScriptBlockText" kind:eq value:"Get-Clipboard" |
powershell.file.script_block_text | in |
| field:"ScriptBlockText" kind:in |
Exclusions
The rule actively suppresses these predicates.
Temporary Binary Execution via Osascript
#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
| Tactic | Techniques |
|---|---|
| Execution |
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.
| Field | Kind | Values | Search |
|---|---|---|---|
event.action | eq |
| field:"EventType" kind:eq value:"exec" |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.parent.name | eq |
| field:"parent_process_basename" kind:eq value:"osascript" |
Unusual GCP Event for a User
#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
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Persistence | |
| Stealth | |
| Lateral Movement | |
| Exfiltration |
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
#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
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation | |
| Discovery |
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/"