[New] Suspicious Kubernetes Pod Exec (#5978)
* [New] 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 (avoid noisy local http services). * Create execution_kubernetes_pod_exec_potential_reverse_shell.toml * Update execution_kubernetes_pod_exec_curl_wget_https.toml * Update execution_kubernetes_pod_exec_potential_reverse_shell.toml * ++ * ++ * Apply suggestion from @terrancedejesus Co-authored-by: Terrance DeJesus <99630311+terrancedejesus@users.noreply.github.com> * Apply suggestion from @terrancedejesus Co-authored-by: Terrance DeJesus <99630311+terrancedejesus@users.noreply.github.com> * Apply suggestion from @terrancedejesus Co-authored-by: Terrance DeJesus <99630311+terrancedejesus@users.noreply.github.com> * Apply suggestion from @terrancedejesus Co-authored-by: Terrance DeJesus <99630311+terrancedejesus@users.noreply.github.com> * Apply suggestion from @terrancedejesus Co-authored-by: Terrance DeJesus <99630311+terrancedejesus@users.noreply.github.com> * Apply suggestion from @terrancedejesus Co-authored-by: Terrance DeJesus <99630311+terrancedejesus@users.noreply.github.com> * Update execution_kubernetes_pod_exec_curl_wget_https.toml * Update execution_kubernetes_pod_exec_potential_reverse_shell.toml * Update credential_access_kubernetes_pod_exec_cloud_instance_metadata.toml * Update credential_access_kubernetes_pod_exec_sensitive_file_access.toml * Update execution_kubernetes_pod_exec_curl_wget_https.toml * Update credential_access_kubernetes_pod_exec_sensitive_file_access.toml * Update credential_access_kubernetes_pod_exec_cloud_instance_metadata.toml --------- Co-authored-by: Terrance DeJesus <99630311+terrancedejesus@users.noreply.github.com>
This commit is contained in:
+125
@@ -0,0 +1,125 @@
|
||||
[metadata]
|
||||
creation_date = "2026/04/23"
|
||||
integration = ["kubernetes"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/04/23"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
description = """
|
||||
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.
|
||||
"""
|
||||
from = "now-6m"
|
||||
interval = "5m"
|
||||
language = "esql"
|
||||
license = "Elastic License v2"
|
||||
name = "Kubernetes Pod Exec Cloud Instance Metadata Access"
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Kubernetes Pod Exec Cloud Instance Metadata Access
|
||||
|
||||
This alert fires when an audited exec requestURI, after URL decoding and command reconstruction, matches patterns
|
||||
associated with instance metadata services across AWS, GCP, and Azure. Use it to catch interactive or scripted access
|
||||
from inside a pod to metadata surfaces that should usually be blocked by network policy or not needed by application
|
||||
code.
|
||||
|
||||
### Possible investigation steps
|
||||
|
||||
- Confirm the Kubernetes identity that performed exec: user name, groups, impersonation, source IP, and user agent.
|
||||
- Map the pod and namespace to a workload owner, image digest, and entrypoint; determine whether the container should
|
||||
ever call metadata endpoints.
|
||||
- Inspect Esql.cloud_target and Esql.is_credential_theft in the alert document and expand the timeline for the same
|
||||
identity for secret reads, IAM changes, or data egress.
|
||||
- Correlate with cloud audit logs on the node identity or instance profile for STS or token issuance around the event
|
||||
time.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Break-glass debugging from platform engineers may include curl to 169.254.169.254; validate change tickets and
|
||||
bastion use.
|
||||
- Misconfigured agents or bootstrap scripts in bespoke images can touch metadata during startup; baseline approved
|
||||
images and tune exclusions narrowly.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If unauthorized, terminate the session, isolate the workload, revoke or rotate instance and workload credentials that
|
||||
could have been read, and tighten RBAC on pods exec plus network policies that deny link-local metadata from pods.
|
||||
"""
|
||||
references = [
|
||||
"https://attack.mitre.org/techniques/T1552/005/",
|
||||
"https://hardenedsecurity.io/blog/aws-imds-vulnerabilities-and-mitigations/",
|
||||
]
|
||||
risk_score = 73
|
||||
rule_id = "a8e7d6c5-b4a3-2918-0f9e-8d7c6b5a4032"
|
||||
severity = "high"
|
||||
tags = [
|
||||
"Data Source: Kubernetes",
|
||||
"Domain: Kubernetes",
|
||||
"Domain: Cloud",
|
||||
"Use Case: Threat Detection",
|
||||
"Tactic: Credential Access",
|
||||
"Tactic: Execution",
|
||||
"Resources: Investigation Guide",
|
||||
]
|
||||
timestamp_override = "event.ingested"
|
||||
type = "esql"
|
||||
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 *
|
||||
'''
|
||||
|
||||
[[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.005"
|
||||
name = "Cloud Instance Metadata API"
|
||||
reference = "https://attack.mitre.org/techniques/T1552/005/"
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0006"
|
||||
name = "Credential Access"
|
||||
reference = "https://attack.mitre.org/tactics/TA0006/"
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
|
||||
[[rule.threat.technique]]
|
||||
id = "T1609"
|
||||
name = "Container Administration Command"
|
||||
reference = "https://attack.mitre.org/techniques/T1609/"
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0002"
|
||||
name = "Execution"
|
||||
reference = "https://attack.mitre.org/tactics/TA0002/"
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
[metadata]
|
||||
creation_date = "2026/04/23"
|
||||
integration = ["kubernetes"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/04/23"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
description = """
|
||||
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.
|
||||
"""
|
||||
from = "now-6m"
|
||||
interval = "5m"
|
||||
language = "esql"
|
||||
license = "Elastic License v2"
|
||||
name = "Kubernetes Pod Exec Sensitive File or Credential Path Access"
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Kubernetes Pod Exec Sensitive File or Credential Path Access
|
||||
|
||||
This alert ties Kubernetes audit exec events to reconstructed command text that matches sensitive path and filename
|
||||
patterns. Use the Esql.access_type field to prioritize: IRSA token paths, default Kubernetes service account tokens,
|
||||
other mounted secrets, certificates and keystores, Kubernetes static config, kubelet state, host passwd or shadow,
|
||||
user home credential stores, and proc environ scraping.
|
||||
|
||||
### Possible investigation steps
|
||||
|
||||
- Identify the Kubernetes user, groups, impersonation, source IP, and user agent for the exec caller.
|
||||
- Map objectRef namespace, pod, and container to an owning team, image digest, and change history.
|
||||
- Compare Esql.executed_command against known runbooks; capture follow-on audit activity such as additional execs,
|
||||
secret reads at the API layer, or RBAC changes.
|
||||
- If host-level paths appear, determine whether the workload runs privileged, with hostPath mounts, or on nodes where
|
||||
break-glass access is expected.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Diagnostic images and vendor agents sometimes cat resolv.conf or kubeconfig-like paths; the rule excludes resolv.conf
|
||||
but other matches may still be legitimate—baseline stable automation identities.
|
||||
- Training containers that deliberately demonstrate passwd reads can trigger; scope exceptions to those images and
|
||||
namespaces.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If malicious, end the exec session, isolate the pod or node, rotate any credentials that could have been read,
|
||||
review and tighten pods exec RBAC and admission controls, and inspect for persistence added after the session.
|
||||
"""
|
||||
references = [
|
||||
"https://attack.mitre.org/techniques/T1552/001/",
|
||||
"https://attack.mitre.org/techniques/T1552/007/",
|
||||
]
|
||||
risk_score = 73
|
||||
rule_id = "b2c3d4e5-f6a7-4890-b1c2-d3e4f5a60789"
|
||||
severity = "high"
|
||||
tags = [
|
||||
"Data Source: Kubernetes",
|
||||
"Domain: Kubernetes",
|
||||
"Use Case: Threat Detection",
|
||||
"Tactic: Credential Access",
|
||||
"Tactic: Execution",
|
||||
"Resources: Investigation Guide",
|
||||
]
|
||||
timestamp_override = "event.ingested"
|
||||
type = "esql"
|
||||
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 *
|
||||
'''
|
||||
|
||||
[[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.001"
|
||||
name = "Credentials In Files"
|
||||
reference = "https://attack.mitre.org/techniques/T1552/001/"
|
||||
|
||||
[[rule.threat.technique.subtechnique]]
|
||||
id = "T1552.007"
|
||||
name = "Container API"
|
||||
reference = "https://attack.mitre.org/techniques/T1552/007/"
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0006"
|
||||
name = "Credential Access"
|
||||
reference = "https://attack.mitre.org/tactics/TA0006/"
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
|
||||
[[rule.threat.technique]]
|
||||
id = "T1609"
|
||||
name = "Container Administration Command"
|
||||
reference = "https://attack.mitre.org/techniques/T1609/"
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0002"
|
||||
name = "Execution"
|
||||
reference = "https://attack.mitre.org/tactics/TA0002/"
|
||||
@@ -0,0 +1,109 @@
|
||||
[metadata]
|
||||
creation_date = "2026/04/23"
|
||||
integration = ["kubernetes"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/04/23"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
description = """
|
||||
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.
|
||||
"""
|
||||
from = "now-6m"
|
||||
interval = "5m"
|
||||
language = "esql"
|
||||
license = "Elastic License v2"
|
||||
name = "Kubernetes Pod Exec with Curl or Wget to HTTPS"
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Kubernetes Pod Exec with Curl or Wget to HTTPS
|
||||
|
||||
Kubernetes audit logs record exec (and similar attach) calls on requestURI, including URL-encoded
|
||||
command segments. This rule URL-decodes the URI, extracts the query portion into a single string, and
|
||||
flags curl or wget combined with https, excluding several ommon health, localhost, and OIDC/JWKS patterns.
|
||||
|
||||
### Possible investigation steps
|
||||
|
||||
- Confirm who may exec into the target namespace: review kubernetes.audit.user.username, groups, impersonation, and
|
||||
source.ip / user_agent.original (kubectl, CI, webhooks).
|
||||
- Map the pod (kubernetes.audit.objectRef.name) and workload owner; retrieve the exact decoded URI from
|
||||
Esql.decoded_uri and the reconstructed Esql.command in the alert.
|
||||
- Search for adjacent audit events from the same identity: secret reads, additional execs, RBAC changes, or anonymous
|
||||
access.
|
||||
- If malicious, revoke credentials used for exec, review RoleBindings for **`pods/exec`**, and inspect the pod
|
||||
filesystem or snapshot for dropped artifacts.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Approved runbooks or support sessions may use kubectl exec with curl/wget to test egress or download vendor tools;
|
||||
document break-glass identities and tune exclusions.
|
||||
- Some cluster components use HTTPS to **kubernetes.default.svc** or **.well-known** endpoints; the rule attempts to
|
||||
filter those—expand the exclusion list if your platform uses additional first-party URLs.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- Rotate any secrets accessible from the pod, cordon or delete the workload if compromised, and tighten RBAC so only
|
||||
required principals retain **`pods/exec`** on sensitive namespaces.
|
||||
"""
|
||||
references = [
|
||||
"https://attack.mitre.org/techniques/T1609/",
|
||||
"https://attack.mitre.org/techniques/T1105/",
|
||||
]
|
||||
risk_score = 73
|
||||
rule_id = "c9d4e8f1-2a3b-4c5d-8e9f-0a1b2c3d4e5f"
|
||||
severity = "high"
|
||||
tags = [
|
||||
"Data Source: Kubernetes",
|
||||
"Domain: Kubernetes",
|
||||
"Use Case: Threat Detection",
|
||||
"Tactic: Execution",
|
||||
"Tactic: Command and Control",
|
||||
"Resources: Investigation Guide",
|
||||
]
|
||||
timestamp_override = "event.ingested"
|
||||
type = "esql"
|
||||
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 *
|
||||
'''
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
|
||||
[[rule.threat.technique]]
|
||||
id = "T1609"
|
||||
name = "Container Administration Command"
|
||||
reference = "https://attack.mitre.org/techniques/T1609/"
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0002"
|
||||
name = "Execution"
|
||||
reference = "https://attack.mitre.org/tactics/TA0002/"
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
|
||||
[[rule.threat.technique]]
|
||||
id = "T1105"
|
||||
name = "Ingress Tool Transfer"
|
||||
reference = "https://attack.mitre.org/techniques/T1105/"
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0011"
|
||||
name = "Command and Control"
|
||||
reference = "https://attack.mitre.org/tactics/TA0011/"
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
[metadata]
|
||||
creation_date = "2026/04/23"
|
||||
integration = ["kubernetes"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/04/23"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
description = """
|
||||
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.
|
||||
"""
|
||||
from = "now-6m"
|
||||
interval = "5m"
|
||||
language = "esql"
|
||||
license = "Elastic License v2"
|
||||
name = "Kubernetes Pod Exec Potential Reverse Shell"
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Kubernetes Pod Exec Potential Reverse Shell
|
||||
|
||||
The rule inspects Kubernetes audit exec requestURI values, URL-decodes them, parses the command query fragment, and
|
||||
matches high-signal shell and socket idioms often used to obtain a allback shell from inside a container.
|
||||
|
||||
### Possible investigation steps
|
||||
|
||||
- Identify the actor (kubernetes.audit.user.username, groups, impersonation), source IP, and user agent
|
||||
(human kubectl vs automation).
|
||||
- Resolve the target namespace, pod, and container from kubernetes.audit.objectRef.* and correlate with
|
||||
workload ownership and change tickets.
|
||||
- Pull the raw and decoded URI from the alert document and replay the inferred command in a sandbox only if policy
|
||||
allows—otherwise rely on audit and platform logs.
|
||||
- Hunt nearby events from the same identity: secret reads, pods/exec to other workloads, RoleBinding
|
||||
changes, or anonymous API use.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Security training, CTF-style images, or vendor diagnostics may include bash redirection or /dev/tcp examples;
|
||||
baseline approved images and break-glass accounts.
|
||||
- Some observability or mesh sidecars use socat or sockets in ways that could overlap; validate container image and
|
||||
command lineage.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If malicious, terminate the exec session, isolate the workload or node, rotate credentials reachable from the
|
||||
pod, and revoke pods/exec for the abused principal unless strictly required.
|
||||
"""
|
||||
references = [
|
||||
"https://attack.mitre.org/techniques/T1609/",
|
||||
"https://attack.mitre.org/techniques/T1059/",
|
||||
]
|
||||
risk_score = 73
|
||||
rule_id = "f1a2b3c4-d5e6-4789-a012-3456789abc01"
|
||||
severity = "high"
|
||||
tags = [
|
||||
"Data Source: Kubernetes",
|
||||
"Domain: Kubernetes",
|
||||
"Use Case: Threat Detection",
|
||||
"Tactic: Execution",
|
||||
"Tactic: Command and Control",
|
||||
"Resources: Investigation Guide",
|
||||
]
|
||||
timestamp_override = "event.ingested"
|
||||
type = "esql"
|
||||
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 *
|
||||
'''
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
|
||||
[[rule.threat.technique]]
|
||||
id = "T1609"
|
||||
name = "Container Administration Command"
|
||||
reference = "https://attack.mitre.org/techniques/T1609/"
|
||||
|
||||
[[rule.threat.technique]]
|
||||
id = "T1059"
|
||||
name = "Command and Scripting Interpreter"
|
||||
reference = "https://attack.mitre.org/techniques/T1059/"
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0002"
|
||||
name = "Execution"
|
||||
reference = "https://attack.mitre.org/tactics/TA0002/"
|
||||
Reference in New Issue
Block a user