CVE-2017-1002101:突破隔离访问宿主机文件系统
前置知识
什么是kubernetes?
kubernetes,简称K8s,是用8代替名字中间的8个字符“ubernete”而成的缩写。
Kubernetes是开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便对应用请求进行负载均衡。
在Kubernetes中,我们可以创建多个容器,每个容器里面运行一个应用实例,然后通过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需要运维人员去进行复杂的手工配置和处理。
kubernetes的工作原理是什么?
Kubernetes是一个开源的容器编排平台,用于自动化容器化应用程序的部署、扩展和管理。它提供了一种在分布式环境中管理和运行容器的方法,支持多种容器运行时,如Docker和containerd。以下是Kubernetes的一些关键组件和它们的工作原理:
集群(Cluster)
Kubernetes集群是一组物理或虚拟机,用于运行容器化应用程序。集群中的每个节点都安装了容器运行时(如Docker)和Kubernetes代理(kubelet)。
控制平面(Control Plane)
控制平面是一组组件,负责管理整个集群的状态。它包括API服务器(API Server)、etcd、控制器管理器(Controller Manager)和调度器(Scheduler)等组件。API服务器是Kubernetes的主要接口,用于接收命令和管理资源;etcd是一个分布式键值存储,用于保存集群的配置数据;控制器管理器负责运行各种控制器,如副本控制器、节点控制器等;调度器负责将容器分配到合适的节点上运行。
节点(Node)
节点是集群中的工作负载单元,可以是物理机或虚拟机。每个节点都运行kubelet(Kubernetes代理)和容器运行时(如Docker)。kubelet负责与控制平面通信,确保节点上的容器按照预期运行。
Pod
Pod是Kubernetes中的最小部署单元,它包含一个或多个紧密相关的容器。Pod内的容器共享相同的网络命名空间和存储卷。Pod可以通过标签(Label)和选择器(Selector)进行分类和筛选。
服务(Service)
服务是一种抽象,用于将一组提供相同功能的Pod暴露为一个网络服务。服务可以通过负载均衡器、集群IP或节点端口等方式访问。
控制器(Controller)
控制器是一种自动化机制,用于确保Kubernetes集群中的资源状态与预期状态一致。例如,副本控制器(ReplicaSet)确保指定数量的Pod副本始终在运行;部署控制器(Deployment)负责管理应用程序的更新和回滚。
配置资源(ConfigMap)和密钥(Secret)
这些资源用于将配置数据和敏感信息(如密码、API密钥等)注入到容器中,以便在不修改容器镜像的情况下更新配置。
SubPath
在容器内部,本地文件通常是非持久化的。对于Kubernetes来说,当容器由于某种原因终止运行并被Kubelet重启后,非持久化的本地文件就会丢失;另外,集群中同一Pod内部或Pod间常常会有文件共享的需求。Kubernetes提供了Volume资源用来解决上述问题
有时,我们需要把一个Volume在多处使用。volumeMounts.subPath特性允许我们在挂载时指定某Volume内的子路径,而非其根路径。
漏洞原理
CVE-2017-1002101 是 Kubernetes 中一个典型的 subPath 卷挂载符号链接容器逃逸漏洞:Pod 可以通过 volumeMounts.subPath 指定只挂载卷里的某个子路径,而 kubelet 在处理这个 subPath 时,会以高权限在宿主机上拼接路径并执行挂载,但早期版本没有校验 subPath 解析后的真实路径是否仍在卷的基础目录内。攻击者可以构造一个多容器 Pod,让容器 A 在共享的可写卷(如 emptyDir)里创建一个指向宿主机 / 或 /etc 的符号链接,容器 B 再用 subPath 引用这个链接;当 kubelet 挂载时就会跟随符号链接,把宿主机敏感目录 bind mount 进容器,攻击者随后就能读写宿主机文件,实现容器逃逸甚至节点权限提升。官方修复思路是在挂载前解析并校验 subPath 的最终路径必须位于该卷基础目录内,并加锁防止验证与挂载之间被篡改。
漏洞复现
创建恶意yaml文件

部署yaml

看 victim 崩溃循环(命中预期)

成功逃逸
