Detection rules › Panther

Panther rules: kubernetes

IOC Activity in K8 Control Plane

#
Severity
medium
Source
github.com/panther-labs/panther-analysis

This detection monitors for any kubernetes API Request originating from an Indicator of Compromise.

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: kubernetes_ioc_activity.py
RuleID: "Kubernetes.IOCActivity"
DisplayName: "IOC Activity in K8 Control Plane"
Description: >
  This detection monitors for any kubernetes API Request originating from an Indicator of Compromise.
Enabled: false
Runbook: >
  .
ScheduledQueries:
  - IOC Activity in K8 Control Plane
Severity: Medium

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query IOC Activity in K8 Control Plane; its Python module (Detection logic above) shapes the alert rather than filtering.

Response runbook

.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "Anything": "any value"
}

IOC Activity in K8 Control Plane

#
Tags
Optional
Source
github.com/panther-labs/panther-analysis

This detection monitors for any kubernetes API Request originating from an Indicator of Compromise.

Rule specification

AnalysisType: scheduled_query
QueryName: IOC Activity in K8 Control Plane
Enabled: false
Tags:
  - Optional
Description: >
  This detection monitors for any kubernetes API Request originating from an Indicator of Compromise.
SnowflakeQuery: |
  SELECT *,
         VALUE as SRC_IP,
         THIS as IP_ADDRESS,
         CASE WHEN INDEX = 0 THEN 'X_Forwarded_For'
           WHEN INDEX = 1 THEN 'X_Real_Ip'
           WHEN INDEX = 2 THEN 'Remote_Address'
         ELSE 'Unknown'
         END AS IP_TYPE
  FROM panther_logs.public.amazon_eks_audit, lateral flatten(source_ips)
   -- as an example, could be replaced with any IOC data store in a lookup table
  INNER JOIN panther_lookups.public.tor_exit_nodes
  ON value = ip
  WHERE p_occurs_since('30 minutes')
  LIMIT 10

DatabricksQuery: |
  SELECT *,
         ip_value AS SRC_IP,
         source_ips AS IP_ADDRESS,
         CASE WHEN ip_index = 0 THEN 'X_Forwarded_For'
           WHEN ip_index = 1 THEN 'X_Real_Ip'
           WHEN ip_index = 2 THEN 'Remote_Address'
         ELSE 'Unknown'
         END AS IP_TYPE
  FROM panther_logs.amazon_eks_audit
    LATERAL VIEW POSEXPLODE(from_json(TO_JSON(source_ips), 'ARRAY<STRING>')) exploded AS ip_index, ip_value
  INNER JOIN panther_lookups.tor_exit_nodes
    ON ip_value = ip
  WHERE p_occurs_since('30 minutes')
  LIMIT 10
Schedule:
  RateMinutes: 30
  TimeoutMinutes: 2

Stages and Predicates

Stage 1: source

Table
panther_logs.public.amazon_eks_audit

Stage 2: filter

Window
30m

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
*
SRC_IPVALUE
IP_ADDRESSTHIS
IP_TYPECASE WHEN INDEX = 0 THEN 'X_Forwarded_For' WHEN INDEX = 1 THEN 'X_Real_Ip' WHEN INDEX = 2 THEN 'Remote_Address' ELSE 'Unknown' END

Kubernetes Cron Job Created or Modified

#
Severity
medium
Source
github.com/panther-labs/panther-analysis

This detection monitor for any modifications or creations of a cron job. Attackers may create or modify an existing scheduled job in order to achieve cluster persistence.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: kubernetes_cron_job_created_or_modified.py
RuleID: "Kubernetes.CronJobCreatedOrModified"
DisplayName: "Kubernetes Cron Job Created or Modified"
Description: >
  This detection monitor for any modifications or creations of a cron job. Attackers may create or modify an existing scheduled job in order to achieve cluster persistence.
Enabled: false
Runbook: >
  .
ScheduledQueries:
  - Kubernetes Cron Job Created or Modified
Severity: Medium

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query Kubernetes Cron Job Created or Modified; its Python module (Detection logic above) shapes the alert rather than filtering.

Response runbook

.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "Anything": "any value"
}

Kubernetes Cron Job Created or Modified

#
Tags
Optional
Source
github.com/panther-labs/panther-analysis

This detection monitor for any modifications or creations of a cron job. Attackers may create or modify an existing scheduled job in order to achieve cluster persistence.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Rule specification

AnalysisType: scheduled_query
QueryName: Kubernetes Cron Job Created or Modified
Enabled: false
Tags:
  - Optional
Description: >
  This detection monitor for any modifications or creations of a cron job. Attackers may create or modify an existing scheduled job in order to achieve cluster persistence.
SnowflakeQuery: |
  SELECT *,
         IFF(sourceIPs[0] IS NOT null, sourceIPs[0], 'N/A') as X_FORWARDED_FOR_IP,
         IFF(sourceIPs[1] IS NOT null, sourceIPs[1], 'N/A') as X_Real_IP,
         IFF(sourceIPs[2] IS NOT null, sourceIPs[2], 'N/A') as Remote_Address_IP
  FROM panther_logs.public.amazon_eks_audit
  WHERE
  verb IN ('create', 'update', 'patch')
  AND objectRef:resource = 'cronjobs'
  AND p_occurs_since('30 minutes')
  --insert allow-list for expected cronjobs in a cluster, for example a sync service
  LIMIT 100

DatabricksQuery: |
  SELECT *,
         COALESCE(try_element_at(sourceIPs, 1), 'N/A') as X_FORWARDED_FOR_IP,
         COALESCE(try_element_at(sourceIPs, 2), 'N/A') as X_Real_IP,
         COALESCE(try_element_at(sourceIPs, 3), 'N/A') as Remote_Address_IP
  FROM panther_logs.amazon_eks_audit
  WHERE
  verb IN ('create', 'update', 'patch')
  AND objectRef:resource = 'cronjobs'
  AND p_occurs_since('30 minutes')
  --insert allow-list for expected cronjobs in a cluster, for example a sync service
  LIMIT 100
Schedule:
  RateMinutes: 30
  TimeoutMinutes: 2

Stages and Predicates

Stage 1: source

Table
panther_logs.public.amazon_eks_audit

Stage 2: filter

  • verb is one of create, update, patch
  • objectRef:resource is cronjobs
Window
30m

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
*
X_FORWARDED_FOR_IPIFF ( sourceIPs [ 0 ] IS NOT NULL , sourceIPs [ 0 ] , 'N/A' )
X_Real_IPIFF ( sourceIPs [ 1 ] IS NOT NULL , sourceIPs [ 1 ] , 'N/A' )
Remote_Address_IPIFF ( sourceIPs [ 2 ] IS NOT NULL , sourceIPs [ 2 ] , 'N/A' )

Kubernetes Pod Created in Pre-Configured or Default Name Spaces

#
Severity
medium
Source
github.com/panther-labs/panther-analysis

This detection monitors for any pod created in pre-configured or default namespaces. Only Cluster Admins should be creating pods in the kube-system namespace, and it is best practice not to run any cluster critical infrastructure here. The kube-public namespace is intended to be readable by unauthenticated users. The default namespace is shipped with the cluster and it is best practice not to deploy production workloads here. These namespaces may be used to evade defenses or hide attacker infrastructure.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: kubernetes_pod_in_default_name_space.py
RuleID: "Kubernetes.PodCreatedDefaultNameSpace"
DisplayName: "Kubernetes Pod Created in Pre-Configured or Default Name Spaces"
Description: >
  This detection monitors for any pod created in pre-configured or default namespaces. Only Cluster Admins should be creating pods in the kube-system namespace, and it is best practice not to run any cluster critical infrastructure here. The kube-public namespace is intended to be readable by unauthenticated users. The default namespace is shipped with the cluster and it is best practice not to deploy production workloads here. These namespaces may be used to evade defenses or hide attacker infrastructure.
Enabled: false
Runbook: >
  .
ScheduledQueries:
  - Kubernetes Pod Created in Pre-Configured or Default Name Spaces
Severity: Medium

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query Kubernetes Pod Created in Pre-Configured or Default Name Spaces; its Python module (Detection logic above) shapes the alert rather than filtering.

