freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

Kubernetes与HostPath的爱恨交织
绿盟科技 2022-09-16 16:01:41 78465
所属地 北京

一、引言

本文翻译整理自Quarkslab实验室[1],主要追溯了三个与Kubernetes相关的漏洞:CVE-2017-1002101、CVE-2021-30465和CVE-2021-25741,分别介绍了这些漏洞的原理以及对应的修复措施,并阐述了它们之间的关联——均与HostPath有关。在介绍漏洞之前,我们需要先了解一下Kubernetes相关的背景知识。

二、背景知识:Volume—>HostPath

在默认情况下,容器中的数据都是非持久化的,当容器关闭或者重新启动时,容器中的文件将会丢失,为了解决这一麻烦,Kubernetes引入了Volume的定义。Volume作为Pod的一个属性,与Pod具有相同的生命周期,即使容器重启,Volume中的原有数据也将会保留,如此可以解决数据的持久性问题;其次,因为Volume可以被Pod中的任意容器使用,这样为多个容器之间的数据共享提供了便利。

Volume的类型多种多样,常见的有emptyDir、HostPath、configMip等,更多的类型可以参考官方文档[2]。本文重点关注的是HostPath类型的Volume,官方对其描述大致如下:HostPath类型的Volume会将宿主机上的文件或目录挂载到Pod中,这不是大多数Pod需要的东西,但一些特定的工作负载仍有访问节点资源的需求,这也是Kubernetes引入HostPath的原因。

然而,使用HostPath时也存在一定的风险,官方文档中就有以下相关警告:

“Warning: HostPath volumes present many security risks, and it is a best practice to avoid the use of HostPaths when possible”。原因是,站在安全的角度来看,HostPath的性质正在破坏容器所承诺的隔离特性:文件系统的隔离。在理想情况下,Pod不应该依赖宿主机的文件系统或配置,不管在它们在集群中的调度情况如何,运行方式应该是一样的。但HostPath是将宿主机上的文件挂载至容器内,依赖宿主机的文件系统,如果配置不当,可能会发生官方文档中举例的风险,如暴露宿主机上特权的集群凭证(如Kubelet)或特权的API(容器运行时套接字)等,导致攻击者可以在容器内进行逃逸攻击或权限提升。

本文暂不讨论因为潜在的配置不当HostPath引发的风险,希望能探究这一功能点如何使Kubernetes受到一些漏洞的影响。

三、HostPath相关漏洞

我们从最新的CVE-2021-25741开始调查,发现了两个相关漏洞,一个是2017年底的CVE-2017-1002101,也与Kubelet有关,另一个是2020年底的CVE-2021-30465,与runC有关。而其中CVE-2021-25741是因为CVE-2021-30465而被发现的,它同时也是CVE-2017-1002101的不完整补丁的结果。

3.1 KubeletCVE-2017-1002101

该漏洞是2018年披露的最严重的Kubernetes漏洞之一。它涉及运行在每个节点上、与API Server进行通信的Kubelet组件。攻击者通过符号链接竞争,有可能在没有实际授权的情况下将任意的HostPath挂载到Pod的容器中。更具体地说,是因为HostPath中的subpath功能是用户可以操纵的入口,它将由Kubelet在容器创建过程中读取和装载。此漏洞正是利用这样的特性:Kubelet在宿主机上是以root身份运行的,而符号链接是相对于“读者”(读取符号链接的用户)解析的。(注:也存在以低权限用户运行Kubelet的情况,被称为rootless Kubernetes,若如此,便可消除此类问题)

下面是一个简化的例子,由Brad Geesaman编写,在/rootfs/host挂载宿主机文件系统。可以在他的项目仓库中找到其他完整的例子[4]。

apiVersion: v1

kind: Pod

metadata:

name: subpath

spec:

containers:

- image: nginx:latest

name: setup

imagePullPolicy: "Always"

command: ["/bin/bash"]

args: ["-c", "cd /rootfs && rm -rf hostetc && ln -s / /rootfs/host && touch /status/done && sleep infinity"]

volumeMounts:

- mountPath: /rootfs

name: escape-volume

- mountPath: /status

name: status-volume

- image: nginx:latest

