昨天在 HN Attack Matrix for Kubernetes (microsoft.com) 上看到推 MS 安全博客写的一篇关于 Kubernetes 安全问题的博客,感觉看完还不错感觉对 Kubernetes 相关的维护人员、开发人员挺有帮助。虽然在原文中有挺多重复的内容,但为了保证原汁原味尽可能的做了保留。

原文 Attack matrix for Kubernetes 由 Yossi Weizman 发表在微软安全博客

以下是正文:


Kubernetes 是至今开源项目中增长最快的项目之一并且也是最受欢迎的容器编排系统,他也是现在许多公司技术栈中非常重要的一环。容器的灵活性以及可伸缩性促使了许多开发者将他们的服务前移到 Kubernetes 上。纵使 Kubernetes 带来了非常多的优势,但它也带来了需要值得考虑的安全挑战。因此获悉在现有的容器化环境中将会面临许多安全问题是非常重要的,特别是在 Kubernetes 中。

MITRE ATT&CK® 框架是一个覆盖已有策略和技术的网络攻击相关知识框架,从多个攻击的阶段(策略)阐述了已知分别在 Windows 和 Linux 平台上的攻击方法并最终形成多个矩阵。这些矩阵可以帮助相关的组织了解他们当前环境中的攻击面并且保证他们能够有充分的检测手段来发现风险和充足的方案来缓解。MITRE ATT&CK® 框架包括了一下几个策略:

当我们在 Azure 安全中心开始梳理 Kubernetes 的安全整体状况时,我们注意到虽然在在 Linux 或者 Windows 上攻击技术可能有很大的差异但实际上他们在策略上是几乎相近的。举个例子,前四个策略从 OS 层面转向容器集群就像这样:

  1. 「初始访问计算机」 变成 「初始访问容器集群」;
  2. 「计算机上的恶意代码」 变成 「集群中的恶意行为」;
  3. 「保持计算机访问能力」 变成 「保持集群访问能力」;
  4. 「在计算机中提权」 变成 「在集群中提权」。

所以我们创建了第一个 Kubernetes 攻击矩阵:一个聚合了与容器编排安全主要技术的 ATT&CK 风格的矩阵(主要集中在 Kubernetes 上)。

kubernetes-security-matrix

你可以看到这个矩阵包含了 9 项策略,每一项都包含了若干种可以让攻击者用来达到不同目的的技术。下面我们将会一项一项的去讲。

1. 初始访问

「初始访问」包括了多种主要用于获取资源访问权限的技术,在容器化环境中这些技术让攻击者触及集群成为可能。这部分的访问权限可以直接被获取,或者间接的通过部署在集群上恶意或者不安全的(易被攻击)资源获取到。

使用云厂的凭证

那些托管在公有云(比如说 Azure 的 AKS,GCP 的 GKE,AWS 的 EKS)上的 Kubernetes 集群,不安全的云凭证可能导致集群被接管。如果攻击者拿到了他们账号的权限(例如说账号密码或者凭证)那么就能一定程度上控制集群。

仓库里不安全的镜像

如果将不安全(此处定义为:易被攻击、易被感染或者恶意)的镜像部署在集群上,可能导致集群被侵入。攻击者如果有私有仓库的权限那么就可以往上面 Push 他们预设好的污染镜像,然后用户又恰好去 Pull 了,那么也可能出现攻击。并且,如果常常使用不受信的公共仓库中 latest 镜像也可能中招。

如果在不受信的基础镜像上构建也可能是同样的结果。

Kubeconfig 文件

Kubeconfig 常常在 kubectl 中使用,这其中包含了集群的地址和访问凭证。如果集群是托管在公有云上的(例如 AKS 或者 GKE)那么它是通过云命令(cloud cli)下载到客户端(译者注:也有一些厂商是走 HTTPS 下载的,比如 Digitalocean、阿里云或者华为云)。如果攻击者也拿到了 kubeconfig 那么也是能够访问到集群的(比如通过让用户使用注入的 kubectl)。

易被攻击的应用