Response runbook

.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "Anything": "any value"
}

Kubernetes Pod Created in Pre-Configured or Default Name Spaces

#
Tags
Optional
Source
github.com/panther-labs/panther-analysis

This detection monitors for any pod created in pre-configured or default namespaces. Only Cluster Admins should be creating pods in the kube-system namespace, and it is best practice not to run any cluster critical infrastructure here. The kube-public namespace is intended to be readable by unauthenticated users. The default namespace is shipped with the cluster and it is best practice not to deploy production workloads here. These namespaces may be used to evade defenses or hide attacker infrastructure.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Rule specification

AnalysisType: scheduled_query
QueryName: Kubernetes Pod Created in Pre-Configured or Default Name Spaces
Enabled: false
Tags:
  - Optional
Description: >
  This detection monitors for any pod created in pre-configured or default namespaces. Only Cluster Admins should be creating pods in the kube-system namespace, and it is best practice not to run any cluster critical infrastructure here. The kube-public namespace is intended to be readable by unauthenticated users. The default namespace is shipped with the cluster and it is best practice not to deploy production workloads here. These namespaces may be used to evade defenses or hide attacker infrastructure.
SnowflakeQuery: |
  SELECT *,
         IFF(sourceIPs[0] IS NOT null, sourceIPs[0], 'N/A') as X_FORWARDED_FOR_IP,
         IFF(sourceIPs[1] IS NOT null, sourceIPs[1], 'N/A') as X_Real_IP,
         IFF(sourceIPs[2] IS NOT null, sourceIPs[2], 'N/A') as Remote_Address_IP
  FROM panther_logs.public.amazon_eks_audit
  WHERE
  verb = 'create'
  AND objectRef:resource = 'pods'
  AND requestObject:kind = 'pod'
  AND objectRef:subresource = 'attach'
  AND objectRef:namespace IN ('kube-system','kube-public','default')
  AND p_occurs_since('30 minutes')
  --insert allow-list for known workloads that are not sensitive or need to run in these namespaces
  LIMIT 100

DatabricksQuery: |
  SELECT *,
         COALESCE(try_element_at(sourceIPs, 1), 'N/A') as X_FORWARDED_FOR_IP,
         COALESCE(try_element_at(sourceIPs, 2), 'N/A') as X_Real_IP,
         COALESCE(try_element_at(sourceIPs, 3), 'N/A') as Remote_Address_IP
  FROM panther_logs.amazon_eks_audit
  WHERE
  verb = 'create'
  AND objectRef:resource = 'pods'
  AND requestObject:kind = 'pod'
  AND objectRef:subresource = 'attach'
  AND objectRef:namespace IN ('kube-system','kube-public','default')
  AND p_occurs_since('30 minutes')
  --insert allow-list for known workloads that are not sensitive or need to run in these namespaces
  LIMIT 100
Schedule:
  RateMinutes: 30
  TimeoutMinutes: 2

Stages and Predicates

Stage 1: source

Table
panther_logs.public.amazon_eks_audit

Stage 2: filter

  • verb is create
  • objectRef:resource is pods
  • requestObject:kind is pod
  • objectRef:subresource is attach
  • objectRef:namespace is one of kube-system, kube-public, default
Window
30m

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
*
X_FORWARDED_FOR_IPIFF ( sourceIPs [ 0 ] IS NOT NULL , sourceIPs [ 0 ] , 'N/A' )
X_Real_IPIFF ( sourceIPs [ 1 ] IS NOT NULL , sourceIPs [ 1 ] , 'N/A' )
Remote_Address_IPIFF ( sourceIPs [ 2 ] IS NOT NULL , sourceIPs [ 2 ] , 'N/A' )

Kubernetes Service with Type Node Port Deployed

#
Severity
medium
Source
github.com/panther-labs/panther-analysis

This detection monitors for any kubernetes service deployed with type node port. A Node Port service allows an attacker to expose a set of pods hosting the service to the internet by opening their port and redirecting traffic here. This can be used to bypass network controls and intercept traffic, creating a direct line to the outside network.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: kubernetes_service_type_node_port_deployed.py
RuleID: "Kubernetes.ServiceTypeNodePortDeployed"
DisplayName: "Kubernetes Service with Type Node Port Deployed"
Description: >
  This detection monitors for any kubernetes service deployed with type node port. A Node Port service allows an attacker to expose a set of pods hosting the service to the internet by opening their port and redirecting traffic here. This can be used to bypass network controls and intercept traffic, creating a direct line to the outside network.
Enabled: false
Runbook: >
  .
ScheduledQueries:
  - Kubernetes Service with Type Node Port Deployed
Severity: Medium

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query Kubernetes Service with Type Node Port Deployed; its Python module (Detection logic above) shapes the alert rather than filtering.

Response runbook

.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "Anything": "any value"
}

Kubernetes Service with Type Node Port Deployed

#
Tags
Optional
Source
github.com/panther-labs/panther-analysis

This detection monitors for any kubernetes service deployed with type node port. A Node Port service allows an attacker to expose a set of pods hosting the service to the internet by opening their port and redirecting traffic here. This can be used to bypass network controls and intercept traffic, creating a direct line to the outside network.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Rule specification

AnalysisType: scheduled_query
QueryName: Kubernetes Service with Type Node Port Deployed
Enabled: false
Tags:
  - Optional
Description: >
  This detection monitors for any kubernetes service deployed with type node port. A Node Port service allows an attacker to expose a set of pods hosting the service to the internet by opening their port and redirecting traffic here. This can be used to bypass network controls and intercept traffic, creating a direct line to the outside network.
SnowflakeQuery: |
  SELECT *,
         objectRef:name as service,
         objectRef:namespace as namespace,
         objectRef:resource as resource_type,
         COALESCE(impersonated_user, USER:username) as src_user,
         userAgent,
         responseObject:spec:externalTrafficPolicy as external_traffic_policy,
         responseObject:spec:internalTrafficPolicy as internal_traffic_policy,
         responseObject:spec:clusterIP as cluster_ip_address,
         VALUE:port as port, --port where traffic gets forwarded to in the pod
         VALUE:protocol as protocol, --protocol the service uses
         VALUE:nodePort as node_port, --which port acts as the nodeport on all the nodes
         requestObject:spec:type as type,
         IFF(requestObject:spec:status:loadBalancer is null, 'No LB Present',
         requestObject:spec:status:loadBalancer) as load_balancer,
         responseStatus:code as response_status
         FROM panther_logs.public.kubernetes_control_plane, lateral flatten(response_object:spec:ports)
         WHERE
         objectRef:resource = 'services'
         AND verb = 'create'
         AND requestObject:spec:type = 'NodePort'
         AND p_occurs_since('30 minutes')
         --Insert allow-list for expected NodePort Services
         LIMIT 100

DatabricksQuery: |
  SELECT *,
         objectRef:name as service,
         objectRef:namespace as namespace,
         objectRef:resource as resource_type,
         COALESCE(impersonated_user, USER:username) as src_user,
         userAgent,
         responseObject:spec:externalTrafficPolicy as external_traffic_policy,
         responseObject:spec:internalTrafficPolicy as internal_traffic_policy,
         responseObject:spec:clusterIP as cluster_ip_address,
         port_value.port as port, --port where traffic gets forwarded to in the pod
         port_value.protocol as protocol, --protocol the service uses
         port_value.nodePort as node_port, --which port acts as the nodeport on all the nodes
         requestObject:spec:type as type,
         IF(requestObject:spec:status:loadBalancer IS NULL, 'No LB Present',
         requestObject:spec:status:loadBalancer) as load_balancer,
         responseStatus:code as response_status
         FROM panther_logs.kubernetes_control_plane
           LATERAL VIEW OUTER EXPLODE(from_json(TO_JSON(response_object:spec:ports), 'ARRAY<STRUCT<port:STRING, protocol:STRING, nodePort:STRING>>')) ports_exploded AS port_value
         WHERE
         objectRef:resource = 'services'
         AND verb = 'create'
         AND requestObject:spec:type = 'NodePort'
         AND p_occurs_since('30 minutes')
         --Insert allow-list for expected NodePort Services
         LIMIT 100