name: exploit

imagePullPolicy: "Always"

command: ["/bin/bash"]

args: ["-c", "if [[ -f /status/done ]];then sleep infinity; else sleep 1; fi"]

volumeMounts:

- mountPath: /rootfs

name: escape-volume

subPath: host

- mountPath: /status

name: status-volume

volumes:

- name: escape-volume

emptyDir: {}

- name: status-volume

emptyDir: {}

关于这个漏洞的更多详情可以参考《逃逸风云再起:从CVE-2017-1002101到CVE-2021-25741

最终解决这个漏洞的方案如下:

  1. 在宿主机上对所有的subPath解析符号链接;
  2. 对解析后的路径,从Volume的根路径开始,使用openat()系统调用依次打开每一个路径段(即路径被分割符/分开的各部分),在这个过程中禁用符号链接。对于每个段,确保当前路径位于在卷内部;
  3. 将/proc/<Kubeletpid>/fd/<final fd>绑定挂载到Kubelet的Pod目录下的一个子目录。该文件是指向打开文件的链接(文件描述符)。如果源文件在被Kubelet打开的时候被替换,那么链接依然指向原始文件;
  4. 关闭文件描述符fd,将绑定挂载传递给Runtime。

使用文件描述符来避免使用路径时可能出现的竞争条件漏洞是一种常见的解决方案。具体可以参考2006年出版的《The Art of Software Security Assessment》[5]一书中找到这方面的详细信息,过去的一些竞争条件漏洞也是用这种方案解决的。

3.2 runCCVE-2021-30465

2020年底,Etienne Champetier在runC中发现了一个新的漏洞,这也是一个符号链接竞争,利用了TOCTOU(time-of-check to time-of-use)。简单来说,TOCTOU指的是程序对某对象的安全检查步骤和使用该对象的步骤之间存在间隙,攻击者可以先构造并放置一个能够通过安全检查的合法对象,顺利通过目标程序的安全检查流程,然后立即使用恶意对象替换之前的合法对象。这样一来,目标程序真正使用的实际上是被替换后的恶意对象。值得注意的是,这个漏洞的发现得益于runC代码中的一个注释。Etienne发布了一篇详实的博客文章[6],介绍了该漏洞的原理以及如何在Kubernetes的环境下利用该漏洞。Kubelet守护程序使用的是容器运行时,而容器运行时在大多数情况下使用的是runC。如果想了解更多信息,也可以参考SIG-Honk的笔记[7]。

这个漏洞导致的后果与前一个漏洞相同,但利用起来相对更复杂,因为它涉及一个竞争条件。其原理是,runC调用一个名为securejoin. SecureJoinVFS()的函数来解析符号链接,然后再调用mount(),这个过程中会发生问题。作为Kubernetes用户,我们可以完全控制挂载的目标,所以我们可以操作这两个语句之间的值,以迫使挂载遵循指定的符号链接。

此漏洞的补丁[8]与之前的CVE-2021-30465漏洞补丁类似,包括使用进程的文件描述符,作为验证路径后的 "权宜之计"。

3.3 Kubelet CVE 2021-25741

CVE-2021-30465的披露激起了Google工程师的好奇心,他们直接在Kubelet二进制中发现了几乎相同的漏洞,即CVE-2021-25741。与前两个漏洞相同的是,在解析路径和实际挂载之间存在一个时间窗口,可以被攻击者利用。

有趣之处在于,它是由前文中的CVE-2017-1002101的不完整的补丁引起的。在之前的解决方案中,确实使用文件描述符来解决符号链接问题,但是新的问题出现在Kubelet的doMount函数中,该函数调用的实际是系统上的mount工具而不是mount系统调用。根据Linux手册[9],mount工具默认情况下是解析符号链接的。而攻击者可以在mount工具解析符号链接后和执行挂载操作前制造竞争条件攻击,从而绕过前述补丁的防御措施,POC可参考[10]。

该漏洞的修复方案较为简单,在调用mount工具时传递--no-canonicalize参数,便不再解析符号链接。

四、总结与思考

