Home/Detection rules

Deployable detection rules

4,399 vendor-native detections · ready to paste into your SIEM · cross-linked to ATT&CK

Detections

50 shown of 4,399
Elastic EQL high T1098, T1558 ↗
KRBTGT Delegation Backdoor
Identifies the modification of the msDS-AllowedToDelegateTo attribute to KRBTGT. Attackers can use this technique to maintain persistence to the domain by having the ability to request tickets for the KRBTGT service.
Show query
iam where host.os.type == "windows" and event.code == "4738" and winlog.event_data.AllowedToDelegateTo : "*krbtgt*"
Kerberos Cached Credentials Dumping
Identifies the use of the Kerberos credential cache (kcc) utility to dump locally cached Kerberos tickets. Adversaries may attempt to dump credential material in the form of tickets that can be leveraged for lateral movement.
Show query
process where host.os.type == "macos" and event.type in ("start", "process_started") and
  process.name == "kcc" and
  process.args like~ "copy_cred_cache"
Elastic EQL high T1547, T1547.006, T1014 ↗
Kernel Module Load from Unusual Location
This rule detects the loading of a kernel module from an unusual location. Threat actors may use this technique to maintain persistence on a system by loading a kernel module into the kernel namespace. This behavior is strongly related to the presence of a rootkit on the system.
Show query
process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and (
  (process.name == "kmod" and process.args == "insmod" and process.args like~ "*.ko*") or
  (process.name == "kmod" and process.args == "modprobe" and not process.args in ("-r", "--remove")) or
  (process.name == "insmod" and process.args like~ "*.ko*") or
  (process.name == "modprobe" and not process.args in ("-r", "--remove"))
) and (
  process.working_directory like (
    "/tmp*", "/var/tmp*", "/dev/shm*", "/run*", "/var/run*", "/home*/*", "/root*",
    "/var/www*", "/boot*", "/srv*", "/mnt*", "/media*"
  ) or
  process.parent.working_directory like (
    "/tmp*", "/var/tmp*", "/dev/shm*", "/run*", "/var/run*", "/home*/*", "/root*",
    "/var/www*", "/boot*", "/srv*", "/mnt*", "/media*"
  ) or
  process.args like (
    "/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/*", "/var/run/*", "/home/*/*", "/root/*",
    "/var/www/*", "/boot/*", "/srv/*", "/mnt/*", "/media/*", "./*"
  )
) and
not (
  process.parent.executable == "/usr/bin/podman" or
  process.working_directory like "/tmp/newroot"
)
Elastic EQL high T1555, T1555.001 ↗
Keychain CommandLine Interaction via Unsigned or Untrusted Process
Adversaries may collect the keychain storage data from a system to acquire credentials. Keychains are the built-in way for macOS to keep track of users' passwords and credentials for many services and features such as WiFi passwords, websites, secure notes and certificates.
Show query
process where host.os.type == "macos" and event.type in ("start", "process_started") and event.action == "exec" and
  process.args like ("/Users/*/Library/Keychains/*", "/Library/Keychains/*", "login.keychain-db", "login.keychain") and 
  ((process.code_signature.trusted == false or process.code_signature.exists == false) or 
   (process.name in ("bash", "sh", "zsh", "osascript", "cat", "echo", "cp") and 
   (process.parent.code_signature.trusted == false or process.parent.code_signature.exists == false)))
Keychain Password Retrieval via Command Line
Adversaries may collect keychain storage data from a system to in order to acquire credentials. Keychains are the built-in way for macOS to keep track of users' passwords and credentials for many services and features, including Wi-Fi and website passwords, secure notes, certificates, and Kerberos.
Show query
process where host.os.type == "macos" and event.action == "exec" and
 process.name == "security" and
 process.args like ("-wa", "-ga") and process.args like~ ("find-generic-password", "find-internet-password") and
 process.command_line : ("*Chrome*", "*Chromium*", "*Opera*", "*Safari*", "*Brave*", "*Microsoft Edge*", "*Firefox*") and
 not process.parent.executable like "/Applications/Keeper Password Manager.app/Contents/Frameworks/Keeper Password Manager Helper*/Contents/MacOS/Keeper Password Manager Helper*"
Elastic EQL high T1003, T1558 ↗
Kirbi File Creation
Identifies the creation of .kirbi files, a suspicious Kerberos ticket artifact often produced by ticket export or dumping tools such as Rubeus or Mimikatz. This can indicate preparation for Kerberos ticket theft or later abuse, including Pass-The-Ticket (PTT), and should be validated with writer process and follow-on activity.
Show query
file where host.os.type == "windows" and event.type == "creation" and file.extension : "kirbi"
Elastic EQL high T1613, T1552 ↗
Kubectl Secrets Enumeration Across All Namespaces
This rule detects the use of the "kubectl get secrets --all-namespaces" command, which enumerates secret resources across the entire Kubernetes cluster. Attackers may use this command to identify accessible secrets in multiple namespaces, aiding credential discovery, privilege escalation, or lateral movement.
Show query
process where host.os.type in ("linux", "macos") and event.type == "start" and
event.action in ("exec", "exec_event", "start", "ProcessRollup2", "executed", "process_started") and
process.name == "kubectl" and process.args in ("get", "describe") and process.args in ("secret", "secrets") and
process.args in ("--all-namespaces", "-A")
Elastic KQL high T1134 ↗
Kubernetes API Request Impersonating Privileged Identity
Detects Kubernetes API requests where a user is impersonating a privileged cluster identity such as system:kube-controller-manager, system:admin, system:anonymous, or a member of the system:masters group. These identities have broad cluster-wide permissions including unrestricted access to all secrets, the ability to create tokens for any service account, schedule pods on any node, and modify RBAC policies. An attacker impersonating system:masters gains full cluster-admin equivalent access, while impersonating system:kube-controller-manager grants access to every secret in every namespace and the ability to mint service account tokens for lateral movement.
Show query
data_stream.dataset:kubernetes.audit_logs and
kubernetes.audit.impersonatedUser.username:(* and not ("eks-event-service:event-controller" or eks\:*)) and 
kubernetes.audit.annotations.authorization_k8s_io/decision:allow and 
kubernetes.audit.verb:(create or delete or get or list or patch or update) and 
(kubernetes.audit.impersonatedUser.username:(admin or cluster-admin or kubernetes-admin or "system:admin" or "system:anonymous" or "system:apiserver" or "system:kube-controller-manager" or "system:kube-proxy" or "system:kube-scheduler" or "system:volume-scheduler" or system\:node\:* or system\:serviceaccount\:kube-system\:*) or kubernetes.audit.impersonatedUser.groups:(cluster-admin or "system:cluster-admins" or "system:masters")) and 
not user.name:(acsService or aksService or masterclient or nodeclient or "system:kube-controller-manager" or "system:kube-scheduler" or arn\:aws\:iam\:*\:role/aws-service-role* or arn\:aws\:sts\:*\:assumed-role/AWSServiceRoleForAmazonEKS* or arn\:aws\:sts\:*\:assumed-role/AWSServiceRoleForAmazonEKSNodegroup* or eks\:* or system\:node\:* or system\:serviceaccount\:kube-system\:*)
Elastic KQL high T1098, T1098.006 ↗
Kubernetes Client Certificate Signing Request Created or Approved
Detects creation or approval of a Kubernetes CertificateSigningRequest (CSR) by a non-system identity. Attackers who have gained cluster access can submit a CSR with a privileged Common Name such as system:kube-controller-manager or system:masters, then approve it themselves to obtain a long-lived client certificate. Unlike service account tokens which expire in hours, client certificates persist until they expire or the cluster CA is rotated, providing durable access that survives pod termination, token revocation, and RBAC changes. On non-EKS clusters, the signed certificate allows the attacker to authenticate as the privileged identity from anywhere without needing cluster network access, making it one of the most persistent backdoor mechanisms available in Kubernetes.
Show query
data_stream.dataset:"kubernetes.audit_logs" and
kubernetes.audit.objectRef.resource:"certificatesigningrequests" and
kubernetes.audit.verb:("create" or "update" or "patch") and
kubernetes.audit.annotations.authorization_k8s_io/decision:"allow" and
not user.name:(
  system\:kube-controller-manager or
  system\:kube-scheduler or
  system\:node\:* or
  system\:serviceaccount\:kube-system\:* or
  eks\:* or aksService
)
Elastic KQL high T1565, T1565.001 ↗
Kubernetes CoreDNS or Kube-DNS Configuration Modified
Detects modifications to the CoreDNS or kube-dns ConfigMap in the kube-system namespace. These ConfigMaps control cluster DNS resolution for all pods. An attacker who modifies the CoreDNS Corefile can redirect internal service DNS names to attacker-controlled IP addresses, enabling man-in-the-middle attacks against the Kubernetes API server, database services, and other internal endpoints. Pods that resolve service names via cluster DNS will transparently connect to the attacker instead of the legitimate service, allowing interception of service account tokens, database credentials, and API traffic. DNS poisoning at the cluster level is particularly dangerous because it affects every pod in every namespace simultaneously and does not require any modification to the victim workloads. CoreDNS configuration changes are rare in normal operations and any unexpected modification should be investigated immediately.
Show query
data_stream.dataset:"kubernetes.audit_logs" and
kubernetes.audit.objectRef.resource:"configmaps" and
kubernetes.audit.objectRef.name:("coredns" or "kube-dns" or "coredns-custom") and
kubernetes.audit.objectRef.namespace:"kube-system" and
kubernetes.audit.verb:("update" or "patch" or "delete") and
kubernetes.audit.annotations.authorization_k8s_io/decision:"allow" and 
not user.name:(
  system\:serviceaccount\:kube-system\:coredns or
  system\:serviceaccount\:kube-system\:kube-dns or
  system\:node\:* or
  eks\:* or aksService or acsService
)
Elastic ESQL high T1552, T1552.005, T1609 ↗
Kubernetes Pod Exec Cloud Instance Metadata Access
Detects Kubernetes pod exec sessions whose decoded command line references cloud instance metadata endpoints or equivalent hostnames and paths. Workloads that reach the link-local metadata IP, AWS IMDS paths, GCP computeMetadata, Azure IMDS token routes, or encoded variants are often attempting to harvest role credentials, tokens, or instance attributes from the underlying node or hypervisor boundary. That behavior is high risk in multi-tenant and regulated environments because it can expose short-lived cloud credentials to code running inside a container. The rule classifies a coarse cloud target label and whether the string looks like credential retrieval versus lighter reconnaissance.
Show query
FROM logs-kubernetes.audit_logs-* metadata _id, _index, _version
| WHERE kubernetes.audit.objectRef.subresource == "exec"
  AND kubernetes.audit.requestURI LIKE "*command=*"
