Deployable detection rules
1,678 vendor-native detections · ready to paste into your SIEM · cross-linked to ATT&CK
◈
Detections
50 shown of 1,678KRBTGT 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"
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"
)
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*"
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"
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")
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\:*)
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
)
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
)
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 *
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 *
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 *
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
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.*
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:*
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"
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
)
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\\*")
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
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
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)
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
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
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"
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))
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"))
)
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"
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"
*/
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")
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.*
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 1,678