Schedule:
  RateMinutes: 30
  TimeoutMinutes: 2

Stages and Predicates

Stage 1: source

Table
panther_logs.public.kubernetes_control_plane

Stage 2: filter

  • objectRef:resource is services
  • verb is create
  • requestObject:spec:type is NodePort
Window
30m

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
*
serviceobjectRef:name
namespaceobjectRef:namespace
resource_typeobjectRef:resource
src_userCOALESCE ( impersonated_user , USER:username )
userAgent
external_traffic_policyresponseObject:spec:externalTrafficPolicy
internal_traffic_policyresponseObject:spec:internalTrafficPolicy
cluster_ip_addressresponseObject:spec:clusterIP
portVALUE:port
protocolVALUE:protocol
node_portVALUE:nodePort
typerequestObject:spec:type
load_balancerIFF ( requestObject:spec:status:loadBalancer IS NULL , 'No LB Present' , requestObject:spec:status:loadBalancer )
response_statusresponseStatus:code

New Admission Controller Created

#
Severity
medium
Source
github.com/panther-labs/panther-analysis

This detection monitors for a new admission controller being created in the cluster. Admission controllers allows an attack to intercept all API requests made within a cluster, allowing for enumeration of resources and common actions. This can be a very powerful tool to understand where to pivot to next.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: kubernetes_admission_controller_created.py
RuleID: "Kubernetes.NewAdmissionControllerCreated"
DisplayName: "New Admission Controller Created"
Description: >
  This detection monitors for a new admission controller being created in the cluster. Admission controllers allows an attack to intercept all API requests made within a cluster, allowing for enumeration of resources and common actions. This can be a very powerful tool to understand where to pivot to next.
Enabled: false
Runbook: >
  .
ScheduledQueries:
  - New Admission Controller Created
Severity: Medium

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query New Admission Controller Created; its Python module (Detection logic above) shapes the alert rather than filtering.

Response runbook

.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "Anything": "any value"
}

New Admission Controller Created

#
Tags
Optional
Source
github.com/panther-labs/panther-analysis

This detection monitors for a new admission controller being created in the cluster. Admission controllers allows an attack to intercept all API requests made within a cluster, allowing for enumeration of resources and common actions. This can be a very powerful tool to understand where to pivot to next.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Rule specification

AnalysisType: scheduled_query
QueryName: New Admission Controller Created
Enabled: false
Tags:
  - Optional
Description: >
  This detection monitors for a new admission controller being created in the cluster. Admission controllers allows an attack to intercept all API requests made within a cluster, allowing for enumeration of resources and common actions. This can be a very powerful tool to understand where to pivot to next.
SnowflakeQuery: |
  SELECT *,
         IFF(sourceIPs[0] IS NOT null, sourceIPs[0], 'N/A') as X_FORWARDED_FOR_IP,
         IFF(sourceIPs[1] IS NOT null, sourceIPs[1], 'N/A') as X_Real_IP,
         IFF(sourceIPs[2] IS NOT null, sourceIPs[2], 'N/A') as Remote_Address_IP
  FROM panther_logs.public.amazon_eks_audit
  WHERE
  verb ='create'
  AND objectRef:resource IN ('mutatingwebhookconfigurations', 'validatingwebhookconfiguration')
  AND p_occurs_since('30 minutes')
  --insert allow-list for known admission controllers such as gatekeeper/OPA
  LIMIT 100

DatabricksQuery: |
  SELECT *,
         COALESCE(try_element_at(sourceIPs, 1), 'N/A') as X_FORWARDED_FOR_IP,
         COALESCE(try_element_at(sourceIPs, 2), 'N/A') as X_Real_IP,
         COALESCE(try_element_at(sourceIPs, 3), 'N/A') as Remote_Address_IP
  FROM panther_logs.amazon_eks_audit
  WHERE
  verb ='create'
  AND objectRef:resource IN ('mutatingwebhookconfigurations', 'validatingwebhookconfiguration')
  AND p_occurs_since('30 minutes')
  --insert allow-list for known admission controllers such as gatekeeper/OPA
  LIMIT 100
Schedule:
  RateMinutes: 30
  TimeoutMinutes: 2

Stages and Predicates

Stage 1: source

Table
panther_logs.public.amazon_eks_audit

Stage 2: filter

  • verb is create
  • objectRef:resource is one of mutatingwebhookconfigurations, validatingwebhookconfiguration
Window
30m

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
objectRef:resourcein
  • mutatingwebhookconfigurations
  • validatingwebhookconfiguration
field:"objectRef:resource" kind:in
verbeq
  • create
field:"verb" kind:eq value:"create"

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
*
X_FORWARDED_FOR_IPIFF ( sourceIPs [ 0 ] IS NOT NULL , sourceIPs [ 0 ] , 'N/A' )
X_Real_IPIFF ( sourceIPs [ 1 ] IS NOT NULL , sourceIPs [ 1 ] , 'N/A' )
Remote_Address_IPIFF ( sourceIPs [ 2 ] IS NOT NULL , sourceIPs [ 2 ] , 'N/A' )

New DaemonSet Deployed to Kubernetes

#
Severity
medium
Source
github.com/panther-labs/panther-analysis

This detection monitors for a new DaemonSet deployed to a kubernetes cluster. A daemonset is a workload that guarantees the presence of exactly one instance of a specific pod on every node in the cluster. This can be a very powerful tool for establishing peristence.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: kubernetes_new_daemonset_deployed.py
RuleID: "Kubernetes.DaemonSetDeployed"
DisplayName: "New DaemonSet Deployed to Kubernetes"
Description: >
  This detection monitors for a new DaemonSet deployed to a kubernetes cluster. A daemonset is a workload that guarantees the presence of exactly one instance of a specific pod on every node in the cluster. This can be a very powerful tool for establishing peristence.
Enabled: false
Runbook: >
  .
ScheduledQueries:
  - New DaemonSet Deployed to Kubernetes
Severity: Medium

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query New DaemonSet Deployed to Kubernetes; its Python module (Detection logic above) shapes the alert rather than filtering.

Response runbook

.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "Anything": "any value"
}

New DaemonSet Deployed to Kubernetes

#
Tags
Optional
Source
github.com/panther-labs/panther-analysis

This detection monitors for a new DaemonSet deployed to a kubernetes cluster. A daemonset is a workload that guarantees the presence of exactly one instance of a specific pod on every node in the cluster. This can be a very powerful tool for establishing peristence.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Rule specification

AnalysisType: scheduled_query
QueryName: New DaemonSet Deployed to Kubernetes
Enabled: false
Tags:
  - Optional
Description: >
  This detection monitors for a new DaemonSet deployed to a kubernetes cluster. A daemonset is a workload that guarantees the presence of exactly one instance of a specific pod on every node in the cluster. This can be a very powerful tool for establishing peristence.
SnowflakeQuery: |
  SELECT *,
         IFF(sourceIPs[0] IS NOT null, sourceIPs[0], 'N/A') as X_FORWARDED_FOR_IP,
         IFF(sourceIPs[1] IS NOT null, sourceIPs[1], 'N/A') as X_Real_IP,
         IFF(sourceIPs[2] IS NOT null, sourceIPs[2], 'N/A') as Remote_Address_IP
  FROM panther_logs.public.amazon_eks_audit
  WHERE
  verb ='create'
  AND objectRef:resource = 'daemonsets'
  AND p_occurs_since('30 minutes')
  --insert allow-list for know daemonsets running kubernetes clusters i.e a security agent
  LIMIT 100

DatabricksQuery: |
  SELECT *,
         COALESCE(try_element_at(sourceIPs, 1), 'N/A') as X_FORWARDED_FOR_IP,
         COALESCE(try_element_at(sourceIPs, 2), 'N/A') as X_Real_IP,
         COALESCE(try_element_at(sourceIPs, 3), 'N/A') as Remote_Address_IP
  FROM panther_logs.amazon_eks_audit
  WHERE
  verb ='create'
  AND objectRef:resource = 'daemonsets'
  AND p_occurs_since('30 minutes')
  --insert allow-list for know daemonsets running kubernetes clusters i.e a security agent
  LIMIT 100
