云原生服务风险测绘分析(一):Docker和Kubernetes

一、概述

近年来随着云原生服务的大规模应用,互联网上暴露的相应资产越来越多,通过网络空间测绘技术可对暴露的资产进行数据统计及进一步的分析,从而有效赋能态势感知、漏洞预警、风险溯源等技术领域。

笔者近期针对云原生各类服务进行了具体的测绘分析。本篇为云原生服务测绘系列的首篇,主要从资产发现、资产脆弱性和漏洞介绍、资产脆弱性发现三个维度分析了我们日常使用的Docker及Kubernetes服务所存在的风险。针对Kubernetes服务,由于其主要暴露资产的方式是通过API Server,Kubelet以及Kubernetes Dashboard组件,考虑到这几个组件的脆弱性、资产指纹均不一,但又与Kubernetes服务有着紧密的联系,故笔者将分别对这些组件进行介绍。最后笔者针对每个组件提供了一些安全建议,希望各位读者通过阅读此文可对云原生服务风险暴露有更清晰的认识。

注:文中统计的测绘数据为近一个月的国内数据,相关技术仅供研究交流,请勿应用于未授权的渗透测试。

二、Docker资产风险测绘分析

2.1 Docker资产暴露情况分析

借助测绘数据,我们可以了解到国内Docker资产地区和版本的分布情况,笔者也以这两个维度为各位读者进行介绍。

2.1.1 Docker资产地区分布

笔者从测绘数据中得到Docker相关资产共179条数据,地区分布如图1所示:

图1 Docker资产地区分布

以上Docker资产暴露的情况笔者进行了统计,如下表所示:

端口 资产数
2375 100
2376 13
其它 66

从以上数据我们可以看出,国内暴露的Docker资产多数来源于北京市、上海市、广东省、浙江省,其中北京暴露数据量最大;端口则主要分布在2375端口和2376端口,其中2375端口数量最多。

2.1.2 Docker资产版本分布

通过测绘数据,笔者对国内暴露的Docker资产版本进行了分析,其分布情况如图2所示:

图2  Docker资产版本分布

从上图可以看出,近50%的Docker资产未获取到具体版本,剩余50%可统计的Docker资产版本中,v1.13.1版本暴露最多,约占已知版本资产总数的33%,第二暴露多的版本为18.09.7,约占已知版本资产总数的10%。

2.2 Docker资产脆弱性和漏洞介绍

2.2.1 脆弱性介绍

通过测绘数据,我们得知暴露的Docker资产端口主要为2375、2376端口,这两个端口为Docker的TCP Socket端口,在版本较新的Docker中,Docker守护进程默认不会监听TCP Socket。用户可通过配置文件来设置Docker守护进程开启对TCP Socket的监听,默认监听端口通常为2375。然而,默认情况下对Docker守护进程TCP Socket的访问是无加密且无认证的。因此,任何网络可达的访问者均可通过该TCP Socket来对Docker守护进程下发命令。2376端口用于与Docker守护进程进行TLS通信,因此需要配置证书才可实现通信加密,默认不开启。

若开放了2375,2376(未配置证书)端口,以下命令能够列出IP为192.168.1.101的主机上的所有活动容器:

docker -H tcp://192.168.1.101:2375 ps

docker -H tcp://192.168.1.101:2376 ps

显而易见,攻击者也能够通过这样的TCP Socket对目标主机上的Docker守护进程下发命令,从而实现对目标主机的控制。控制方式与通过Unix Socket的控制类似,只是需要通过-H tcp://参数来设置目标地址和端口。

2.2.2 漏洞介绍

Docker自2013年发布以来,共曝出34个漏洞[2],根据CVSS 2.0标准,其中含高危漏洞9个,中危漏洞7个,中高危漏洞类型以容器逃逸、命令执行、目录遍历、权限提升为主。

更多内容各位读者可以参考CVE网站对Docker漏洞的统计,此处由于篇幅原因不再赘述。