| EVAL decoded_uri = URL_DECODE(kubernetes.audit.requestURI)
| GROK decoded_uri "%{DATA}/exec\\?%{DATA:raw_commands}&(?:container|stdin|stdout|stderr)=%{GREEDYDATA}"
| EVAL command = REPLACE(raw_commands, "command=", "")
| EVAL command = REPLACE(command, "&", " ")
| EVAL Esql.executed_command = REPLACE(command, "\\+", " ")
| WHERE Esql.executed_command IS NOT NULL 
  AND Esql.executed_command RLIKE """.*(169\.254\.169\.254|2852039166|0xa9fea9fe|/latest/api/token|/latest/meta-data|/latest/user-data|/latest/dynamic/instance-identity|computeMetadata/v1|metadata\.google\.internal|metadata/identity/oauth2/token|metadata/instance).* """| EVAL Esql.cloud_target = CASE(
    Esql.executed_command RLIKE """.*(169\.254\.169\.254|2852039166|0xa9fea9fe|/latest/meta-data|/latest/api/token|/latest/user-data|/latest/dynamic).*""", "AWS_IMDS",
    Esql.executed_command RLIKE """.*(computeMetadata/v1|metadata\.google\.internal).*""", "GCP_METADATA",
    Esql.executed_command RLIKE """.*metadata/identity/oauth2/token.*""", "AZURE_IMDS",
    "UNKNOWN"
  )
| EVAL Esql.is_credential_theft = CASE(
    Esql.executed_command RLIKE """.*(security-credentials|/api/token|oauth2/token|service-accounts/.*/token).*""", "yes",
    "recon"
  )
| KEEP *
Elastic ESQL high T1609, T1059 ↗
Kubernetes Pod Exec Potential Reverse Shell
Flags exec into a pod when the URL-decoded command payload resembles reverse-shell or bind-shell one-liners invocation patterns. Legitimate debug sessions sometimes use similar building blocks, but together these patterns align with post-exploitation interactive access and command-and-control.
Show query
FROM logs-kubernetes.audit_logs-* metadata _id, _index, _version
| WHERE kubernetes.audit.objectRef.subresource == "exec"
  AND kubernetes.audit.requestURI LIKE "*command=*"
| EVAL decoded_uri = URL_DECODE(kubernetes.audit.requestURI)
| GROK decoded_uri "%{DATA}/exec\\?%{DATA:raw_commands}&(?:container|stdin|stdout|stderr)=%{GREEDYDATA}"
| EVAL command = REPLACE(raw_commands, "command=", "")
| EVAL command = REPLACE(command, "&", " ")
| EVAL Esql.executed_command = REPLACE(command, "\\+", " ")
| WHERE Esql.executed_command IS NOT NULL 
| WHERE Esql.executed_command IS NOT NULL AND command RLIKE """.*(/dev/tcp/|/dev/udp/|zsh/net/tcp|zsh/net/udp|nc\s+-e|ncat\s+-e|netcat\s+-e|nc\s.*\s-c\s|mkfifo|socat\s.*exec|socat\s.*pty|bash\s+-i\s+>&|0>&1|>&\s*/dev/tcp|import\s+socket.*connect|import\s+pty.*spawn|socket\.socket.*connect|IO::Socket::INET|fsockopen|TCPSocket\.new|/inet/tcp/).*""" AND 
 // local service health check patterns
  NOT command RLIKE """.*/dev/tcp/(localhost|127\.0\.0\.1)/(8080|8443|9090|3000|5000|8888|80|443).* """| KEEP *
Kubernetes Pod Exec Sensitive File or Credential Path Access
Detects Kubernetes pod exec sessions whose decoded command line references high-value host or in-cluster paths and material types: mounted service account or platform tokens, kubelet and control-plane configuration areas, host identity stores, root dot-directories for cloud and kubeconfig material, common private-key and keystore extensions, process environment dumps, and configuration filenames suggestive of embedded secrets. The intent is to catch interactive or scripted access that often precedes lateral movement, privilege escalation, or credential theft from the node or workload boundary. A narrow exclusion ignores benign reads of resolv.conf. The query also labels an access_type bucket to speed triage without altering the detection predicates you validated.
Show query
from logs-kubernetes.audit_logs-* metadata _id, _index, _version
| WHERE kubernetes.audit.objectRef.subresource == "exec"
  AND kubernetes.audit.requestURI LIKE "*command=*"
| EVAL decoded_uri = URL_DECODE(kubernetes.audit.requestURI)
| GROK decoded_uri "%{DATA}/exec\\?%{DATA:raw_commands}&(?:container|stdin|stdout|stderr)=%{GREEDYDATA}"
| EVAL command = REPLACE(raw_commands, "command=", "")
| EVAL command = REPLACE(command, "&", " ")
| EVAL Esql.executed_command = REPLACE(command, "\\+", " ")
| WHERE Esql.executed_command IS NOT NULL 
  AND Esql.executed_command RLIKE """.*(/var/run/secrets/|/etc/kubernetes/|/var/lib/kubelet/|/etc/shadow|/etc/passwd|/etc/sudoers|(/root|/home/[^/]+)/\.(ssh|aws|azure|kube|config/gcloud)|\.p12|\.pem|\.key|\.jks|\.keystore|/etc/.*\.conf.*(password|secret|key|token|credential)|/proc/.*/environ).* """  AND NOT Esql.executed_command RLIKE """.*/etc/resolv\.conf.* """| EVAL Esql.access_type = CASE(
    Esql.executed_command RLIKE """.*/var/run/secrets/eks\.amazonaws\.com.*""", "AWS_IRSA_TOKEN",
    Esql.executed_command RLIKE """.*/var/run/secrets/azure/tokens/.*""", "AZURE_WORKLOAD_IDENTITY_TOKEN",
    Esql.executed_command RLIKE """.*/var/run/secrets/tokens/gcp-ksa/.*""", "GCP_WORKLOAD_IDENTITY_TOKEN",
    Esql.executed_command RLIKE """.*/var/run/secrets/kubernetes\.io/serviceaccount/token.*""", "K8S_SA_TOKEN",
    Esql.executed_command RLIKE """.*/var/run/secrets/.*""", "MOUNTED_SECRET",
    Esql.executed_command RLIKE """.*\.(p12|pem|key|jks|keystore).*""", "CERTIFICATE_OR_KEY",
    Esql.executed_command RLIKE """.*/etc/kubernetes/.*""", "K8S_CONFIG",
    Esql.executed_command RLIKE """.*/var/lib/kubelet/.*""", "KUBELET_CONFIG",
    Esql.executed_command RLIKE """.*/etc/shadow.*""", "HOST_CREDENTIALS",
    Esql.executed_command RLIKE """.*/etc/passwd.*""", "USER_ENUMERATION",
    Esql.executed_command RLIKE """.*/etc/sudoers.*""", "SUDOERS_ACCESS",
    Esql.executed_command RLIKE """.*(/root|/home)/\.(ssh|aws|azure|kube|config/gcloud).*""", "USER_CREDENTIALS",
    Esql.executed_command RLIKE """.*/proc/.*/environ.*""", "PROCESS_ENV_SECRETS",
    Esql.executed_command RLIKE """.*/etc/.*\.conf.*(password|secret|key|token|credential).*""", "EMBEDDED_CONFIG_SECRET",
    "OTHER_SENSITIVE"
  )