Schedule:
  RateMinutes: 30
  TimeoutMinutes: 2

Stages and Predicates

Stage 1: source

Table
panther_logs.public.amazon_eks_audit

Stage 2: filter

  • verb is create
  • objectRef:resource is daemonsets
Window
30m

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
*
X_FORWARDED_FOR_IPIFF ( sourceIPs [ 0 ] IS NOT NULL , sourceIPs [ 0 ] , 'N/A' )
X_Real_IPIFF ( sourceIPs [ 1 ] IS NOT NULL , sourceIPs [ 1 ] , 'N/A' )
Remote_Address_IPIFF ( sourceIPs [ 2 ] IS NOT NULL , sourceIPs [ 2 ] , 'N/A' )

Pod attached to the Node Host Network

#
Severity
medium
Source
github.com/panther-labs/panther-analysis

This detection monitor for the creation of pods which are attached to the host's network. This allows a pod to listen to all network traffic for all deployed computer on that particular node and communicate with other compute on the network namespace. Attackers can use this to capture secrets passed in arguments or connections.

Telemetry coverage

PlatformRecord / event type
Kubernetescreate-pods: create pods

Rules detecting the same action

These rules filter on the same operation.

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: kubernetes_pod_attached_to_node_host_network.py
RuleID: "Kubernetes.PodAttachedHostNetwork"
DisplayName: "Pod attached to the Node Host Network"
Description: >
  This detection monitor for the creation of pods which are attached to the host's network. This allows a pod to listen to all network traffic for all deployed computer on that particular node and communicate with other compute on the network namespace. Attackers can use this to capture secrets passed in arguments or connections.
Enabled: false
Runbook: >
  .
ScheduledQueries:
  - Pod attached to the Node Host Network
Severity: Medium

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query Pod attached to the Node Host Network; its Python module (Detection logic above) shapes the alert rather than filtering.

Response runbook

.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "Anything": "any value"
}

Pod attached to the Node Host Network

#
Tags
Optional
Source
github.com/panther-labs/panther-analysis

This detection monitor for the creation of pods which are attached to the host's network. This allows a pod to listen to all network traffic for all deployed computer on that particular node and communicate with other compute on the network namespace. Attackers can use this to capture secrets passed in arguments or connections.

Telemetry coverage

PlatformRecord / event type
Kubernetescreate-pods: create pods

Rules detecting the same action

These rules filter on the same operation.

Rule specification

AnalysisType: scheduled_query
QueryName: Pod attached to the Node Host Network
Enabled: false
Tags:
  - Optional
Description: >
  This detection monitor for the creation of pods which are attached to the host's network. This allows a pod to listen to all network traffic for all deployed computer on that particular node and communicate with other compute on the network namespace. Attackers can use this to capture secrets passed in arguments or connections.
SnowflakeQuery: |
  SELECT *,
         IFF(sourceIPs[0] IS NOT null, sourceIPs[0], 'N/A') as X_FORWARDED_FOR_IP,
         IFF(sourceIPs[1] IS NOT null, sourceIPs[1], 'N/A') as X_Real_IP,
         IFF(sourceIPs[2] IS NOT null, sourceIPs[2], 'N/A') as Remote_Address_IP
  FROM panther_logs.public.amazon_eks_audit
  WHERE
  verb = 'create'
  AND objectRef:resource = 'pods'
  AND requestObject:spec:hostNetwork = True
  AND p_occurs_since('30 minutes')
  --insert allow-list for expected pods that are attached to the node's network
  LIMIT 10

DatabricksQuery: |
  SELECT *,
         COALESCE(try_element_at(sourceIPs, 1), 'N/A') as X_FORWARDED_FOR_IP,
         COALESCE(try_element_at(sourceIPs, 2), 'N/A') as X_Real_IP,
         COALESCE(try_element_at(sourceIPs, 3), 'N/A') as Remote_Address_IP
  FROM panther_logs.amazon_eks_audit
  WHERE
  verb = 'create'
  AND objectRef:resource = 'pods'
  AND requestObject:spec:hostNetwork = True
  AND p_occurs_since('30 minutes')
  --insert allow-list for expected pods that are attached to the node's network
  LIMIT 10
Schedule:
  RateMinutes: 30
  TimeoutMinutes: 2

Stages and Predicates

Stage 1: source

Table
panther_logs.public.amazon_eks_audit

Stage 2: filter

  • verb is create
  • objectRef:resource is pods
  • requestObject:spec:hostNetwork is TRUE
Window
30m

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
*
X_FORWARDED_FOR_IPIFF ( sourceIPs [ 0 ] IS NOT NULL , sourceIPs [ 0 ] , 'N/A' )
X_Real_IPIFF ( sourceIPs [ 1 ] IS NOT NULL , sourceIPs [ 1 ] , 'N/A' )
Remote_Address_IPIFF ( sourceIPs [ 2 ] IS NOT NULL , sourceIPs [ 2 ] , 'N/A' )

Pod Created or Modified Using the Host IPC Namespace

#
Severity
medium
Source
github.com/panther-labs/panther-analysis

This detection monitors for any pod creation or modification using the host IPC Namespace. Deploying pods in the Host IPC Namespace, breaks isolation between the pod and the underlying host meaning the pod has direct access to the same IPC objects and communications channels as the host system.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: kubernetes_pod_using_host_ipc_namespace.py
RuleID: "Kubernetes.PodUsingIPCNamespace"
DisplayName: "Pod Created or Modified Using the Host IPC Namespace"
Description: >
  This detection monitors for any pod creation or modification using the host IPC Namespace. Deploying pods in the Host IPC Namespace, breaks isolation between the pod and the underlying host meaning the pod has direct access to the same IPC objects and communications channels as the host system.
Enabled: false
Runbook: >
  .
ScheduledQueries:
  - Pod Created or Modified Using the Host IPC Namespace
Severity: Medium

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query Pod Created or Modified Using the Host IPC Namespace; its Python module (Detection logic above) shapes the alert rather than filtering.

Response runbook

.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "Anything": "any value"
}

Pod Created or Modified Using the Host IPC Namespace

#
Tags
Optional
Source
github.com/panther-labs/panther-analysis

This detection monitors for any pod creation or modification using the host IPC Namespace. Deploying pods in the Host IPC Namespace, breaks isolation between the pod and the underlying host meaning the pod has direct access to the same IPC objects and communications channels as the host system.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Rule specification

AnalysisType: scheduled_query
QueryName: Pod Created or Modified Using the Host IPC Namespace
Enabled: false
Tags:
  - Optional
Description: >
  This detection monitors for any pod creation or modification using the host IPC Namespace. Deploying pods in the Host IPC Namespace, breaks isolation between the pod and the underlying host meaning the pod has direct access to the same IPC objects and communications channels as the host system.
SnowflakeQuery: |
  SELECT *,
         IFF(sourceIPs[0] IS NOT null, sourceIPs[0], 'N/A') as X_FORWARDED_FOR_IP,
         IFF(sourceIPs[1] IS NOT null, sourceIPs[1], 'N/A') as X_Real_IP,
         IFF(sourceIPs[2] IS NOT null, sourceIPs[2], 'N/A') as Remote_Address_IP
  FROM panther_logs.public.amazon_eks_audit
  WHERE
  verb IN ('create', 'update', 'patch')
  AND objectRef:resource = 'pods'
  AND requestObject:spec:hostIPC = True
  AND p_occurs_since('30 minutes')
  --insert allow-list for pods that are expected to use the Host IPC namespace
  LIMIT 100

DatabricksQuery: |
  SELECT *,
         COALESCE(try_element_at(sourceIPs, 1), 'N/A') as X_FORWARDED_FOR_IP,
         COALESCE(try_element_at(sourceIPs, 2), 'N/A') as X_Real_IP,
         COALESCE(try_element_at(sourceIPs, 3), 'N/A') as Remote_Address_IP
  FROM panther_logs.amazon_eks_audit
  WHERE
  verb IN ('create', 'update', 'patch')
  AND objectRef:resource = 'pods'
  AND requestObject:spec:hostIPC = True
  AND p_occurs_since('30 minutes')
  --insert allow-list for pods that are expected to use the Host IPC namespace
  LIMIT 100
