Kubernetes Pod Using Host PID Namespace


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.

Query · python

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))

Analyst notes

  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
Raw source Kubernetes Pod Using Host PID Namespace · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
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))

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.