腾讯安全专家对kubernetes中间人劫持漏洞(CVE-2020-8554)的分析
Posted 腾讯安全威胁情报中心
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了腾讯安全专家对kubernetes中间人劫持漏洞(CVE-2020-8554)的分析相关的知识,希望对你有一定的参考价值。
长按二维码关注
腾讯安全威胁情报中心
一
漏洞简介
2020年12月8日,Kubernetes安全通告中披露了一个中间人劫持漏洞CVE-2020-8554。如果攻击者在Kubernetes集群中具有创建和更新Service和Pod对象权限,那么通过设置LoadBalancer或ExternalIP,攻击者能够劫持集群内其他Pod或者节点访问该ExternalIP的流量,并将其转发到攻击者创建的恶意Pod中,造成中间人攻击。
该漏洞影响Kubernetes所有版本,是设计上的缺陷,目前没有针对该漏洞的补丁更新。
以下是腾讯安全专家对Kubernetes基本架构、Kubernetes service的介绍,及kubernetes中间人劫持漏洞(CVE-2020-8554)成因的详细分析,供Kubernetes开发、运维、及网络安全研究人员参考。
二
Kubernetes基本架构
Kubernetes是一套容器集群管理系统,可以实现容器集群的自动化部署、自动扩缩容、维护等功能。由Google公司在2014年启动,最初源于Google内部的Borg。Kubernetes 拥有自动缩放、健康检查、服务发现、负载均衡、滚动更新、存储编排等等特性,为管理各种基础架构中相关分布式组件和服务提供了非常高效的解决方案。整体架构如下图所示:
Kubernetes架构中涉及到的一些概念:
1
负责整个集群的管理控制,用于监控、编排、调度集群中的各个工作节点。开发维护人员通过访问API Server,实现对kubernetes集群中各种资源的增加、删除、修改、查询等操作。Master节点通常会占据一个独立的服务器,基于高可用原因,也可能占据多台。
2
Node是Kubernetes集群中的各个工作节点,可以是物理机也可以是虚拟机,由Master管理,提供运行容器所需的各种环境,对容器进行实际的控制。一个Kubernetes集群中可以有多个Node节点,可以不断地将新Node节点加入到Kubernetes集群中。
3
Kubernetes管理的基本对象是pod,而不是容器。一个pod由一个或者多个关系密切的容器组成,它们共享环境、存储、网络空间,有着相同的生命周期,一起作为一个整体编排到Node节点上。
4
Pod可以赋予一个标签,通过标签选择器对Pod进行逻辑分组,并定义了分组访问策略。前端应用不需要关心后端Pod是否变化,只需要访问Service即可。一个service可以包含一个或多个pod。
三
Kubernetes service
3.1
192.168.100.0/24网段中,有5台服务器:
Master 192.168.100.100
Node① 192.168.100.101
Node② 192.168.100.102
Node③ 192.168.100.103
ServerN 192.168.100.104
其中192.168.100.100、192.168.100.101、192.168.100.102、192.168.100.103组成了一个Kubernetes集群,但是ServerN 192.168.100.104没有加入到集群中。即便如此,ServerN也可以和Kubernetes集群中的192.168.100.100、192.168.100.101、192.168.100.102、192.168.100.103相互通信,因为它们属于同一个网段。
在集群外部的ServerN 192.168.100.104,无法访问集群内部的service 10.96.0.1、也无法访问pod② 10.244.1.7、pod③ 10.244.2.4
3.2
如上图所示,netfilter在网络协议栈内加了5个挂载点,对应iptables的5条内置链,根据实际情况的不同,数据报文经过的链可能不同:
INPUT:处理输入本地进程的数据包;
FORWARD:处理转发到其他机器、network namespace 的数据包;
OUTPUT:处理本地进程的输出数据包;
在每条链上,都放置了一连串的规则,每个经过这条链的数据报文,都要将这"链上的所有规则匹配一遍,如果有符合条件的规则,则执行规则对应的动作:
链上的规则有些很相似,例如一些规则用于过滤IP或者端口,一些规则用于修改报文,这时,可以把具有相同功能的规则放在一起,组成一个集合,叫做“表”。不同功能的规则,放置在不同的表中进行管理。在iptables中,按优先级从高到低,有如下5种表:
raw表:用于去除iptables对数据包的连接追踪机制;
mangle表:修改数据包的IP 头信息;
filter表:控制到达某条链上的数据包是继续放行、直接丢弃、拒绝;
security表:用于在数据包上应用SELinux,不常用。
并不是每一条链都能挂上所有的表,以PREROUTING为例,它只能挂raw、mangle、nat三个表:
其他链能挂的表可以参加本节内容第一张图。
3.3
3.3.1 NodePort
3.3.2 LoadBalancer
NodePort可以让服务被集群外部的主机访问,更进一步,如果想让service能在互联网上被访问,可以采取LoadBalancer的发布方式。
3.3.3 ExternalIP
四
漏洞分析
4.1
由此引发了本文所述的CVE-2020-8554 kubernetes中间人劫持漏洞。
4.2
在了解Kubernetes基本架构、iptables规则后,现在可以来分析CVE-2020-8554 kubernetes中间人劫持漏洞底层原因了。
搭建了4台主机,均采用CentOS 7,Kubernetes 1.20.0:
k8smaster 192.168.100.100
k8snode1 192.168.100.101
k8snode2 192.168.100.102
k8snode3 192.168.100.103
采用python:3.7镜像创建一个pod,标签设为test: testpodlabel,namespace默认是default:
创建一个类型为NodePort的service:
查看pod的创建结果:
继续查看service的创建结果:
此时,如果访问一下k8snode1节点的80端口:
默认情况下没有web服务在k8snode1节点上监听80端口,所以此时curl访问结果是拒绝连接。
4.3
Kubernetes扩充了iptables默认的5条链,自定义了KUBE-SERVICES,KUBE-NODEPORTS,KUBE-POSTROUTING,KUBE-MARK-MASQ和KUBE-MARK-DROP等五个链。
访问service的虚拟IP,主要是通过 KUBE-SERVICES链来实现。在k8snode1节点上运行iptables -L -v -n -t nat,可以查看系统中nat表的所有规则,规则有点多,一步步分析。
从中可以看到,KUBE-SERVICES链附加在系统默认的PREROUTING和OUTPUT链上,所有到达系统的流量、进程即将发出的流量,都将经过KUBE-SERVICES链:
/*和*/之间,是Kubernetes在添加规则时加上的注释,从这些注释里面,我们可以找到创建的default/testservice有两行规则:
4.4
以上创建的pod、service都是在default namespace下,现在创建一个新的名为cve-2020-8554的namespace:
在cve-2020-8554 namespace下,创建一个劫持用的pod:
查看一下创建结果:
结果是符合预期的。现在再访问一下192.168.100.101:
这个结果就不一样了。在上文的“4.2. 搭建分析环境”中,因为没有web服务在k8snode1节点上监听80端口,所以curl访问结果是拒绝连接,但现在却可以顺利访问。这意味着192.168.100.101:80被劫持了!
在添加了externalIPs后,每个节点的KUBE-SERVICES中新添加了如下的iptables规则:
KUBE-MARK-MASQ继续不管,分析下面的两条规则的匹配条件:
4.5
查看创建结果:
可以看到EXTERNAL-IP显示的是pending,说明这个service还没有完全创建成功,必须要手动修改service的状态:
之后查看创建结果:
这条规则非常简单,没有其他的匹配条件,只要访问14.215.177.38并且端口是80,将跳转到KUBE-FW-SFLNKK2MY3Y4V7NO链。按照上文的分析,一步步追踪这条链:
进一步无条件地跳转到KUBE-SVC-SFLNKK2MY3Y4V7NO这条链:
再无条件地跳转到KUBE-SEP-VZTFGMFKC7VACONL这条链:
4.6
随着Kubernetes集群规模的增长,资源的可扩展性变得越来越重要,特别是对于那些运行大型工作负载的企业,其服务的可扩展性尤其重要。iptables是为防火墙而设计的,底层路由表的实现是链表,对路由规则的增加、删除、修改、查询等操作都涉及遍历一次链表。
在集群规模扩大时,随着服务的增多,pod的增多,将使得内核非常频繁地处理iptables规则的刷新,将带来严重的性能问题。为解决iptables的性能问题,Kubernetes引入了IPVS模式,在1.11版本中达到稳定。
IPVS仍然会依赖iptables规则,在开启IPVS模式后,以“4.4. ExternalIP”中所述配置,重新创建一个service,指定externalIPs为14.215.177.38,在k8snode1(192.168.100.101)上查看iptables规则,KUBE-SERVICES链仍然存在,如下所示:
和之前描述的已经不一样了,KUBE-SERVICES链中不再有单独的service的跳转规则,和externalIP相关的,是如下两条规则:
再看一下Kubernetes集群中创建的所有service:
这里实现了对整个Kubernetes集群访问14.215.177.38的劫持:
对比可以看到,在IPVS模式下,劫持情形更为严重。
4.7
1)iptables模式下,采用ExternalIP无法劫持集群外部IP,但LoadBalancer可以;
2)ipvs模式下,两者都可以劫持集群外部IP;
3)从上文分析中可以看到,在Linux内核中执行各种规则的匹配、链的跳转,是没有Kubernetes中namespace概念的,所以这种劫持是跨namespace的,一个恶意用户的劫持,能影响集群中其他所有的用户;
4)iptables规则遍布Kubernetes集群所有的master、node节点,所以劫持效果也遍布所有的master、node节点;
5)事实上,不仅可以劫持TCP流量,甚至可以劫持UDP流量,因此可以利用该漏洞实现对集群内部DNS的劫持,由此产生更严重的利用效果。
五
防御建议
六
参考链接
[Security Advisory]
CVE-2020-8554: Man in the middle using LoadBalancer or ExternalIPs
https://groups.google.com/g/kubernetes-security-announce/c/iZWsF9nbKE8
以上是关于腾讯安全专家对kubernetes中间人劫持漏洞(CVE-2020-8554)的分析的主要内容,如果未能解决你的问题,请参考以下文章