Schedule:
  RateMinutes: 30
  TimeoutMinutes: 2

Stages and Predicates

Stage 1: source

Table
panther_logs.public.amazon_eks_audit

Stage 2: filter

  • verb is one of create, update, patch
  • objectRef:resource is pods
  • requestObject:spec:hostIPC is TRUE
Window
30m

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
*
X_FORWARDED_FOR_IPIFF ( sourceIPs [ 0 ] IS NOT NULL , sourceIPs [ 0 ] , 'N/A' )
X_Real_IPIFF ( sourceIPs [ 1 ] IS NOT NULL , sourceIPs [ 1 ] , 'N/A' )
Remote_Address_IPIFF ( sourceIPs [ 2 ] IS NOT NULL , sourceIPs [ 2 ] , 'N/A' )

Pod Created or Modified Using the Host PID Namespace

#
Severity
medium
Source
github.com/panther-labs/panther-analysis

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 of the hosts processes. This can offer a powerful escape hatch to the underlying host.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: kubernetes_pod_using_host_pid_namespace.py
RuleID: "Kubernetes.PodUsingHostPIDNamespace"
DisplayName: "Pod Created or Modified Using the 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 of the hosts processes. This can offer a powerful escape hatch to the underlying host.
Enabled: false
Runbook: >
  .
ScheduledQueries:
  - Pod Created or Modified Using the Host PID Namespace
Severity: Medium

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query Pod Created or Modified Using the Host PID Namespace; its Python module (Detection logic above) shapes the alert rather than filtering.

Response runbook

.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "Anything": "any value"
}

Pod Created or Modified Using the Host PID Namespace

#
Tags
Optional
Source
github.com/panther-labs/panther-analysis

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 of the host’s processes. This can offer a powerful escape hatch to the underlying host.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Rule specification

AnalysisType: scheduled_query
QueryName: Pod Created or Modified Using the Host PID Namespace
Enabled: false
Tags:
  - Optional
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 of the host’s processes. This can offer a powerful escape hatch to the underlying host.
SnowflakeQuery: |
  SELECT *,
         IFF(sourceIPs[0] IS NOT null, sourceIPs[0], 'N/A') as X_FORWARDED_FOR_IP,
         IFF(sourceIPs[1] IS NOT null, sourceIPs[1], 'N/A') as X_Real_IP,
         IFF(sourceIPs[2] IS NOT null, sourceIPs[2], 'N/A') as Remote_Address_IP
  FROM panther_logs.public.amazon_eks_audit
  WHERE
  verb IN ('create', 'update', 'patch')
  AND objectRef:resource = 'pods'
  AND requestObject:spec:hostPID = True
  AND p_occurs_since('30 minutes')
  --insert allow-list for pods expected to use the Host PID namespace
  LIMIT 100

DatabricksQuery: |
  SELECT *,
         COALESCE(try_element_at(sourceIPs, 1), 'N/A') as X_FORWARDED_FOR_IP,
         COALESCE(try_element_at(sourceIPs, 2), 'N/A') as X_Real_IP,
         COALESCE(try_element_at(sourceIPs, 3), 'N/A') as Remote_Address_IP
  FROM panther_logs.amazon_eks_audit
  WHERE
  verb IN ('create', 'update', 'patch')
  AND objectRef:resource = 'pods'
  AND requestObject:spec:hostPID = True
  AND p_occurs_since('30 minutes')
  --insert allow-list for pods expected to use the Host PID namespace
  LIMIT 100
Schedule:
  RateMinutes: 30
  TimeoutMinutes: 2

Stages and Predicates

Stage 1: source

Table
panther_logs.public.amazon_eks_audit

Stage 2: filter

  • verb is one of create, update, patch
  • objectRef:resource is pods
  • requestObject:spec:hostPID is TRUE
Window
30m

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
*
X_FORWARDED_FOR_IPIFF ( sourceIPs [ 0 ] IS NOT NULL , sourceIPs [ 0 ] , 'N/A' )
X_Real_IPIFF ( sourceIPs [ 1 ] IS NOT NULL , sourceIPs [ 1 ] , 'N/A' )
Remote_Address_IPIFF ( sourceIPs [ 2 ] IS NOT NULL , sourceIPs [ 2 ] , 'N/A' )

Pod Created with Overly Permissive Linux Capabilities

#
Severity
medium
Source
github.com/panther-labs/panther-analysis

This detection monitors for a pod created with overly permissive linux capabilities. Excessive pod permissions and capabilities can be a launch point for privilege escalation or container breakout.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: kubernetes_overly_permissive_linux_capabilities.py
RuleID: "Kubernetes.OverlyPermissivePod"
DisplayName: "Pod Created with Overly Permissive Linux Capabilities"
Description: >
  This detection monitors for a pod created with overly permissive linux capabilities. Excessive pod permissions and capabilities can be a launch point for privilege escalation or container breakout.
Enabled: false
Runbook: >
  .
ScheduledQueries:
  - Pod Created with Overly Permissive Linux Capabilities
Severity: Medium

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query Pod Created with Overly Permissive Linux Capabilities; its Python module (Detection logic above) shapes the alert rather than filtering.

Response runbook

.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "Anything": "any value"
}

Pod Created with Overly Permissive Linux Capabilities

#
Tags
Optional
Source
github.com/panther-labs/panther-analysis

This detection monitors for a pod created with overly permissive linux capabilities. Excessive pod permissions and capabilities can be a launch point for privilege escalation or container breakout.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Rule specification

AnalysisType: scheduled_query
QueryName: Pod Created with Overly Permissive Linux Capabilities
Enabled: false
Tags:
  - Optional
Description: >
  This detection monitors for a pod created with overly permissive linux capabilities. Excessive pod permissions and capabilities can be a launch point for privilege escalation or container breakout.
SnowflakeQuery: |-
  SELECT *,
         ARRAY_INTERSECTION(requestObject:spec:containers[0]:securityContext:capabilities:add, ARRAY_CONSTRUCT('BPF','NET_ADMIN','SYS_ADMIN')) as linux_capabilities, --linux capabilities the pod was deployed with
         IFF(sourceIPs[0] IS NOT null, sourceIPs[0], 'N/A') as X_FORWARDED_FOR_IP,
         IFF(sourceIPs[1] IS NOT null, sourceIPs[1], 'N/A') as X_Real_IP,
         IFF(sourceIPs[2] IS NOT null, sourceIPs[2], 'N/A') as Remote_Address_IP
  FROM panther_logs.public.amazon_eks_audit
  WHERE
  verb IN ('create', 'update')
  AND objectRef:resource = 'pods'
  AND ARRAY_INTERSECTION(requestObject:spec:containers[0]:securityContext:capabilities:add, ARRAY_CONSTRUCT('BPF','NET_ADMIN','SYS_ADMIN')) != [] --linux capabilities array intersect to identify if any are present
  AND requestObject:spec:containers[0]:securityContext is not null
  AND p_occurs_since('30 minutes')
  --insert allow-list for pods that are expected to have privileged linux capabilities, for example a observability agent
  LIMIT 100

DatabricksQuery: |-
  SELECT *,
         ARRAY_INTERSECT(try_element_at(requestObject.spec.containers, 1).securityContext.capabilities.add, ARRAY('BPF','NET_ADMIN','SYS_ADMIN')) as linux_capabilities, --linux capabilities the pod was deployed with
         COALESCE(try_element_at(sourceIPs, 1), 'N/A') as X_FORWARDED_FOR_IP,
         COALESCE(try_element_at(sourceIPs, 2), 'N/A') as X_Real_IP,
         COALESCE(try_element_at(sourceIPs, 3), 'N/A') as Remote_Address_IP
  FROM panther_logs.amazon_eks_audit
  WHERE
  verb IN ('create', 'update')
  AND objectRef:resource = 'pods'
  AND SIZE(ARRAY_INTERSECT(try_element_at(requestObject.spec.containers, 1).securityContext.capabilities.add, ARRAY('BPF','NET_ADMIN','SYS_ADMIN'))) > 0 --linux capabilities array intersect to identify if any are present
  AND try_element_at(requestObject.spec.containers, 1).securityContext IS NOT NULL
  AND p_occurs_since('30 minutes')
  --insert allow-list for pods that are expected to have privileged linux capabilities, for example a observability agent
  LIMIT 100
