执行摘要
-
Akamai安全研究员Tomer Peled最近发现了一个Kubernetes漏洞,该漏洞被分配了CVE-2024-9042。
-
该漏洞允许在Kubernetes集群的所有Windows端点上以SYSTEM权限执行远程代码(RCE)。要利用此漏洞,集群必须配置为运行新的日志机制"Log Query"。
-
该漏洞可以通过对远程节点的简单GET请求触发。
-
成功利用此漏洞可导致集群中所有Windows节点的完全接管。
-
这个漏洞可以在默认安装且选择使用测试版功能的Kubernetes上(1.32.1版本之前)利用,并在本地部署和Azure Kubernetes服务上进行了测试。
-
在这篇博客文章中,我们提供了一个概念验证的curl命令并讨论可能的缓解措施。
引言
Kubernetes和容器已成为安全领域的主导力量——因此,它们成为全球研究人员的关注点(包括我们自己)。我们的研究之旅最初引导我们发现了CVE-2023-3676:一个可以通过应用恶意YAML文件来利用的命令注入漏洞。这项研究还发现了几个其他问题,这些问题同样允许完全接管集群。
这些漏洞并非我们的全部发现——我们还在sidecar项目git-sync中发现了重大问题。我们在DEF CON 32的红队村展示了这些发现,在为演讲做准备的过程中,我们偶然发现了这篇博客文章的主题:Kubernetes更大型日志框架Log Query中又一个命令注入的机会。
Log Query是什么?
Log Query允许用户使用CLI或curl查询远程机器的系统状态。例如,用户可以输入以下命令来查询远程节点上kubelet服务的状态:
kubectl get --raw "/api/v1/nodes/node-1.example/proxy/logs/?query=kubelet"
当我们看到上面的示例命令时,我们想起了之前的研究:发送到远程机器的查询是否会被验证?
图1是我们发现包含多个PowerShell命令的Log Query源代码的示例。
这些命令用于根据多个不同参数(如Windows服务名称、使用时间模式等)从给定节点检索日志。
根据之前的经验(CVE-2023-3676),我们知道Kubernetes在构建PowerShell命令时不一定会在插入用户输入之前验证用户输入。我们想查看Log Query是否也是如此,发现服务名称实际上是使用预定义的正则表达式进行验证的(图2)。
_reServiceNameUnsafeCharacters_这个名称表明这个检查仅针对服务。这个假设进一步得到了解析过程中没有其他正则表达式的事实的支持。
在查看其他参数后,很明显,被验证的唯一参数是服务名称。这意味着我们可以查看其他参数,希望实现命令注入。在Log Query中,用户可以提供几个不同的可选参数,但唯一的字符串参数是_Pattern_参数(图3)。如前所述,除了长度之外,该参数没有任何验证。
值得注意的是,利用此漏洞并不容易。我们尝试通过使用几种不同的PowerShell有效负载排列(如添加括号、使用分隔符等)来触发远程计算机上的命令,但似乎都不起作用——也没有出现错误,这使得找出问题变得更加困难。
有效负载不是问题
在尝试了多种命令注入方法后,我们最终发现问题不在于有效负载本身。要利用此漏洞,我们需要指定一个原生记录其状态到Windows事件跟踪(ETW)而非常规_klog_框架的服务,因为有问题的检查仅在记录到ETW时存在。
使用Calico(Kubernetes的流行开源网络接口)的Kubernetes环境通过非吸引力服务管理器(NSSM)提供了可靠的利用此漏洞的方法。
-
在Calico设置中,NSSM通常用于控制Kubernetes服务的状态。在其他环境/设置中,他们使用不同的方式来处理服务状态。
-
Kubernetes不管理NSSM的日志输出,确保日志直接写入ETW而不是通过_klog_。
展示利用查询
这是利用查询的样子:
curl "<Kubernetes API 代理服务器 IP>/api/v1/nodes/<节点名称>/proxy/logs/?query=nssm&pattern='$(Start-process cmd)'"
与API服务器通信所需的身份验证令牌已删除
敏锐的读者可能会对用于转义恶意命令的单引号感到好奇。我们需要它们,因为Kubernetes使用以下命令插入我们的输入:
…Where-Object -Property Message -Match '%s'...
类似于经典的SQL注入攻击,我们需要添加单引号以转义它们的模式,使我们的输入被解析为单独的命令(图4)。
优先修补
要受到此漏洞影响,您必须使用1.32.1版本之前的Kubernetes。如果您还没有修补此漏洞,最好优先处理这个问题。对于具有集群中Windows节点的组织尤其如此,这是漏洞所在的地方。
幸运的是,这似乎并非行业标准。管理员可以通过在集群控制器上运行以下命令轻松测试您的组织集群是否包含Windows节点(图5)。
我是否易受攻击?
判断是否易受攻击很容易。请注意"os=windows"部分。如果没有Windows节点,该命令将没有输出,意味着您不易受攻击。
由于这是一个测试版功能,集群还需要配置为使用框架本身。
为了检查功能是否已启用,管理员可以查看"kubelet"的"feature-gate"启动参数。您可以在Kubernetes网站](https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/
)获取更多信息。
补丁分析
为修复此漏洞,Kubernetes决定在将值传递给PowerShell命令之前使用名为"kubelet_pattern"的环境变量。
这样,用户输入将被视为字符串文字,而不是需要求值的子表达式。
缓解措施
为帮助缓解此漏洞,管理员可以使用基于角色的访问控制(RBAC)模块来控制谁可以访问Log Query,甚至完全禁用对它的访问。RBAC是根据用户身份分段用户操作的方法。例如,每个用户只能在自己的命名空间中创建Pod,或只能查看允许的命名空间的信息。这不仅可以减少RCE的执行风险,还可以减少检测风险——异常用户行为通常是不轨的征兆。
请记住,此漏洞仅影响Windows节点。如果您的Kubernetes集群没有任何Windows节点,您就没事了。但是,仍然建议尽可能保持补丁为最新,以避免其他未知漏洞。
由于问题出在源代码中,这种威胁将持续存在,利用它的可能性可能会增加——这就是为什么我们强烈建议即使没有Windows节点也要为集群打补丁。
结论
在这篇博客文章中,我们展示了具有查询权限的攻击者如何在集群内的任何Windows节点上执行命令。这个漏洞可以通过简单的curl命令利用,而不是必须提交YAML文件。这一事实带来了很大风险,因为其利用更难缓解和检测。Kubernetes的输入清理问题并非仅限于Log Query,正如我们之前讨论的那样。
蓝队成员应密切关注进入组织的异常行为。这种攻击向量可能导致完全接管集群;因此,我们有必要提高意识,帮助安全管理员了解潜在危险。
我们要感谢Kubernetes团队的响应和沟通。
时间线
06/28/2024 — 向Kubernetes团队披露漏洞
07/18/2024 — Kubernetes团队开始处理修复问题
07/30/2024 — Kubernetes团队分配CVE编号
01/16/2025 — Kubernetes发布CVE修复
01/24/2025 — 发布博客文章
原文始发于微信公众号(独眼情报):K8S 日志查询中的命令注入
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论