2.3 Docker资产脆弱性暴露情况分析

借助测绘数据,笔者从Docker脆弱性及CVE漏洞维度,统计了现有暴露资产的漏洞分布情况,如图3所示:

图3  Docker脆弱性及漏洞分布

可以看出,在国内互联网暴露的179个Docker资产中,有81个资产被曝出含有未授权访问脆弱性,57个资产被曝出含有CVE-2021-21284漏洞, 53个资产被曝出含有CVE-2020-27534漏洞,49个资产被曝出含有CVE-2019-14271漏洞,其中每个资产可能命中多条CVE。

值得一提的是,早在2018年绿盟科技发布的《容器安全技术报告》[1]中已针对全球范围内5-7月暴露的Docker资产(2375端口)进行了分析,其中中国地区共暴露197个资产,与本次Docker的测绘数据(2375端口)量对比多出近一倍,由此我们可以看出,经过三年半的时间,2375端口的暴露量在不断减少,从侧面也可以反映出Docker用户的安全意识在不断增强。

2.4 安全建议

  • 建议不开启2375端口远程监听
  • 使用Docker的TLS端口(2376)并为其配置证书
  • 应用CIS Docker Benchmark最佳实践[3]
  • 根据官方通告及时升级版本,更新补丁

三、Kubernetes资产风险测绘分析

3.1 Kubelet

Kubelet 是在Kubernetes集群中每个节点上运行的代理组件,它是工作节点上的主要服务,职责为定期从Kubernetes API Server组件中接收新增或修改的Pods请求,并确保Pods在用户期望的状态下运行。同时,该组件作为节点的监控组件,定时向Kubernetes API Server汇报所在节点Pods的运行状况。

3.1.1 Kubelet资产暴露情况分析

借助测绘数据,笔者统计了国内暴露的Kubelet资产,数量近8220个,其中地区分布如图4所示:

端口 端口服务介绍
10248 Kubelet healthz的服务端口,用于判断Kubelet组件的健康状态,已于Kubernetes v1.16版本后弃用,访问该端口默认需要认证授权
10250 Kubelet的HTTPS服务,读写端口,提供Kubernetes基本资源运行状态, 访问该端口默认需要认证授权
10255 Kubelet的HTTP服务,只读端口,提供只读形式的Kubernetes基本资源运行状态,该端口无需进行认证授权,默认为禁用
4194 cAdvisor 的HTTP服务端口,自Kubernetes v1.10版本开始,官方去除了–cadvisor-port参数配置,不再支持对cAdvisor的访问

图4  Kubelet资产地区分布

从数据中我们可以了解到国内暴露的Kubelet资产主要来源于北京市、福建省、江苏省、广东省、上海市,其中北京市暴露983条数据,位居第一。

3.1.2 Kubelet脆弱性分析

Kubelet服务启动后会监听多个端口,用于接收Kubernetes API Server组件发送的请求,笔者统计了这些端口的相关信息,汇总为如下表格:

笔者对以上端口服务的脆弱性进行了分析并总结如下,供各位读者参考:

  • 10250端口,笔者通过查看Kubernetes GitHub仓库中Kubelet部分的源码[4]得知,该端口服务在默认授权情况下提供如下API以供用户查看,我们可以看出这些都是较为敏感的操作:
    • /pods, /runningpods
    • /metrics、/spec、/stats、/stats/container、/logs
    • /run/、/exec/, /attach/, /portForward/, /containerLogs/