| KEEP *
Elastic ESQL high T1609, T1105 ↗
Kubernetes Pod Exec with Curl or Wget to HTTPS
Detects pod or attach exec API calls where the decoded request query implies **curl** or wget fetching an **https** URL. Attackers with permission to exec into workloads often run one-liners to stage tooling, pull scripts or binaries, or exfiltrate data over HTTPS—activity that should be rare compared to shells, debuggers, or expected health checks. The rule decodes the audit requestURI, reconstructs a readable command string from repeated command parameters, and applies **noise filters** for common cluster health and OIDC/JWKS endpoints so benign automation is less likely to alert.
Show query
FROM logs-kubernetes.audit_logs-* metadata _id, _index, _version
| WHERE kubernetes.audit.objectRef.subresource == "exec"
  AND kubernetes.audit.requestURI LIKE "*command=*"
| EVAL decoded_uri = URL_DECODE(kubernetes.audit.requestURI)
| GROK decoded_uri "%{DATA}/exec\\?%{DATA:raw_commands}&(?:container|stdin|stdout|stderr)=%{GREEDYDATA}"
| EVAL command = REPLACE(raw_commands, "command=", "")
| EVAL command = REPLACE(command, "&", " ")
| EVAL Esql.executed_command = REPLACE(command, "\\+", " ")
| WHERE Esql.executed_command IS NOT NULL 
  AND Esql.executed_command RLIKE """.*(curl.*https|wget.*https).* """  AND NOT Esql.executed_command RLIKE """.*(/api/v1/health|/healthz|/readyz|/livez|127\.0\.0\.1|localhost|/openid/v1/jwks|/openid-connect/certs|/.well-known/openid-configuration|/.well-known/jwks\.json|kubernetes\.default\.svc).* """| KEEP *
Elastic ESQL high T1098, T1098.006 ↗
Kubernetes RBAC Wildcard Elevation on Existing Role
Flags an existing Role or ClusterRole being changed (patch or update) so the effective rules become cluster-admin-like: wildcard on every API resource and wildcard on every verb. That is usually a deliberate privilege expansion, not a typo. RequestResponse audit and the response body are required so the detection reads the merged role after apply; loopback source IPs are ignored.
Show query
from logs-kubernetes.audit_logs-* metadata _id, _index, _version
| where
  kubernetes.audit.objectRef.resource in ("roles", "clusterroles") and
  kubernetes.audit.verb in ("update", "patch") and
  `kubernetes.audit.annotations.authorization_k8s_io/decision` == "allow" and
  kubernetes.audit.level == "RequestResponse" and
  kubernetes.audit.stage == "ResponseComplete" and
  kubernetes.audit.sourceIPs is not null and
  not kubernetes.audit.sourceIPs in ("::1", "127.0.0.1") and
  KQL(""" kubernetes.audit.responseObject.rules.verbs:"*" and kubernetes.audit.responseObject.rules.resources:"*" """)
| keep user.name, user_agent.original, event.action, source.ip, kubernetes.audit.verb, kubernetes.audit.objectRef.resource, kubernetes.audit.objectRef.name, kubernetes.audit.requestURI, kubernetes.audit.user.username, kubernetes.audit.user.groups, `kubernetes.audit.annotations.authorization_k8s_io/decision`, event.original, _id, _version, _index, data_stream.namespace
Elastic ESQL high T1552, T1552.007 ↗
Kubernetes Rapid Secret GET Activity Against Multiple Objects
This rule detects an unusual volume of Kubernetes API get requests against multiple distinct Secret objects from the same client fingerprint (user, source IP, and user agent) within a defined lookback window. This can indicate credential access or in-cluster reconnaissance, where a user or token is used to enumerate and retrieve sensitive data such as service account tokens, registry credentials, TLS material, or application configuration. Failed get requests are also included, as they may reveal RBAC boundaries, confirm the existence of targeted secrets, or reflect automated probing activity.
Show query
from logs-kubernetes.audit_logs-* metadata _id, _index, _version
| where event.dataset == "kubernetes.audit_logs"
    and event.action == "get"
    and kubernetes.audit.objectRef.resource == "secrets"
    and source.ip is not null and user.name is not null 
    and not to_string(source.ip) in ("127.0.0.1", "::1") and 
    not user.name in ("system:kube-controller-manager", "system:kube-scheduler") and 
    not kubernetes.audit.objectRef.name like "sh.helm.release.*" and 
    not kubernetes.audit.user.username in ("system:serviceaccount:flux-system:kustomize-controller", "system:serviceaccount:flux-system:helm-controller", "system:serviceaccount:flux-system:source-controller", "system:serviceaccount:security:trivy-operator")
| stats
    Esql.unique_credentials = count_distinct(kubernetes.audit.objectRef.name),
    Esql.secrets_names = values(kubernetes.audit.objectRef.name),
    Esql.namespaces = values(kubernetes.audit.objectRef.namespace),
    Esql.outcome = values(`kubernetes.audit.annotations.authorization_k8s_io/decision`)
  by user.name, kubernetes.audit.user.username, source.ip, user_agent.original