Schedule:
  RateMinutes: 30
  TimeoutMinutes: 2

Stages and Predicates

Stage 1: source

Table
panther_logs.public.amazon_eks_audit

Stage 2: filter

  • verb is one of create, update
  • objectRef:resource is pods
  • requestObject:spec:containers[0]:securityContext is present
Window
30m

This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
*
linux_capabilitiesARRAY_INTERSECTION ( requestObject:spec:containers [ 0 ] : securityContext:capabilities:add , ARRAY_CONSTRUCT ( 'BPF' , 'NET_ADMIN' , 'SYS_ADMIN' ) )
X_FORWARDED_FOR_IPIFF ( sourceIPs [ 0 ] IS NOT NULL , sourceIPs [ 0 ] , 'N/A' )
X_Real_IPIFF ( sourceIPs [ 1 ] IS NOT NULL , sourceIPs [ 1 ] , 'N/A' )
Remote_Address_IPIFF ( sourceIPs [ 2 ] IS NOT NULL , sourceIPs [ 2 ] , 'N/A' )

Pod creation or modification to a Host Path Volume Mount

#
Severity
medium
Source
github.com/panther-labs/panther-analysis

This detection monitors for pod creation with a hostPath volume mount. The attachment to a node's volume can allow for privilege escalation through underlying vulnerabilities or it can open up possibilities for data exfiltration or unauthorized file access. It is very rare to see this being a pod requirement.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: kubernetes_pod_create_or_modify_host_path_vol_mount.py
RuleID: "Kubernetes.PodHostPathVolumeMount"
DisplayName: "Pod creation or modification to a Host Path Volume Mount"
Description: >
  This detection monitors for pod creation with a hostPath volume mount. The attachment to a node's volume can allow for privilege escalation through underlying vulnerabilities or it can open up possibilities for data exfiltration or unauthorized file access. It is very rare to see this being a pod requirement.
Enabled: false
Runbook: >
  .
ScheduledQueries:
  - Pod creation or modification to a Host Path Volume Mount
Severity: Medium

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query Pod creation or modification to a Host Path Volume Mount; its Python module (Detection logic above) shapes the alert rather than filtering.

Response runbook

.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "Anything": "any value"
}

Pod creation or modification to a Host Path Volume Mount

#
Tags
Optional
Source
github.com/panther-labs/panther-analysis

This detection monitors for pod creation with a hostPath volume mount. The attachment to a node's volume can allow for privilege escalation through underlying vulnerabilities or it can open up possibilities for data exfiltration or unauthorized file access. It is very rare to see this being a pod requirement.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Rule specification

AnalysisType: scheduled_query
QueryName: Pod creation or modification to a Host Path Volume Mount
Enabled: false
Tags:
  - Optional
Description: >
  This detection monitors for pod creation with a hostPath volume mount. The attachment to a node's volume can allow for privilege escalation through underlying vulnerabilities or it can open up possibilities for data exfiltration or unauthorized file access. It is very rare to see this being a pod requirement.
SnowflakeQuery: |
  SELECT *,
         IFF(sourceIPs[0] IS NOT null, sourceIPs[0], 'N/A') as X_FORWARDED_FOR_IP,
         IFF(sourceIPs[1] IS NOT null, sourceIPs[1], 'N/A') as X_Real_IP,
         IFF(sourceIPs[2] IS NOT null, sourceIPs[2], 'N/A') as Remote_Address_IP
  FROM panther_logs.public.amazon_eks_audit
  WHERE
  verb IN ('create', 'update', 'patch')
  AND objectRef:resource = 'pods'
  AND requestObject:spec:volumes[0]:hostPath:path ilike ANY ('/var/run/docker.sock','/var/run/crio/crio.sock','/var/lib/kubelet','/var/lib/kubelet/pki','/var/lib/docker/overlay2','/etc/kubernetes','/etc/kubernetes/manifests','/etc/kubernetes/pki','/home/admin')
  AND p_occurs_since('30 minutes')
  --insert allow-list for expected workloads that require a sensitive mount
  LIMIT 10

DatabricksQuery: |
  SELECT *,
         COALESCE(try_element_at(sourceIPs, 1), 'N/A') as X_FORWARDED_FOR_IP,
         COALESCE(try_element_at(sourceIPs, 2), 'N/A') as X_Real_IP,
         COALESCE(try_element_at(sourceIPs, 3), 'N/A') as Remote_Address_IP
  FROM panther_logs.amazon_eks_audit
  WHERE
  verb IN ('create', 'update', 'patch')
  AND objectRef:resource = 'pods'
  AND (
    try_element_at(requestObject.spec.volumes, 1).hostPath.path ILIKE '/var/run/docker.sock'
    OR try_element_at(requestObject.spec.volumes, 1).hostPath.path ILIKE '/var/run/crio/crio.sock'
    OR try_element_at(requestObject.spec.volumes, 1).hostPath.path ILIKE '/var/lib/kubelet'
    OR try_element_at(requestObject.spec.volumes, 1).hostPath.path ILIKE '/var/lib/kubelet/pki'
    OR try_element_at(requestObject.spec.volumes, 1).hostPath.path ILIKE '/var/lib/docker/overlay2'
    OR try_element_at(requestObject.spec.volumes, 1).hostPath.path ILIKE '/etc/kubernetes'
    OR try_element_at(requestObject.spec.volumes, 1).hostPath.path ILIKE '/etc/kubernetes/manifests'
    OR try_element_at(requestObject.spec.volumes, 1).hostPath.path ILIKE '/etc/kubernetes/pki'
    OR try_element_at(requestObject.spec.volumes, 1).hostPath.path ILIKE '/home/admin'
  )
  AND p_occurs_since('30 minutes')
  --insert allow-list for expected workloads that require a sensitive mount
  LIMIT 10
Schedule:
  RateMinutes: 30
  TimeoutMinutes: 2

Stages and Predicates

Stage 1: source

Table
panther_logs.public.amazon_eks_audit

Stage 2: filter

  • verb is one of create, update, patch
  • objectRef:resource is pods
  • any of:
    • requestObject:spec:volumes[0]:hostPath:path is /var/run/docker.sock (case-insensitive)
    • requestObject:spec:volumes[0]:hostPath:path is /var/run/crio/crio.sock (case-insensitive)
    • requestObject:spec:volumes[0]:hostPath:path is /var/lib/kubelet (case-insensitive)
    • requestObject:spec:volumes[0]:hostPath:path is /var/lib/kubelet/pki (case-insensitive)
    • requestObject:spec:volumes[0]:hostPath:path is /var/lib/docker/overlay2 (case-insensitive)
    • requestObject:spec:volumes[0]:hostPath:path is /etc/kubernetes (case-insensitive)
    • requestObject:spec:volumes[0]:hostPath:path is /etc/kubernetes/manifests (case-insensitive)
    • requestObject:spec:volumes[0]:hostPath:path is /etc/kubernetes/pki (case-insensitive)
    • requestObject:spec:volumes[0]:hostPath:path is /home/admin (case-insensitive)
Window
30m

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
objectRef:resourceeq
  • pods
field:"objectRef:resource" kind:eq value:"pods"
requestObject:spec:volumes[0]:hostPath:patheq
  • /etc/kubernetes transforms: nocase
  • /etc/kubernetes/manifests transforms: nocase
  • /etc/kubernetes/pki transforms: nocase
  • /home/admin transforms: nocase
  • /var/lib/docker/overlay2 transforms: nocase
  • /var/lib/kubelet transforms: nocase
  • /var/lib/kubelet/pki transforms: nocase
  • /var/run/crio/crio.sock transforms: nocase
  • /var/run/docker.sock transforms: nocase
field:"requestObject:spec:volumes[0]:hostPath:path" kind:eq
verbin
  • create
  • patch
  • update
field:"verb" kind:in

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
*
X_FORWARDED_FOR_IPIFF ( sourceIPs [ 0 ] IS NOT NULL , sourceIPs [ 0 ] , 'N/A' )
X_Real_IPIFF ( sourceIPs [ 1 ] IS NOT NULL , sourceIPs [ 1 ] , 'N/A' )
Remote_Address_IPIFF ( sourceIPs [ 2 ] IS NOT NULL , sourceIPs [ 2 ] , 'N/A' )

