HexBrain

Kubernetes · Report #1036886

Kubelet follows symlinks as root in /var/log from the /logs server endpoint

Informativestatus
mediumseverity
1upvotes
1 Apr 2021disclosed

How it was found

Summary:

Privilege escalation from a pod, to root read permissions on the entire filesytem of the node, by creating symlinks inside /var/log. The kubelet is simply serving a fileserver at /var/log:

kubernetes\pkg\kubelet\kubelet.go:1371

if kl.logServer == nil {
		kl.logServer = http.StripPrefix("/logs/", http.FileServer(http.Dir("/var/log/")))
	}

The kubelet naturally runs as root on the node, so this basically gives the ability for pods with write permissions to /var/log directory a directory traversal as a root user on the host (potentially taking over the whole cluster by getting secret keys) An easy fix is checking the symlink destination, to figure out whether it is inside /var/lib/docker or other whitelisted paths to not break to mechanism of logs correlations

A while back, I discovered this bug, when you didn't had the Bug Bounty program. I Published the following blog: https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts Describing the vulnerability.

(it requires RBAC permissions to read logs, or a kubelet configured with AlwaysAllow. and a mount point to any child directory inside /var/log) I researched some log collectors projects in github, seems like alot of them are freely using this mount point. As a user I would not imagine those projects can potentially take clusters.

Kubernetes Version:

All versions

Component Version:

The kubelet

Steps To Reproduce:

  1. create a pod with a mount path to /var/log
  2. create a symlink in the mount point: /var/log/rootfs_symlink -> /
  3. curl from within the pod: https://<ip_of_node>:10250/logs/rootfs_symlink/etc/shadow

Supporting Material/References:

https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts https://github.com/danielsagi/kube-pod-escape

Impact

Root read permissions on the entire filesystem of the node

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original