需要云计算吗? 即刻开始体验

无法控制:Kubernetes 中存在命令注入漏洞

Tomer Peled

寫於

Tomer Peled

September 13, 2023

Tomer Peled

寫於

Tomer Peled

Tomer Peled 是 Akamai 的安全研究员。他的日常研究工作主要涉及漏洞和操作系统内部结构等方面。闲暇时,他喜欢烹饪美食、练马伽术以及玩 PC 游戏。

管理员应为他们的 Kubernetes 集群安装补丁以升级到可用的最新版本,从而避免这些漏洞被利用,这一点很重要。

编辑和评论补充:Tricia Howard

执行摘要

  • Akamai 安全研究人员 Tomer Peled 最近在 Kubernetes 中发现了一个 高严重性漏洞 ,该漏洞编号为 CVE-2023-3676,CVSS 评分为 8.8。

  • 本次发现还识别出另外两个漏洞,因为它们具有相同的根本原因:不安全的函数调用并且缺少用户输入清理。

  • 利用该漏洞,攻击者能够在 Kubernetes 集群中的所有 Windows 端点上使用 SYSTEM 特权实现远程代码执行。要利用该漏洞,攻击者需要在集群上应用恶意 YAML 文件。

  • 此漏洞可在 Kubernetes 的默认安装版本上被利用,并且已针对本地部署和 Azure Kubernetes Service 进行了测试。

  • 我们提供一个 概念验证 YAML 文件以及一条 OPA 规则 ,用于阻断该漏洞。

简介

YAML(表示 YAML 不是标记语言)是类似于 JSON 的一种数据序列化语言,主要用在配置文件中。因此,它在 Kubernetes 中发挥着重要作用。Kubernetes 是无处不在的新型容器编排系统,可有助于企业自动完成容器化应用程序的部署、扩展和管理。Kubernetes 框架几乎将 YAML 文件用于各个方面,从配置容器网络接口到 Pod 管理,甚至是密钥处理都会用到该文件。

近年来,Kubernetes 中的 YAML 文件已成为人们研究的主题。考虑到 Kubernetes 依赖 YAML 进行集群配置,因此这个研究课题特别值得深入研究。

先前 YAML 和 Kubernetes 是如何被利用的?

2022 年, CVE-2022-1471 在知名的 YAML 文件解析器 SnakeYAML 的构造函数中被发现。利用该漏洞,攻击者能够创建不安全的对象。这样,当易受攻击的应用程序使用这些对象时,攻击者便能够在这些应用程序上执行代码。另一个示例也说明了 YAML 文件可能的影响,您可以在 Kubernetes 安全团队所编写的关于 CVE-2021-25749 的 CVE 公告 中查看此示例。利用该漏洞,攻击者只需在 YAML 文件中将其名称拼写错误便能够绕过相关验证,从而实现以 root 用户身份运行。

在对 Kubernetes 的研究过程中,我们发现了 CVE-2017-1002101CVE-2021-25741。这两个漏洞揭示了攻击者如何将争用条件和符号链接与 YAML 文件中的 subPath  子属性结合使用,从而在容器外获取对特权数据的访问权限。

受到这两个漏洞的启发,我们沿着 Kubernetes 代码库中的路径处理方向继续深入研究,最终发现了现在所讨论的这个漏洞。

在本博文中,我们会演示拥有“apply”特权(即,与 Kubernetes API 进行交互所需的特权)的攻击者如何注入将使用 SYSTEM 特权在远程 Windows 机器上执行的代码。

漏洞详情

在某个 Pod 被创建后,用户可以选择在该 Pod 与主机之间创建一个共享目录。称为 的这项功能非常有用,例如,它可用于通过 Pod 中的容器为网站提供服务。我们可能需要共享与主机所共享的某个目录中的站点文件;这样,我们便能够根据自己的需要更改站点布局,以便每次重新编译包含该站点的映像。

通过在 Pod 的 YAML 文件中包含 volume 参数 即可启用卷。 mountPath (容器中的位置)和 hostPath (主机上的位置)中列出了装载卷的位置。

对于我们来说,最重要的是,我们可以使用 subPath 子属性在所选位置装载共享目录或文件。图 1 显示的是卷的所有相关属性。

图 1 显示的是卷的所有相关属性。 图 1:YAML 卷配置

YAML 文件的解析由 kubelet 执行,kubelet 是 Kubernetes 中的核心服务,负责在节点上运行容器化应用程序。作为 CVE-2021-25741 修补方法的一部分,kubelet 会验证 YAML 文件中的每个参数,并且还会调用内部函数“isLinkPath”来确保使用 subPath 参数不会导致创建任何符号链接。图 2 中显示的函数。

 

subPath 函数 图 2:用于检查符号链接路径的 subPath 函数

该函数可作为用户在 YAML 文件中提供的 subPath 的参数。然后,它会使用此路径创建用于确定路径类型(即,它是否为符号链接)的 PowerShell 命令。“exec.Command”函数调用随后会直接调用带格式的 PowerShell 命令。

exec.Command”与未清理的用户输入内容同时存在,强烈暗示攻击者有机会进行命令注入。

利用 PowerShell,用户能够在字符串内的值被使用之前对这些值进行计算。例如,可以通过向您的字符串中添加 $(<experssion_to_be_evaluated>) 来完成此操作(图 3)。

  PS> echo “the value of 1+1 is $(1+1)

  Output:
  the value of 1+1 is 2