Privileged Pod Created

#
Severity
medium
Source
github.com/panther-labs/panther-analysis

This detection monitors for a privileged pod is created either by default or with permissions to run as root. These particular pods have full access to the hosts namespace and devices, ability to exploit the kernel, have dangerous linux capabilities, and can be a powerful launching point for further attacks.

Telemetry coverage

PlatformRecord / event type
Kubernetescreate-pods: create pods

Rules detecting the same action

These rules filter on the same operation.

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: kubernetes_privileged_pod_created.py
RuleID: "Kubernetes.PrivilegedPodCreated"
DisplayName: "Privileged Pod Created"
Description: >
  This detection monitors for a privileged pod is created either by default or with permissions to run as root. These particular pods have full access to the hosts namespace and devices, ability to exploit the kernel, have dangerous linux capabilities, and can be a powerful launching point for further attacks.
Enabled: false
Runbook: >
  .
ScheduledQueries:
  - Privileged Pod Created
Severity: Medium

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query Privileged Pod Created; its Python module (Detection logic above) shapes the alert rather than filtering.

Response runbook

.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "Anything": "any value"
}

Privileged Pod Created

#
Tags
Optional
Source
github.com/panther-labs/panther-analysis

This detection monitors for a privileged pod is created either by default or with permissions to run as root. These particular pods have full access to the hosts namespace and devices, ability to exploit the kernel, have dangerous linux capabilities, and can be a powerful launching point for further attacks.

Telemetry coverage

PlatformRecord / event type
Kubernetescreate-pods: create pods

Rules detecting the same action

These rules filter on the same operation.

Rule specification

AnalysisType: scheduled_query
QueryName: Privileged Pod Created
Enabled: false
Tags:
  - Optional
Description: >
  This detection monitors for a privileged pod is created either by default or with permissions to run as root. These particular pods have full access to the hosts namespace and devices, ability to exploit the kernel, have dangerous linux capabilities, and can be a powerful launching point for further attacks.
SnowflakeQuery: |
  SELECT *,
         IFF(sourceIPs[0] IS NOT null, sourceIPs[0], 'N/A') as X_FORWARDED_FOR_IP,
         IFF(sourceIPs[1] IS NOT null, sourceIPs[1], 'N/A') as X_Real_IP,
         IFF(sourceIPs[2] IS NOT null, sourceIPs[2], 'N/A') as Remote_Address_IP
  FROM panther_logs.public.amazon_eks_audit
  WHERE
  verb ='create'
  AND objectRef:resource = 'pods'
  AND (requestObject:spec:containers[0]:securityContext:privileged = 'true' OR requestObject:spec:securityContext:runAsNonRoot = 'false')
  AND p_occurs_since('30 minutes')
  --insert allow-list for pods that are expected to run as privileged workloads or as root
  LIMIT 100

DatabricksQuery: |
  SELECT *,
         COALESCE(try_element_at(sourceIPs, 1), 'N/A') as X_FORWARDED_FOR_IP,
         COALESCE(try_element_at(sourceIPs, 2), 'N/A') as X_Real_IP,
         COALESCE(try_element_at(sourceIPs, 3), 'N/A') as Remote_Address_IP
  FROM panther_logs.amazon_eks_audit
  WHERE
  verb ='create'
  AND objectRef:resource = 'pods'
  AND (requestObject:spec:containers[0]:securityContext:privileged = 'true' OR requestObject:spec:securityContext:runAsNonRoot = 'false')
  AND p_occurs_since('30 minutes')
  --insert allow-list for pods that are expected to run as privileged workloads or as root
  LIMIT 100
Schedule:
  RateMinutes: 30
  TimeoutMinutes: 2

Stages and Predicates

Stage 1: source

Table
panther_logs.public.amazon_eks_audit

Stage 2: filter

  • verb is create
  • objectRef:resource is pods
  • any of:
    • requestObject:spec:containers[0]:securityContext:privileged is true
    • requestObject:spec:securityContext:runAsNonRoot is false
Window
30m

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
*
X_FORWARDED_FOR_IPIFF ( sourceIPs [ 0 ] IS NOT NULL , sourceIPs [ 0 ] , 'N/A' )
X_Real_IPIFF ( sourceIPs [ 1 ] IS NOT NULL , sourceIPs [ 1 ] , 'N/A' )
Remote_Address_IPIFF ( sourceIPs [ 2 ] IS NOT NULL , sourceIPs [ 2 ] , 'N/A' )

Secret Enumeration by a User

#
Status
Deprecated
Severity
medium
Source
github.com/panther-labs/panther-analysis

This detection monitors for a large number of secrets requests by a single user. This could potentially indicate secret enumeration, which can potentially enable lateral or vertical movement and unauthorized access to critical resources.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: kubernetes_secret_enumeration.py
RuleID: "Kubernetes.SecretEnumeration"
DisplayName: "Secret Enumeration by a User"
Description: >
  This detection monitors for a large number of secrets requests by a single user. This could potentially indicate secret enumeration, which can potentially enable lateral or vertical movement and unauthorized access to critical resources.
Enabled: false
Status: Deprecated
Runbook: >
  .
ScheduledQueries:
  - Secret Enumeration by a User
Severity: Medium

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query Secret Enumeration by a User; its Python module (Detection logic above) shapes the alert rather than filtering.

Response runbook

.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "Anything": "any value"
}

Secret Enumeration by a User

#
Tags
Optional
Source
github.com/panther-labs/panther-analysis

This detection monitors for a large number of secrets requests by a single user. This could potentially indicate secret enumeration, which can potentially enable lateral or vertical movement and unauthorized access to critical resources.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Rule specification

AnalysisType: scheduled_query
QueryName: Secret Enumeration by a User
Enabled: false
Tags:
  - Optional
Description: >
  This detection monitors for a large number of secrets requests by a single user. This could potentially indicate secret enumeration, which can potentially enable lateral or vertical movement and unauthorized access to critical resources.
SnowflakeQuery: |
  SELECT userAgent,
         user:username as username,
         ARRAY_UNIQUE_AGG(objectRef:name) as secrets_enumerated,
         ARRAY_SIZE(ARRAY_UNIQUE_AGG(objectRef:name)) as total_secrets,
         ARRAY_UNIQUE_AGG(responseStatus:code) as status,
         count(*) as total_request
  FROM panther_logs.public.amazon_eks_audit
  WHERE
  verb IN ('list','get','watch')
  AND objectRef:resource = 'secrets'
  AND p_occurs_since('30 minutes')
  GROUP BY
         userAgent,
         username
  HAVING
   total_secrets >=15 --This is on an environment by envionrment basis and should be tuned to your deployment
  LIMIT 100

DatabricksQuery: |
  SELECT userAgent,
         user:username as username,
         COLLECT_SET(objectRef:name) as secrets_enumerated,
         SIZE(COLLECT_SET(objectRef:name)) as total_secrets,
         COLLECT_SET(responseStatus:code) as status,
         count(*) as total_request
  FROM panther_logs.amazon_eks_audit
  WHERE
  verb IN ('list','get','watch')
  AND objectRef:resource = 'secrets'
  AND p_occurs_since('30 minutes')
  GROUP BY
         userAgent,
         username
  HAVING
   total_secrets >=15 --This is on an environment by envionrment basis and should be tuned to your deployment
  LIMIT 100
Schedule:
  RateMinutes: 30
  TimeoutMinutes: 2

Stages and Predicates

Stage 1: source

Table
panther_logs.public.amazon_eks_audit

Stage 2: filter

  • verb is one of list, get, watch
  • objectRef:resource is secrets
Grouped by
userAgent, username
Window
30m

Stage 3: having

  • total_secrets is at least 15

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
userAgent
usernameuser:username
secrets_enumeratedARRAY_UNIQUE_AGG ( objectRef:name )
total_secretsARRAY_SIZE ( ARRAY_UNIQUE_AGG ( objectRef:name ) )
statusARRAY_UNIQUE_AGG ( responseStatus:code )
total_requestcount ( * )