由于Kubernetes的Kubelet默认启动参数可在Master节点的/var/lib/kubelet/config.yaml文件中进行修改,其中就包含认证及授权的配置项–anonymous-auth和–authorization-mode, 若我们将–anonymous-auth项设置为true开启匿名访问, –authorization-mode项设置为AlwaysAllow,用户可通过curl命令不附带任何认证信息连接至Kubelet服务的10250端口,从而对Kubernetes运行资源达到未授权访问的目的。

  • 10255端口,通过参考文献[5][6],我们知道10255端口已于2018年5月份被废弃,废弃原因GitHub上给出的解释是为了安全考虑,如若开启10255端口的访问,将会导致与开启10250端口匿名访问配置同样的未授权风险,因此Kubernetes开发团队为避免让用户感知到此项配置的存在,在Kubeadm中默认设置了此项启动参数为禁用状态。该项配置被废弃之前,通常需要在Kubernetes的Kubelet配置文件中添加–read-only-port: 0 来禁止10255端口的访问。
  • 4194和10248端口,也许是因为其服务自身不带有较为敏感的信息,所以无法被攻击者轻易利用。

从以上Kubelet组件脆弱性分析中,我们可以看出4194、10248、10255端口由于各种原因已被Kubernetes开发团队先后弃用,因此风险也可谓逐渐减少,但10250端口的未授权访问风险依然存在,值得我们注意。

3.1.3 安全建议

  • 将Kubelet组件的启动参数–anonymous-auth值设为false,即不允许匿名访问
  • 将Kubelet组件的启动参数–authorization-mode值设为Webhook
  • 根据官方通告及时升级版本,更新补丁
  • 应用CIS Kubernetes Benchmark最佳实践[7]

3.2 Kubernetes API Server

3.2.1 API Server资产暴露情况分析

借助测绘数据,我们可以了解到国内API Server资产地区、资产版本的分布情况,笔者也以这两个维度为各位读者进行介绍。

3.2.1.1 资产地区分布

笔者从测绘数据中得到API Server相关资产共17130条数据,地区分布如图5所示:

图5 Kubernetes API Server资产地区分布

此外,笔者对 API Server 资产暴露的端口情况进行了统计,如下表所示:

端口 资产数
6443 16986
8443 92
其他 52

从测绘数据可以看出,国内暴露的 Kubernetes API Server 组件资产中有约 87% 左右的数据来源于北京市、浙江省、上海市、广东省、香港特别行政区,其中北京市暴露 4940 条数据位居第一;端口主要分布在 6443、 8443、8080 端口,其中 6443 口数量 16986 个位居第一。

3.2.1.2 资产版本分布

借助测绘数据,笔者对国内暴露的API Server资产版本进行了分析,其分布情况如图6所示:

图6 Kubernetes API Server资产版本分布

从测绘数据可以看出,绝大多数版本分布在1.18.8、 1.20.4、1.20.11、 1.16.9、 1.14.8、 1.22.3范围,其中暴露数量较多的版本为 1.18.8(共 2569 个)、1.20.4(近 2000 个)、1.20.11(约 2300 个)、1.16.9(1516个),1.14.8(近1100个),剩余版本资产由于存在数量较少,且分布范围较大,笔者认为没有太多参考价值,故此处不再赘述。

此外,从测绘数据中我们进一步发现暴露较多版本的资产中,绝大多数资产(约90%)选择部署在阿里云上。

3.2.2 API Server资产脆弱性分析及漏洞介绍

3.2.2.1 脆弱性分析

熟悉Kubernetes的读者都知道API Server组件在8080和6443两个端口上提供服务,其中,8080端口提供的是没有TLS加密的HTTP服务,且所有到达该端口的请求将绕过所有认证和授权模块(但是仍然会被准入控制模块处理)。保留该端口主要是为了方便测试以及集群初启动。然而在生产环境开放8080端口,即使绑定本地环回地址(localhost)也是很危险的。如果将该端口暴露在互联网上,那么任何网络可达的攻击者都能够通过该端口直接与API Server交互,进而控制整个集群。

用户可以通过以下操作开启外部对API Server的未授权访问:

  • 在Kubernetes主节点的kube-apiserver.yaml文件中将–insecure-port=0配置项修改为–insecure-port=8080
  • 在Kubernetes主节点的kube-apiserver.yaml文件中修改–insecure-bind-address配置项值为0.0.0

