diff --git a/rules/integrations/kubernetes/credential_access_kubernetes_multiple_secret_retrieval_burst.toml b/rules/integrations/kubernetes/credential_access_kubernetes_multiple_secret_retrieval_burst.toml new file mode 100644 index 000000000..4d557ed0b --- /dev/null +++ b/rules/integrations/kubernetes/credential_access_kubernetes_multiple_secret_retrieval_burst.toml @@ -0,0 +1,94 @@ +[metadata] +creation_date = "2026/04/22" +integration = ["kubernetes"] +maturity = "production" +updated_date = "2026/04/22" + +[rule] +author = ["Elastic"] +description = """ +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. +""" +from = "now-6m" +language = "esql" +license = "Elastic License v2" +name = "Kubernetes Rapid Secret GET Activity Against Multiple Objects" +note = """## Triage and analysis + +### Investigating Kubernetes Rapid Secret GET Activity Against Multiple Objects + +This rule surfaces clusters of `get` operations on the `secrets` API where the same identity and client path +(`user.name`, `source.ip`, `user_agent.original`) touch several different secret names within the rule lookback window. +**Allowed and denied** outcomes are included: successful reads may indicate harvesting; repeated **forbidden** or +**unauthorized** responses can still signal reconnaissance, RBAC probing, or scripted spray against secret names that +exist in the cluster. + +### Investigation steps + +- Inspect `Esql.outcome` for a mix of allow vs deny and whether failures cluster on sensitive namespaces. +- Map the identity to RBAC and namespace scope; review `Esql.secrets_names` and `Esql.namespaces` for high-value + targets (tokens, registry credentials, TLS bundles, application secrets). +- Pivot on the same `source.ip` and user for follow-on API activity (exec, pod create, role changes, broad `list` on secrets). +- Validate against expected automation (CI, GitOps, backup, in-cluster controllers) before treating as malicious. + +### False positives + +- Startup, Helm, or controllers may legitimately touch many secrets in one window; tune by user, namespace, or IP + allowlists when baselined. +""" +references = [ + "https://attack.mitre.org/techniques/T1552/007/", +] +risk_score = 73 +rule_id = "b4c8e2a1-9f3d-4e7c-a2b1-0d5e6f7a8b9c" +severity = "high" +tags = [ + "Data Source: Kubernetes", + "Domain: Kubernetes", + "Use Case: Threat Detection", + "Tactic: Credential Access", + "Resources: Investigation Guide", +] +timestamp_override = "event.ingested" +type = "esql" +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.*" +| 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, source.ip, user_agent.original +| where Esql.unique_credentials >= 3 +| KEEP user.name, source.ip, user_agent.original, Esql.* +''' + +[[rule.threat]] +framework = "MITRE ATT&CK" + +[[rule.threat.technique]] +id = "T1552" +name = "Unsecured Credentials" +reference = "https://attack.mitre.org/techniques/T1552/" + +[[rule.threat.technique.subtechnique]] +id = "T1552.007" +name = "Container API" +reference = "https://attack.mitre.org/techniques/T1552/007/" + +[rule.threat.tactic] +id = "TA0006" +name = "Credential Access" +reference = "https://attack.mitre.org/tactics/TA0006/" +