Detection rules › Panther

Kubernetes API Activity from Tor Exit Node

Severity
medium
Log types
Amazon.EKS.Audit, Azure.MonitorActivity, GCP.AuditLog
Tags
Kubernetes, Security Control, Command and Control, Encrypted Channel, Unified Detection
Reference
https://medium.com/snowflake/from-logs-to-detection-using-snowflake-and-panther-to-detect-k8s-threats-d72f70a504d7
Source
github.com/panther-labs/panther-analysis

This detection monitors for Kubernetes API requests originating from known Indicators of Compromise, specifically Tor exit nodes. Tor usage may indicate attempts to hide the true source of malicious activity or unauthorized access attempts. This detection works across AWS EKS, Azure AKS, and GCP GKE clusters.

MITRE ATT&CK coverage

Rules detecting the same action

Other rules on this platform that filter on the same API call or operation.

Rule body yaml

AnalysisType: rule
RuleID: "Kubernetes.API.IOC.Activity"
DisplayName: "Kubernetes API Activity from Tor Exit Node"
Enabled: true
Filename: k8s_ioc_activity.py
LogTypes:
  - Amazon.EKS.Audit
  - Azure.MonitorActivity
  - GCP.AuditLog
Tags:
  - Kubernetes
  - Security Control
  - Command and Control
  - Encrypted Channel
  - Unified Detection
Severity: Medium
Description: >
  This detection monitors for Kubernetes API requests originating from known Indicators
  of Compromise, specifically Tor exit nodes. Tor usage may indicate attempts to hide
  the true source of malicious activity or unauthorized access attempts. This detection
  works across AWS EKS, Azure AKS, and GCP GKE clusters.
Runbook: |
  1. Find all API operations performed by username through the Tor exit node IP in the 6 hours before and after the alert
  2. Compare the operations and resources accessed against normal baseline activity for this user in the past 30 days to identify anomalous behavior
  3. Check if the Tor exit node IP has accessed other clusters or sensitive resources in the past 24 hours to assess campaign scope
Reference: https://medium.com/snowflake/from-logs-to-detection-using-snowflake-and-panther-to-detect-k8s-threats-d72f70a504d7
Reports:
  MITRE ATT&CK:
    - TA0011:T1573.002 # Command and Control: Encrypted Channel - Asymmetric Cryptography
DedupPeriodMinutes: 60
SummaryAttributes:
  - username
  - p_any_ip_addresses
  - p_source_label
Tests:
  - Name: EKS Activity from Tor Exit Node
    ExpectedResult: true
    Log:
      {
        "kind": "Event",
        "apiVersion": "audit.k8s.io/v1",
        "auditID": "abc-123",
        "verb": "list",
        "user": {"username": "admin@example.com"},
        "sourceIPs": ["1.2.3.4"],
        "userAgent": "kubectl/v1.28.0",
        "objectRef": {
          "resource": "pods",
          "namespace": "default",
          "apiVersion": "v1"
        },
        "responseStatus": {"code": 200},
        "requestURI": "/api/v1/namespaces/default/pods",
        "p_log_type": "Amazon.EKS.Audit",
        "p_source_label": "eks-cluster",
        "p_enrichment": {
          "tor_exit_nodes": ["1.2.3.4"]
        }
      }
  - Name: AKS Activity from Tor Exit Node
    ExpectedResult: true
    Log:
      {
        "p_log_type": "Azure.MonitorActivity",
        "category": "kube-audit",
        "operationName": "Microsoft.ContainerService/managedClusters/diagnosticLogs/Read",
        "properties": {
          "log": "{\"kind\":\"Event\",\"apiVersion\":\"audit.k8s.io/v1\",\"verb\":\"get\",\"user\":{\"username\":\"admin@example.com\"},\"sourceIPs\":[\"5.5.5.5\"],\"objectRef\":{\"resource\":\"pods\",\"namespace\":\"default\"},\"responseStatus\":{\"code\":200}}"
        },
        "p_source_label": "aks-cluster",
        "p_enrichment": {
          "tor_exit_nodes": ["5.5.5.5"]
        }
      }
  - Name: GCP GKE Activity from Tor Exit Node
    ExpectedResult: true
    Log:
      {
        "operation": {"producer": "k8s.io"},
        "protoPayload": {
          "authenticationInfo": {"principalEmail": "user@company.com"},
          "authorizationInfo": [{
            "granted": true,
            "permission": "io.k8s.core.v1.pods.list",
            "resource": "core/v1/namespaces/default/pods"
          }],
          "methodName": "io.k8s.core.v1.pods.list",
          "requestMetadata": {
            "callerIP": "8.8.8.8",
            "callerSuppliedUserAgent": "kubectl/v1.27.0"
          },
          "resourceName": "core/v1/namespaces/default/pods",
          "serviceName": "k8s.io"
        },
        "resource": {
          "type": "k8s_cluster",
          "labels": {"project_id": "test-project"}
        },
        "p_log_type": "GCP.AuditLog",
        "p_source_label": "gke-cluster",
        "p_enrichment": {
          "tor_exit_nodes": ["8.8.8.8"]
        }
      }
  - Name: Non-K8s GCP Activity (Excluded)
    ExpectedResult: false
    Log:
      {
        "operation": {"producer": "compute.googleapis.com"},
        "protoPayload": {
          "authenticationInfo": {"principalEmail": "user@company.com"},
          "methodName": "compute.instances.list",
          "serviceName": "compute.googleapis.com"
        },
        "p_log_type": "GCP.AuditLog",
        "p_enrichment": {
          "tor_exit_nodes": ["8.8.8.8"]
        }
      }
  - Name: K8s Activity Without Tor Enrichment
    ExpectedResult: false
    Log:
      {
        "kind": "Event",
        "verb": "list",
        "user": {"username": "admin@example.com"},
        "sourceIPs": ["192.168.1.1"],
        "objectRef": {"resource": "pods"},
        "p_log_type": "Amazon.EKS.Audit",
        "p_source_label": "eks-cluster"
      }
  - Name: Non-K8s Azure Activity (Excluded)
    ExpectedResult: false
    Log:
      {
        "p_log_type": "Azure.MonitorActivity",
        "category": "Administrative",
        "operationName": "Microsoft.Compute/virtualMachines/write",
        "p_enrichment": {
          "tor_exit_nodes": ["1.2.3.4"]
        }
      }

Detection logic

Condition

p_log_type in ["Amazon.EKS.Audit", "Azure.MonitorActivity", "GCP.AuditLog"]
(p_log_type eq "GCP.AuditLog" and protoPayload.serviceName eq "k8s.io") or (p_log_type eq "Azure.MonitorActivity" and category in ["kube-audit", "kube-audit-admin"])
p_enrichment.tor_exit_nodes is_not_null

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
categoryin
  • kube-audit
  • kube-audit-admin
p_enrichment.tor_exit_nodesis_not_null
  • (no value, null check)
p_log_typeeq
  • Azure.MonitorActivity
  • GCP.AuditLog
p_log_typein
  • Amazon.EKS.Audit
  • Azure.MonitorActivity
  • GCP.AuditLog
protoPayload.serviceNameeq
  • k8s.io

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
username
sourceIPs
userAgent
namespace
verb
resource
requestURI
responseStatus
clusterp_source_label