| where Esql.unique_credentials >= 3
| KEEP user.name, kubernetes.audit.user.username, source.ip, user_agent.original, Esql.*
Elastic KQL high T1552, T1552.007 ↗
Kubernetes Secret get or list with Suspicious User Agent
Detects read access to Kubernetes Secrets (`get`/`list`) with a user agent matching a curated set of non-standard or attacker-leaning clients, for example minimal HTTP tooling, common scripting stacks, default library fingerprints, or distribution-tagged strings associated with offensive-security Linux images. Legitimate in-cluster automation usually presents stable, purpose-specific user agents (for example controller or client-go variants used by known components).
Show query
data_stream.dataset:"kubernetes.audit_logs" and
event.action:(get or list) and
kubernetes.audit.objectRef.resource:"secrets" and
user_agent.original:(curl* or python* or Python* or wget* or Go-http* or perl* or java* or node* or php* or *distrib#kali* or *kali-amd64 or *kali-arm64*) and
source.ip:*
Elastic KQL high T1552, T1552.007, T1613 ↗
Kubernetes Secrets List Across Cluster or Sensitive Namespaces
Detects list operations on Kubernetes Secrets from a non-loopback client when the request URI targets cluster-wide secrets or list operations under kube-system or default. Useful for spotting broad secret enumeration from remote clients.
Show query
event.dataset:"kubernetes.audit_logs" and event.action:list and
kubernetes.audit.objectRef.resource:secrets and 
kubernetes.audit.requestURI :(/api/v1/secrets or /api/v1/secrets?limit* or /api/v1/namespaces/kube-system/secrets or /api/v1/namespaces/kube-system/secrets?limit* or /api/v1/namespaces/default/secrets or /api/v1/namespaces/default/secrets?limit*) and 
source.ip:(* and not ("::1" or "127.0.0.1")) and 
not user.name: (system\:kube-controller-manager or eks\:cloud-controller-manager or eks\:kms-storage-migrator) and 
not kubernetes.audit.user.groups:"system:serviceaccounts:ibm-csi"
Elastic KQL high T1552, T1552.001, T1528 ↗
Kubernetes and Cloud Credential Path Access via Process Arguments
Flags Linux process executions whose arguments reference high-value Kubernetes service-account material, kubeconfig or node PKI paths, or common cloud files, when invoked via typical file-reading utilities or from ephemeral directories. Useful for spotting in-cluster and hybrid credential theft early.
Show query
host.os.type:linux and event.category:process and event.action:(exec or executed) and
(
  process.name:(
    busybox or cat or head or tail or more or less or sed or awk or 
    find or grep or ls or whereis or cp or mv or ln or
    curl or wget or scp or rsync or tar or zip or gzip or
    base64 or xxd or od or dd or tee or strings or xargs or jq or yq or
    openssl or ssh or sftp or nc or ncat or netcat or socat or
    python* or perl* or ruby* or node or php* or lua* or .*
  ) or
  process.args:(
    cat or head or tail or more or less or sed or awk or 
    find or grep or cp or mv or curl or wget or base64 or 
    tar or scp or dd or strings or xargs
  ) or
  process.executable:(/tmp/* or /var/tmp/* or /dev/shm/* or /home/* or /run/user/*)
) and process.args:(
  "/var/run/secrets/kubernetes.io/serviceaccount/token" or
  "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" or
  "/var/run/secrets/eks.amazonaws.com/serviceaccount/token" or
  "/var/run/secrets/azure/tokens/azure-identity-token" or
  "/var/run/secrets/tokens/azure-identity-token" or
  "/var/lib/kubelet/kubeconfig" or
  "/etc/kubernetes/admin.conf" or
  "/etc/kubernetes/pki/ca.key" or
  "/etc/kubernetes/pki/apiserver-kubelet-client.key" or
  "/var/lib/kubelet/pki/kubelet-client-current.pem" or
  "/etc/rancher/k3s/k3s.yaml" or
  */.aws/credentials or
  */.aws/cli/cache/*.json or
  */.aws/sso/cache/*.json or
  */.azure/accessTokens.json or
  */.azure/azureProfile.json or
  */.azure/msal_token_cache.json or
  */confluence/confluence.cfg.xml or 
  *confluence/conf/server.xml
  */.config/gcloud/application_default_credentials.json or
  */.config/gcloud/credentials.db or
  */.config/gcloud/access_tokens.db or
  */.config/gcloud/legacy_credentials or
  */.kube/config or
  */.docker/config.json
) 
Elastic EQL high T1003, T1003.001 ↗
LSASS Memory Dump Creation
Identifies creation of LSASS memory dump artifacts with filenames matching LSASS dumps or common dumping-tool outputs, including dumpert.dmp, Andrew.dmp, SQLDmpr*.mdmp, and Coredump.dmp. This can indicate credential access through trusted utilities such as Task Manager or SQLDumper, or known tooling such as Dumpert and AndrewSpecial.
Show query
file where host.os.type == "windows" and event.action != "deletion" and
  file.name : ("lsass*.dmp", "dumpert.dmp", "Andrew.dmp", "SQLDmpr*.mdmp", "Coredump.dmp") and

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

  not (
        process.executable : (
          "?:\\Windows\\system32\\WerFault.exe",
          "?:\\Windows\\System32\\WerFaultSecure.exe"
          ) and
        file.path : (
          "?:\\Windows\\System32\\config\\systemprofile\\AppData\\Local\\CrashDumps\\lsass.exe.*.dmp",
          "?:\\Windows\\System32\\%LOCALAPPDATA%\\CrashDumps\\lsass.exe.*.dmp"
        )
  )
Elastic ESQL high
Lateral Movement Alerts from a Newly Observed Source Address
This rule detects source IPs that triggered their first lateral movement alert within the last 10 minutes (i.e., newly observed), while also triggering at least 2 distinct lateral movement detection rules. This surfaces new potentially malicious IPs exhibiting immediate lateral movement behavior.
Show query
FROM .alerts-security.* METADATA _index

// Lateral Movement related rules with fields of interest
| where kibana.alert.rule.threat.tactic.name is not null and
        source.ip IS NOT NULL and destination.ip is not null and
        host.id is not null and KQL("""kibana.alert.rule.threat.tactic.name : "Lateral Movement" and not kibana.alert.rule.tags : "Rule Type: Higher-Order Rule" """)

// aggregate stats by source.ip
| stats  Esql.first_time_seen = MIN(@timestamp),
         Esql.alerts_count = count(*),
         Esql.unique_rules_count = COUNT_DISTINCT(kibana.alert.rule.name),
         Esql.unique_count_host_id = COUNT_DISTINCT(host.id),
         Esql.rule_name_values = VALUES(kibana.alert.rule.name),
         Esql.user_name_values = VALUES(user.name),
         Esql.host_id_values = VALUES(host.id),
         Esql.host_ip_values = VALUES(host.ip),
         Esql.tactic_name_values = VALUES(kibana.alert.rule.threat.tactic.name) by source.ip

// values we will need for next filter
| eval isLocal = locate(MV_CONCAT(to_string(Esql.host_ip_values), ","), to_string(source.ip)),
       Esql.date_diff = DATE_DIFF("minute", Esql.first_time_seen, now())

// at least 2 unique rules from same source.ip and that was first seen in last 5 days
| where Esql.unique_rules_count >= 2 and
        // matches are within 10m of the rule execution time to avoid alert duplicates
        Esql.date_diff <= 10 and
        // make sure source.ip is not equal to host.ip
        not isLocal > 0 and
        // reduce noise from SCCM, Nessus and alike
        Esql.unique_count_host_id <= 3 and Esql.alerts_count <= 20
| eval host.id = MV_FIRST(Esql.host_id_values), user.name = MV_FIRST(Esql.user_name_values)
| KEEP Esql.*, source.ip, host.id, user.name
Elastic ESQL high
Lateral Movement Alerts from a Newly Observed User
This rule detects multiple lateral movement alerts from a user that was observed for the first time in the previous 5 days of alerts history. Analysts can use this high-order detection to prioritize triage and response.
Show query
FROM .alerts-security.* METADATA _index

// Lateral Movement related rules
| where kibana.alert.rule.threat.tactic.name is not null and user.id is not null and 
        (to_string(user.id) like "S-1-5-21*" or to_string(user.id) like "S-1-12-*") and
        host.id is not null and KQL("""kibana.alert.rule.threat.tactic.name : "Lateral Movement" """) and
        not KQL("""kibana.alert.rule.tags : "Rule Type: Higher-Order Rule" """)

// aggregate stats by user.id
| stats  Esql.first_time_seen = MIN(@timestamp),
         Esql.alerts_count = count(*),
         Esql.unique_rules_count = COUNT_DISTINCT(kibana.alert.rule.name),
         Esql.unique_count_host_id = COUNT_DISTINCT(host.id),
         Esql.rule_name_values = VALUES(kibana.alert.rule.name),
         Esql.host_id_values = VALUES(host.id),
         Esql.host_ip_values = VALUES(host.ip),
         Esql.source_ip_values = VALUES(source.ip),
         Esql.process_cmd_line = VALUES(process.command_line),
         Esql.tactic_name_values = VALUES(kibana.alert.rule.threat.tactic.name) by user.id, user.name

// at least 2 unique lateral movement detection rules from same user.id and that was first seen in last 5 days
| eval Esql.date_diff = DATE_DIFF("minute", Esql.first_time_seen, now())
| where Esql.unique_rules_count >= 2 and
        // matches are within 10m of the rule execution time to avoid alert duplicates
        Esql.date_diff <= 10
| eval source.ip = MV_FIRST(Esql.source_ip_values),  host.id = MV_FIRST(Esql.host_id_values) 
| KEEP Esql.*, user.id, user.name, host.id, source.ip
Lateral Movement via Startup Folder
Identifies suspicious file creations in the startup folder of a remote system. An adversary could abuse this to move laterally by dropping a malicious script or executable that will be executed after a reboot or user logon.
Show query
file where host.os.type == "windows" and event.type in ("creation", "change") and

 /* via RDP TSClient mounted share or SMB */
  (process.name : "mstsc.exe" or process.pid == 4) and

   file.path : ("?:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\*",
                "?:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\*")
Elastic EQL high T1003, T1003.007, T1005 ↗
Linux init (PID 1) Secret Dump via GDB
This rule monitors for the potential memory dump of the init process (PID 1) through gdb. Attackers may leverage memory dumping techniques to attempt secret extraction from privileged processes. Tools that display this behavior include "truffleproc" and "bash-memory-dump". This behavior should not happen by default, and should be investigated thoroughly.
Show query
process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "exec_event", "start", "ProcessRollup2", "executed", "process_started") and
process.name == "gdb" and process.args in ("--pid", "-p") and process.args == "1"
Long Base64 Encoded Command via Scripting Interpreter
Identifies oversized command lines used by Python, PowerShell, Node.js, or Deno that contain base64 decoding or encoded-command patterns. Adversaries may embed long inline encoded payloads in scripting interpreters to evade inspection and execute malicious content across Windows, macOS, and Linux systems.
Show query
FROM logs-endpoint.events.process-* METADATA _id, _index, _version, _ignored
| MV_EXPAND _ignored
| WHERE _ignored == "process.command_line"
| WHERE event.category == "process" and event.type == "start"
| EVAL command_line = TO_LOWER(process.command_line.text), pname = TO_LOWER(process.name)
| WHERE 
(
    (
        /* Python: inline exec with base64 decode or -c flag with encoded payload */
        pname like "python*" and
        (
            command_line like "*b64decode*" or
            (command_line like "*-c*" and command_line like "*base64*")
        )
    ) or
    (
        /* PowerShell: encoded command flag — require trailing space to avoid matching
           -Encoding, -EncryptionType, -EncryptionProvider, etc. */
        (pname like "powershell*" or pname like "pwsh*") and
        (
            command_line rlike ".* -(e|en|enc|enco|encod|encode|encoded|encodedcommand) .+" or
            command_line like "*-encodedcommand*" or
            command_line like "*frombase64string*"
        )
    ) or
    (
        /* Node.js: buffer.from must be paired with base64 to avoid matching
           general Buffer usage; atob is always base64 */
        pname like "node*" and
        (
            (command_line like "*buffer.from*" and command_line like "*base64*") or
            command_line like "*atob(*"
        )
    ) or
    (
        /* Deno: eval( (not eval/evaluate/evaluation), atob, or buffer+base64 */
        pname like "deno*" and
        (
            command_line like "*atob(*" or
            (command_line like "*buffer.from*" and command_line like "*base64*") or
            command_line like "*eval(*"
        )
    )
)
| EVAL Esql.length_cmdline = LENGTH(command_line)
| WHERE Esql.length_cmdline >= 4000
| KEEP *
M365 Identity OAuth Flow by First-Party Microsoft App from Multiple IPs
Identifies sign-ins on behalf of a principal user to the Microsoft Graph or legacy Azure AD API from multiple IPs using first-party Microsoft applications from the FOCI (Family of Client IDs) group. Developer tools like Azure CLI, VSCode, and Azure PowerShell accessing these resources from multiple IPs are flagged, along with any FOCI application accessing the deprecated Windows Azure Active Directory from multiple IPs. This behavior may indicate an adversary using a phished OAuth authorization code or refresh token, as seen in attacks like ConsentFix where attackers steal localhost OAuth codes and replay them from attacker infrastructure.
Show query
from logs-o365.audit-*
| where
    data_stream.dataset == "o365.audit" and
    event.action == "UserLoggedIn" and
    source.ip is not null and
    o365.audit.UserId is not null and
    o365.audit.ApplicationId is not null and
    o365.audit.UserType in ("0", "2", "3", "10") and
    (
        /* Developer tools accessing Graph OR Legacy AAD */
        (
            o365.audit.ApplicationId in (
                "aebc6443-996d-45c2-90f0-388ff96faa56",
                "29d9ed98-a469-4536-ade2-f981bc1d605e",
                "04b07795-8ddb-461a-bbee-02f9e1bf7b46",
                "1950a258-227b-4e31-a9cf-717495945fc2"
            ) and
            o365.audit.ObjectId in (
                "00000003-0000-0000-c000-000000000000",
                "00000002-0000-0000-c000-000000000000"
            )
        ) or
        /* Any FOCI app accessing Legacy AAD only */
        (
            o365.audit.ApplicationId in (
                "00b41c95-dab0-4487-9791-b9d2c32c80f2",
                "1fec8e78-bce4-4aaf-ab1b-5451cc387264",
                "26a7ee05-5602-4d76-a7ba-eae8b7b67941",
                "27922004-5251-4030-b22d-91ecd9a37ea4",
                "4813382a-8fa7-425e-ab75-3b753aab3abb",
                "ab9b8c07-8f02-4f72-87fa-80105867a763",
                "d3590ed6-52b3-4102-aeff-aad2292ab01c",
                "872cd9fa-d31f-45e0-9eab-6e460a02d1f1",
                "af124e86-4e96-495a-b70a-90f90ab96707",
                "2d7f3606-b07d-41d1-b9d2-0d0c9296a6e8",
                "844cca35-0656-46ce-b636-13f48b0eecbd",
                "87749df4-7ccf-48f8-aa87-704bad0e0e16",
                "cf36b471-5b44-428c-9ce7-313bf84528de",
                "0ec893e0-5785-4de6-99da-4ed124e5296c",
                "22098786-6e16-43cc-a27d-191a01a1e3b5",
                "4e291c71-d680-4d0e-9640-0a3358e31177",
                "57336123-6e14-4acc-8dcf-287b6088aa28",
                "57fcbcfa-7cee-4eb1-8b25-12d2030b4ee0",
                "66375f6b-983f-4c2c-9701-d680650f588f",
                "9ba1a5c7-f17a-4de9-a1f1-6178c8d51223",
                "a40d7d7d-59aa-447e-a655-679a4107e548",
                "a569458c-7f2b-45cb-bab9-b7dee514d112",
                "b26aadf8-566f-4478-926f-589f601d9c74",
                "c0d2a505-13b8-4ae0-aa9e-cddd5eab0b12",
                "d326c1ce-6cc6-4de2-bebc-4591e5e13ef0",
                "e9c51622-460d-4d3d-952d-966a5b1da34c",
                "eb539595-3fe1-474e-9c1d-feb3625d1be5",
                "ecd6b820-32c2-49b6-98a6-444530e5a77a",
                "f05ff7c9-f75a-4acd-a3b5-f4b6a870245d",
                "f44b1140-bc5e-48c6-8dc0-5cf5a53c0e34",
                "be1918be-3fe3-4be9-b32b-b542fc27f02e",
                "cab96880-db5b-4e15-90a7-f3f1d62ffe39",
                "d7b530a4-7680-4c23-a8bf-c52c121d2e87",
                "dd47d17a-3194-4d86-bfd5-c6ae6f5651e3",
                "e9b154d0-7658-433b-bb25-6b8e0a8a7c59"
            ) and
            o365.audit.ObjectId == "00000002-0000-0000-c000-000000000000"
        )
    )
| eval
    Esql.time_window_date_trunc = date_trunc(30 minutes, @timestamp),
    Esql.oauth_authorize_user_id_case = case(
        o365.audit.ExtendedProperties.RequestType == "OAuth2:Authorize" and o365.audit.ExtendedProperties.ResultStatusDetail == "Redirect",
        o365.audit.UserId,
        null
    ),
    Esql.oauth_token_user_id_case = case(
        o365.audit.ExtendedProperties.RequestType == "OAuth2:Token",
        o365.audit.UserId,
        null
    )
| stats
    Esql.source_ip_count_distinct = count_distinct(source.ip),
    Esql.source_ip_values = values(source.ip),
    Esql.o365_audit_ApplicationId_values = values(o365.audit.ApplicationId),
    Esql.source_as_organization_name_values = values(source.`as`.organization.name),
    Esql.oauth_token_count_distinct = count_distinct(Esql.oauth_token_user_id_case),
    Esql.oauth_authorize_count_distinct = count_distinct(Esql.oauth_authorize_user_id_case)
  by
    o365.audit.UserId,
    Esql.time_window_date_trunc,
    o365.audit.ApplicationId,
    o365.audit.ObjectId
| keep
    Esql.time_window_date_trunc,
    Esql.source_ip_values,
    Esql.source_ip_count_distinct,
    Esql.o365_audit_ApplicationId_values,
    Esql.source_as_organization_name_values,
    Esql.oauth_token_count_distinct,
    Esql.oauth_authorize_count_distinct
| where
    Esql.source_ip_count_distinct >= 2 and
    Esql.oauth_token_count_distinct > 0 and
    Esql.oauth_authorize_count_distinct > 0
M365 Identity OAuth Flow by User Sign-in to Device Registration
Identifies attempts to register a new device in Microsoft Entra ID after OAuth authentication with authorization code grant. Adversaries may use OAuth phishing techniques to obtain an OAuth authorization code, which can then be exchanged for access and refresh tokens. This rule detects a sequence of events where a user principal authenticates via OAuth, followed by a device registration event, indicating potential misuse of the OAuth flow to establish persistence or access resources.
Show query
sequence by related.user with maxspan=30m
[authentication where event.action == "UserLoggedIn" and
 o365.audit.ExtendedProperties.RequestType == "OAuth2:Authorize" and o365.audit.ExtendedProperties.ResultStatusDetail == "Redirect" and
 o365.audit.UserType: ("0", "2", "3", "10")] // victim source.ip
[authentication where event.action == "UserLoggedIn" and
 o365.audit.ExtendedProperties.RequestType == "OAuth2:Token" and o365.audit.ExtendedProperties.ResultStatusDetail == "Success"] // attacker source.ip to convert oauth code to token
[web where data_stream.dataset == "o365.audit" and event.action == "Add registered users to device."] // user.name is captured in related.user
Elastic KQL high T1080, T1608, T1608.001 ↗
M365 OneDrive Malware File Upload
Identifies the occurrence of files uploaded to OneDrive being detected as Malware by the file scanning engine. Attackers can use File Sharing and Organization Repositories to spread laterally within the company and amplify their access. Users can inadvertently share these files without knowing their maliciousness, giving adversaries an opportunity to gain initial access to other endpoints in the environment.
Show query
data_stream.dataset:o365.audit and event.provider:OneDrive and event.code:SharePointFileOperation and event.action:FileMalwareDetected
Elastic KQL high T1566, T1539 ↗
M365 Potential AiTM UserLoggedIn via Office App (Tycoon2FA)
Detects Microsoft 365 audit "UserLoggedIn" events consistent with Tycoon 2FA phishing-as-a-service (PhaaS) adversary-in-the-middle (AiTM) activity: the Microsoft Authentication Broker requesting access where the object identifier matches Microsoft Graph or Exchange Online, or the Office web client application authenticating to itself, combined with Node.js-style user agents (node, axios, undici). Tycoon 2FA bypasses MFA by relaying authentication and capturing session material, often targeting Microsoft 365 and Gmail. Baseline legitimate automation and developer tooling before tuning.
Show query
data_stream.dataset:"o365.audit" and event.category:"authentication" and event.action:"UserLoggedIn" and
(
    (
        o365.audit.ApplicationId:"29d9ed98-a469-4536-ade2-f981bc1d605e" and
        o365.audit.ObjectId:(
            "00000002-0000-0ff1-ce00-000000000000" or "00000003-0000-0000-c000-000000000000"
        )
    ) or
    (
        o365.audit.ApplicationId:"4765445b-32c6-49b0-83e6-1d93765276ca" and
        o365.audit.ObjectId:"4765445b-32c6-49b0-83e6-1d93765276ca"
    )
) and user_agent.original:(node or axios* or undici)
Elastic KQL high T1080, T1608, T1608.001 ↗
M365 SharePoint Malware File Detected
Identifies the occurrence of files uploaded to SharePoint being detected as Malware by the file scanning engine. Attackers can use File Sharing and Organization Repositories to spread laterally within the company and amplify their access. Users can inadvertently share these files without knowing their maliciousness, giving adversaries opportunities to gain initial access to other endpoints in the environment.
Show query
data_stream.dataset:o365.audit and event.provider:SharePoint and event.code:SharePointFileOperation and event.action:FileMalwareDetected
Elastic ESQL high T1078 ↗
M365 or Entra ID Identity Sign-in from a Suspicious Source
This rule correlate Entra-ID or Microsoft 365 mail successful sign-in events with network security alerts by source address. Adversaries may trigger some network security alerts such as reputation or other anomalies before accessing cloud resources.
Show query
from logs-o365.audit-*, logs-azure.signinlogs-*, .alerts-security.*
// filter for azure or m365 sign-in and external alerts with source.ip not null
| where to_ip(source.ip) is not null
  and (data_stream.dataset in ("o365.audit", "azure.signinlogs") or kibana.alert.rule.rule_id == "eb079c62-4481-4d6e-9643-3ca499df7aaa")
  and not cidr_match(
    to_ip(source.ip),
    "10.0.0.0/8", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24", "192.0.0.0/29",
    "192.0.0.8/32", "192.0.0.9/32", "192.0.0.10/32", "192.0.0.170/32", "192.0.0.171/32", "192.0.2.0/24",
    "192.31.196.0/24", "192.52.193.0/24", "192.168.0.0/16", "192.88.99.0/24", "224.0.0.0/4",
    "100.64.0.0/10", "192.175.48.0/24", "198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24",
    "240.0.0.0/4", "::1", "FE80::/10", "FF00::/8"
  )

// capture relevant raw fields
| keep source.ip, event.action, event.outcome, data_stream.dataset, kibana.alert.rule.rule_id, event.category

// classify each source ip based on alert type
| eval
  Esql.source_ip_mail_access_case = case(data_stream.dataset == "o365.audit" and event.action == "MailItemsAccessed" and event.outcome == "success", to_ip(source.ip)),
  Esql.source_ip_azure_signin_case = case(data_stream.dataset == "azure.signinlogs" and event.outcome == "success", to_ip(source.ip)),
  Esql.source_ip_network_alert_case = case(kibana.alert.rule.rule_id == "eb079c62-4481-4d6e-9643-3ca499df7aaa" and not data_stream.dataset in ("o365.audit", "azure.signinlogs"), to_ip(source.ip))

// aggregate by source ip
| stats
    Esql.event_count = count(*),
    Esql.source_ip_mail_access_case_count_distinct = count_distinct(Esql.source_ip_mail_access_case),
    Esql.source_ip_azure_signin_case_count_distinct = count_distinct(Esql.source_ip_azure_signin_case),
    Esql.source_ip_network_alert_case_count_distinct = count_distinct(Esql.source_ip_network_alert_case),
    Esql.data_stream_dataset_count_distinct = count_distinct(data_stream.dataset),
    Esql.data_stream_dataset_values = values(data_stream.dataset),
    Esql.kibana_alert_rule_id_values = values(kibana.alert.rule.rule_id),
    Esql.event_category_values = values(event.category)
  by Esql.source_ip = to_ip(source.ip)

// correlation condition
| where
  Esql.source_ip_network_alert_case_count_distinct > 0
  and Esql.data_stream_dataset_count_distinct >= 2
  and (Esql.source_ip_mail_access_case_count_distinct > 0 or Esql.source_ip_azure_signin_case_count_distinct > 0)
  and Esql.event_count <= 100
Machine Learning Detected DGA activity using a known SUNBURST DNS domain
A supervised machine learning model has identified a DNS question name that used by the SUNBURST malware and is predicted to be the result of a Domain Generation Algorithm.
Show query
ml_is_dga.malicious_prediction:1 and dns.question.registered_domain:avsvmcloud.com
Elastic EQL high T1036, T1036.004 ↗
Machine Learning Detected a Suspicious Windows Event with a High Malicious Probability Score
A supervised machine learning model (ProblemChild) has identified a suspicious Windows process event with high probability of it being malicious activity. Alternatively, the model's blocklist identified the event as being malicious.
Show query
process where ((problemchild.prediction == 1 and problemchild.prediction_probability > 0.98) or
blocklist_label == 1) and not process.args : ("*C:\\WINDOWS\\temp\\nessus_*.txt*", "*C:\\WINDOWS\\temp\\nessus_*.tmp*") and
process.parent.executable != null and not user.id in ("S-1-5-18", "S-1-5-19", "S-1-5-20") and
not process.parent.name : ("cmd.exe", "powershell.exe", "Perplexity.exe", "vmtoolsd.exe", "Code.exe", "explorer.exe", "git.exe") and
not (process.name : "msedgewebview2.exe" and process.parent.name : "msedgewebview2.exe") and
not (process.name : "opera.exe" and process.parent.name : "opera.exe") and
not (process.parent.executable : "C:\\Windows\\System32\\svchost.exe" and
     process.name : ("UCPDMgr.exe", "sdbinst.exe", "gpupdate.exe", "rundll32.exe", "taskhostw.exe", "taskeng.exe", "rdpclip.exe", "firefox.exe", "w3wp.exe")) and
not process.executable : ("C:\\Program Files\\*.exe", "C:\\Program Files (x86)\\*.exe") and
not (process.name : "MpCmdRun.exe" and process.parent.name : ("MsMpEng.exe", "MpCmdRun.exe", "svchost.exe")) and
not (process.name : "slack.exe" and process.parent.name : "slack.exe") and
not (process.name : "reg.exe" and process.parent.name : "pycharm64.exe") and
not (process.name : "reg.exe" and process.parent.name : "rider64.exe") and
not (process.name : "LogiLuUpdater.exe" and process.parent.name : "LogiOptionsMgr.exe") and
not (process.name : "chrome.exe" and process.parent.name : "node.exe" and process.command_line  : "*playwright*") and
not (process.name : "powershell.exe" and process.command_line : "*\\Zabbix_Scripts\\*.ps1*") and
not (process.parent.name : "opera.exe" and process.command_line: "*--type=renderer*")
Elastic KQL high
Malware - Prevented - Elastic Endgame
Elastic Endgame prevented Malware. Click the Elastic Endgame icon in the event.module column or the link in the rule.reference column for additional information.
Show query
event.kind:alert and event.module:endgame and endgame.metadata.type:prevention and (event.action:file_classification_event or endgame.event_subtype_full:file_classification_event)
Manual Loading of a Suspicious Chromium Extension
Detects the manual loading of a Chromium-based browser extension via command line arguments. This activity is suspicious and could indicate a threat actor loading a malicious extension to persist or collect browsing secrets such as cookies and authentication tokens.
Show query
process where host.os.type == "macos" and event.action == "exec" and
  process.name in ("Google Chrome", "Brave Browser", "Microsoft Edge") and
  process.args like "--load-extension=/*" and
  not (process.args like "--load-extension=/Users/*/Library/Application Support/Cypress/*" and
       process.parent.executable like ("/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
                                        "/Users/*/Library/Caches/Cypress/*/Cypress.app/Contents/MacOS/Cypress")) and
  not process.parent.executable like ("/opt/homebrew/Caskroom/chromedriver/*/chromedriver",
                                    "/Applications/Cypress.app/Contents/MacOS/Cypress",
                                    "/usr/local/bin/chromedriver")
Manual Memory Dumping via Proc Filesystem
This rule monitors for manual memory dumping via the proc filesystem. The proc filesystem in Linux provides a virtual filesystem that contains information about system processes and their memory mappings. Attackers may use this technique to dump the memory of a process, potentially extracting sensitive information such as credentials or encryption keys.
Show query
process where host.os.type == "linux" and event.type == "start" and event.action in ("exec", "exec_event", "start", "ProcessRollup2", "executed", "process_started") and
process.name in ("cat", "grep", "tail", "less", "more", "egrep", "fgrep") and process.command_line like "/proc/*/mem"
Elastic KQL high T1055, T1620 ↗
Memory Threat - Detected - Elastic Defend
Generates a detection alert each time an Elastic Defend alert for memory signatures are received. Enabling this rule allows you to immediately begin investigating your Endpoint memory signature alerts. This rule identifies Elastic Defend memory signature detections only, and does not include prevention alerts.
Show query
event.kind : alert and event.code : (memory_signature or shellcode_thread) and (event.type : allowed or (event.type: denied and event.outcome: failure))
Elastic KQL high T1055, T1620 ↗
Memory Threat - Prevented- Elastic Defend
Generates a detection alert each time an Elastic Defend alert for memory signatures are received. Enabling this rule allows you to immediately begin investigating your Endpoint memory signature alerts. This rule identifies Elastic Defend memory signature preventions only, and does not include detection only alerts.
Show query
event.kind : alert and event.code : (memory_signature or shellcode_thread) and event.type : denied and event.outcome : success
Microsoft Build Engine Started by an Office Application
An instance of MSBuild, the Microsoft Build Engine, was started by an Office application. This is unusual behavior for the Build Engine and could have been caused by a malicious document executing a script payload.
Show query
process where host.os.type == "windows" and event.type == "start" and
  process.name : "MSBuild.exe" and
  process.parent.name : ("eqnedt32.exe",
                         "excel.exe",
                         "fltldr.exe",
                         "msaccess.exe",
                         "mspub.exe",
                         "outlook.exe",
                         "powerpnt.exe",
                         "winword.exe" )
Microsoft Exchange Worker Spawning Suspicious Processes
Identifies suspicious processes being spawned by the Microsoft Exchange Server worker process (w3wp). This activity may indicate exploitation activity or access to an existing web shell backdoor.
Show query
process where host.os.type == "windows" and event.type == "start" and
  process.parent.name : "w3wp.exe" and process.parent.args : "MSExchange*AppPool" and
  (
    (process.name : ("cmd.exe", "powershell.exe", "pwsh.exe", "powershell_ise.exe") or
    ?process.pe.original_file_name in ("Cmd.Exe", "PowerShell.EXE", "pwsh.dll", "powershell_ise.EXE"))
  )
Elastic EQL high T1003, T1552, T1552.001 ↗
Microsoft IIS Connection Strings Decryption
Identifies use of aspnet_regiis to decrypt Microsoft IIS connection strings. An attacker with Microsoft IIS web server access via a webshell or similar access can decrypt and dump any hardcoded connection strings, such as the MSSQL service account password using the aspnet_regiis command.
Show query
process where host.os.type == "windows" and event.type == "start" and
  (process.name : "aspnet_regiis.exe" or ?process.pe.original_file_name == "aspnet_regiis.exe") and
  process.args : "connectionStrings" and process.args : ("-pdf", "-pd")
Mimikatz Memssp Log File Detected
Identifies the default Mimikatz MemSSP credential log file, mimilsa.log. This file is created after the misc::memssp module injects a malicious Security Support Provider into LSASS and can contain credentials from subsequent logons to the host.
Show query
file where host.os.type == "windows" and file.name : "mimilsa.log" and process.name : "lsass.exe"
Elastic EQL high T1112, T1562, T1562.001 ↗
Modification of AmsiEnable Registry Key
Identifies modifications of the AmsiEnable registry key to 0, which disables Windows Script AMSI scanning for the affected user. Adversaries can modify this key to bypass AMSI protections for Windows Script Host or JScript execution.
Show query
registry where host.os.type == "windows" and event.type in ("creation", "change") and
  registry.value : "AmsiEnable" and registry.data.strings: ("0", "0x00000000")

  /*
    Full registry key path omitted due to data source variations:
    HKEY_USERS\\*\\Software\\Microsoft\\Windows Script\\Settings\\AmsiEnable"
  */
Elastic EQL high T1003, T1003.001, T1112 ↗
Modification of WDigest Security Provider
Identifies attempts to modify the WDigest security provider in the registry to force the user's password to be stored in clear text in memory. Windows 8.1+ and Server 2012 R2+ disable WDigest plaintext credential caching by default, but setting UseLogonCredential to 1 re-enables it, causing LSASS to retain cleartext passwords for subsequent interactive logons. Adversaries abuse this to prepare for credential dumping from LSASS memory.
Show query
registry where host.os.type == "windows" and event.type in ("creation", "change") and
    registry.value : "UseLogonCredential" and
    registry.path : "*\\SYSTEM\\*ControlSet*\\Control\\SecurityProviders\\WDigest\\UseLogonCredential" and
    registry.data.strings : ("1", "0x00000001") and
    not (process.executable : "?:\\Windows\\System32\\svchost.exe" and user.id : "S-1-5-18")
Elastic ESQL high T1528, T1552, T1552.001 ↗
Multi-Cloud CLI Token and Credential Access Commands
Correlates process telemetry for shells and major cloud/Kubernetes CLIs when command lines match token or credential material access patterns (GCP, Azure, AWS, GitHub, kubectl, DigitalOcean, OCI). Flags hosts where multiple cloud targets appear within a five-minute window.
Show query
FROM logs-endpoint.events.process-*, logs-system.security-*, logs-windows.sysmon_operational-* METADATA _id, _index, _version
| WHERE event.category == "process" AND KQL(""" event.type : "start" and not event.action : "fork" """)
  AND process.command_line IS NOT NULL 
  AND (
    TO_LOWER(process.name) IN (
      "cmd.exe", "powershell.exe", "pwsh.exe", 
      "sh", "bash", "zsh", "dash", "fish", "ksh",
      "gcloud", "gcloud.cmd", "az", "az.cmd", "azd", "azd.exe",
      "gh", "gh.exe", "aws", "aws.exe",
      "kubectl", "kubectl.exe",
      "doctl", "doctl.exe",
      "oci", "oci.exe"
    ) OR
    TO_LOWER(process.parent.name) IN (
      "cmd.exe", "powershell.exe", "pwsh.exe",
      "sh", "bash", "zsh", "dash", "fish", "ksh", "bun", "bun.exe", 
      "node", "node.exe", "java", "java.exe"
    )
  )
  AND process.command_line RLIKE """.*(config-helper\s.*--format|auth\s+print-access-token|auth\s+print-identity-token|auth\s+application-default\s+print|get-access-token\s.*--output|Get-AzAccessToken|azd\s+auth\s+token|az\s+account\s+get-access-token|gh\s+auth\s+(token|status)|aws\s+sts\s+(get-session-token|get-caller-identity|assume-role)|aws\s+configure\s+(export-credentials|list)|kubectl\s+config\s+view\s.*--raw|kubectl\s+get\s+secret|doctl\s+auth\s+(list|init)|oci\s+session\s+authenticate|oci\s+iam\s.*token).* """| EVAL cloud_target = CASE(
    process.command_line RLIKE ".*(gcloud|config-helper|print-access-token|print-identity-token).*", "GCP",
    process.command_line RLIKE ".*(azd auth|az account|Get-AzAccessToken).*", "AZURE",
    process.command_line RLIKE ".*(aws sts|aws configure).*", "AWS",
    process.command_line RLIKE ".*(gh auth).*", "GITHUB",
    process.command_line RLIKE ".*(kubectl config|kubectl get secret).*", "KUBERNETES",
    process.command_line RLIKE ".*(doctl).*", "DIGITALOCEAN",
    process.command_line RLIKE ".*(oci session|oci iam).*", "ORACLE"
  )
| WHERE cloud_target IS NOT NULL // drop unclassified events before aggregation
| STATS
    Esql.cloud_targets = VALUES(cloud_target),
    Esql.unique_clouds = COUNT_DISTINCT(cloud_target),
    Esql.process_command_line_values = VALUES(process.command_line),
    Esql.process_parent_executable_values = VALUES(process.parent.executable),
    Esql.first_seen = MIN(@timestamp),
    Esql.last_seen = MAX(@timestamp),
    Esql.event_count = COUNT(*)
  BY host.name, host.id, user.name
| WHERE Esql.unique_clouds >= 2
| KEEP Esql.*, user.name, host.name, host.id
Elastic ESQL high
Multiple Alerts Involving a User
This rule uses alert data to determine when multiple different alerts involving the same user are triggered. Analysts can use this to prioritize triage and response, as these users are more likely to be compromised.
Show query
from .alerts-security.*
| where kibana.alert.rule.name is not null and user.id is not null and
  // Exclude low severity alerts
  kibana.alert.risk_score > 21 and
  not KQL("""kibana.alert.rule.tags : "Rule Type: Higher-Order Rule" """)
| stats
    Esql.kibana_alert_rule_name_distinct_count = COUNT_DISTINCT(kibana.alert.rule.name), 
    Esql.kibana_alert_rule_rule_id_distinct_count = COUNT_DISTINCT(kibana.alert.rule.rule_id),
    Esql.host_id_distinct_count = COUNT_DISTINCT(host.id),
    Esql.kibana_alert_risk_score_distinct_count = COUNT_DISTINCT(kibana.alert.risk_score),
    Esql.event_dataset_distinct_count = COUNT_DISTINCT(event.dataset),
    Esql.kibana_alert_rule_name_values = VALUES(kibana.alert.rule.name), 
    Esql.kibana_alert_risk_score_values = VALUES(kibana.alert.risk_score), 
    Esql.event_dataset_values = VALUES(event.dataset),
    Esql.event_module_values = VALUES(event.module), 
    Esql.process_command_line_values = VALUES(process.command_line), 
    Esql.host_id_values = VALUES(host.id), 
    Esql.source_ip_values = VALUES(source.ip), 
    Esql.destination_ip_values = VALUES(destination.ip) by user.id

| where Esql.kibana_alert_rule_name_distinct_count >= 4 AND Esql.kibana_alert_rule_rule_id_distinct_count >= 2 and
 // Exclude known system accounts with matches in more than one host
 not (
   (length(TO_STRING(user.id)) <= 4 or user.id IN ("S-1-5-18", "S-1-5-19", "S-1-5-20", "0")) and
   (Esql.host_id_distinct_count >= 2 or Esql.host_id_distinct_count == 0)
 )

| keep user.id, Esql.*
Elastic KQL high
Multiple Alerts in Different ATT&CK Tactics on a Single Host
This rule uses alert data to determine when multiple alerts in different phases of an attack involving the same host are triggered. Analysts can use this to prioritize triage and response, as these hosts are more likely to be compromised.
Show query
signal.rule.name:* and kibana.alert.rule.threat.tactic.id:*
Elastic ESQL high
Multiple Alerts in Same ATT&CK Tactic by Host
This rule correlates multiple security alerts associated with the same ATT&CK tactic on a single host within a defined time window. By requiring alerts from multiple distinct detection rules, this detection helps identify hosts exhibiting concentrated malicious behavior, which may indicate an active intrusion or post-compromise activity. The rule is intended to assist analysts in prioritizing triage toward hosts with higher likelihood of compromise rather than signaling a single discrete event.
Show query
from .alerts-security.*  metadata _id

| where kibana.alert.risk_score > 21 and
        kibana.alert.rule.name IS NOT NULL and
        host.id is not null and event.dataset is not null and

        // excluding ML and Threat Match rules as they tend to be noisy
        not kibana.alert.rule.type in ("threat_match", "machine_learning") and

        // excluding noisy tactics like Discovery, Persistence and Lateral Movement
        kibana.alert.rule.threat.tactic.name in ("Credential Access", "Defense Evasion", "Execution", "Command and Control") and

        // excluding some noisy rules
        not kibana.alert.rule.name in ("Agent Spoofing - Mismatched Agent ID", "Process Termination followed by Deletion") and
        not KQL("""kibana.alert.rule.tags : "Rule Type: Higher-Order Rule" """)

// extract unique counts and values by host.id and tactic name
| stats Esql.alerts_count = COUNT(*),
        Esql.kibana_alert_rule_name_distinct_count = COUNT_DISTINCT(kibana.alert.rule.name),
        Esql.event_module_distinct_count = COUNT_DISTINCT(event.module),
        Esql.event_module_values = VALUES(event.module),
        Esql.kibana_alert_rule_name_values = VALUES(kibana.alert.rule.name),
        Esql.threat_technique_id_distinct_count = COUNT_DISTINCT(kibana.alert.rule.threat.technique.id),
        Esql.threat_technique_name_values = VALUES(kibana.alert.rule.threat.technique.name),
        Esql.process_executable_values = VALUES(process.executable),
        Esql.process_parent_executable_values = VALUES(process.parent.executable),
        Esql.process_command_line_values = VALUES(process.command_line),
        Esql.process_entity_id_distinct_count = COUNT_DISTINCT(process.entity_id) by host.id, kibana.alert.rule.threat.tactic.name

// filter for at least 3 unique rules and exclude noisy patterns like high count of alerts or processes often associated with noisy FPs
| where Esql.kibana_alert_rule_name_distinct_count >= 3 and Esql.process_entity_id_distinct_count <= 10 and Esql.alerts_count <= 20

// fields populated in the resulting alerts
| Keep host.id, kibana.alert.rule.threat.tactic.name, Esql.*
Elastic ESQL high T1555, T1555.006 ↗
Multiple Cloud Secrets Accessed by Source Address
This rule detects authenticated sessions accessing secret stores across multiple environments from the same source address within a short period of time, including cloud providers (AWS, GCP, Azure) and Kubernetes clusters. Adversaries with access to compromised credentials or session tokens may attempt to retrieve secrets from services such as AWS Secrets Manager, Google Secret Manager, Azure Key Vault, or Kubernetes Secrets in rapid succession to expand their access or exfiltrate sensitive information.
Show query
FROM logs-azure.platformlogs-*, logs-aws.cloudtrail-*, logs-gcp.audit-*, logs-kubernetes.audit_logs-* METADATA _id, _version, _index
| WHERE 
  ( 
    /* AWS Secrets Manager */ 
    (data_stream.dataset == "aws.cloudtrail" AND event.action == "GetSecretValue") OR 
    
    // Azure Key Vault (platform logs)
    (data_stream.dataset == "azure.platformlogs" AND event.action IN ("SecretGet", "KeyGet")) or 
    
    /* Google Secret Manager */ 
    (data_stream.dataset IN ("googlecloud.audit", "gcp.audit") AND 
     event.action IN ("google.cloud.secretmanager.v1.SecretManagerService.AccessSecretVersion", "google.cloud.secretmanager.v1.SecretManagerService.GetSecretRequest")) OR 

    /* Kubernetes Secrets */
    (data_stream.dataset == "kubernetes.audit_logs" AND kubernetes.audit.objectRef.resource == "secrets" AND kubernetes.audit.verb IN ("get", "list"))

   ) AND source.ip IS NOT NULL

// Cloud vendor label based on dataset
| EVAL Esql.cloud_vendor = CASE(
    data_stream.dataset == "aws.cloudtrail", "aws",
    data_stream.dataset == "azure.platformlogs", "azure",
    data_stream.dataset IN ("googlecloud.audit","gcp.audit"), "gcp",
    data_stream.dataset == "kubernetes.audit_logs", "k8s",
    "unknown"
  )
// Vendor+tenant label, e.g. aws:123456789012, azure:tenant, gcp:project
| EVAL Esql.tenant_label = CASE(
    Esql.cloud_vendor == "aws", CONCAT("aws:", cloud.account.id),
    Esql.cloud_vendor == "azure", CONCAT("azure:", cloud.account.id),
    Esql.cloud_vendor == "gcp", CONCAT("gcp:", cloud.account.id),
    Esql.cloud_vendor == "k8s", CONCAT("k8s:", orchestrator.cluster.name),
    "unknown"
  )
| WHERE Esql.cloud_vendor != "unknown"
| STATS
    // Core counts
    Esql.events_count = COUNT(*),
    Esql.vendor_count_distinct = COUNT_DISTINCT(Esql.cloud_vendor),
    // Action & data source context
    Esql.event_action_values = VALUES(event.action),
    Esql.data_source_values = VALUES(data_stream.dataset),
    // Cloud vendor + tenant context
    Esql.cloud_vendor_values = VALUES(Esql.cloud_vendor),
    Esql.tenant_label_values = VALUES(Esql.tenant_label),
    // Hyperscaler-specific IDs
    Esql.aws_account_id_values = VALUES(CASE(Esql.cloud_vendor == "aws", cloud.account.id, "unknown")),
    Esql.azure_tenant_id_values = VALUES(CASE(Esql.cloud_vendor == "azure", cloud.account.id, "unknown")),
    Esql.gcp_project_id_values = VALUES(CASE(Esql.cloud_vendor == "gcp", cloud.account.id, "unknown")),
    // Generic cloud metadata
    Esql.cloud_region_values = VALUES(cloud.region),
    Esql.k8s_namespace_values = VALUES(kubernetes.audit.objectRef.namespace),
    // Namespace values
    Esql.data_stream_namespace_values = VALUES(data_stream.namespace), 
    Esql_priv.user_name_values = VALUES(user.name)
  BY source.ip
// Require multi-vendor cred-access from same source IP
| WHERE Esql.vendor_count_distinct >= 2
| SORT Esql.events_count DESC
| KEEP Esql.*, Esql_priv.*, source.ip
Elastic ESQL high
Multiple Elastic Defend Alerts by Agent
This rule uses alert data to determine when multiple alerts from Elastic Defend involving the same host are triggered. Analysts can use this to prioritize triage and response, as these hosts are more likely to be compromised.
Show query
from logs-endpoint.alerts-* metadata _id
| eval target_time_window = DATE_TRUNC(24 hours, @timestamp)
| where event.code in ("malicious_file", "memory_signature", "shellcode_thread", "behavior") and
        agent.id is not null and not rule.name in ("Multi.EICAR.Not-a-virus")
| stats Esql.alerts_count = COUNT(*),
        Esql.event_code_distinct_count = count_distinct(event.code),
        Esql.rule_name_distinct_count = COUNT_DISTINCT(rule.name),
        Esql.file_hash_distinct_count = COUNT_DISTINCT(file.hash.sha256),
        Esql.process_name_distinct_count = COUNT_DISTINCT(process.entity_id),
        Esql.event_code_values = VALUES(event.code),
        Esql.rule_name_values = VALUES(rule.name),
        Esql.message_values = VALUES(message),
        Esql.file_path_values = VALUES(file.path),
        Esql.dll_path_values = VALUES(dll.path),
        Esql.process_executable_values = VALUES(process.executable),
        Esql.process_parent_executable_values = VALUES(process.parent.executable),
        Esql.process_command_line_values = VALUES(process.command_line),
        Esql.process_hash_sha256_values = VALUES(process.hash.sha256),
        Esql.file_hash_sha256_values = VALUES(file.hash.sha256),
        Esql.dll_hash_sha256_values = VALUES(dll.hash.sha256) by agent.id
| where (Esql.event_code_distinct_count >= 2 or Esql.rule_name_distinct_count >= 3 or Esql.file_hash_distinct_count >= 2)
| keep agent.id,
       Esql.alerts_count,
       Esql.event_code_distinct_count,
       Esql.rule_name_distinct_count,
       Esql.message_values,
       Esql.event_code_values,
       Esql.rule_name_values,
       Esql.process_executable_values,
       Esql.process_parent_executable_values,
       Esql.process_command_line_values,
       Esql.file_path_values,
       Esql.dll_path_values,
       Esql.process_hash_sha256_values,
       Esql.file_hash_sha256_values,
       Esql.dll_hash_sha256_values
Showing 151-200 of 4,399