SteamCloud Hackthebox

SteamCloud Hackthebox

Table of contents

No heading

No headings in the article.

Welcome to the new blog in the Hack The Box series. Since I am trying to learn more about Kubernetes security, I was looking for a box related to Kubernetes on Hack The Box and found Steamcloud

let us spin up our box, and start the VPN with the OVPN file provided, after getting the IP of the box, let us do a basic Nmap scan on the IP**

Nmap scan gives basic information on open ports and services, let us try to connect with port 8443 in the browser.

Accept the risk and continue,

Forbidden, which we already knew in Nmap scan, by default nmap does not scan all 65,535 ports. So let us try to expand our scanning scope, initially, I tried all ports scanning with all default scripts, but it took much longer than expected, I found a few open ports and then tried to enumerate those with a shorter Nmap script

and found a few open ports, let us try to look up what default services run on these ports. The first port, 2379, says etcd-client; you can guess it as the etcd component comes in the picture. Other running components would be part of Kubernetes architecture (kubelet, API-server). These are pure guesses; let us now search for the Kubernetes pentest guide.

https://cloud.hacktricks.xyz/pentesting-cloud/kubernetes-security

we can see that 10250 is the default port for Kubelet service

let us try to access pods via curl or browser

We can see a list of all pods, but this is only a read-only view, and we won't be able to enumerate much further on this, so let us try to use a new utility called

kubeletctl

You can install kubeletctl using

wget https://github.com/cyberark/kubeletctl/releases/download/v1.9/kubeletctl_linux_amd64 && chmod a+x ./kubeletctl_linux_amd64 && mv ./kubeletctl_linux_amd64 /usr/local/bin/kubeletctl

Reference: https://github.com/cyberark/kubeletctl

As we can see in the examples, let us try to view pods and scan for tokens or RCE using the above commands.

For RCE,

We can see two pods are vulnerable, and we can execute commands on these pods, namely kube-proxy-7fgk4 and nginx pods.

I tried to get a proper reverse shell, but it failed. Enumerating further the directory of the nginx pod, I found various directories and found a user flag.

(Note: This was not the intended way to get a user flag but let us continue further)

Next, we want to get a foothold on the pod as a root user or at least access the root directory to get the root.txt file

Scratching my head, I could think of a way we can do this might be through the shared volumes concept in Kubernetes, the way this works is a volume is created on the host machine and a volumeMount is created on the underlying pod such that the contents, that is the files on pod can be stored on this volume

Let's not get distracted from our goal: to gain access to the file systems on the host machine. To achieve this, we need to find a way to create a pod inside this host machine and use 'hostPath' to mount the host machine's directory onto the pod. I hope this makes sense. I will create a short video at the end to explain it better.

Since we now have access to the initial container, nginx, we can try to obtain the token and CA certificate from this pod. (A service account is always created when starting a pod, so the nginx pod would have a token.)

We can once again use the kubeletctl utility to scan for tokens.

kubeletctl --server 10.10.11.133 scan token

Using a token of the nginx pod,

echo token="eyJhb..."

Sadly we can't use same technique to get ca certificate, but we can look up for default place where the ca crt is stored in a pod

https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/

I am storing this certificate on my machine as a 'ca.crt' file.

Now, let's check what rights we have by using the identity of this service account (using the token and 'ca.crt')

We do have permission to create a new pod using this service account

Great!!!😁

Now using https://kubernetes.io/docs/concepts/storage/volumes/#hostpath , we can create a new pod using the host volume and mount it on the pod

A template file for creating a new pod with host path ⬇️

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on host
      path: /data
      # this field is optional
      type: Directory

Also, I tried to take a better look at the nginx pod just to have a good view

You can use the above Yaml file or make a few tweaks like I did below

Just make sure to not change the hostPath: path parameter as it specifies that it will mount the whole directories of the host machine on my new pod and all those directories would be available inside /root path of my newly created pod, you can change this to any path you want by changing the mountPath parameter.

Now that we have a yaml/manifest file for our new pod, we can start this pod by following the command

kubectl --server=https://10.10.11.133:8443 --token=$token --certificate-authority=ca.crt get pods

You can see I have 2 failed pods 🫣 , It was my mistake specifying the wrong image name (Confirmed with the error name ImagePullbackOff)
But But we do have a running pod gimme-root-2, Now let us do the magic to access files of this pod and ultimately view files of the host system

As we have mounted all the files from the host machine to the container gimme-root-2, we can see from the above command that using ls /root

we can view all directories of the host machine, now we can easily view the user and root flag

This Box was satisfying enough for me to understand Kubernetes misconfigurations and exploits that can be used if hostPath is used 😁🥳🥳

Did you find this article valuable?

Support Pranav Patil by becoming a sponsor. Any amount is appreciated!