Query Details

Unusual Kubelet Node Authentication Activity

Query

let Lookback = 7d;
let DetectWindow = 1h;
let NodeAudit = CloudAuditEvents
| where Timestamp > ago(Lookback)
| where DataSource =~ "Kubernetes Audit"
| extend User = tostring(RawEventData.user.username)
| where User startswith "system:node:"
| extend SourceIp = tostring(RawEventData.sourceIPs[0]),
         UserAgent = tostring(RawEventData.userAgent),
         UAFamily = tolower(tostring(split(tostring(RawEventData.userAgent), "/")[0])),
         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);
let Baseline = NodeAudit
| where Timestamp < ago(DetectWindow)
| summarize KnownIps = make_set(SourceIp, 50), KnownUA = make_set(UAFamily, 20) by User, AzureResourceId;
NodeAudit
| where Timestamp >= ago(DetectWindow)
| join kind=leftouter Baseline on User, AzureResourceId
| extend HasBaseline = array_length(KnownIps) > 0
| extend NewIp = HasBaseline and not(set_has_element(KnownIps, SourceIp)),
         NewUA = (HasBaseline and not(set_has_element(KnownUA, UAFamily))) or UAFamily != "kubelet",
         SensitiveAttempt = (Resource == "secrets" and Verb in ("list", "watch"))
                         or (Resource == "pods" and SubResource in ("exec", "attach", "portforward"))
                         or (Resource in ("rolebindings", "clusterrolebindings", "serviceaccounts"))
| summarize FirstSeen = min(Timestamp), LastSeen = max(Timestamp), Requests = count(),
            NewIp = max(toint(NewIp)), NewUA = max(toint(NewUA)),
            SensitiveAttempts = countif(SensitiveAttempt), Forbidden = countif(Code == 403),
            DistinctNamespaces = dcount(Namespace),
            Actions = make_set(strcat(Verb, " ", Resource, iff(isnotempty(SubResource), strcat("/", SubResource), "")), 30),
            UserAgents = make_set(UserAgent, 5)
    by User, SourceIp, AzureResourceId
| extend Score = NewIp * 2 + NewUA * 3 + iff(SensitiveAttempts > 0, 2, 0) + iff(Forbidden >= 3, 2, 0)
| where Score >= 3
| order by Score desc

About this query

Unusual Kubelet Node Authentication Activity

Query Information

MITRE ATT&CK Technique(s)

Technique IDTitleLink
T1609Container Administration Commandhttps://attack.mitre.org/techniques/T1609
T1613Container Ressource Discoveryhttps://attack.mitre.org/techniques/T1613

Description

This rule detects anomalous actions performed by accounts identifying as 'system:node', which corresponds to Kubelet service accounts. It monitors for unusual source IPs, non-standard User-Agents, and sensitive API verb interactions (such as 'list' secrets or 'exec' into pods) which deviate from established baselines for a given node.

Author <Optional>

Defender XDR

Explanation

This query is designed to detect unusual activities related to Kubelet node authentication in a Kubernetes environment. Here's a simplified breakdown of what it does:

  1. Time Frame: It looks at Kubernetes audit events from the past 7 days, with a focus on the last hour for detecting anomalies.

  2. Focus on Kubelet Accounts: It specifically monitors actions performed by accounts that start with "system:node:", which are typically associated with Kubelet service accounts.

  3. Anomaly Detection: The query identifies unusual behavior by checking:

    • Source IPs: Whether the IP address from which the request originated is new or unusual for the node.
    • User Agents: If the user agent string is different from the usual "kubelet" or is otherwise unexpected.
    • Sensitive Actions: If the account is attempting sensitive operations like listing secrets, executing commands in pods, or interacting with role bindings and service accounts.
  4. Baseline Comparison: It compares current activity against a baseline of known IPs and user agents to determine if the behavior is unusual.

  5. Scoring System: Each detected anomaly is assigned a score based on:

    • New IP usage
    • New or unusual user agents
    • Attempts to perform sensitive actions
    • Multiple forbidden actions (HTTP 403 errors)
  6. Alerting: If the score for an account's activity is 3 or higher, it is flagged as suspicious and listed in descending order of severity.

This query helps security teams identify potential security incidents involving Kubelet nodes by highlighting deviations from normal behavior patterns.