容器在默认情况下拥有自己的文件系统,并通过各种机制进行隔离。Kubernetes的Volume功能允许将不同的文件系统附加到容器的现有文件系统中。但是,允许用户在mount的参数中输入任意的文件系统结构,特别是符号链接,是极其危险的行为,已经导致产生了各种漏洞。上文提到的三个漏洞也显示了漏洞修复工作的困难以及一个漏洞的披露可能导致类似或相关软件的其他漏洞披露。下面梳理了与这三个漏洞相关的主要事件和资源的简要时间线:

DATE

CVE

DESCRIPTION

2018年3月

2017-1002101

CVE-2017-1002101在Github的issue #60813中披露。

2018年3月

2017-1002101

Twistlock撰写的关于迄今为止最严重的Kubernetes漏洞的深挖文章和Brad Geesaman撰写的POC文章已经发表。

2018年4月

2017-1002101

Kubernetes博客发布文章.Fixing the Subpath Volume Vulnerability in Kubernetes

2018年12月

2017-1002101

Michelle Au and Jan Šafránek在2018年KubeCon NA会议上.How Symlinks Pwned Kubernetes (And How We Fixed It)

2020年12月

2021-30465

Etienne Champetier 发现了runC漏洞CVE-2021-30465

2021年3月

2021-30465

Githuband OSS-Security上披露了漏洞, Etienne Champetier发表了文章和POC write-up and a POC

2021年9月

2021-25741

CVE-2021-25741在Github issue #104980上由Google工程师Fabricio Voznika和Mark Wolters披露

2021年10月

2021-30465

Sig security Ian Coldwater、Brad Geesaman、Rory McCune和Duffie Cooley在2021年KubeCon NA上发表并展示了他们的POC

2022年1月

2021-25741

Google在其安全博客上发布了《探索容器安全:存储漏洞深究》

2022年1月

2021-25741

Arkadiy Litvinenko发表了 POC

挂载+符号链接≈风险

研究员在调研CVE-2021-25741遇到了符号链接和绑定挂载的结合,觉得十分有趣,因此希望通过一个简化的例子来说明两者结合时会发生的问题。

问题

见图1,灰色方框是目录,黄色是符号链接:

图1 符号链接示例

如果你想做实验,请在一个单独的虚拟机中进行以下命令创建文件系统结构:

mkdir -p base/dir1 base/dir2 && ln -s ../../base base/dir1/loop && ln -s / base/dir2/root

如果你在base文件夹中运行以下mount(8)命令,会发生什么?

mount -o bind base/dir2 base/dir1/loop

答案

通过观察可以发现,该命令效果与以下相同:

mount -o bind base/dir2 base

结果是dir2被绑定至base上,覆盖了文件系统中base下的所有文件,从而证明将一个子文件夹挂载到其父文件夹上是完全有效的,如图2所示:

图2 符号链接示例

希望读者能够在程序设计与使用Kubernetes时谨慎使用符号链接、谨慎使用HostPath,全面考虑可能存在的风险,保证云原生环境的安全。

参考文献

[1] https://blog.quarkslab.com/kubernetes-and-hostpath-a-love-hate-relationship.html

[2] https://kubernetes.io/docs/concepts/storage/volumes/

[3] https://kubernetes.io/docs/concepts/security/pod-security-policy/#volumes-and-file-systems

[4] https://github.com/bgeesaman/subpath-exploit

[5] https://flylib.com/books/en/2.294.1.83/1/

[6] http://blog.champtar.fr/runC-symlink-CVE-2021-30465/

[7] https://hackmd.io/jAnCrvWEQ-u3JBDtf1N8TA#more-hacks

[8] https://github.com/opencontainers/runC/commit/0ca91f44f1664da834bc61115a849b56d22f595f

[9] https://man7.org/linux/man-pages/man8/mount.8.html

[10] https://github.com/Betep0k/CVE-2021-25741

# 云安全
本文为 绿盟科技 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
绿盟科技创新研究院
绿盟科技 LV.10
绿盟科技官方账号
  • 1639 文章数
  • 336 关注者
《高级威胁研究报告(2025版)》发布
2025-04-03
《网络安全2025:冲刺“十四五”》发布
2025-04-01
《2025网络安全趋势报告》发布
2025-04-01
文章目录