GCP K8S Privileged Pod Created


Description

Alerts when a user creates privileged pod. These particular pods have full access to the host’s namespace and devices, have the ability to exploit the kernel, have dangerous linux capabilities, and can be a powerful launching point for further attacks. In the event of a successful container escape where a user is operating with root privileges, the attacker retains this role on the node.

Query · python

from panther_base_helpers import deep_get
from panther_gcp_helpers import gcp_alert_context, is_gke_system_namespace, is_gke_system_principal


def rule(event):
    # Check basic conditions that would exclude this event
    if (
        event.deep_get("protoPayload", "response", "status") == "Failure"
        or event.deep_get("protoPayload", "methodName") != "io.k8s.core.v1.pods.create"
    ):
        return False

    # Check if this is a known service account or system namespace that should be excluded
    principal_email = event.deep_get(
        "protoPayload", "authenticationInfo", "principalEmail", default=""
    )
    resource_name = event.deep_get("protoPayload", "resourceName", default="")

    if is_gke_system_principal(principal_email) or is_gke_system_namespace(resource_name):
        return False

    # Check for privileged pod creation
    authorization_info = event.deep_walk("protoPayload", "authorizationInfo")
    if not authorization_info:
        return False

    containers_info = event.deep_walk("protoPayload", "response", "spec", "containers")
    for auth in authorization_info:
        if auth.get("permission") == "io.k8s.core.v1.pods.create" and auth.get("granted") is True:
            for security_context in containers_info:
                # Check for privileged pods and pods running as root
                # Reference:
                # https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted
                if (
                    deep_get(security_context, "securityContext", "privileged") is True
                    or deep_get(security_context, "securityContext", "runAsNonRoot") is False
                ):
                    return True

    return False


def title(event):
    actor = event.deep_get(
        "protoPayload", "authenticationInfo", "principalEmail", default="<ACTOR_NOT_FOUND>"
    )
    pod_name = event.deep_get("protoPayload", "resourceName", default="<RESOURCE_NOT_FOUND>")
    project_id = event.deep_get("resource", "labels", "project_id", default="<PROJECT_NOT_FOUND>")

    return f"[GCP]: [{actor}] created a privileged pod [{pod_name}] in project [{project_id}]"


def dedup(event):
    return event.deep_get(
        "protoPayload", "authenticationInfo", "principalEmail", default="<ACTOR_NOT_FOUND>"
    )


def alert_context(event):
    context = gcp_alert_context(event)
    containers_info = event.deep_walk("protoPayload", "response", "spec", "containers", default=[])
    context["pod_security_context"] = [i.get("securityContext") for i in containers_info]
    return context

Analyst notes

Investigate the reason of creating privileged pod. Advise that it is discouraged practice. Create ticket if appropriate.

Raw source GCP K8S Privileged Pod Created · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: rule
RuleID: "GCP.K8S.Privileged.Pod.Created"
DisplayName: "GCP K8S Privileged Pod Created"
Enabled: false
Status: Deprecated
LogTypes:
  - GCP.AuditLog
Severity: High
Tags:
  - Deprecated
Filename: gcp_k8s_privileged_pod_created.py
Description: >
  Alerts when a user creates privileged pod. These particular pods have full access to the host’s namespace and
  devices, have the ability to exploit the kernel, have dangerous linux capabilities, and can be a powerful launching
  point for further attacks. In the event of a successful container escape where a user is operating with root
  privileges, the attacker retains this role on the node.
Runbook: |
  Investigate the reason of creating privileged pod. Advise that it is discouraged practice.
  Create ticket if appropriate.
Reference: https://www.golinuxcloud.com/kubernetes-privileged-pod-examples/
Reports:
  MITRE ATT&CK:
    - TA0004:T1548 # Abuse Elevation Control Mechanism