如果在集群上跑一个易被攻击的公开服务,那也是能够让外部拿到集群权限的。如果一个容器运行了一个容易被远程执行代码的应用就可能被利用。如果 Service Account 挂载到容器里,那么攻击者可以直接用他来访问 APIServer(这是 Kubernetes 的默认行为。译者注:权限够不够是另说,但 SA 确实是具备一定的权限,至少是一定范围内的)。

暴露 Kubernetes Dashboard

Kubernetes Dashboard 是一个基于网页用户界面用来监控和管理集群,默认情况下他只在集群内网暴露(只提供 ClusterIP)。如果这个面板被暴露到外部,比如公网,它是可以允许被匿名使用的(译者注:在 1.7 版本中默认开启了认证)。

2. 执行

「执行」 包括了很多被攻击者用来在集群里面运行他们的代码的技术。

附着(Exec)到容器

攻击者如果有权限执行 exec 命令(例如 kubectl exec)那么就可以在容器里跑他们的恶意代码。比如说可以拿合法的镜像(比如 Ubuntu 一类的系统镜像)作为他们的后门容器,然后在上面跑恶意代码。

新起容器

攻击者可能尝试通过起一个新的容器来跑他们的代码,比如说如果攻击者有权限部署 Pod 或者控制器(Kubernetes Controller)那么就能这么干。

应用漏洞

如果应用本身提供远程执行或者通过漏洞可以远程执行代码的话,那么也能够为攻击者提供在集群中执行代码的能力。如上面所说如果 Service Account 挂载到容器里,那么攻击者可以直接用他来访问 APIServer。

在容器里运行 SSH 服务端

如果在容器里运行 SSH 服务端也能被攻击者利用,如果攻击者获取了合法的凭证,无论是通过暴力尝试还是其他手段(例如钓鱼)他们都能通过 SSH 进到容器里。

3. 持久化控制

「持久化控制」一系列技术是能够让攻击者能够持续拥有访问权限的技术以防他们丢失了初始的据点。

后门容器

攻击者可以使用 Kubernetes 控制器例如说 DaemonSet 或者 Deployments 来保持有一定量跑着他们恶意代码的容器在集群内一个或者多个节点上。

可写的 HostPath 挂载

HostPath 卷可以把宿主机上的目录或者文件挂到容器里,攻击者如果有权限创建一个容器挂一个可写的 HostPath 那么就能够能够持久化一些东西到下层宿主上(译者注:比如说恶意代码之类甚至是宿主的关键文件)。比如说可以创建一个 cron job 到宿主上。

Kubernetes 定时任务

Kubernetes 任务系统可以创建一个或者多个 Pod 并且保证他们执行成功,这就可以被拿来批处理去执行有限的任务。 攻击者就可以拿来有计划的通过容器在集群里跑一些恶意代码。

4. 提权

「提权」技术可以让人攻击者用来获取比现有更高的权限,在容器环境包括了在容器中访问宿主机、在集群共获取更高的权限甚至是访问云上的资源。

特权容器

特权容器是拥有上所有能力(Linux Capabilities)的容器可以做很多宿主层面的事情,它不像普通容器那样有那么多的限制。不严谨的说,在特权容器里做的操作几乎等同于直接在宿主上操作。如果攻击者能够访问或者有权限创建一个特权容器,那么他们就能够访问容器所在宿主的资源。

集群 Admin 角色绑定

RBAC 可以管控 Kubernetes 上的各种身份的行为准许,是一个非常关键的安全功能。如果攻击者能够创建 Role Binding 或者 Cluster Role Binding 到集群 Admin 角色(内建的高权限角色)或者更高权限的角色,那么也能够达到提权的目的。

HostPath 挂载

HostPath 挂载可以让攻击者访问下层宿主机,从而达到破坏宿主机的目的(详见 「可写的 HostPath 挂载」)

访问云上资源

如果 Kubernetes 集群是部署在云上,在某些情况下攻击者可以通过容器实现访问其他集群外资源。举个例子,在 ASK 的节点中,都存储服务主体的凭证在 /etc/kubernetes/azure.json, AKS 用这个凭证来创建和管理 Azure 的资源。

