AnalysisType: rule
RuleID: "Kubernetes.Pod.Host.PID"
DisplayName: "Kubernetes Pod Using Host PID Namespace"
Enabled: true
Filename: k8s_pod_host_pid.py
LogTypes:
- Amazon.EKS.Audit
- Azure.MonitorActivity
- GCP.AuditLog
Tags:
- Kubernetes
- Security Control
- Escape to Host
- Deploy Container
- Unified Detection
Severity: Medium
Description:
This detection monitors for any pod creation or modification using the host PID namespace.
The Host PID namespace enables a pod and its containers to have direct access and share the
same view as the host's processes. This can offer a powerful escape hatch to the underlying host.
Runbook: |
1. Query API calls by the username in the 24 hours before and after the alert to understand the deployment context and related activity
2. Check if the pod namespace indicates system or infrastructure purpose (kube-system, kube-monitoring) versus user workloads
3. Search for other host PID pod creations by this user in the past 30 days to determine if this is an established pattern or new behavior
Reports:
MITRE ATT&CK:
- TA0004:T1611 # Escape to Host
- TA0002:T1610 # Deploy Container
Reference: >
- https://kubernetes.io/docs/concepts/security/pod-security-standards/#host-namespaces
- https://medium.com/@chrispisano/limiting-pod-privileges-hostpid-57ce07b05896
Tests:
- Name: EKS Pod With Host PID
ExpectedResult: true
Log:
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"verb": "create",
"user": {"username": "admin@example.com"},
"sourceIPs": ["1.2.3.4"],
"objectRef": {
"resource": "pods",
"namespace": "default",
"name": "nginx-test",
"apiVersion": "v1"
},
"responseStatus": {"code": 201},
"requestObject": {
"kind": "Pod",
"spec": {
"hostPID": true,
"containers": [{"name": "nginx", "image": "nginx"}]
}
},
"p_log_type": "Amazon.EKS.Audit",
"p_source_label": "eks-cluster"
}
- Name: AKS Pod With Host PID
ExpectedResult: true
Log:
{
"p_log_type": "Azure.MonitorActivity",
"category": "kube-audit",
"operationName": "Microsoft.ContainerService/managedClusters/diagnosticLogs/Read",
"properties": {
"log": "{\"kind\":\"Event\",\"apiVersion\":\"audit.k8s.io/v1\",\"verb\":\"create\",\"user\":{\"username\":\"admin@example.com\"},\"sourceIPs\":[\"10.0.0.1\"],\"objectRef\":{\"resource\":\"pods\",\"namespace\":\"default\",\"name\":\"nginx-test\"},\"responseStatus\":{\"code\":201},\"requestObject\":{\"kind\":\"Pod\",\"spec\":{\"hostPID\":true,\"containers\":[{\"name\":\"nginx\"}]}}}"
},
"p_source_label": "aks-cluster"
}
- Name: GCP GKE Pod With Host PID
ExpectedResult: true
Log:
{
"protoPayload": {
"authenticationInfo": {"principalEmail": "user@example.com"},
"authorizationInfo": [{
"granted": true,
"permission": "io.k8s.core.v1.pods.create",
"resource": "core/v1/namespaces/default/pods/nginx-test"
}],
"methodName": "io.k8s.core.v1.pods.create",
"request": {
"spec": {
"hostPID": true,
"containers": [{"name": "nginx"}]
}
},
"resourceName": "core/v1/namespaces/default/pods/nginx-test",
"serviceName": "k8s.io"
},
"resource": {
"type": "k8s_cluster",
"labels": {"project_id": "test-project"}
},
"p_log_type": "GCP.AuditLog",
"p_source_label": "gke-cluster"
}
- Name: Pod Without Host PID
ExpectedResult: false
Log:
{
"kind": "Event",
"verb": "create",
"objectRef": {"resource": "pods", "namespace": "default"},
"responseStatus": {"code": 201},
"requestObject": {
"spec": {
"hostPID": false,
"containers": [{"name": "nginx"}]
}
},
"p_log_type": "Amazon.EKS.Audit"
}
- Name: Pod Creation Failed
ExpectedResult: false
Log:
{
"kind": "Event",
"verb": "create",
"objectRef": {"resource": "pods", "namespace": "default"},
"responseStatus": {"code": 403},
"requestObject": {
"spec": {"hostPID": true}
},
"p_log_type": "Amazon.EKS.Audit"
}
# ------ paired body: k8s_pod_host_pid.py ------
from panther_kubernetes_helpers import (
get_pod_context_fields,
get_pod_name,
is_failed_request,
is_system_namespace,
is_system_principal,
k8s_alert_context,
)
def rule(event):
verb = event.udm("verb")
resource = event.udm("resource")
namespace = event.udm("namespace")
username = event.udm("username")
response_status = event.udm("responseStatus")
# Only check pod creation events
if verb != "create" or resource != "pods":
return False
# Skip failed requests
if is_failed_request(response_status):
return False
# Exclude system principals creating pods in system namespaces (legitimate)
# but alert on system principals in user namespaces (malicious Deployments)
# and alert on user-created pods in system namespaces (suspicious)
if is_system_principal(username) and is_system_namespace(namespace):
return False
# Check if hostPID is set to true in the request
host_pid = event.udm("hostPID")
if host_pid is True:
return True
return False
def title(event):
username = event.udm("username") or "<UNKNOWN_USER>"
namespace = event.udm("namespace") or "<UNKNOWN_NAMESPACE>"
name = get_pod_name(event)
return f"[{username}] created pod [{namespace}/{name}] using host PID namespace"
def alert_context(event):
return k8s_alert_context(event, extra_fields=get_pod_context_fields(event))