Nodes
| Operation | Description | Sample | Rule |
|---|---|---|---|
| get-nodes | Reads a single Node object: a worker's capacity, labels, taints, and addresses. Elastic's new-terms rule flags a not-previously-seen identity reading node inventory. | Y | Y |
| list-nodes | Lists all Nodes, mapping the cluster's infrastructure (IPs, capacity, labels) in one call, a classic reconnaissance step before targeting a specific node. | Y | Y |
| watch-nodes | Opens a long-lived watch on Node changes cluster-wide. Elastic's new-terms user-agent rule flags a not-previously-seen identity doing this. | Y | Y |
| create-nodes | N | Y | |
| update-nodes | Y | Y | |
| patch-nodes | Modifies a Node's labels or taints, which can affect pod scheduling (e.g. clearing a taint to land a pod on a hardened node) or spoof node metadata. | Y | Y |
| delete-nodes | N | N | |
| deletecollection-nodes | N | N | |
| get-nodes-proxy | Proxy request to node API endpoint (privilege escalation: node-proxy allows kubelet API access). | N | Y |
| create-nodes-proxy | N | Y | |
| update-nodes-proxy | N | Y | |
| patch-nodes-proxy | N | Y | |
| delete-nodes-proxy | N | Y | |
| get-nodes-status | Y | N | |
| update-nodes-status | Y | N | |
| patch-nodes-status | Y | N | |
| any-nodes | Synthetic aggregation for rules that filter the nodes resource with no specific verb. Not a distinct audit record; hosts rule listings that key on objectRef.resource alone. | N | Y |
get nodes
#Description
Reads a single Node object: a worker's capacity, labels, taints, and addresses. Elastic's new-terms rule flags a not-previously-seen identity reading node inventory.
Example Audit Event #
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "Metadata",
"auditID": "00000000-0000-0000-0000-000000000000",
"stage": "ResponseComplete",
"requestURI": "/api/v1/nodes/node-control-plane",
"verb": "get",
"user": {
"username": "kubernetes-admin",
"groups": [
"kubeadm:cluster-admins",
"system:authenticated"
],
"extra": {
"authentication.kubernetes.io/credential-id": [
"X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
]
}
},
"sourceIPs": [
"203.0.113.10"
],
"userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
"objectRef": {
"resource": "nodes",
"name": "node-control-plane",
"apiVersion": "v1"
},
"responseStatus": {
"metadata": {},
"code": 200
},
"requestReceivedTimestamp": "2026-07-02T04:49:00.942261Z",
"stageTimestamp": "2026-07-02T04:49:00.944470Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
}
}
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries → Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs. This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload. The rule groups GKE audit get/list events on namespaces, nodes, pods, configmaps, serviceaccounts, roles, rolebindings, clusterroles, and clusterrolebindings into one-minute windows per Elastic #
T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches list-nodes: list nodes, watch-nodes: watch nodes, create-nodes: create nodes, update-nodes: update nodes, patch-nodes: patch nodes Investigation guide
Triage and analysis#
Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#
Possible investigation steps#
False positive analysis#
Response and remediation#
T1613↳ also matches list-nodes: list nodes Investigation guide
Triage and analysis#
Investigating GKE Multi-Resource Discovery#
client.user.email, source.ip, and user_agent.original. It alerts when five or more distinct resource kinds appear and the burst includes both cluster-layout kinds (namespaces, pods, or nodes) and RBAC kinds. Allowed and denied authorizations are both included: failures still signal probing.Possible investigation steps#
Esql.enumerated_resources, Esql.enumerated_namespaces, and Esql.enumerated_resource_names for ordering and targeted APIs.source.ip and user_agent.original match expected admin or automation clients.False positive analysis#
Response and remediation#
References #
list nodes
#Description
Lists all Nodes, mapping the cluster's infrastructure (IPs, capacity, labels) in one call, a classic reconnaissance step before targeting a specific node.
Example Audit Event #
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "Metadata",
"auditID": "00000000-0000-0000-0000-000000000000",
"stage": "ResponseComplete",
"requestURI": "/api/v1/nodes?limit=500",
"verb": "list",
"user": {
"username": "kubernetes-admin",
"groups": [
"kubeadm:cluster-admins",
"system:authenticated"
],
"extra": {
"authentication.kubernetes.io/credential-id": [
"X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
]
}
},
"sourceIPs": [
"203.0.113.10"
],
"userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
"objectRef": {
"resource": "nodes",
"apiVersion": "v1"
},
"responseStatus": {
"metadata": {},
"code": 200
},
"requestReceivedTimestamp": "2026-07-02T04:49:00.881187Z",
"stageTimestamp": "2026-07-02T04:49:00.883360Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
}
}
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries → Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs. This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload. The rule groups GKE audit get/list events on namespaces, nodes, pods, configmaps, serviceaccounts, roles, rolebindings, clusterroles, and clusterrolebindings into one-minute windows per Elastic #
T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-nodes: get nodes, watch-nodes: watch nodes, create-nodes: create nodes, update-nodes: update nodes, patch-nodes: patch nodes Investigation guide
Triage and analysis#
Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#
Possible investigation steps#
False positive analysis#
Response and remediation#
T1613↳ also matches get-nodes: get nodes Investigation guide
Triage and analysis#
Investigating GKE Multi-Resource Discovery#
client.user.email, source.ip, and user_agent.original. It alerts when five or more distinct resource kinds appear and the burst includes both cluster-layout kinds (namespaces, pods, or nodes) and RBAC kinds. Allowed and denied authorizations are both included: failures still signal probing.Possible investigation steps#
Esql.enumerated_resources, Esql.enumerated_namespaces, and Esql.enumerated_resource_names for ordering and targeted APIs.source.ip and user_agent.original match expected admin or automation clients.False positive analysis#
Response and remediation#
References #
watch nodes
#Description
Opens a long-lived watch on Node changes cluster-wide. Elastic's new-terms user-agent rule flags a not-previously-seen identity doing this.
Example Audit Event #
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "Metadata",
"auditID": "00000000-0000-0000-0000-000000000000",
"stage": "ResponseComplete",
"requestURI": "/api/v1/nodes?resourceVersion=1480&timeout=3s&watch=true",
"verb": "watch",
"user": {
"username": "kubernetes-admin",
"groups": [
"kubeadm:cluster-admins",
"system:authenticated"
],
"extra": {
"authentication.kubernetes.io/credential-id": [
"X509SHA256=97ca5ec05d5b7c1923d58d85f4449a4c26b2df61defa2a59b4045149ffed589e"
]
}
},
"sourceIPs": [
"203.0.113.10"
],
"userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
"objectRef": {
"resource": "nodes",
"apiVersion": "v1"
},
"responseStatus": {
"metadata": {},
"code": 200
},
"requestReceivedTimestamp": "2026-07-02T22:49:24.869155Z",
"stageTimestamp": "2026-07-02T22:49:27.883684Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
}
}
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries → Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs. This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.Elastic #
T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-nodes: get nodes, list-nodes: list nodes, create-nodes: create nodes, update-nodes: update nodes, patch-nodes: patch nodes Investigation guide
Triage and analysis#
Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#
Possible investigation steps#
False positive analysis#
Response and remediation#
References #
create nodes
#Common Indicators #
Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.
| Field | Kind | Value | Rules | Vendors |
|---|---|---|---|---|
jevt.rawtime (falco rule field) | is_null | | 2 rules | falco |
objectRef.resource (falco rule field) | eq | nodes | 2 rules | falco |
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries →Elastic #
T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-nodes: get nodes, list-nodes: list nodes, watch-nodes: watch nodes, update-nodes: update nodes, patch-nodes: patch nodes Falco #
update nodes
#Example Audit Event #
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "RequestResponse",
"auditID": "00000000-0000-0000-0000-000000000000",
"stage": "ResponseComplete",
"requestURI": "/api/v1/nodes/node-control-plane?fieldManager=kubectl-replace&fieldValidation=Strict",
"verb": "update",
"user": {
"username": "kubernetes-admin",
"groups": [
"kubeadm:cluster-admins",
"system:authenticated"
],
"extra": {
"authentication.kubernetes.io/credential-id": [
"X509SHA256=97ca5ec05d5b7c1923d58d85f4449a4c26b2df61defa2a59b4045149ffed589e"
]
}
},
"sourceIPs": [
"203.0.113.10"
],
"userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
"objectRef": {
"resource": "nodes",
"name": "node-control-plane",
"uid": "00000000-0000-0000-0000-000000000000",
"apiVersion": "v1",
"resourceVersion": "1488"
},
"responseStatus": {
"metadata": {},
"code": 200
},
"requestObject": {
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "node-control-plane",
"uid": "00000000-0000-0000-0000-000000000000",
"resourceVersion": "1488",
"creationTimestamp": "2026-07-02T22:44:51Z",
"labels": {
"beta.kubernetes.io/arch": "amd64",
"beta.kubernetes.io/os": "linux",
"kubernetes.io/arch": "amd64",
"kubernetes.io/hostname": "node-control-plane",
"kubernetes.io/os": "linux",
"node-role.kubernetes.io/control-plane": ""
},
"annotations": {
"node.alpha.kubernetes.io/ttl": "0",
"volumes.kubernetes.io/controller-managed-attach-detach": "true"
}
},
"spec": {
"podCIDR": "10.244.0.0/24",
"podCIDRs": [
"10.244.0.0/24"
],
"providerID": "kind://docker/dw-k8s-harness/node-control-plane"
},
"status": {
"capacity": {
"cpu": "18",
"ephemeral-storage": "514938800Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "128807008Ki",
"pods": "110"
},
"allocatable": {
"cpu": "18",
"ephemeral-storage": "514938800Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "128807008Ki",
"pods": "110"
},
"conditions": [
{
"type": "MemoryPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:44:50Z",
"reason": "KubeletHasSufficientMemory",
"message": "kubelet has sufficient memory available"
},
{
"type": "DiskPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:44:50Z",
"reason": "KubeletHasNoDiskPressure",
"message": "kubelet has no disk pressure"
},
{
"type": "PIDPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:44:50Z",
"reason": "KubeletHasSufficientPID",
"message": "kubelet has sufficient PID available"
},
{
"type": "Ready",
"status": "True",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:45:13Z",
"reason": "KubeletReady",
"message": "kubelet is posting ready status"
}
],
"addresses": [
{
"type": "InternalIP",
"address": "172.19.0.2"
},
{
"type": "Hostname",
"address": "node-control-plane"
}
],
"daemonEndpoints": {
"kubeletEndpoint": {
"Port": 10250
}
},
"nodeInfo": {
"machineID": "815df19d528a443e902d7ee3648f1bf5",
"systemUUID": "00000000-0000-0000-0000-000000000000",
"bootID": "00000000-0000-0000-0000-000000000000",
"kernelVersion": "6.1.0-41-amd64",
"osImage": "Debian GNU/Linux 13 (trixie)",
"containerRuntimeVersion": "containerd://2.3.1",
"kubeletVersion": "v1.36.1",
"kubeProxyVersion": "",
"operatingSystem": "linux",
"architecture": "amd64"
},
"images": [
{
"names": [
"docker.io/library/import-2026-06-02@sha256:48e12aa71c24cf624334ae6f0373f1e1b85825254085475eda149111a926e33c",
"registry.k8s.io/kube-apiserver-amd64:v1.36.1",
"registry.k8s.io/kube-apiserver:v1.36.1"
],
"sizeBytes": 96683252
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:3fb749e08554fac4cde5dc53397de761b92939d34ead7e3c89248a8bf5b621e4",
"registry.k8s.io/kube-controller-manager-amd64:v1.36.1",
"registry.k8s.io/kube-controller-manager:v1.36.1"
],
"sizeBytes": 85870692
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:834d6b8414308aed626e67979c4665f21b3651e5d8d04ae68d960a4f844b4e81",
"registry.k8s.io/kube-proxy-amd64:v1.36.1",
"registry.k8s.io/kube-proxy:v1.36.1"
],
"sizeBytes": 79126247
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:77add4a58677c7fa1a02b42381a024adc860f8d6bbdf38a89d7f8803c116e43c",
"registry.k8s.io/kube-scheduler-amd64:v1.36.1",
"registry.k8s.io/kube-scheduler:v1.36.1"
],
"sizeBytes": 60683997
},
{
"names": [
"docker.io/kindest/kindnetd:v20260528-9350166c"
],
"sizeBytes": 39749049
},
{
"names": [
"registry.k8s.io/coredns/coredns:v1.14.2"
],
"sizeBytes": 23257541
},
{
"names": [
"registry.k8s.io/etcd:3.6.8-0"
],
"sizeBytes": 22885795
},
{
"names": [
"docker.io/kindest/local-path-provisioner:v20260521-9fb22683"
],
"sizeBytes": 15864063
},
{
"names": [
"docker.io/kindest/local-path-helper:v20260131-7181c60a"
],
"sizeBytes": 2872608
},
{
"names": [
"docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
"docker.io/library/busybox:1.36"
],
"sizeBytes": 2217006
},
{
"names": [
"registry.k8s.io/pause:3.10"
],
"sizeBytes": 320368
}
],
"runtimeHandlers": [
{
"name": "",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
},
{
"name": "runc",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
},
{
"name": "test-handler",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
}
],
"features": {
"supplementalGroupsPolicy": true
},
"declaredFeatures": [
"ExtendWebSocketsToKubelet",
"InPlacePodLevelResourcesVerticalScaling",
"InPlacePodVerticalScalingInitContainers",
"RestartAllContainersOnContainerExits"
]
}
},
"responseObject": {
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "node-control-plane",
"uid": "00000000-0000-0000-0000-000000000000",
"resourceVersion": "1488",
"creationTimestamp": "2026-07-02T22:44:51Z",
"labels": {
"beta.kubernetes.io/arch": "amd64",
"beta.kubernetes.io/os": "linux",
"kubernetes.io/arch": "amd64",
"kubernetes.io/hostname": "node-control-plane",
"kubernetes.io/os": "linux",
"node-role.kubernetes.io/control-plane": ""
},
"annotations": {
"node.alpha.kubernetes.io/ttl": "0",
"volumes.kubernetes.io/controller-managed-attach-detach": "true"
}
},
"spec": {
"podCIDR": "10.244.0.0/24",
"podCIDRs": [
"10.244.0.0/24"
],
"providerID": "kind://docker/dw-k8s-harness/node-control-plane"
},
"status": {
"capacity": {
"cpu": "18",
"ephemeral-storage": "514938800Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "128807008Ki",
"pods": "110"
},
"allocatable": {
"cpu": "18",
"ephemeral-storage": "514938800Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "128807008Ki",
"pods": "110"
},
"conditions": [
{
"type": "MemoryPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:44:50Z",
"reason": "KubeletHasSufficientMemory",
"message": "kubelet has sufficient memory available"
},
{
"type": "DiskPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:44:50Z",
"reason": "KubeletHasNoDiskPressure",
"message": "kubelet has no disk pressure"
},
{
"type": "PIDPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:44:50Z",
"reason": "KubeletHasSufficientPID",
"message": "kubelet has sufficient PID available"
},
{
"type": "Ready",
"status": "True",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:45:13Z",
"reason": "KubeletReady",
"message": "kubelet is posting ready status"
}
],
"addresses": [
{
"type": "InternalIP",
"address": "172.19.0.2"
},
{
"type": "Hostname",
"address": "node-control-plane"
}
],
"daemonEndpoints": {
"kubeletEndpoint": {
"Port": 10250
}
},
"nodeInfo": {
"machineID": "815df19d528a443e902d7ee3648f1bf5",
"systemUUID": "00000000-0000-0000-0000-000000000000",
"bootID": "00000000-0000-0000-0000-000000000000",
"kernelVersion": "6.1.0-41-amd64",
"osImage": "Debian GNU/Linux 13 (trixie)",
"containerRuntimeVersion": "containerd://2.3.1",
"kubeletVersion": "v1.36.1",
"kubeProxyVersion": "",
"operatingSystem": "linux",
"architecture": "amd64"
},
"images": [
{
"names": [
"docker.io/library/import-2026-06-02@sha256:48e12aa71c24cf624334ae6f0373f1e1b85825254085475eda149111a926e33c",
"registry.k8s.io/kube-apiserver-amd64:v1.36.1",
"registry.k8s.io/kube-apiserver:v1.36.1"
],
"sizeBytes": 96683252
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:3fb749e08554fac4cde5dc53397de761b92939d34ead7e3c89248a8bf5b621e4",
"registry.k8s.io/kube-controller-manager-amd64:v1.36.1",
"registry.k8s.io/kube-controller-manager:v1.36.1"
],
"sizeBytes": 85870692
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:834d6b8414308aed626e67979c4665f21b3651e5d8d04ae68d960a4f844b4e81",
"registry.k8s.io/kube-proxy-amd64:v1.36.1",
"registry.k8s.io/kube-proxy:v1.36.1"
],
"sizeBytes": 79126247
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:77add4a58677c7fa1a02b42381a024adc860f8d6bbdf38a89d7f8803c116e43c",
"registry.k8s.io/kube-scheduler-amd64:v1.36.1",
"registry.k8s.io/kube-scheduler:v1.36.1"
],
"sizeBytes": 60683997
},
{
"names": [
"docker.io/kindest/kindnetd:v20260528-9350166c"
],
"sizeBytes": 39749049
},
{
"names": [
"registry.k8s.io/coredns/coredns:v1.14.2"
],
"sizeBytes": 23257541
},
{
"names": [
"registry.k8s.io/etcd:3.6.8-0"
],
"sizeBytes": 22885795
},
{
"names": [
"docker.io/kindest/local-path-provisioner:v20260521-9fb22683"
],
"sizeBytes": 15864063
},
{
"names": [
"docker.io/kindest/local-path-helper:v20260131-7181c60a"
],
"sizeBytes": 2872608
},
{
"names": [
"docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
"docker.io/library/busybox:1.36"
],
"sizeBytes": 2217006
},
{
"names": [
"registry.k8s.io/pause:3.10"
],
"sizeBytes": 320368
}
],
"runtimeHandlers": [
{
"name": "",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
},
{
"name": "runc",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
},
{
"name": "test-handler",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
}
],
"features": {
"supplementalGroupsPolicy": true
},
"declaredFeatures": [
"ExtendWebSocketsToKubelet",
"InPlacePodLevelResourcesVerticalScaling",
"InPlacePodVerticalScalingInitContainers",
"RestartAllContainersOnContainerExits"
]
}
},
"requestReceivedTimestamp": "2026-07-02T22:49:28.246601Z",
"stageTimestamp": "2026-07-02T22:49:28.251154Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
}
}
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries → Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs. This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.Elastic #
T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-nodes: get nodes, list-nodes: list nodes, watch-nodes: watch nodes, create-nodes: create nodes, patch-nodes: patch nodes Investigation guide
Triage and analysis#
Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#
Possible investigation steps#
False positive analysis#
Response and remediation#
References #
patch nodes
#Description
Modifies a Node's labels or taints, which can affect pod scheduling (e.g. clearing a taint to land a pod on a hardened node) or spoof node metadata.
Example Audit Event #
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "RequestResponse",
"auditID": "00000000-0000-0000-0000-000000000000",
"stage": "ResponseComplete",
"requestURI": "/api/v1/nodes/node-control-plane?fieldManager=kubectl-patch",
"verb": "patch",
"user": {
"username": "kubernetes-admin",
"groups": [
"kubeadm:cluster-admins",
"system:authenticated"
],
"extra": {
"authentication.kubernetes.io/credential-id": [
"X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
]
}
},
"sourceIPs": [
"203.0.113.10"
],
"userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
"objectRef": {
"resource": "nodes",
"name": "node-control-plane",
"apiVersion": "v1"
},
"responseStatus": {
"metadata": {},
"code": 200
},
"requestObject": {
"metadata": {
"labels": {
"dw-harn-probe": "1"
}
}
},
"responseObject": {
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "node-control-plane",
"uid": "00000000-0000-0000-0000-000000000000",
"resourceVersion": "1862",
"creationTimestamp": "2026-07-02T04:36:42Z",
"labels": {
"beta.kubernetes.io/arch": "amd64",
"beta.kubernetes.io/os": "linux",
"dw-harn-probe": "1",
"kubernetes.io/arch": "amd64",
"kubernetes.io/hostname": "node-control-plane",
"kubernetes.io/os": "linux",
"node-role.kubernetes.io/control-plane": ""
},
"annotations": {
"node.alpha.kubernetes.io/ttl": "0",
"volumes.kubernetes.io/controller-managed-attach-detach": "true"
}
},
"spec": {
"podCIDR": "10.244.0.0/24",
"podCIDRs": [
"10.244.0.0/24"
],
"providerID": "kind://docker/dw-k8s-harness/node-control-plane"
},
"status": {
"capacity": {
"cpu": "10",
"ephemeral-storage": "514938800Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "82361532Ki",
"pods": "110"
},
"allocatable": {
"cpu": "10",
"ephemeral-storage": "514938800Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "82361532Ki",
"pods": "110"
},
"conditions": [
{
"type": "MemoryPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T04:45:24Z",
"lastTransitionTime": "2026-07-02T04:36:41Z",
"reason": "KubeletHasSufficientMemory",
"message": "kubelet has sufficient memory available"
},
{
"type": "DiskPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T04:45:24Z",
"lastTransitionTime": "2026-07-02T04:36:41Z",
"reason": "KubeletHasNoDiskPressure",
"message": "kubelet has no disk pressure"
},
{
"type": "PIDPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T04:45:24Z",
"lastTransitionTime": "2026-07-02T04:36:41Z",
"reason": "KubeletHasSufficientPID",
"message": "kubelet has sufficient PID available"
},
{
"type": "Ready",
"status": "True",
"lastHeartbeatTime": "2026-07-02T04:45:24Z",
"lastTransitionTime": "2026-07-02T04:37:03Z",
"reason": "KubeletReady",
"message": "kubelet is posting ready status"
}
],
"addresses": [
{
"type": "InternalIP",
"address": "172.19.0.2"
},
{
"type": "Hostname",
"address": "node-control-plane"
}
],
"daemonEndpoints": {
"kubeletEndpoint": {
"Port": 10250
}
},
"nodeInfo": {
"machineID": "644a23c05a804d8abdd101de8fc3821c",
"systemUUID": "00000000-0000-0000-0000-000000000000",
"bootID": "00000000-0000-0000-0000-000000000000",
"kernelVersion": "6.1.0-41-amd64",
"osImage": "Debian GNU/Linux 13 (trixie)",
"containerRuntimeVersion": "containerd://2.3.1",
"kubeletVersion": "v1.36.1",
"kubeProxyVersion": "",
"operatingSystem": "linux",
"architecture": "amd64"
},
"images": [
{
"names": [
"docker.io/library/import-2026-06-02@sha256:48e12aa71c24cf624334ae6f0373f1e1b85825254085475eda149111a926e33c",
"registry.k8s.io/kube-apiserver-amd64:v1.36.1",
"registry.k8s.io/kube-apiserver:v1.36.1"
],
"sizeBytes": 96682870
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:3fb749e08554fac4cde5dc53397de761b92939d34ead7e3c89248a8bf5b621e4",
"registry.k8s.io/kube-controller-manager-amd64:v1.36.1",
"registry.k8s.io/kube-controller-manager:v1.36.1"
],
"sizeBytes": 85870301
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:834d6b8414308aed626e67979c4665f21b3651e5d8d04ae68d960a4f844b4e81",
"registry.k8s.io/kube-proxy-amd64:v1.36.1",
"registry.k8s.io/kube-proxy:v1.36.1"
],
"sizeBytes": 79126247
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:77add4a58677c7fa1a02b42381a024adc860f8d6bbdf38a89d7f8803c116e43c",
"registry.k8s.io/kube-scheduler-amd64:v1.36.1",
"registry.k8s.io/kube-scheduler:v1.36.1"
],
"sizeBytes": 60683997
},
{
"names": [
"docker.io/kindest/kindnetd:v20260528-9350166c"
],
"sizeBytes": 39749049
},
{
"names": [
"registry.k8s.io/coredns/coredns:v1.14.2"
],
"sizeBytes": 23257541
},
{
"names": [
"registry.k8s.io/etcd:3.6.8-0"
],
"sizeBytes": 22885795
},
{
"names": [
"docker.io/kindest/local-path-provisioner:v20260521-9fb22683"
],
"sizeBytes": 15864063
},
{
"names": [
"docker.io/kindest/local-path-helper:v20260131-7181c60a"
],
"sizeBytes": 2872608
},
{
"names": [
"docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
"docker.io/library/busybox:1.36"
],
"sizeBytes": 2217006
},
{
"names": [
"registry.k8s.io/pause:3.10"
],
"sizeBytes": 320368
}
],
"runtimeHandlers": [
{
"name": "",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
},
{
"name": "runc",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
},
{
"name": "test-handler",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
}
],
"features": {
"supplementalGroupsPolicy": true
},
"declaredFeatures": [
"ExtendWebSocketsToKubelet",
"InPlacePodLevelResourcesVerticalScaling",
"InPlacePodVerticalScalingInitContainers",
"RestartAllContainersOnContainerExits"
]
}
},
"requestReceivedTimestamp": "2026-07-02T04:49:01.007690Z",
"stageTimestamp": "2026-07-02T04:49:01.014428Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
}
}
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries → Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs. This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.Elastic #
T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-nodes: get nodes, list-nodes: list nodes, watch-nodes: watch nodes, create-nodes: create nodes, update-nodes: update nodes Investigation guide
Triage and analysis#
Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#
Possible investigation steps#
False positive analysis#
Response and remediation#
References #
delete nodes
#deletecollection nodes
#get nodes/proxy
#Description
Proxy request to node API endpoint (privilege escalation: node-proxy allows kubelet API access).
Common Indicators #
Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.
| Field | Kind | Value | Rules | Vendors |
|---|---|---|---|---|
EventType (elastic rule field) | eq | microsoft.containerservice/managedclusters/diagnosticlogs/read | 2 rules | elastic |
azure.platformlogs.category (elastic rule field) | eq | kube-audit | 2 rules | elastic |
azure.platformlogs.properties.log.objectRef.resource (elastic rule field) | eq | nodes | 2 rules | elastic |
azure.platformlogs.properties.log.objectRef.subresource (elastic rule field) | eq | proxy | 2 rules | elastic |
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries →Elastic #
T1210, T1609↳ also matches create-nodes-proxy: create nodes/proxy, update-nodes-proxy: update nodes/proxy, patch-nodes-proxy: patch nodes/proxy, delete-nodes-proxy: delete nodes/proxy T1210, T1609↳ also matches create-nodes-proxy: create nodes/proxy, update-nodes-proxy: update nodes/proxy, patch-nodes-proxy: patch nodes/proxy, delete-nodes-proxy: delete nodes/proxy T1550, T1550.001, T1611, T1613↳ also matches create-nodes-proxy: create nodes/proxy
create nodes/proxy
#Common Indicators #
Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.
| Field | Kind | Value | Rules | Vendors |
|---|---|---|---|---|
EventType (elastic rule field) | eq | microsoft.containerservice/managedclusters/diagnosticlogs/read | 2 rules | elastic |
azure.platformlogs.category (elastic rule field) | eq | kube-audit | 2 rules | elastic |
azure.platformlogs.properties.log.objectRef.resource (elastic rule field) | eq | nodes | 2 rules | elastic |
azure.platformlogs.properties.log.objectRef.subresource (elastic rule field) | eq | proxy | 2 rules | elastic |
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries →Elastic #
T1210, T1609↳ also matches get-nodes-proxy: get nodes/proxy, update-nodes-proxy: update nodes/proxy, patch-nodes-proxy: patch nodes/proxy, delete-nodes-proxy: delete nodes/proxy T1210, T1609↳ also matches get-nodes-proxy: get nodes/proxy, update-nodes-proxy: update nodes/proxy, patch-nodes-proxy: patch nodes/proxy, delete-nodes-proxy: delete nodes/proxy T1550, T1550.001, T1611, T1613↳ also matches get-nodes-proxy: get nodes/proxy
update nodes/proxy
#Common Indicators #
Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.
| Field | Kind | Value | Rules | Vendors |
|---|---|---|---|---|
EventType (elastic rule field) | eq | microsoft.containerservice/managedclusters/diagnosticlogs/read | 2 rules | elastic |
azure.platformlogs.category (elastic rule field) | eq | kube-audit | 2 rules | elastic |
azure.platformlogs.properties.log.objectRef.resource (elastic rule field) | eq | nodes | 2 rules | elastic |
azure.platformlogs.properties.log.objectRef.subresource (elastic rule field) | eq | proxy | 2 rules | elastic |
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries →Elastic #
T1210, T1609↳ also matches get-nodes-proxy: get nodes/proxy, create-nodes-proxy: create nodes/proxy, patch-nodes-proxy: patch nodes/proxy, delete-nodes-proxy: delete nodes/proxy T1210, T1609↳ also matches get-nodes-proxy: get nodes/proxy, create-nodes-proxy: create nodes/proxy, patch-nodes-proxy: patch nodes/proxy, delete-nodes-proxy: delete nodes/proxy T1550, T1550.001, T1611, T1613↳ also matches get-nodes-proxy: get nodes/proxy, create-nodes-proxy: create nodes/proxy, patch-nodes-proxy: patch nodes/proxy, delete-nodes-proxy: delete nodes/proxy
patch nodes/proxy
#Common Indicators #
Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.
| Field | Kind | Value | Rules | Vendors |
|---|---|---|---|---|
EventType (elastic rule field) | eq | microsoft.containerservice/managedclusters/diagnosticlogs/read | 2 rules | elastic |
azure.platformlogs.category (elastic rule field) | eq | kube-audit | 2 rules | elastic |
azure.platformlogs.properties.log.objectRef.resource (elastic rule field) | eq | nodes | 2 rules | elastic |
azure.platformlogs.properties.log.objectRef.subresource (elastic rule field) | eq | proxy | 2 rules | elastic |
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries →Elastic #
T1210, T1609↳ also matches get-nodes-proxy: get nodes/proxy, create-nodes-proxy: create nodes/proxy, update-nodes-proxy: update nodes/proxy, delete-nodes-proxy: delete nodes/proxy T1210, T1609↳ also matches get-nodes-proxy: get nodes/proxy, create-nodes-proxy: create nodes/proxy, update-nodes-proxy: update nodes/proxy, delete-nodes-proxy: delete nodes/proxy T1550, T1550.001, T1611, T1613↳ also matches get-nodes-proxy: get nodes/proxy, create-nodes-proxy: create nodes/proxy, update-nodes-proxy: update nodes/proxy, delete-nodes-proxy: delete nodes/proxy
delete nodes/proxy
#Common Indicators #
Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.
| Field | Kind | Value | Rules | Vendors |
|---|---|---|---|---|
EventType (elastic rule field) | eq | microsoft.containerservice/managedclusters/diagnosticlogs/read | 2 rules | elastic |
azure.platformlogs.category (elastic rule field) | eq | kube-audit | 2 rules | elastic |
azure.platformlogs.properties.log.objectRef.resource (elastic rule field) | eq | nodes | 2 rules | elastic |
azure.platformlogs.properties.log.objectRef.subresource (elastic rule field) | eq | proxy | 2 rules | elastic |
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries →Elastic #
T1210, T1609↳ also matches get-nodes-proxy: get nodes/proxy, create-nodes-proxy: create nodes/proxy, update-nodes-proxy: update nodes/proxy, patch-nodes-proxy: patch nodes/proxy T1210, T1609↳ also matches get-nodes-proxy: get nodes/proxy, create-nodes-proxy: create nodes/proxy, update-nodes-proxy: update nodes/proxy, patch-nodes-proxy: patch nodes/proxy T1550, T1550.001, T1611, T1613↳ also matches get-nodes-proxy: get nodes/proxy, create-nodes-proxy: create nodes/proxy, update-nodes-proxy: update nodes/proxy, patch-nodes-proxy: patch nodes/proxy
get nodes/status
#Example Audit Event #
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "Metadata",
"auditID": "00000000-0000-0000-0000-000000000000",
"stage": "ResponseComplete",
"requestURI": "/api/v1/nodes/node-control-plane/status",
"verb": "get",
"user": {
"username": "kubernetes-admin",
"groups": [
"kubeadm:cluster-admins",
"system:authenticated"
],
"extra": {
"authentication.kubernetes.io/credential-id": [
"X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
]
}
},
"sourceIPs": [
"203.0.113.10"
],
"userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
"objectRef": {
"resource": "nodes",
"name": "node-control-plane",
"apiVersion": "v1",
"subresource": "status"
},
"responseStatus": {
"metadata": {},
"code": 200
},
"requestReceivedTimestamp": "2026-07-02T04:49:01.144634Z",
"stageTimestamp": "2026-07-02T04:49:01.146884Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
}
}
References #
update nodes/status
#Example Audit Event #
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "RequestResponse",
"auditID": "00000000-0000-0000-0000-000000000000",
"stage": "ResponseComplete",
"requestURI": "/api/v1/nodes/node-control-plane/status?fieldManager=kubectl-replace&fieldValidation=Strict",
"verb": "update",
"user": {
"username": "kubernetes-admin",
"groups": [
"kubeadm:cluster-admins",
"system:authenticated"
],
"extra": {
"authentication.kubernetes.io/credential-id": [
"X509SHA256=97ca5ec05d5b7c1923d58d85f4449a4c26b2df61defa2a59b4045149ffed589e"
]
}
},
"sourceIPs": [
"203.0.113.10"
],
"userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
"objectRef": {
"resource": "nodes",
"name": "node-control-plane",
"uid": "00000000-0000-0000-0000-000000000000",
"apiVersion": "v1",
"resourceVersion": "1488",
"subresource": "status"
},
"responseStatus": {
"metadata": {},
"code": 200
},
"requestObject": {
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "node-control-plane",
"uid": "00000000-0000-0000-0000-000000000000",
"resourceVersion": "1488",
"creationTimestamp": "2026-07-02T22:44:51Z",
"labels": {
"beta.kubernetes.io/arch": "amd64",
"beta.kubernetes.io/os": "linux",
"kubernetes.io/arch": "amd64",
"kubernetes.io/hostname": "node-control-plane",
"kubernetes.io/os": "linux",
"node-role.kubernetes.io/control-plane": ""
},
"annotations": {
"node.alpha.kubernetes.io/ttl": "0",
"volumes.kubernetes.io/controller-managed-attach-detach": "true"
}
},
"spec": {
"podCIDR": "10.244.0.0/24",
"podCIDRs": [
"10.244.0.0/24"
],
"providerID": "kind://docker/dw-k8s-harness/node-control-plane"
},
"status": {
"capacity": {
"cpu": "18",
"ephemeral-storage": "514938800Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "128807008Ki",
"pods": "110"
},
"allocatable": {
"cpu": "18",
"ephemeral-storage": "514938800Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "128807008Ki",
"pods": "110"
},
"conditions": [
{
"type": "MemoryPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:44:50Z",
"reason": "KubeletHasSufficientMemory",
"message": "kubelet has sufficient memory available"
},
{
"type": "DiskPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:44:50Z",
"reason": "KubeletHasNoDiskPressure",
"message": "kubelet has no disk pressure"
},
{
"type": "PIDPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:44:50Z",
"reason": "KubeletHasSufficientPID",
"message": "kubelet has sufficient PID available"
},
{
"type": "Ready",
"status": "True",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:45:13Z",
"reason": "KubeletReady",
"message": "kubelet is posting ready status"
}
],
"addresses": [
{
"type": "InternalIP",
"address": "172.19.0.2"
},
{
"type": "Hostname",
"address": "node-control-plane"
}
],
"daemonEndpoints": {
"kubeletEndpoint": {
"Port": 10250
}
},
"nodeInfo": {
"machineID": "815df19d528a443e902d7ee3648f1bf5",
"systemUUID": "00000000-0000-0000-0000-000000000000",
"bootID": "00000000-0000-0000-0000-000000000000",
"kernelVersion": "6.1.0-41-amd64",
"osImage": "Debian GNU/Linux 13 (trixie)",
"containerRuntimeVersion": "containerd://2.3.1",
"kubeletVersion": "v1.36.1",
"kubeProxyVersion": "",
"operatingSystem": "linux",
"architecture": "amd64"
},
"images": [
{
"names": [
"docker.io/library/import-2026-06-02@sha256:48e12aa71c24cf624334ae6f0373f1e1b85825254085475eda149111a926e33c",
"registry.k8s.io/kube-apiserver-amd64:v1.36.1",
"registry.k8s.io/kube-apiserver:v1.36.1"
],
"sizeBytes": 96683252
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:3fb749e08554fac4cde5dc53397de761b92939d34ead7e3c89248a8bf5b621e4",
"registry.k8s.io/kube-controller-manager-amd64:v1.36.1",
"registry.k8s.io/kube-controller-manager:v1.36.1"
],
"sizeBytes": 85870692
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:834d6b8414308aed626e67979c4665f21b3651e5d8d04ae68d960a4f844b4e81",
"registry.k8s.io/kube-proxy-amd64:v1.36.1",
"registry.k8s.io/kube-proxy:v1.36.1"
],
"sizeBytes": 79126247
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:77add4a58677c7fa1a02b42381a024adc860f8d6bbdf38a89d7f8803c116e43c",
"registry.k8s.io/kube-scheduler-amd64:v1.36.1",
"registry.k8s.io/kube-scheduler:v1.36.1"
],
"sizeBytes": 60683997
},
{
"names": [
"docker.io/kindest/kindnetd:v20260528-9350166c"
],
"sizeBytes": 39749049
},
{
"names": [
"registry.k8s.io/coredns/coredns:v1.14.2"
],
"sizeBytes": 23257541
},
{
"names": [
"registry.k8s.io/etcd:3.6.8-0"
],
"sizeBytes": 22885795
},
{
"names": [
"docker.io/kindest/local-path-provisioner:v20260521-9fb22683"
],
"sizeBytes": 15864063
},
{
"names": [
"docker.io/kindest/local-path-helper:v20260131-7181c60a"
],
"sizeBytes": 2872608
},
{
"names": [
"docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
"docker.io/library/busybox:1.36"
],
"sizeBytes": 2217006
},
{
"names": [
"registry.k8s.io/pause:3.10"
],
"sizeBytes": 320368
}
],
"runtimeHandlers": [
{
"name": "",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
},
{
"name": "runc",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
},
{
"name": "test-handler",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
}
],
"features": {
"supplementalGroupsPolicy": true
},
"declaredFeatures": [
"ExtendWebSocketsToKubelet",
"InPlacePodLevelResourcesVerticalScaling",
"InPlacePodVerticalScalingInitContainers",
"RestartAllContainersOnContainerExits"
]
}
},
"responseObject": {
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "node-control-plane",
"uid": "00000000-0000-0000-0000-000000000000",
"resourceVersion": "1488",
"creationTimestamp": "2026-07-02T22:44:51Z",
"labels": {
"beta.kubernetes.io/arch": "amd64",
"beta.kubernetes.io/os": "linux",
"kubernetes.io/arch": "amd64",
"kubernetes.io/hostname": "node-control-plane",
"kubernetes.io/os": "linux",
"node-role.kubernetes.io/control-plane": ""
},
"annotations": {
"node.alpha.kubernetes.io/ttl": "0",
"volumes.kubernetes.io/controller-managed-attach-detach": "true"
}
},
"spec": {
"podCIDR": "10.244.0.0/24",
"podCIDRs": [
"10.244.0.0/24"
],
"providerID": "kind://docker/dw-k8s-harness/node-control-plane"
},
"status": {
"capacity": {
"cpu": "18",
"ephemeral-storage": "514938800Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "128807008Ki",
"pods": "110"
},
"allocatable": {
"cpu": "18",
"ephemeral-storage": "514938800Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "128807008Ki",
"pods": "110"
},
"conditions": [
{
"type": "MemoryPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:44:50Z",
"reason": "KubeletHasSufficientMemory",
"message": "kubelet has sufficient memory available"
},
{
"type": "DiskPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:44:50Z",
"reason": "KubeletHasNoDiskPressure",
"message": "kubelet has no disk pressure"
},
{
"type": "PIDPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:44:50Z",
"reason": "KubeletHasSufficientPID",
"message": "kubelet has sufficient PID available"
},
{
"type": "Ready",
"status": "True",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:45:13Z",
"reason": "KubeletReady",
"message": "kubelet is posting ready status"
}
],
"addresses": [
{
"type": "InternalIP",
"address": "172.19.0.2"
},
{
"type": "Hostname",
"address": "node-control-plane"
}
],
"daemonEndpoints": {
"kubeletEndpoint": {
"Port": 10250
}
},
"nodeInfo": {
"machineID": "815df19d528a443e902d7ee3648f1bf5",
"systemUUID": "00000000-0000-0000-0000-000000000000",
"bootID": "00000000-0000-0000-0000-000000000000",
"kernelVersion": "6.1.0-41-amd64",
"osImage": "Debian GNU/Linux 13 (trixie)",
"containerRuntimeVersion": "containerd://2.3.1",
"kubeletVersion": "v1.36.1",
"kubeProxyVersion": "",
"operatingSystem": "linux",
"architecture": "amd64"
},
"images": [
{
"names": [
"docker.io/library/import-2026-06-02@sha256:48e12aa71c24cf624334ae6f0373f1e1b85825254085475eda149111a926e33c",
"registry.k8s.io/kube-apiserver-amd64:v1.36.1",
"registry.k8s.io/kube-apiserver:v1.36.1"
],
"sizeBytes": 96683252
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:3fb749e08554fac4cde5dc53397de761b92939d34ead7e3c89248a8bf5b621e4",
"registry.k8s.io/kube-controller-manager-amd64:v1.36.1",
"registry.k8s.io/kube-controller-manager:v1.36.1"
],
"sizeBytes": 85870692
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:834d6b8414308aed626e67979c4665f21b3651e5d8d04ae68d960a4f844b4e81",
"registry.k8s.io/kube-proxy-amd64:v1.36.1",
"registry.k8s.io/kube-proxy:v1.36.1"
],
"sizeBytes": 79126247
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:77add4a58677c7fa1a02b42381a024adc860f8d6bbdf38a89d7f8803c116e43c",
"registry.k8s.io/kube-scheduler-amd64:v1.36.1",
"registry.k8s.io/kube-scheduler:v1.36.1"
],
"sizeBytes": 60683997
},
{
"names": [
"docker.io/kindest/kindnetd:v20260528-9350166c"
],
"sizeBytes": 39749049
},
{
"names": [
"registry.k8s.io/coredns/coredns:v1.14.2"
],
"sizeBytes": 23257541
},
{
"names": [
"registry.k8s.io/etcd:3.6.8-0"
],
"sizeBytes": 22885795
},
{
"names": [
"docker.io/kindest/local-path-provisioner:v20260521-9fb22683"
],
"sizeBytes": 15864063
},
{
"names": [
"docker.io/kindest/local-path-helper:v20260131-7181c60a"
],
"sizeBytes": 2872608
},
{
"names": [
"docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
"docker.io/library/busybox:1.36"
],
"sizeBytes": 2217006
},
{
"names": [
"registry.k8s.io/pause:3.10"
],
"sizeBytes": 320368
}
],
"runtimeHandlers": [
{
"name": "",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
},
{
"name": "runc",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
},
{
"name": "test-handler",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
}
],
"features": {
"supplementalGroupsPolicy": true
},
"declaredFeatures": [
"ExtendWebSocketsToKubelet",
"InPlacePodLevelResourcesVerticalScaling",
"InPlacePodVerticalScalingInitContainers",
"RestartAllContainersOnContainerExits"
]
}
},
"requestReceivedTimestamp": "2026-07-02T22:49:28.523884Z",
"stageTimestamp": "2026-07-02T22:49:28.528919Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
}
}
References #
patch nodes/status
#Example Audit Event #
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "RequestResponse",
"auditID": "00000000-0000-0000-0000-000000000000",
"stage": "ResponseComplete",
"requestURI": "/api/v1/nodes/node-control-plane/status?fieldManager=kubectl-patch",
"verb": "patch",
"user": {
"username": "kubernetes-admin",
"groups": [
"kubeadm:cluster-admins",
"system:authenticated"
],
"extra": {
"authentication.kubernetes.io/credential-id": [
"X509SHA256=97ca5ec05d5b7c1923d58d85f4449a4c26b2df61defa2a59b4045149ffed589e"
]
}
},
"sourceIPs": [
"203.0.113.10"
],
"userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
"objectRef": {
"resource": "nodes",
"name": "node-control-plane",
"apiVersion": "v1",
"subresource": "status"
},
"responseStatus": {
"metadata": {},
"code": 200
},
"requestObject": {},
"responseObject": {
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "node-control-plane",
"uid": "00000000-0000-0000-0000-000000000000",
"resourceVersion": "1488",
"creationTimestamp": "2026-07-02T22:44:51Z",
"labels": {
"beta.kubernetes.io/arch": "amd64",
"beta.kubernetes.io/os": "linux",
"kubernetes.io/arch": "amd64",
"kubernetes.io/hostname": "node-control-plane",
"kubernetes.io/os": "linux",
"node-role.kubernetes.io/control-plane": ""
},
"annotations": {
"node.alpha.kubernetes.io/ttl": "0",
"volumes.kubernetes.io/controller-managed-attach-detach": "true"
}
},
"spec": {
"podCIDR": "10.244.0.0/24",
"podCIDRs": [
"10.244.0.0/24"
],
"providerID": "kind://docker/dw-k8s-harness/node-control-plane"
},
"status": {
"capacity": {
"cpu": "18",
"ephemeral-storage": "514938800Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "128807008Ki",
"pods": "110"
},
"allocatable": {
"cpu": "18",
"ephemeral-storage": "514938800Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "128807008Ki",
"pods": "110"
},
"conditions": [
{
"type": "MemoryPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:44:50Z",
"reason": "KubeletHasSufficientMemory",
"message": "kubelet has sufficient memory available"
},
{
"type": "DiskPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:44:50Z",
"reason": "KubeletHasNoDiskPressure",
"message": "kubelet has no disk pressure"
},
{
"type": "PIDPressure",
"status": "False",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:44:50Z",
"reason": "KubeletHasSufficientPID",
"message": "kubelet has sufficient PID available"
},
{
"type": "Ready",
"status": "True",
"lastHeartbeatTime": "2026-07-02T22:49:19Z",
"lastTransitionTime": "2026-07-02T22:45:13Z",
"reason": "KubeletReady",
"message": "kubelet is posting ready status"
}
],
"addresses": [
{
"type": "InternalIP",
"address": "172.19.0.2"
},
{
"type": "Hostname",
"address": "node-control-plane"
}
],
"daemonEndpoints": {
"kubeletEndpoint": {
"Port": 10250
}
},
"nodeInfo": {
"machineID": "815df19d528a443e902d7ee3648f1bf5",
"systemUUID": "00000000-0000-0000-0000-000000000000",
"bootID": "00000000-0000-0000-0000-000000000000",
"kernelVersion": "6.1.0-41-amd64",
"osImage": "Debian GNU/Linux 13 (trixie)",
"containerRuntimeVersion": "containerd://2.3.1",
"kubeletVersion": "v1.36.1",
"kubeProxyVersion": "",
"operatingSystem": "linux",
"architecture": "amd64"
},
"images": [
{
"names": [
"docker.io/library/import-2026-06-02@sha256:48e12aa71c24cf624334ae6f0373f1e1b85825254085475eda149111a926e33c",
"registry.k8s.io/kube-apiserver-amd64:v1.36.1",
"registry.k8s.io/kube-apiserver:v1.36.1"
],
"sizeBytes": 96683252
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:3fb749e08554fac4cde5dc53397de761b92939d34ead7e3c89248a8bf5b621e4",
"registry.k8s.io/kube-controller-manager-amd64:v1.36.1",
"registry.k8s.io/kube-controller-manager:v1.36.1"
],
"sizeBytes": 85870692
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:834d6b8414308aed626e67979c4665f21b3651e5d8d04ae68d960a4f844b4e81",
"registry.k8s.io/kube-proxy-amd64:v1.36.1",
"registry.k8s.io/kube-proxy:v1.36.1"
],
"sizeBytes": 79126247
},
{
"names": [
"docker.io/library/import-2026-06-02@sha256:77add4a58677c7fa1a02b42381a024adc860f8d6bbdf38a89d7f8803c116e43c",
"registry.k8s.io/kube-scheduler-amd64:v1.36.1",
"registry.k8s.io/kube-scheduler:v1.36.1"
],
"sizeBytes": 60683997
},
{
"names": [
"docker.io/kindest/kindnetd:v20260528-9350166c"
],
"sizeBytes": 39749049
},
{
"names": [
"registry.k8s.io/coredns/coredns:v1.14.2"
],
"sizeBytes": 23257541
},
{
"names": [
"registry.k8s.io/etcd:3.6.8-0"
],
"sizeBytes": 22885795
},
{
"names": [
"docker.io/kindest/local-path-provisioner:v20260521-9fb22683"
],
"sizeBytes": 15864063
},
{
"names": [
"docker.io/kindest/local-path-helper:v20260131-7181c60a"
],
"sizeBytes": 2872608
},
{
"names": [
"docker.io/library/busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662",
"docker.io/library/busybox:1.36"
],
"sizeBytes": 2217006
},
{
"names": [
"registry.k8s.io/pause:3.10"
],
"sizeBytes": 320368
}
],
"runtimeHandlers": [
{
"name": "",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
},
{
"name": "runc",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
},
{
"name": "test-handler",
"features": {
"recursiveReadOnlyMounts": true,
"userNamespaces": true
}
}
],
"features": {
"supplementalGroupsPolicy": true
},
"declaredFeatures": [
"ExtendWebSocketsToKubelet",
"InPlacePodLevelResourcesVerticalScaling",
"InPlacePodVerticalScalingInitContainers",
"RestartAllContainersOnContainerExits"
]
}
},
"requestReceivedTimestamp": "2026-07-02T22:49:28.602803Z",
"stageTimestamp": "2026-07-02T22:49:28.606679Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
}
}
References #
any verb on nodes (synthetic aggregation)
#Description
Synthetic aggregation for rules that filter the nodes resource with no specific verb. Not a distinct audit record; hosts rule listings that key on objectRef.resource alone.
Common Indicators #
Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.
| Field | Kind | Value | Rules | Vendors |
|---|---|---|---|---|
kubernetes.audit.objectRef.resource (elastic rule field) | in | nodes | 2 rules | elastic |
kubernetes.audit.objectRef.resource (elastic rule field) | in | pods | 2 rules | elastic |
EventType (elastic rule field) | in | get | 1 rule | elastic |
EventType (elastic rule field) | in | list | 1 rule | elastic |
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries →Elastic #
get/list traffic across distinct API resource kinds that answer those questions (namespaces, workloads, roles, cluster-wide roles) is a common setup and orientation pattern for both interactive attackers and automated recon scripts. It is less typical for steady-state controllers, which usually touch a narrow set of resources repeatedly. This rule highlights that cross-resource burst from a single client fingerprint within a one-minute bucket so analysts can separate routine automation from potential discovery and permission reconnaissance ahead of follow-on actions.T1613T1078