Query Details

Kubernetes Suspicious Probing And Subsequent Escalation Activity

Query

let Lookback = 1d;
let ProbeBin = 30m;
let FollowUp = 1h;
let Audit = CloudAuditEvents
| where Timestamp > ago(Lookback)
| where DataSource =~ "Kubernetes Audit"
| extend User = tostring(RawEventData.user.username),
         Verb = tolower(tostring(RawEventData.verb)),
         Resource = tolower(tostring(RawEventData.objectRef.resource)),
         SubResource = tolower(tostring(RawEventData.objectRef.subresource)),
         Namespace = tostring(RawEventData.objectRef.namespace),
         Code = toint(RawEventData.responseStatus.code),
         SourceIp = tostring(RawEventData.sourceIPs[0])
| extend Action = strcat(Verb, " ", Resource, iff(isnotempty(SubResource), strcat("/", SubResource), ""))
| where not(User startswith "system:") or User startswith "system:serviceaccount:"
| where not(User startswith "system:serviceaccount:kube-system:");
let Probing = Audit
| extend IsSelfReview = Resource in ("selfsubjectrulesreviews", "selfsubjectaccessreviews")
| where IsSelfReview or Code == 403
| summarize SelfReviews = countif(IsSelfReview),
            Forbidden = countif(Code == 403),
            DeniedActions = make_set_if(Action, Code == 403, 50),
            ProbeStart = min(Timestamp), ProbeEnd = max(Timestamp)
    by User, AzureResourceId, SourceIp, bin(Timestamp, ProbeBin)
| where (SelfReviews > 0 and Forbidden > 0) or array_length(DeniedActions) >= 5;
let Escalation = Audit
| where Code between (200 .. 299)
| extend ImpersonatedUser = tostring(RawEventData.impersonatedUser.username)
| where (Resource == "secrets" and Verb in ("get", "list", "watch"))
     or (Resource == "pods" and SubResource in ("exec", "attach"))
     or (Resource == "pods" and Verb == "create" and isempty(SubResource))
     or (Resource in ("rolebindings", "clusterrolebindings", "roles", "clusterroles") and Verb in ("create", "update", "patch"))
     or (Resource == "serviceaccounts" and SubResource == "token")
     or (Resource == "nodes" and SubResource == "proxy")
     or isnotempty(ImpersonatedUser)
| project EscAt = Timestamp, User, AzureResourceId, Action, Namespace, ImpersonatedUser;
Probing
| join kind=inner Escalation on User, AzureResourceId
| where EscAt between (ProbeStart .. (ProbeEnd + FollowUp))
| summarize FirstProbe = min(ProbeStart), FirstEscalation = min(EscAt),
            SelfReviews = max(SelfReviews), Forbidden = max(Forbidden),
            DeniedActions = take_any(DeniedActions),
            SuccessfulActions = make_set(Action, 30),
            Namespaces = make_set(Namespace, 20),
            ImpersonatedUsers = make_set_if(ImpersonatedUser, isnotempty(ImpersonatedUser))
    by User, AzureResourceId, SourceIp

About this query

Kubernetes Suspicious Probing and Subsequent Escalation Activity

Query Information

MITRE ATT&CK Technique(s)

Technique IDTitleLink
T1613Container and Resource Discoveryhttps://attack.mitre.org/techniques/T1613
T1078Valid Accountshttps://attack.mitre.org/techniques/T1078

Description

This rule detects a multi-stage attack pattern in Kubernetes environments where an entity first performs suspicious probing activities (e.g., numerous self-subject rules/access reviews or repeated 403 Forbidden errors) followed by privileged or sensitive API actions within a short timeframe. The logic correlates reconnaissance attempts against the API server with subsequent successful escalation-related operations such as accessing secrets, pod execution, or role/clusterrole modifications.

Author <Optional>

Defender XDR

Explanation

This query is designed to detect suspicious activity in Kubernetes environments that may indicate a multi-stage attack. Here's a simplified breakdown of what the query does:

  1. Timeframe and Data Source: It looks at Kubernetes audit logs from the past day (Lookback = 1d).

  2. Probing Activity:

    • It identifies suspicious probing activities by checking for:
      • Self-subject rules or access reviews.
      • Repeated 403 Forbidden errors.
    • It groups these activities into 30-minute intervals (ProbeBin = 30m).
    • It flags users who have both self-reviews and forbidden actions or have a significant number of denied actions.
  3. Escalation Activity:

    • It looks for successful actions (HTTP status codes 200-299) that indicate privilege escalation, such as:
      • Accessing secrets.
      • Executing or attaching to pods.
      • Creating or modifying roles and cluster roles.
      • Impersonating other users.
    • These actions are considered within an hour (FollowUp = 1h) after the probing activity.
  4. Correlation:

    • It correlates the probing activities with subsequent escalation activities by matching the user and resource ID.
    • It checks if the escalation happened within the timeframe of the probing activity plus the follow-up period.
  5. Summary:

    • The query summarizes the findings by user, resource ID, and source IP.
    • It provides details such as the first probe and escalation times, counts of self-reviews and forbidden actions, denied and successful actions, namespaces involved, and any impersonated users.

Overall, this query helps identify potential security threats by detecting patterns of reconnaissance followed by privilege escalation in Kubernetes environments.