3.2.2.2 漏洞介绍

Kubernetes自2014年从Google内部的Borg系统对外开源后,共曝出46个漏洞[8],根据CVSS 2.0标准,其中含高危漏洞3个,中危漏洞15个,中高危漏洞类型以权限提升、命令注入、未授权访问、DoS、中间人攻击、容器逃逸为主,关于容器逃逸、权限提升类漏洞,绿盟科技研究通信公众号曾发表相关技术文章,读者可参考:

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

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

更多内容各位读者可以参考CVE网站[7]对Kubernetes漏洞的统计,此处由于篇幅原因不再赘述。

3.2.3 API Server资产脆弱性暴露情况分析

通过以上针对API Server的脆弱性分析,笔者统计了目前含有未授权访问的API Server资产共347个,具体地区分布如图7所示:

图7 Kubernetes API Server未授权访问资产地区分布

同时笔者也统计了未授权访问资产的端口分布情况,如图8所示:

图8 Kubernetes API Server未授权访问资产端口分布

从图7、图8中我们有如下发现:

  • 北京市、广东省、上海市、浙江省暴露的未授权访问资产最多,北京市暴露103条位居第一
  • 存在未授权访问的Kubernetes资产只占总资产数的2%,这是非常小的一个数目,也可间接说明用户现在的安全意识在逐步增强。
  • 未授权资产中8443端口、6443端口及8080端口数量最多,约占未授权资产总数的86%

2018年绿盟科技发布的《容器安全技术报告》[1]中,除了Docker之外,我们还针对全球范围内7月暴露的Kubernetes资产(6443端口)进行了扫描分析,其中中国地区共暴露约2500个资产,与本次笔者统计的测绘数据量(6443端口资产数约17000个)对比少了近七倍。由此我们可以看出,仅仅三年半的时间,Kubernetes经历了从试用期,磨合期再到大规模生产落地,因而互联网上暴露的资产愈来愈多,同时相应的风险也在不断增大,也时刻提醒着用户群体的安全意识需要不断增强。

此外,笔者也从CVE漏洞维度统计了现有暴露资产的脆弱性分布情况,如图9所示:

图9 Kubernetes API Server资产脆弱性和漏洞分布

从测绘数据我们可以看出,现有暴露资产中有12482个资产被曝含有CVE-2021-25741漏洞,11628个资产被曝含有CVE-2021-25735漏洞, 9377个资产被曝含有CVE-2018-1002105漏洞,其中每个资产可能命中多条CVE。通过测绘数据我们还可看出命中CVE-2021-25741漏洞的资产数约占总资产数的73%,命中CVE-2021-25735漏洞的资产数约占总资产数的68%,命中CVE-2018-1002105漏洞的资产数约占总资产数的55%,汇总得出平均超过65%的资产会受到以上三个CVE的影响,可见影响面之大。

3.2.4 安全建议

  • 根据官方通告及时升级版本,更新补丁
  • 根据官方提供的缓解措施进行临时缓解
  • 禁止在Kubernetes API Server组件的配置文件中修改–insecure-port启动参数值为8080,使用默认配置值
  • 禁止在Kubernetes API Server组件的配置文件中修改–insecure-bind-address启动参数值为0.0.0,使用默认配置值
  • 使用API Server的安全端口(6443),并为其设置证书
  • 应用用CIS Kubernetes Benchmark最佳实践[7]

3.3 Kubernetes Dashboard

Kubernetes Dashboard是一个通用的,基于Web的Kubernetes集群用户界面。它允许用户管理集群中运行的应用程序,并对其进行故障排除,以及管理集群本身。

3.3.1 Kubernetes Dashboard资产暴露情况分析

借助测绘数据,笔者统计了国内暴露的Kubernetes Dashboard资产数据,数量为902个,其中地区分布如图10所示:

图10 Kubernetes Dashboard资产地区分布