DedupPeriodMinutes: 360
Tests:
  - Name: Privileged Pod Created
    ExpectedResult: true
    Log:
      {
        "logName": "projects/some-project/logs/cloudaudit.googleapis.com%2Factivity",
        "operation": {},
        "protoPayload":
          {
            "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog",
            "authenticationInfo": { "principalEmail": "john.doe@company.com" },
            "authorizationInfo":
              [
                {
                  "granted": true,
                  "permission": "io.k8s.core.v1.pods.create",
                  "resource": "core/v1/namespaces/default/pods/test-privileged-pod",
                },
              ],
            "methodName": "io.k8s.core.v1.pods.create",
            "request":
              {
                "@type": "core.k8s.io/v1.Pod",
                "apiVersion": "v1",
                "kind": "Pod",
                "metadata":
                  { "name": "test-privileged-pod", "namespace": "default" },
                "spec":
                  {
                    "containers":
                      [
                        {
                          "image": "nginx",
                          "imagePullPolicy": "Always",
                          "name": "nginx",
                          "resources": {},
                          "securityContext": { "privileged": true },
                        },
                      ],
                    "securityContext": {},
                  },
                "status": {},
              },
            "requestMetadata": { "callerIP": "1.2.3.4" },
            "resourceName": "core/v1/namespaces/default/pods/test-privileged-pod",
            "response":
              {
                "@type": "core.k8s.io/v1.Pod",
                "apiVersion": "v1",
                "kind": "Pod",
                "metadata": {},
                "spec":
                  {
                    "containers":
                      [
                        {
                          "image": "nginx",
                          "imagePullPolicy": "Always",
                          "name": "nginx",
                          "resources": {},
                          "securityContext": { "privileged": true },
                        },
                      ],
                    "securityContext": {},
                    "serviceAccount": "default",
                    "serviceAccountName": "default",
                    "terminationGracePeriodSeconds": 30,
                  },
                "status": {},
              },
            "serviceName": "k8s.io",
            "status": {},
          },
        "receiveTimestamp": "2024-02-13 12:45:20.058795785",
        "resource":
          {
            "labels":
              {
                "cluster_name": "some-project-cluster",
                "location": "us-west1",
                "project_id": "some-project",
              },
            "type": "k8s_cluster",
          },
        "timestamp": "2024-02-13 12:45:06.073905000",
      }
  - Name: Run-As-Root Pod Created
    ExpectedResult: true
    Log:
      {
        "logName": "projects/some-project/logs/cloudaudit.googleapis.com%2Factivity",
        "operation": {},
        "protoPayload":
          {
            "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog",
            "authenticationInfo": { "principalEmail": "john.doe@company.com" },
            "authorizationInfo":
              [
                {
                  "granted": true,
                  "permission": "io.k8s.core.v1.pods.create",
                  "resource": "core/v1/namespaces/default/pods/test-runasroot-pod",
                },
              ],
            "methodName": "io.k8s.core.v1.pods.create",
            "request":
              {
                "@type": "core.k8s.io/v1.Pod",
                "apiVersion": "v1",
                "kind": "Pod",
                "metadata": {},
                "spec":
                  {
                    "containers":
                      [
                        {
                          "image": "nginx",
                          "imagePullPolicy": "Always",
                          "name": "nginx",
                          "resources": {},
                          "securityContext": { "runAsNonRoot": false },
                        },
                      ],
                  },
                "status": {},
              },
            "requestMetadata": { "callerIP": "1.2.3.4" },
            "resourceName": "core/v1/namespaces/default/pods/test-runasroot-pod",
            "response":
              {
                "@type": "core.k8s.io/v1.Pod",
                "apiVersion": "v1",
                "kind": "Pod",
                "metadata": {},
                "spec":
                  {
                    "containers":
                      [
                        {
                          "image": "nginx",
                          "imagePullPolicy": "Always",
                          "name": "nginx",
                          "resources": {},
                          "securityContext": { "runAsNonRoot": false },
                        },
                      ],
                  },
                "status": { "phase": "Pending", "qosClass": "BestEffort" },
              },
            "serviceName": "k8s.io",
            "status": {},
          },
        "receiveTimestamp": "2024-02-13 13:13:53.113465457",
        "resource":
          {
            "labels":
              {
                "cluster_name": "some-project-cluster",
                "location": "us-west1",
                "project_id": "some-project",
              },
            "type": "k8s_cluster",
          },
        "timestamp": "2024-02-13 13:13:45.363388000",
      }
  - Name: Non-Privileged Pod Created
    ExpectedResult: false
    Log:
      {
        "logName": "projects/some-project/logs/cloudaudit.googleapis.com%2Factivity",
        "operation":
          {
            "first": true,
            "id": "7f8c5bec-01ff-4079-97e3-065ac34e10e8",
            "last": true,
            "producer": "k8s.io",
          },
        "protoPayload":
          {
            "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog",
            "authenticationInfo": { "principalEmail": "john.doe@company.com" },
            "authorizationInfo":
              [
                {
                  "granted": true,
                  "permission": "io.k8s.core.v1.pods.create",
                  "resource": "core/v1/namespaces/default/pods/test-non-privileged-pod",
                },
              ],
            "methodName": "io.k8s.core.v1.pods.create",
            "request":
              {
                "@type": "core.k8s.io/v1.Pod",
                "apiVersion": "v1",
                "kind": "Pod",
                "metadata":
                  { "name": "test-non-privileged-pod", "namespace": "default" },
                "spec":
                  {
                    "containers":
                      [
                        {
                          "image": "nginx",
                          "imagePullPolicy": "Always",
                          "name": "nginx",
                          "resources": {},
                        },
                      ],
                  },
                "status": {},
              },
            "requestMetadata": { "callerIP": "1.2.3.4" },
            "resourceName": "core/v1/namespaces/default/pods/test-non-privileged-pod",
            "response":
              {
                "@type": "core.k8s.io/v1.Pod",
                "apiVersion": "v1",
                "kind": "Pod",
                "metadata": {},
                "spec":
                  {
                    "containers":
                      [
                        {
                          "image": "nginx",
                          "imagePullPolicy": "Always",
                          "name": "nginx",
                          "resources": {},
                        },
                      ],
                  },
                "status": {},
              },
            "serviceName": "k8s.io",
            "status": {},
          },
        "receiveTimestamp": "2024-02-13 13:07:54.642331675",
        "resource":
          {
            "labels":
              {
                "cluster_name": "some-project-cluster",
                "location": "us-west1",
                "project_id": "some-project",
              },
            "type": "k8s_cluster",
          },
        "timestamp": "2024-02-13 13:07:29.505948000",
      }
  - Name: Error Creating Pod
    ExpectedResult: false
    Log:
      {
        "logName": "projects/some-project/logs/cloudaudit.googleapis.com%2Factivity",
        "protoPayload":
          {
            "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog",
            "authenticationInfo": { "principalEmail": "john.doe@company.com" },
            "authorizationInfo":
              [
                {
                  "granted": true,
                  "permission": "io.k8s.core.v1.pods.create",
                  "resource": "core/v1/namespaces/default/pods/test-privileged-pod",
                },
              ],
            "methodName": "io.k8s.core.v1.pods.create",
            "request":
              {
                "@type": "core.k8s.io/v1.Pod",
                "apiVersion": "v1",
                "kind": "Pod",
                "metadata":
                  { "name": "test-privileged-pod", "namespace": "default" },
                "spec":
                  {
                    "containers":
                      [
                        {
                          "image": "nginx",
                          "imagePullPolicy": "Always",
                          "name": "nginx",
                          "resources": {},
                          "securityContext": { "runAsNonRoot": false },
                        },
                      ],
                  },
                "status": {},
              },
            "requestMetadata": { "callerIP": "1.2.3.4" },
            "resourceName": "core/v1/namespaces/default/pods/test-privileged-pod",
            "response":
              {
                "@type": "core.k8s.io/v1.Status",
                "apiVersion": "v1",
                "code": 409,
                "details": { "kind": "pods", "name": "test-privileged-pod" },
                "kind": "Status",
                "message": 'pods "test-privileged-pod" already exists',
                "metadata": {},
                "reason": "AlreadyExists",
                "status": "Failure",
              },
            "serviceName": "k8s.io",
            "status":
              {
                "code": 10,
                "message": 'pods "test-privileged-pod" already exists',
              },
          },
        "receiveTimestamp": "2024-02-13 13:13:33.486605432",
        "resource":
          {
            "labels":
              {
                "cluster_name": "some-project-cluster",
                "location": "us-west1",
                "project_id": "some-project",
              },
            "type": "k8s_cluster",
          },
        "timestamp": "2024-02-13 13:13:24.079140000",
      }
  - Name: GCP Service Account Creating Privileged Pod (Excluded)
    ExpectedResult: false
    Log:
      {
        "logName": "projects/some-project/logs/cloudaudit.googleapis.com%2Factivity",
        "operation": {},
        "protoPayload":
          {
            "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog",
            "authenticationInfo": { "principalEmail": "container-engine-robot@some-project.iam.gserviceaccount.com" },
            "authorizationInfo":
              [
                {
                  "granted": true,
                  "permission": "io.k8s.core.v1.pods.create",
                  "resource": "core/v1/namespaces/kube-system/pods/gke-metrics-agent",
                },
              ],
            "methodName": "io.k8s.core.v1.pods.create",
            "request":
              {
                "@type": "core.k8s.io/v1.Pod",
                "apiVersion": "v1",
                "kind": "Pod",
                "metadata":
                  { "name": "gke-metrics-agent", "namespace": "kube-system" },
                "spec":
                  {
                    "containers":
                      [
                        {
                          "image": "gke.gcr.io/gke-metrics-agent:latest",
                          "imagePullPolicy": "Always",
                          "name": "gke-metrics-agent",
                          "resources": {},
                          "securityContext": { "privileged": true },
                        },
                      ],
                    "securityContext": {},
                  },
                "status": {},
              },
            "requestMetadata": { "callerIP": "10.0.0.1" },
            "resourceName": "core/v1/namespaces/kube-system/pods/gke-metrics-agent",
            "response":
              {
                "@type": "core.k8s.io/v1.Pod",
                "apiVersion": "v1",
                "kind": "Pod",
                "metadata": {},
                "spec":
                  {
                    "containers":
                      [
                        {
                          "image": "gke.gcr.io/gke-metrics-agent:latest",
                          "imagePullPolicy": "Always",
                          "name": "gke-metrics-agent",
                          "resources": {},
                          "securityContext": { "privileged": true },
                        },
                      ],
                    "securityContext": {},
                    "serviceAccount": "gke-metrics-agent",
                    "serviceAccountName": "gke-metrics-agent",
                    "terminationGracePeriodSeconds": 30,
                  },
                "status": {},
              },
            "serviceName": "k8s.io",
            "status": {},
          },
        "receiveTimestamp": "2024-02-13 12:45:20.058795785",
        "resource":
          {
            "labels":
              {
                "cluster_name": "some-project-cluster",
                "location": "us-west1",
                "project_id": "some-project",
              },
            "type": "k8s_cluster",
          },
        "timestamp": "2024-02-13 12:45:06.073905000",
      }
  - Name: Privileged Pod in System Namespace (Excluded)
    ExpectedResult: false
    Log:
      {
        "logName": "projects/some-project/logs/cloudaudit.googleapis.com%2Factivity",
        "operation": {},
        "protoPayload":
          {
            "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog",
            "authenticationInfo": { "principalEmail": "system:serviceaccount:kube-system:deployment-controller" },
            "authorizationInfo":
              [
                {
                  "granted": true,
                  "permission": "io.k8s.core.v1.pods.create",
                  "resource": "core/v1/namespaces/gke-system/pods/network-agent",
                },
              ],
            "methodName": "io.k8s.core.v1.pods.create",
            "request":
              {
                "@type": "core.k8s.io/v1.Pod",
                "apiVersion": "v1",
                "kind": "Pod",
                "metadata":
                  { "name": "network-agent", "namespace": "gke-system" },
                "spec":
                  {
                    "containers":
                      [
                        {
                          "image": "gke.gcr.io/network-agent:latest",
                          "imagePullPolicy": "Always",
                          "name": "network-agent",
                          "resources": {},
                          "securityContext": { "privileged": true },
                        },
                      ],
                    "securityContext": {},
                  },
                "status": {},
              },
            "requestMetadata": { "callerIP": "10.0.0.2" },
            "resourceName": "core/v1/namespaces/gke-system/pods/network-agent",
            "response":
              {
                "@type": "core.k8s.io/v1.Pod",
                "apiVersion": "v1",
                "kind": "Pod",
                "metadata": {},
                "spec":
                  {
                    "containers":
                      [
                        {
                          "image": "gke.gcr.io/network-agent:latest",
                          "imagePullPolicy": "Always",
                          "name": "network-agent",
                          "resources": {},
                          "securityContext": { "privileged": true },
                        },
                      ],
                    "securityContext": {},
                    "serviceAccount": "network-agent",
                    "serviceAccountName": "network-agent",
                    "terminationGracePeriodSeconds": 30,
                  },
                "status": {},
              },
            "serviceName": "k8s.io",
            "status": {},
          },
        "receiveTimestamp": "2024-02-13 12:45:20.058795785",
        "resource":
          {
            "labels":
              {
                "cluster_name": "some-project-cluster",
                "location": "us-west1",
                "project_id": "some-project",
              },
            "type": "k8s_cluster",
          },
        "timestamp": "2024-02-13 12:45:06.073905000",
      }


