Query Details

Suspicious Kubernetes Admission Controller Webhook Creation

Query

let Lookback = 1d;
let AllowedWebhookCreators = dynamic([
    "system:serviceaccount:flux-system:kustomize-controller",
    "system:serviceaccount:argocd:argocd-application-controller"]);
let KnownWebhookNamespaces = dynamic(["gatekeeper-system", "kyverno", "cert-manager", "kube-system"]);
let Audit = CloudAuditEvents
| where Timestamp > ago(Lookback)
| where DataSource =~ "Kubernetes Audit"
| extend Verb = tolower(tostring(RawEventData.verb)),
         Resource = tolower(tostring(RawEventData.objectRef.resource)),
         Actor = tostring(RawEventData.user.username),
         Code = toint(RawEventData.responseStatus.code);
let NewWebhooks = Audit
| where Resource in ("mutatingwebhookconfigurations", "validatingwebhookconfigurations")
| where Verb == "create" and Code between (200 .. 299)
| where Actor !in (AllowedWebhookCreators)
| extend Req = RawEventData.requestObject, SourceIp = tostring(RawEventData.sourceIPs[0])
| extend Config = coalesce(tostring(RawEventData.objectRef.name), tostring(Req.metadata.name))
| mv-expand WH = Req.webhooks
| extend WebhookName = tostring(WH.name),
         ExternalUrl = tostring(WH.clientConfig.url),
         SvcNamespace = tostring(WH.clientConfig.service.namespace),
         SvcName = tostring(WH.clientConfig.service.name),
         FailurePolicy = tostring(WH.failurePolicy),
         NsSelectorEmpty = isnull(WH.namespaceSelector) or array_length(bag_keys(WH.namespaceSelector)) == 0,
         Rules = WH.rules
| mv-apply R = Rules on (
    mv-expand Res = R.resources, Op = R.operations
    | summarize Resources = make_set(tostring(Res)), Operations = make_set(tostring(Op)))
| extend TargetsPods = set_has_element(Resources, "pods") or set_has_element(Resources, "*"),
         TargetsSecrets = set_has_element(Resources, "secrets") or set_has_element(Resources, "*")
| extend Score = iff(isnotempty(ExternalUrl), 4, 0)
               + iff(isnotempty(SvcNamespace) and SvcNamespace !in (KnownWebhookNamespaces), 2, 0)
               + iff(Resource == "mutatingwebhookconfigurations" and TargetsPods, 2, 0)
               + iff(TargetsSecrets, 3, 0)
               + iff(FailurePolicy =~ "Ignore", 1, 0)
               + iff(NsSelectorEmpty, 1, 0)
| project CreatedAt = Timestamp, AzureResourceId, WebhookType = Resource, Config, WebhookName, Actor, SourceIp,
          ExternalUrl, SvcNamespace, SvcName, FailurePolicy, NsSelectorEmpty, Resources, Operations, Score;
let Mutations = Audit
| where Resource == "pods" and Verb == "create"
| extend Ann = RawEventData.annotations, PodNamespace = tostring(RawEventData.objectRef.namespace)
| where tostring(Ann) has "mutation.webhook.admission.k8s.io"
| mv-apply AnnKey = bag_keys(Ann) to typeof(string) on (
    where AnnKey startswith "mutation.webhook.admission.k8s.io"
    | extend AnnVal = parse_json(tostring(Ann[AnnKey]))
    | where tobool(AnnVal.mutated)
    | project Config = tostring(AnnVal.configuration))
| summarize MutatedPods = count(), MutatedNamespaces = make_set(PodNamespace, 20), FirstMutation = min(Timestamp)
    by AzureResourceId, Config;
NewWebhooks
| join kind=leftouter Mutations on AzureResourceId, Config
| extend MutatedPods = coalesce(MutatedPods, 0)
| extend Score = Score + iff(MutatedPods > 0 and FirstMutation >= CreatedAt, 2, 0)
| where Score >= 3
| extend Severity = iff(Score >= 6, "High", "Medium")
| project-away AzureResourceId1, Config1
| order by Score desc

About this query

Suspicious Kubernetes Admission Controller Webhook Creation*

Query Information

MITRE ATT&CK Technique(s)

Technique IDTitleLink
T1611Escape to Hosthttps://attack.mitre.org/techniques/T1611
T1610Deploy to Containerhttps://attack.mitre.org/techniques/T1610

Description

This rule detects the creation of new Mutating or Validating Webhook Configurations in a Kubernetes cluster that bypass established trusted actors. It scores these creations based on risk factors such as targeting sensitive resources (pods, secrets), absence of namespace selectors, use of 'Ignore' failure policies, and external URLs. The rule further correlates these webhooks with evidence of successful object mutations to identify potential malicious interceptors or privilege escalation attempts.

Author <Optional>

Defender XDR

Explanation

This query is designed to detect potentially suspicious activities related to the creation of Kubernetes Admission Controller Webhooks, which are used to intercept and modify requests to the Kubernetes API. Here's a simplified breakdown of what the query does:

  1. Lookback Period: It examines events from the past day (1d).

  2. Allowed Creators: It defines a list of trusted service accounts (AllowedWebhookCreators) that are permitted to create webhooks without raising suspicion.

  3. Known Namespaces: It specifies known namespaces (KnownWebhookNamespaces) where webhook services are expected to be found.

  4. Audit Log Filtering: It filters Kubernetes audit logs to find events where new mutating or validating webhook configurations are created. It excludes actions by trusted service accounts and focuses on successful creation events (HTTP status codes 200-299).

  5. Webhook Analysis: For each new webhook, it extracts details such as:

    • External URLs used by the webhook.
    • The namespace and name of the service associated with the webhook.
    • Failure policies and whether namespace selectors are empty.
    • The resources and operations targeted by the webhook (e.g., pods, secrets).
  6. Risk Scoring: It calculates a risk score for each webhook based on several factors:

    • Use of external URLs.
    • Targeting sensitive resources like pods or secrets.
    • Use of "Ignore" failure policies.
    • Absence of namespace selectors.
  7. Mutation Detection: It checks for evidence of successful mutations (changes) to Kubernetes objects, specifically pods, which might indicate that the webhook is actively intercepting and modifying requests.

  8. Score Adjustment: If mutations are detected and occurred after the webhook was created, the score is increased.

  9. Severity Classification: Webhooks with a score of 3 or higher are flagged as suspicious, with scores of 6 or more classified as "High" severity and others as "Medium."

  10. Output: The query outputs details of suspicious webhooks, ordered by their risk score, to help identify potential security threats such as privilege escalation or unauthorized access attempts.

In essence, this query helps security teams monitor and identify potentially malicious webhook activities in a Kubernetes environment, focusing on those that deviate from normal, trusted operations.