本篇介绍CICD中的K8S安全,之前发过关于Gitea的安全,感兴趣的公众老爷们可以去看看CICD之 Gitea Security,关于k8s的安全,也是边摸索边看,写的不好的地方多多担待
介绍
众所周知,Kubernetes 安全性很难在第一次就做好,特别是有如此多的移动部件、资源、RBAC、云管理 IAM、其他相邻 VPC 和计算、服务或应用程序级漏洞,或者在集群设置期间简单地使用易受攻击的配置,或者即使在工作负载编排阶段也是如此。
在 Kubernetes 集群上运行了多次渗透测试,跨各种云提供商的托管集群以及托管在本地和云计算实例上的独立集群。无论设置如何,我们都看到了很多常见的错误配置导致存在安全风险
漏洞和错误配置
大多数在 Kubernetes 中成为安全漏洞的错误配置都是由各种可能的配置选项引起的,这些配置选项可用于创建集群、设置工作负载、配置网络策略以及使用身份验证和授权。
基于网络/服务可见性的错误配置
Kubernetes 具有广泛的外部和内部攻击面 - Kubernetes 管理员通常依靠网络(基于云或其他方式)防火墙来限制对 API 服务器、负载均衡器和 NodePort 的访问。
例如,对于 AWS EKS 集群中 NodeGroup 中的节点,AWS 安全组用于限制 SSH 访问、对 API 服务的访问,甚至限制对 LoadBalancer 的访问(该 LoadBalancer 设置为允许用户访问托管在其中的应用程序/产品)集群。
一个危险的可能性是运行 Kubernetes HTTP API 代理服务器,通常使用允许在默认端口 8001 上使用 kubectl kubeconfig kubectl proxy --address 0.0.0.0 --accept-hosts ^.* 用户的权限不受限制地访问 API 服务器的命令 。默认情况下,HTTP 代理不允许任何不满足以下正则表达式的主机访问 ,但通过添加该 参数,API 会接受所有指定接口上的请求。 ^localhost$,^127.0.0.1$,^[::1]$ --accept-hosts ^.*
kubectl proxy 命令在所有接口上公开控制平面 API
使用 kubectl 代理访问 API
在内部,如果网络策略较差或缺失,通过 Pod 访问服务会带来另一个攻击面。
对 Pod(在任何命名空间中)具有 shell 访问权限的攻击者可以运行端口扫描并识别 Pod 网络中由于业务限制而不应可见的服务。配置错误的网络策略可能会破坏可能为模拟应用程序层租户隔离而设置的隔离。
最后,在托管集群上,通过同一 VPC 上的计算机访问节点 SSH/其他服务也经常被忽视。这是一个有趣的攻击场景,因为对同一 VPC 中的不同计算具有 shell 访问权限的用户可能能够访问受保护的服务。
以下是从相邻计算机对控制计划节点和工作节点进行端口扫描的情况。
来自相邻计算的控制平面节点的端口扫描
来自相邻计算的工作节点的端口扫描
过于宽松的卷安装错误配置
通常, volumeMount 可能会使用危险的 主机路径 ,导致 pod 获得它们不应该拥有的文件系统访问权限。
危险的 VolumeMount 可以让 Pod 访问底层节点的文件系统,这可能会危及整个集群。
危险的卷安装和主机路径
攻击者可以在上面所示的 pod 中使用 pod shell,并使用危险的挂载点逃逸到底层节点主机
通过pod逃逸到底层节点
暴露的只读端口配置错误
某些集群被配置为公开可通过节点上臭名昭著的 kubelet 端口 TCP 10255 访问的只读信息服务,从而允许未经身份验证地访问有关整个集群的信息,包括有关所有 pod、服务、命名空间、部署作业等的信息。简单的 cURL 请求,例如 curl http://
通过 TCP 10255 ReadOnly 未经身份验证的端口提取信息
如果端口可通过互联网访问(Censys 搜索将向您显示有趣的结果😱)或云帐户内的另一个相邻计算,这显然是一个更大的问题。
10255端口暴露在互联网上的机器(可能是蜜罐,也可能是真实的机器)
权限和特权 RBAC 管理不佳
Kubernetes RBAC 是通过使用关联(角色绑定/集群角色绑定)将权限(动词)作为一个组(角色/集群角色)分配给用户、组或服务帐户来实现的。
基本上,可以通过与角色绑定绑定在一起的角色为用户或服务帐户分配权限(或一组权限)。角色和角色绑定仅限于特定的命名空间,而 ClusterRoles 和 ClusterRoleBindings 是集群范围内的。
我遇到的一个常见的错误配置是,将特权过高的角色绑定和集群角色绑定分配给任意用户、默认服务帐户,甚至更糟糕的情况分配给该 system:anonymous 帐户。下面是一个通过 ClusterRoleBinding 具有集群管理员访问权限的特权服务帐户的示例 app-admin-deployer 。
具有 cluster-admin 角色的自定义 clusterrole 绑定
cluster-admin clusterrole 绑定到 app-admin-deployer-sa 服务帐户
服务帐户内的秘密
Secret 包含构建工作 kubeconfig 文件所需的所有关键元素
攻击者可以使用 ca.crt 和 token 从这里成为集群管理员。这两个值也可以通过 pod 挂载的文件系统 /var/run/secrets/kubernetes.io/serviceaccount 访问
Pod 挂载的文件系统中的 token 和 ca.crt
要发现特权过高的服务帐户或用户,请按照以下步骤操作
1列出所有 clusterroles ,为每个 clusterrole 获取指定的动词使用 -o json
1识别任何可以执行 CRUD 操作的特权 clusterroles 或臭名昭著的价值 “*”
1列出所有 clusterrolebindings 并查找 clusterrolebindings 具有特权 clusterrole 附加的
1对于其中的每一个 clusterrolebindings 用途,并确定 部分 -o json 下列出的服务帐户和用户 subjects
1对于每个有问题的每个主题 clusterrolebinding ,评估它的使用位置。
ClusterRoleBindings 提供跨整个集群的权限,并且在大多数情况下可以使用工具轻松检测到,但是每个命名空间的 RoleBindings 通常不会被工具检查。这些可用于构建集群范围的权限范围(想象一下跨每个命名空间的角色绑定,分别授予管理权限,使其与集群范围的管理相同)。在这种情况下,攻击者将分别使用每个名称空间的 ca.crt 和 token 来模拟集群范围的访问。
具有系统访问权限的角色绑定:匿名用户。默认命名空间无需授权即可读取
云 IAM、K8S 映射和集群到云逃逸
EKS 和 GKE 等云托管集群在云平台层和 Kubernetes 之间实现了 RBAC 映射层,以便任何配置为使用 Kubernetes 的云 IAM 用户都可以在集群内分配适当的角色。
例如,在 AWS 中,您可以按照本指南了解如何为未创建集群的 AWS IAM 用户分配 Kubernetes 用户角色。
https://kloudle.com/academy/allowing-iam-users-to-access-aws-eks-using-kubectl/
想象一个场景,其中存在一个 AWS IAM 用户(我们称之为用户 eksadmin ),该用户可以创建 EKS 集群,但无权访问 AWS S3 或 IAM 等其他服务。在这种情况下,如果 AmazonEKSNodeRole 附加到集群节点组 EC2 实例的角色权限过高,如下图所示,则 IAM 用户 eksadmin 将能够通过节点实例配置文件获得对这些其他权限的访问权限。
附加到 AmazonEKSNodeRole 的特权过高的角色
用户 eksadmin 可以生成一个 kubeconfig 文件并使用它来执行到正在运行的 pod 中。进入 Pod 后,用户可以直接使用 AWS cli,或者通过节点上的 IMDS 使用 STS 服务生成特权临时凭证。
Exec到pod以访问底层节点上的Instance Metadata服务
这些凭证将具有与 IAM 角色相同的权限 AmazonEKSNodeRole ,在本例中,该角色也将授予对 IAM 和 S3 的完全访问权限。
对于 GKE,访问 http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-env CA_CERT 端点包含、 KUBELET_CERT 和 的值 KUBELET_KEY ,它们是 kubelet 在将节点附加到 GKE 时使用的初始引导凭据簇。
GKE kube-env 在非屏蔽 GKE 节点上公开引导凭据
这些可用于构造 kubeconfig yaml 来访问集群或直接在命令行中使用
kubectl -s=https://cluster-server-ip
--client-certificate=/path/to/kubelet.crt
--client-key=/path/to/kubelet.key
--certificate-authority= /path/to/ca.crt
获取节点
然而,这仅适用于 禁用屏蔽节点 并启用旧元数据端点的 GKE 集群,这两者都是非默认设置,使得这种攻击在现代 GKE 集群中很少见。
此外,通过引导凭证获得的权限仅具有CertificateSigningRequests(CSR)权限,需要额外利用该权限来生成假CSR以升级权限。
除了 CSR 创建和获取权限之外,kubelet bootstrap 凭证没有任何有用的权限
对于非屏蔽 GKE 节点,您可以使用kubeletmein 等工具 自动为不存在的节点生成 CSR,并从 kube-controller-manager 获取证书作为回报,该证书可用于构建具有更高权限的 kubeconfig。
使用 CSR 进行虚假工作节点注册,并使用 kubeletmein 进行 kubeconfig 生成
GKE 通常通过其更现代的默认设置提供更难的攻击和利用体验。
公开的集群管理仪表板
管理 Kubernetes 集群的最常见方法是使用 kubectl 二进制文件。Kubectl 本质上是向 Kubernetes API 服务器发出 HTTP 和 websocket 请求。还有其他 UI 产品可用于与控制平面 API 交互,例如 Kubernetes 仪表板、Weave Scope、Lens 等。
通常,这些管理工具有身份验证要求,但在最坏的情况下,这些仪表板可以通过互联网访问,无需任何身份验证。快速 Shodan/Censys 搜索将为您提供一些非常有趣的结果😱
Censys 上公开的 Kubernetes 仪表板
这些是实时结果,因此建议您不要与使用 Censys 或 Shodan 发现的集群进行交互。
攻击者可以简单地选择一个目标、运行 Pod、关闭部署、执行运行中的 Pod、ping 扫描和端口扫描相邻的 Pod 并进行计算、提取令牌和证书、到达实例元数据服务端点、提取云环境变量和凭据并逃脱到云层。对于攻击者来说,可能性是无限的。
原文始发于微信公众号(暴暴的皮卡丘):CICD之Kubernetes 安全
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论