# ------ paired body: gcp_k8s_privileged_pod_created.py ------

from panther_base_helpers import deep_get
from panther_gcp_helpers import gcp_alert_context, is_gke_system_namespace, is_gke_system_principal


def rule(event):
    # Check basic conditions that would exclude this event
    if (
        event.deep_get("protoPayload", "response", "status") == "Failure"
        or event.deep_get("protoPayload", "methodName") != "io.k8s.core.v1.pods.create"
    ):
        return False

    # Check if this is a known service account or system namespace that should be excluded
    principal_email = event.deep_get(
        "protoPayload", "authenticationInfo", "principalEmail", default=""
    )
    resource_name = event.deep_get("protoPayload", "resourceName", default="")

    if is_gke_system_principal(principal_email) or is_gke_system_namespace(resource_name):
        return False

    # Check for privileged pod creation
    authorization_info = event.deep_walk("protoPayload", "authorizationInfo")
    if not authorization_info:
        return False

    containers_info = event.deep_walk("protoPayload", "response", "spec", "containers")
    for auth in authorization_info:
        if auth.get("permission") == "io.k8s.core.v1.pods.create" and auth.get("granted") is True:
            for security_context in containers_info:
                # Check for privileged pods and pods running as root
                # Reference:
                # https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted
                if (
                    deep_get(security_context, "securityContext", "privileged") is True
                    or deep_get(security_context, "securityContext", "runAsNonRoot") is False
                ):
                    return True

    return False


def title(event):
    actor = event.deep_get(
        "protoPayload", "authenticationInfo", "principalEmail", default="<ACTOR_NOT_FOUND>"
    )
    pod_name = event.deep_get("protoPayload", "resourceName", default="<RESOURCE_NOT_FOUND>")
    project_id = event.deep_get("resource", "labels", "project_id", default="<PROJECT_NOT_FOUND>")

    return f"[GCP]: [{actor}] created a privileged pod [{pod_name}] in project [{project_id}]"


def dedup(event):
    return event.deep_get(
        "protoPayload", "authenticationInfo", "principalEmail", default="<ACTOR_NOT_FOUND>"
    )


def alert_context(event):
    context = gcp_alert_context(event)
    containers_info = event.deep_walk("protoPayload", "response", "spec", "containers", default=[])
    context["pod_security_context"] = [i.get("securityContext") for i in containers_info]
    return context

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.