图 3:对字符串内的表达式求值的 PowerShell 的示例

此示例非常简单,但实际上可以在括号中插入 任何 PowerShell 命令并对其进行求值,例如 $(Start-Process cmd)、$(Invoke-Expression exp) 以及其他 PowerShell 处理。

攻击者可以滥用此 subPath 求值以访问易受攻击的代码,并使用 SYSTEM 特权 从远程节点 执行任何所需的命令(kubelet 自己的上下文),从而获得对集群中所有 Windows 节点的控制。图 4 显示了一个恶意的 subPath 值。

 YAML 文件 图 4:subPath 参数中包含命令注入的 YAML 文件

展示 CVE-2023-3676 的概念验证

此概念验证只是一个 YAML 文件 ,其中包含了 PowerShell 命令的求值。您可以在我们的 GitHub 存储库中找到此文件,以及一段 视频 ,该视频显示了正在启动的终端。

借助此 CVE,我们发现并修复了更多命令注入漏洞。这些漏洞的共同 CVE 编号为 CVE-2023-3955 和 CVE-2023-3893。

修补分析

Kubernetes 团队选择传递来自环境变量而不是用户输入的参数,以此修补此类漏洞(图 5)。通过以此方式向下传递值,这些参数会被视为字符串,因此 PowerShell 不会将它们作为表达式进行求值。

修补函数 图 5:针对 CVE-2023-3676 的修补函数

我是否容易受到攻击?

正如我们先前所提到的,所有低于 1.28 版本的 Kubernetes 都因存在此 CVE 而容易受到攻击。有几种方法可以确定您的集群中是否有某个节点为 Windows 节点。其中一种方法是执行图 6 中的命令。

kubectl get nodes -o wide --show-labels | grep “os=windows”


输出:

akswin000000                        Ready    agent   4d17h   v1.26.6   agentpool=win,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=windows…


akswin000001                        Ready    agent   4d17h   v1.26.6   agentpool=win,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=windows…

图 6:用于确定您的集群中是否有某个节点为 Windows 节点的 kubectl 命令

抵御措施

安装补丁是保护自己免受此漏洞威胁的最可靠方法。如果无法安装该补丁,我们还给出了一些能够抵御此漏洞的方法,您可以从中选择适合您环境的方法。

先前的解决方案

对于 CVE-2023-3676,Kubernetes 管理员可以禁用 Volume.Subpath。这将确保您的集群能够抵御此漏洞,但会禁用有时在生产中对集群来说很重要的一项机制。

OPA

开放策略代理 (OPA) 是一种开源代理,用户通过该代理可以接收流入和流出节点的流量的相关数据,并且可以对接收到的数据执行基于策略的操作。OPA 使用 Rego 作为其引擎的语言,管理员可以利用该语言创建用于阻止实施特定 YAML 文件的规则。图 7 说明了将拒绝使用恶意 subPath 创建 Pod 的规则。

  package kubernetes.admission

  deny[msg] {                                                                 
    input.request.kind.kind == "Pod"
    path := input.request.object.spec.containers.volumeMounts.subPath                 
    not startswith(path, "$(")                                     
    msg := sprintf("malicious path: %v was found", [path])     
}

图 7:将阻止使用恶意 subPath 创建 Pod 的规则

RBAC

基于角色的访问控制 (RBAC) 是一种根据用户角色划分用户操作的方法。例如,每个用户只能在自己的命名空间中创建 Pod,或者只能查看允许访问的命名空间的信息。这可能有助于限制能对集群执行操作的用户的数量,并且有助于将注意力集中在拥有漏洞利用相关特权的用户身上。

结论

CVE-2023-3676 需要较低特权,因此对攻击者来说,其利用门槛较低:他们只需要拥有对某个节点的访问权限以及 应用 特权即可利用该漏洞。正如我们在本博文中讨论的那样,成功利用此漏洞会让攻击者可以在机器上的任何 Windows 节点中使用 SYSTEM 特权实现远程代码执行。

影响重大且易于利用通常意味着各企业遭遇此攻击(及类似攻击)的可能性更高。实际上,对于此漏洞,唯一的局限性是其作用范围,即它只对如今不太流行的 Windows 节点起作用。

管理员应为他们的 Kubernetes 集群安装补丁以升级到可用的最新版本,从而避免这些漏洞被利用,这一点很重要。如果您无法立即安装补丁,我们建议您采用上述方法之一来抵御此漏洞。

对于做出快速响应并与我们进行了顺畅沟通的 Kubernetes 团队,我们在此深表感谢。

披露时间表

  • 2023 年 7 月 13 日,我们将漏洞披露给 Kubernetes 团队。

  • 2023 年 7 月 19 日,Kubernetes 团队分配了 CVE 编号

  • 2023 年 8 月 23 日,Kubernetes 发布了 CVE 修复方法

  • 2023 年 9 月 13 日,博文发布



Tomer Peled

寫於

Tomer Peled

September 13, 2023

Tomer Peled

寫於

Tomer Peled

Tomer Peled 是 Akamai 的安全研究员。他的日常研究工作主要涉及漏洞和操作系统内部结构等方面。闲暇时,他喜欢烹饪美食、练马伽术以及玩 PC 游戏。