Get the latest, first
Kubelet vulnerabilities on Windows nodes: CVE-2023-3676, CVE-2023-3955 and CVE-2023-3893

Kubelet vulnerabilities on Windows nodes: CVE-2023-3676, CVE-2023-3955 and CVE-2023-3893

Aug 23, 2023

Ben Hirschberg
CTO & Co-founder

Recently, the Kubernetes Security Response Committee disclosed three interrelated vulnerabilities affecting the Windows versions of Kubelet and the Kubernetes CSI proxy. These vulnerabilities pose a significant risk, allowing even users with limited permissions to escalate their privileges to administrator level on affected nodes.

Kubelet privilege escalation via Pod spec command injection – CVE-2023-3676

A malicious actor could craft a special workload specification (Pod spec) with host path strings that contain power shell commands. Due to lack of input sanitization, the Kubelet would pass this crafted path string to the command executor as an argument but it would execute parts of the string as separate commands. These commands would run with the same administrative privileges as Kubelet has. This vulnerability can be exploited by a user capable of creating pods on Windows nodes.

We can take a look at the following code snippets from the Kubernetes source code, and see that the powershell command will execute without sanitization:

func isLinkPath(path string) (bool, error) {
cmd := fmt.Sprintf("(Get-Item -LiteralPath %q).LinkType", path)
output, err := exec.Command("powershell", "/c", cmd).CombinedOutput()
...
}

And the fix:

func isLinkPath(path string) (bool, error) {
cmd := exec.Command("powershell", "/c", "$ErrorActionPreference = 'Stop'; (Get-Item -Force -LiteralPath $env:linkpath).LinkType")
    cmd.Env = append(os.Environ(), fmt.Sprintf("linkpath=%s", path))
    klog.V(8).Infof("Executing command: %q", cmd.String())
output, err := cmd.CombinedOutput()
...
}

We can see the new way of passing the arguments using environment variables, which means the subexpression won’t be evaluated.

Bulletin: CVE-2023-3676

Kubelet privilege escalation – CVE-2023-3955

Another alarming flaw within Kubelet for Windows, this vulnerability shares the same risk profile as the previous one. It grants users who can create pods, with the ability to execute code at the same permission level as the Kubelet agent, privileged permissions.

As the above code snippets shows, we can see it here as well, the user can control an argument that will later be passed without sanitization to the powershell command:

func WriteVolumeCache(deviceMountPath string, exec utilexec.Interface) error {
// If runtime os is windows, execute Write-VolumeCache powershell command on the disk
if runtime.GOOS == "windows" {
cmd := fmt.Sprintf("Get-Volume -FilePath %s | Write-Volumecache", deviceMountPath)
output, err := exec.Command("powershell", "/c", cmd).CombinedOutput()
klog.Infof("command (%q) execeuted: %v, output: %q", cmd, err, string(output))
... 
}
...
}

And the fix:

func WriteVolumeCache(deviceMountPath string, exec utilexec.Interface) error {
// If runtime os is windows, execute Write-VolumeCache powershell command on the disk
if runtime.GOOS == "windows" {
cmdString := "Get-Volume -FilePath $env:mountpath | Write-Volumecache"
cmd := exec.Command("powershell", "/c", cmdString)
env := append(os.Environ(), fmt.Sprintf("mountpath=%s", deviceMountPath))
cmd.SetEnv(env)
klog.V(8).Infof("Executing command: %q", cmdString)
output, err := cmd.CombinedOutput()
klog.Infof("command (%q) execeuted: %v, output: %q", cmdString, err, string(output))
...
}
...
}

As we can see again, the same fix of using environment variables for the arguments passing.

Bulletin: CVE-2023-3955

Kubernetes CSI proxy privilege escalation – CVE-2023-3893

Though this vulnerability is associated with the Kubernetes CSI proxy, its impact aligns with the previous two. Users who can create pods on Windows nodes can exploit this flaw to elevate their privileges, effectively obtaining administrator access on those nodes.

Taking a look again at the Kubernetes agent source code we can see the same issue:

func getVolumeSize(volumeID string) (int64, error) {
cmd := fmt.Sprintf("(Get-Volume -UniqueId \"%s\" | Get-partition).Size", volumeID)
out, err := utils.RunPowershellCmd(cmd)
...
}

And the fix:

func getVolumeSize(volumeID string) (int64, error) {
cmd := `(Get-Volume -UniqueId "$Env:volumeID" | Get-partition).Size`
cmdEnv := fmt.Sprintf("volumeID=%s", volumeID)
out, err := utils.RunPowershellCmd(cmd, cmdEnv)
...
}

Bulletin: CVE-2023-3893

Root cause

A recurring theme among these vulnerabilities is a lapse in input sanitization in the Windows-specific porting of the Kubelet. Specifically, when handling Pod definitions, the software fails to adequately validate or sanitize user inputs. This oversight enables malicious users to craft pods with environment variables and host paths that, when processed, lead to undesired behaviors, such as privilege escalation.

Am I affected?

Run this command to see if you have Windows nodes:

kubectl get nodes -l kubernetes.io/os=windows

The affected Kubelet versions for CVE-2023-3676 & CVE-2023-3955 are:

  • kubelet <= v1.28.0
  • kubelet <= v1.27.4
  • kubelet <= v1.26.7
  • kubelet <= v1.25.12
  • kubelet <= v1.24.16

And for CVE-2023-3893 are:

  • kubernetes-csi-proxy <= v2.0.0-alpha.0
  • kubernetes-csi-proxy <= v1.1.2

Recommendations

Organizations relying on Kubernetes, especially those utilizing Windows nodes, should take these vulnerabilities seriously.

  1. Patch Immediately: Ensure you are running the latest version of Kubernetes, which includes fixes for these vulnerabilities. 
  2. Restrict Access: Limit who can create or modify pods in your cluster. Implement strict Role-Based Access Control (RBAC) policies. 
  3. Auditing & Monitoring: Keep a keen eye on your logs. Unusual or unauthorized pod creation activities should be flagged and investigated especially if you see Pod create events with embedded powershell commands and/or Config maps and secrets that contain embedded powershell commands and are mounted into pods. All of those are also a strong indication of exploitation.

Conclusion

Security is a journey, not a destination. Even the most robust systems can exhibit vulnerabilities. By staying informed, patching regularly, and adhering to security best practices, administrators can keep their Kubernetes deployments safe and resilient. 

In order to do that you can always use ARMO Platform which offers misconfiguration and vulnerability management, compliance and governance, and RBAC visualization — everything organizations need to secure their Kubernetes deployments effectively on any public or private cloud. Give ARMO a try today. Protect your Kubernetes workloads with confidence and ensure a strong security posture across your clouds.

Actionable, contextual, end-to-end <br/> {<mark>Kubernetes-native security</mark>}

From code to cluster, helm to node, we’ve got your Kubernetes covered:

Cut the CVE noise by significantly reducing CVE-related work by over 90%

Automatic Kubernetes compliance for CIS, NSA, Mitre, SOC2, PCI, and more

Manage Kubernetes role-based-access control (RBAC) visually

slack_logos

Continue to Slack

Get the information you need directly from our experts!

new-messageContinue as a guest