笔者同时统计了上述资产的端口分布情况,如图11所示:

图11 Kubernetes Dashboard资产端口分布

从图10、图11中我们有如下发现:

  • 暴露资产中近60%数据来源于北京市、上海市、广东省,其中北京市暴露248条数据位居第一
  • 暴露资产端口主要分布在30001、443、8443、9090端口,其中30001端口数量598个位居第一

值得注意的是,Kubernetes Dashboard虽然默认未设置对外暴露的nodePort,但从数据上我们可看出近70%用户选择暴露30001端口,因而我们可在某种程度上将30001端口的资产与Kubernetes Dashboard进行关联。

3.3.2 资产脆弱性分析

笔者对Kubernetes Dashboard的脆弱性进行了分析,在其早期版本中(v1.10.1之前)存在未授权访问风险,用户在按照官方文档所给方式部署完成后,默认情况下,我们需要先执行kubectl proxy,然后才能通过本地8001端口访问Dashboard。但是,如果直接将Dashboard端口映射在宿主机节点上,或者在执行kubectl proxy时指定了额外地址参数,如:

kubectl proxy --address 0.0.0.0 --accept-hosts='^*$'

那么所有能够访问到宿主机的用户,包括攻击者,都将能够直接访问Dashboard

另外,默认情况下Dashboard需要登录认证,但是,如果用户在Dashboard的启动参数中添加了–enable-skip-login选项,那么攻击者就能够直接点击Dashboard界面的跳过按钮,无需登录便可直接进入Dashboard关于如何设置–enable-skip-login,在v1.10.1前,实则是无需配置的,通过在Kubernetes Dashboard的Web登录界面点击“跳过”按钮即可访问,也是因为这个原因,安全意识较为薄弱的用户直接将早期版本以默认的配置方式部署在互联网上使得攻击者无需花费丝毫力气就可以轻易浏览到Kubernetes集群的运行状态,因而在v1.10.1版本后,开发团队增加了显式配置的功能,需要用户在相应部署的yaml文件中指定–enable-skip-login参数配置才能开启未授权访问。

在测绘数据中,笔者在现有暴露的818个资产中未发现含有未授权访问的Dashboard, 由此我们也可以看出目前互联网已经很少有用户部署低版本(<v1.10.1)的Kubernetes Dashboard,实际上这也大大降低了Kubernetes集群失陷的风险。

3.3.3 安全建议

  • 将Kubernetes Dashboard升级至高于10.1的版本

四、总结

行文至此,云原生服务风险测绘分析Docker、Kubernetess篇告一段落,笔者认为,随着业务需求的不断变化,容器技术的不断演进,用户逐渐从使用Docker转变为使用Kubernetes, 由于Docker的生产落地时间较长,相应暴露风险呈减少趋势。与此同时,Kubernetes不断走向大规模落地应用,互联网暴露资产数量倍增,以未授权访问、容器逃逸为主的安全风险为开发者、运维人员、安全从业人员敲响了警钟。

下一篇笔者将针对云原生环境下的其它组件进行相应的测绘风险分析,欢迎各位读者持续关注,若有任何问题欢迎提出,互相交流学习。

参考文献

[1] 绿盟科技 2018年《容器安全技术报告》

[2] Docker CVE漏洞参考 https://www.cvedetails.com/product/28125/Docker-Docker.html?vendor_id=13534

[3] CIS Docker Benchmark https://www.cisecurity.org/benchmark/docker

[4] Kubelet server.go Github源码https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/server/server.go#L434:3

[5] https://github.com/kubernetes/kubernetes/pull/64187

[6] https://github.com/kubernetes/kubeadm/issues/732

[7] CIS Kubernetes Benchmark https://www.cisecurity.org/benchmark/kubernetes

[8] https://www.cvedetails.com/vulnerability-list/vendor_id-15867/product_id-34016/Kubernetes-Kubernetes.html

Spread the word. Share this post!

Meet The Author