Unauthenticated Kubernetes API Request

#
Severity
medium
Source
github.com/panther-labs/panther-analysis

This detection monitors for any unauthenticated kubernetes api request. Unauthenticated Requests are performed by the anonymous user and have unfederated access to the cluster.

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: kubernetes_unauthenticated_api_request.py
RuleID: "Kubernetes.UnauthenticatedAPIRequest"
DisplayName: "Unauthenticated Kubernetes API Request"
Description: >
  This detection monitors for any unauthenticated kubernetes api request. Unauthenticated Requests are performed by the anonymous user and have unfederated access to the cluster.
Enabled: false
Runbook: >
  .
ScheduledQueries:
  - Unauthenticated Kubernetes API Request
Severity: Medium

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query Unauthenticated Kubernetes API Request; its Python module (Detection logic above) shapes the alert rather than filtering.

Response runbook

.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "Anything": "any value"
}

Unauthenticated Kubernetes API Request

#
Tags
Optional
Source
github.com/panther-labs/panther-analysis

This detection monitors for any unauthenticated kubernetes api request. Unauthenticated Requests are performed by the anonymous user and have unfederated access to the cluster.

Rule specification

AnalysisType: scheduled_query
QueryName: Unauthenticated Kubernetes API Request
Enabled: false
Tags:
  - Optional
Description: >
  This detection monitors for any unauthenticated kubernetes api request. Unauthenticated Requests are performed by the anonymous user and have unfederated access to the cluster.
SnowflakeQuery: |
  SELECT *,
         IFF(sourceIPs[0] IS NOT null, sourceIPs[0], 'N/A') as X_FORWARDED_FOR_IP,
         IFF(sourceIPs[1] IS NOT null, sourceIPs[1], 'N/A') as X_Real_IP,
         IFF(sourceIPs[2] IS NOT null, sourceIPs[2], 'N/A') as Remote_Address_IP
  FROM panther_logs.public.amazon_eks_audit
  WHERE USER:username = 'system:anonymous'
  --health endpoint in k8s cluster
  AND requestURI NOT ilike '%/readyz%'
  AND requestURI NOT ilike '%/livez%'
  AND requestURI NOT ilike '%/healthz%'
  AND p_occurs_since('30 minutes')
  LIMIT 100

DatabricksQuery: |
  SELECT *,
         COALESCE(try_element_at(sourceIPs, 1), 'N/A') as X_FORWARDED_FOR_IP,
         COALESCE(try_element_at(sourceIPs, 2), 'N/A') as X_Real_IP,
         COALESCE(try_element_at(sourceIPs, 3), 'N/A') as Remote_Address_IP
  FROM panther_logs.amazon_eks_audit
  WHERE USER:username = 'system:anonymous'
  --health endpoint in k8s cluster
  AND requestURI NOT ilike '%/readyz%'
  AND requestURI NOT ilike '%/livez%'
  AND requestURI NOT ilike '%/healthz%'
  AND p_occurs_since('30 minutes')
  LIMIT 100
Schedule:
  RateMinutes: 30
  TimeoutMinutes: 2

Stages and Predicates

Stage 1: source

Table
panther_logs.public.amazon_eks_audit

Stage 2: filter

  • USER:username is system:anonymous
  • requestURI does not match the pattern */readyz* (case-insensitive)
  • requestURI does not match the pattern */livez* (case-insensitive)
  • requestURI does not match the pattern */healthz* (case-insensitive)
Window
30m

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
*
X_FORWARDED_FOR_IPIFF ( sourceIPs [ 0 ] IS NOT NULL , sourceIPs [ 0 ] , 'N/A' )
X_Real_IPIFF ( sourceIPs [ 1 ] IS NOT NULL , sourceIPs [ 1 ] , 'N/A' )
Remote_Address_IPIFF ( sourceIPs [ 2 ] IS NOT NULL , sourceIPs [ 2 ] , 'N/A' )

Unauthorized Kubernetes Pod Execution

#
Severity
medium
Source
github.com/panther-labs/panther-analysis

This detection monitors for any pod execution in a kubernetes cluster. Pod execution should never be done in a production cluster, and can indicate a user performing unauthorized actions.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Detection logic

def rule(_):
    return True

Rule specification

AnalysisType: scheduled_rule
Filename: kubernetes_unauthorized_pod_execution.py
RuleID: "Kubernetes.UnauthorizedPodExecution"
DisplayName: "Unauthorized Kubernetes Pod Execution"
Description: >
  This detection monitors for any pod execution in a kubernetes cluster. Pod execution should never be done in a production cluster, and can indicate a user performing unauthorized actions.
Enabled: false
Runbook: >
  .
ScheduledQueries:
  - Unauthorized Kubernetes Pod Execution
Severity: Medium

Stages and Predicates

Rule logic

This rule alerts on rows returned by its scheduled query Unauthorized Kubernetes Pod Execution; its Python module (Detection logic above) shapes the alert rather than filtering.

Response runbook

.

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "Anything": "any value"
}

Unauthorized Kubernetes Pod Execution

#
Tags
Optional
Source
github.com/panther-labs/panther-analysis

This detection monitors for any pod execution in a kubernetes cluster. Pod execution should never be done in a production cluster, and can indicate a user performing unauthorized actions.

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Rule specification

AnalysisType: scheduled_query
QueryName: Unauthorized Kubernetes Pod Execution
Enabled: false
Tags:
  - Optional
Description: >
  This detection monitors for any pod execution in a kubernetes cluster. Pod execution should never be done in a production cluster, and can indicate a user performing unauthorized actions.
SnowflakeQuery: |
  SELECT *,
         split(split(impersonatedUser:username,'remote-')[1],'-')[0] as src_user,
         SPLIT(requestURI,'exec?')[1] as command_executed,
         IFF(sourceIPs[0] IS NOT null, sourceIPs[0], 'N/A') as X_FORWARDED_FOR_IP,
         IFF(sourceIPs[1] IS NOT null, sourceIPs[1], 'N/A') as X_Real_IP,
         IFF(sourceIPs[2] IS NOT null, sourceIPs[2], 'N/A') as Remote_Address_IP
  FROM panther_logs.public.amazon_eks_audit
  WHERE
  objectRef:resource = 'pods'
  AND objectRef:subresource = 'exec'
  AND p_occurs_since('30 minutes')
  --insert allow-list here for example namespaces where exec is expected for debugging or log gathering
  LIMIT 100

DatabricksQuery: |
  SELECT *,
         split(split(impersonatedUser:username,'remote-')[1],'-')[0] as src_user,
         SPLIT(requestURI,'exec?')[1] as command_executed,
         COALESCE(try_element_at(sourceIPs, 1), 'N/A') as X_FORWARDED_FOR_IP,
         COALESCE(try_element_at(sourceIPs, 2), 'N/A') as X_Real_IP,
         COALESCE(try_element_at(sourceIPs, 3), 'N/A') as Remote_Address_IP
  FROM panther_logs.amazon_eks_audit
  WHERE
  objectRef:resource = 'pods'
  AND objectRef:subresource = 'exec'
  AND p_occurs_since('30 minutes')
  --insert allow-list here for example namespaces where exec is expected for debugging or log gathering
  LIMIT 100
Schedule:
  RateMinutes: 30
  TimeoutMinutes: 2

Stages and Predicates

Stage 1: source

Table
panther_logs.public.amazon_eks_audit

Stage 2: filter

  • objectRef:resource is pods
  • objectRef:subresource is exec
Window
30m

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
*
src_usersplit ( split ( impersonatedUser:username , 'remote-' ) [ 1 ] , '-' ) [ 0 ]
command_executedSPLIT ( requestURI , 'exec?' ) [ 1 ]
X_FORWARDED_FOR_IPIFF ( sourceIPs [ 0 ] IS NOT NULL , sourceIPs [ 0 ] , 'N/A' )
X_Real_IPIFF ( sourceIPs [ 1 ] IS NOT NULL , sourceIPs [ 1 ] , 'N/A' )
Remote_Address_IPIFF ( sourceIPs [ 2 ] IS NOT NULL , sourceIPs [ 2 ] , 'N/A' )