大多数情况下,服务主体拥有集群资源组(译者注:原文是写 contributor permissions)管理权限,如果攻击者可以用这个权限去访问或者修改云上资源。

5. 防御绕过

「防御绕过」技术是攻击者用来反侦查并且隐藏他们行为所用。

清除容器日志

攻击者可能删除掉在被污染容器中的应用或者 OS 日志来避免他们的行为被发现。

删除 Kubernetes Event

一条 Kubernetes Event 可以用来描述集群中的状态改变或者失败事件,例如容器创建、镜像拉取、Pod 调度。

Kubernetes Event 在甄别集群状态变化上起到非常大的作用,所以攻击者极有可能通过删除 Event(例如使用 kubectl delete events-all)来防止他们的行为被发现。

相似的Pod / 容器名称

那些通过控制器比如说 Deployment(原文中有 typo)或者 DaemonSet 创建的 Pod 都会有一个随机的后缀,攻击者可以用这个机制来创建一个长得很像是控制器创建的 Pod 来伪装后面 Pod。比如,创建一个恶意 Pod 起名叫 coredns-{DS Hash}-{随机后缀} 看起来就很像是 CoreDNS Deployment 创建出来的(原文此处写的 Pod 名是 coredns-{random suffix} 但这个格式明显不是 Deployment 创建的)。

并且攻击者可以把他们的 Pod 放到 kube-system 里面(这边是大多数管理容器存放的地方)。

通过代理连接

攻击者可能用代理服务器来隐藏他们的源 IP,特别是像 T_R(译者注:不便全写)这样的匿名网络来访问应用或者 APIServer。

6. 凭证访问

「凭证访问」技术常常用来「偷」凭证访问资源。在容器环境中,凭证包括了运行的应用、身份、存储在集群中的密钥或者云厂凭证。(译者注:个人对于这边的理解是,偷用合法的凭证去访问资源)

获取 Kubernetes Secrets

Kubernetes Secret 常常让用户用来存储和管理像密码这样的敏感信息,可以通过引用在 Pod 内被使用。攻击者可以在 APIServer 中获取这些 Secret(比如说通过 Pod 中的 Service Account)就可以拿到里面的可能包括可以访问各种各样服务凭证的敏感信息。

挂载服务主体

当集群是部署在云上的时候,攻击者可以通过访问容器来拿到云上凭证,例如在 AKS 上每个节点都包含了服务主体的凭证(详见「访问云上资源」)。

获取容器 Service Account

Service Account(SA)是一个应用的身份,默认情况下 Kubernetes 会为每个 Pod 在创建的时候挂载一个 SA。使用在 Pod 内可以使用 SA 访问 APIServer。攻击者可以进入 Pod 通过 SA token 对集群做一些操作(取决于 SA 给到的权限,默认挂载位置在 /var/run/secrets/kubernetes.io/serviceaccount/token)。如果 RBAC 没开,那么 SA 就拥有无限的权限(译者注:目前在 Kubernetes 默认是无权的),如果开了的话那就看 SA 跟那个 Role 做了什么类型的 Binding。

配置文件中的应用凭证

开发者常常会在 Kubernetes 的配置文件中(译者注:比如 Pod Spec 或者 Configmap)存储他们的应用凭证(译者注:例如像 MySQL 密码一类的),这类行为在受监控 Azure 安全中心监控的集群中很常见。攻击者如果能够访问这些配置或者通过 APIServer 亦或者从开发者入口拿到,那么就可以偷偷的用这些存储的凭证。

7. 发现

「发现」包括了一系列技术让攻击者探索他们已获取权限的环境,帮助他们横向渗透并且获取额外资源的权限。

访问 Kubernetes APIServer

Kubernetes APIServer 集群的 gateway,集群上的操作都是通过各式各样请求发向 RESTful API 实现的。集群上部署的所有组件的状态都可以通过 APIServer 被获取到,攻击者可以向 APIServer 发送请求去探测集群并且获取这些信息包括容器、Secrets 以及集群上的其他资源。

访问 Kubelet API

Kubelet 是 Kubernetes 部署在各个节点上用来负责分配到该节点上执行的 Pod。Kubelet 暴露了一个无鉴权要求的只读 API(TCP 端口 10255)。攻击者只要能够访问节点的网络(比如在容器里跑恶意代码)就可以向这个 API 发起请求。特别的说下,https://[NODE IP]:10255/pods/ 这个接口可以拿到所有正在这个节点上运行的 Pod,https://[NODE IP]:10255/spec/ 可以获取宿主的 CPU、内存等等节点信息。

网络拓扑

攻击者可以遍历整个集群网络来获取运行中的应用信息包括扫描已知的攻击点。默认情况下,Pod 间的网络是互通的,所以一旦攻击者拿下了一个容器就能够触及集群所在平面的网络。

访问 Kubernetes Dashboard

Kubernetes Dashboard 是一个基于网页用户界面用来监控和管理集群,上面的用户可以通过其 Service Account 来执行集群管理操作(具体权限取决于实际的 Role Binding)。攻击者可以通过其他的容器来访问 Dashboard,那么就能够它的身份凭证来获取集群里各种各样资源的信息。

实例元信息接口

云厂提供了实例元信息服务可以获取 VM 网络配置、磁盘、SSH PubKey 一类的信息,这个服务只能在 VM 内的网络层面直接访问(译者注:例如 VPC 网络平面)。攻击者通过进入到其中一个容器,那么也就能够访问这个 API 获取到下层节点的信息。举例说,Auzre 中通过 http:///metadata/instance?api-version=2019-06-01 可以去到所有节点的元信息。

8. 横向渗透

「横向渗透」包括了一系列技术让攻击者在被攻击者的环境中「渗透」,在容器环境中,可以是从一个容器访问云上各式各样的资源、通过容器渗透到下层宿主、渗透到云上环境等等。

访问云上资源

攻击者可以通过一个已被感染的容器渗透到云上环境(详见「访问云上资源」)

容器 Service Account

攻击者可以使用挂载在容器中的 Service Account 访问 APIServer 从而获取更多的集群资源(详见「获取容器 Service Account」)。

集群内部网络

Kubernetes 集群内部网络默认是相互可达,如果攻击者能够访问其他一个容器那么也意味着他可以以此访问集群内的其他容器。

配置文件中的应用凭证

有的开发者会在 Kubernetes 配置文件中例如像 ENV 中写 secret,那么攻击者拿到配置后就能够去访问对应的一些资源(详见「配置文件中的应用凭证」)。

宿主上可写的挂载卷

攻击者在挂载这类卷的容器上就有可能渗透到宿主中(详见「HostPath 挂载」)。

访问 Kubernetes Dashboard

攻击者如果可以访问到 Kubernetes Dashboard 的话就可以管理集群资源也可以通过内建的执行能力在容器上运行恶意代码(详见「访问 Kubernetes Dashboard」)。

访问 Tiller 入口

Helm 是 CNCF 维护的 Kubernetes 包管理工具,Tiller 是 Helm 截止 version 2 都在用的服务端组件。

Tiller 会暴露一个 gRPC 入口在集群上(端口 44134),默认情况下这个端口不会要求鉴权,所以攻击者就可以在随意的其他容器上跑一些恶意代码访问 Tiller 然后以此来做一些操作(通常来说 Tiller 的 Service Account 有比较高的权限。译者注:比如像部署)

9. 冲击

冲击策略包括一系列攻击者用来破坏、滥用、影响环境正常影响的技术。

数据损坏

攻击者可能删除集群中的数据或者资源,比如说删除 Deployment、配置、存储和计算资源等。

资源劫持

攻击者可以滥用被感染的资源来运行一些任务,常见的像是挖矿。如果能够进到集群上的容器或者创建一个新容器的话,那就可能发生。

DoS

攻击者可以做 DoS 攻击让服务不可用,在容器集群里可能是屏蔽容器的、下层宿主的或者 APIServer 的访问能力。

小结

了解容器环境的攻击面是构建安全环境的第一步,上面的这个矩阵可以帮助组织了解他们当前的防御是否覆盖了针对 Kubernetes 的不同威胁。Azure 安全中心可以帮助保护你的容器环境,了解更多关于 Azure 安全中心的容器安全协助