Infiltr8: Red-Book
Cloud & CI/CD PentestingKubernetes

Reconnaissance

>-

Overview

Most of the time, you will not directly interact with critical Kubernetes components. Instead, you must first gain a foothold in a Kubernetes pod, which then allows access to internal Kubernetes APIs. Because these pods often host web services, obtaining an initial foothold typically relies more on traditional web application pentesting skills than on Kubernetes-specific techniques.

This table sums up all the important ports to recon inside a Kubernetes cluster:

PortProcessDescription
443/TCPkube-apiserverKubernetes API port
2379/TCPetcdetcd,etcdAPI
6666/TCPetcdetcd
4194/TCPcAdvisorContainer metrics
6443/TCPkube-apiserverKubernetes API port (HTTPS)
8443/TCPkube-apiserverMinikube API port
8080/TCPkube-apiserverInsecure API port (HTTP, deprecated)
10250/TCPkubeletHTTPS API which allows full mode access
10255/TCPkubeletUnauthenticated read-only HTTP port: pods, running pods and node state (deprecated)
10256/TCPkube-proxyKube Proxy health check server
9099/TCPcalico-felixHealth check server for Calico
6782-4/TCPweaveMetrics and endpoints
30000-32767/TCPNodePortProxy to the services
44134/TCPTillerHelm service listening

Several Kubernetes Components to make note of:

  • Pod - The smallest object of the Kubernetes ecosystem, a group of containers running together on your cluster.
  • Node - What pods run on, each with a kubelet and kube-proxy.
  • Kubelet - Uses the Kubernetes API server to make sure pods are running; registers and reports nodes within a cluster.
  • Kube-proxy - A proxy that runs on each node in a cluster, maintaining and allowing network communication.
  • Cluster - A group of nodes (made up of a control panel node and a set of worker nodes) that run containerized applications.
  • Container - Packages an application and dependencies in an optimized way, most often as microservices.
  • etcd - A distributed key-value store for managing configuration, state, and metadata.
  • Kubectl - A command-line tool for communicating with a Kubernetes API server.
  • Kubernetes API Server - Front-end for the cluster, allowing other components to interact. Additionally, configures valid data for API objects.
  • Kube-scheduler - Default option for scheduling pods onto nodes.
  • Namespace - A virtual cluster allowing for provisioning of resources and establishing scope for pods, services, and deployments using unique naming.

Kubernetes Control Plane Exposure

Even though it shouldn’t be exposed to untrusted networks, some Kubernetes control planes are publicly exposed. This clearly facilitates our work because we can directly interact with the control plane API to retrieve important information.

Network Reconnaissance

# Basic Kubernetes service discovery
nmap -sS -p 6443,8080,10250,10255,2379,2380 <target_range>

# Comprehensive scan with service detection
nmap -sS -sV -p 6443,8080,10250,10255,2379,2380,30000-32767 \
     --script=ssl-cert,http-title <target_range>

# Aggressive scan for detailed information
nmap -A -p 6443,8080,10250,10255,2379,2380 <target_range>

# UDP scan for potential services
nmap -sU -p 53,123,161 <target_range>

K8S API Access

If the Control Plane is accessible the authentication enforcement might be disabled. A common misconfiguration in Kubernetes exposes API endpoints. By navigating to the IP address in a browser, the server may respond with a list of the API paths https://<CONTROL_PLANE_IP>. Thus you can try interacting with the Master API to see if you can retrieve information anonymously.

Sample curl requests to kube-apiserver that might reveal useful information:

# Check API Documentation
curl -k https://<CONTROL_PLANE_IP>:6443/swaggerapi

# Check API Status
curl -k https://<CONTROL_PLANE_IP>:6443/healthz

# Check API server version
curl -k https://<CONTROL_PLANE_IP>:6443/version

# Discover available API versions
curl -k https://<CONTROL_PLANE_IP>:6443/api
curl -k https://<CONTROL_PLANE_IP>:6443/apis
curl -k https://<CONTROL_PLANE_IP>:6443/api/v1

# Check for anonymous access
curl -k https://<CONTROL_PLANE_IP>:6443/api/v1/namespaces

# Comprehensive API discovery
curl -k https://<CONTROL_PLANE_IP>:6443/openapi/v2 | jq '.paths | keys[]'

# Check for metrics endpoint
curl -k https://<CONTROL_PLANE_IP>:6443/metrics

List of standard API endpoints:

/api  
/api/v1  
/apis  
/apis/admissionregistration.k8s.io  
/apis/apiextensions.k8s.io  
/apis/apiextensions.k8s.io  
/apis/apiregistration.k8s.io  
/apis/apiregistration.k8s.io/v1  
/apis/apps  
/apis/apps/v1  
/apis/authentication.k8s.io  
/apis/authentication.k8s.io/v1  
/apis/authorization.k8s.io/v1beta  
/apis/autoscaling  
/apis/autoscaling/v1  
/apis/autoscaling/v1beta  
/apis/batch  
/apis/batch/v1  
/apis/certificates.k8s.io/  
/apis/certificates.k8s.io/v1

Sample requests to access etcdAPI that might reveal useful information:

curl -k https://<CONTROL_PLANE_IP>:2379  
curl -k https://<CONTROL_PLANE_IP>:2379/version
etcdctl --endpoints=http://<CONTROL_PLANE_IP>:2379 get / --prefix --keys-only

kubelet API Access

Access to the read-only kubelet port 10255 can expose cluster configuration elements, such as pod names, location of internal files, and other configurations that might be used to identify sensitive information or craft other attacks.

# Check kubelet read-only API (deprecated)
curl -k http://<target>:10255/pods

# Test kubelet API authentication
curl -k https://<target>:10250/pods

# Enumerate running pods
curl -k https://<target>:10250/runningpods/

# Check kubelet metrics
curl -k https://<target>:10250/metrics 

If the kubelet API is accessible you can use Kubeletctl to interact easily with it. Some useful kubeletctl commands are given here.

etcd API Access

The etcd API stores the entire state of the Kubernetes cluster, including secrets, configuration data, and service account information. If the etcd service is accessible over the network without proper authentication or encryption, it represents a critical security risk. Detecting exposed etcd endpoints allows us to verify service availability, enumerate cluster members, and assess health status.

etcd Service Detection:

# Check etcd accessibility
curl -k https://<target>:2379/version

# Enumerate etcd members
curl -k https://<target>:2379/v2/members

# Check etcd health
curl -k https://<target>:2379/health

etcd Data Enumeration:

# List all keys (if accessible)
curl -k https://<target>:2379/v2/keys/?recursive=true

# Enumerate Kubernetes secrets
curl -k https://<target>:2379/v2/keys/registry/secrets

# Check for service accounts
curl -k https://<target>:2379/v2/keys/registry/serviceaccounts

Cloud Provider Discovery

# DNS enumeration for EKS clusters
dig +short <cluster-name>.<region>.eks.amazonaws.com

# S3 bucket enumeration for cluster configs
aws s3 ls s3://<bucket-name> --recursive | grep -i kube

# CloudTrail analysis for cluster activities
aws logs describe-log-groups | grep -i eks

SSL Certificate Inspection

# Extract certificate information
echo | openssl s_client -connect <target>:6443 2>/dev/null | \
openssl x509 -noout -text

# Certificate Subject Alternative Names
echo | openssl s_client -connect <target>:6443 2>/dev/null | \
openssl x509 -noout -text | grep -A1 "Subject Alternative Name"

# Certificate validity and issuer
nmap --script ssl-cert -p 6443 <target>

Internal Enumeration (From Compromised Pod)

Once a pod is compromised, internal enumeration becomes significantly more effective. Kubernetes automatically mounts a service account token inside most pods, which can be used to authenticate against the Kubernetes API and enumerate cluster resources based on the assigned RBAC permissions.

However, kubectl is not always available inside containers, either due to minimal images or security hardening. In such cases, direct interaction with the Kubernetes API using tools like curl becomes essential for performing enumeration and permission discovery.

Container Environment Discovery

Depending on the privileges associated with this service account token, the easiness of rooting the cluster can change.

# Check if running in Kubernetes
ls -la /var/run/secrets/kubernetes.io/serviceaccount/

# Examine service account token
cat /var/run/secrets/kubernetes.io/serviceaccount/token

# Check namespace
cat /var/run/secrets/kubernetes.io/serviceaccount/namespace

# Examine CA certificate
cat /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

# Environment variables
env

Network Environment Analysis

Retrieving the following information will help you map the internal cluster network and facilitate the pivoting step.

# Check network interfaces
ip addr show

# Examine routing table
ip route show

# Check DNS configuration
cat /etc/resolv.conf

# Test internal DNS resolution
nslookup kubernetes.default.svc.cluster.local

Internal Service Enumeration

# Discover services via DNS
nslookup kubernetes.default
nslookup kube-dns.kube-system

# Enumerate all services in default namespace
kubectl get services

# Discover services across all namespaces
kubectl get services --all-namespaces

# Check for exposed NodePort services
kubectl get services --all-namespaces -o wide | grep NodePort

Network Scanning from Pod (requires network pivoting):

# Scan internal cluster network
nmap -sn 10.0.0.0/8

# Scan for common Kubernetes services
nmap -p 6443,8080,10250,10255,2379,2380 10.0.0.0/8

# Scan service network range
nmap -p 80,443,8080,8443 <service_cidr>

RBAC and Permission Enumeration

Service Account Analysis:

# Check current service account
kubectl auth whoami

# Test permissions with can-i
kubectl auth can-i --list

# Check specific permissions
kubectl auth can-i get pods
kubectl auth can-i create pods
kubectl auth can-i get secrets

# Enumerate cluster roles
kubectl get clusterroles

# Check role bindings
kubectl get rolebindings --all-namespaces
kubectl get clusterrolebindings

Advanced Permission Discovery:

# Use kubectl-who-can for detailed analysis
kubectl who-can get pods
kubectl who-can create pods --all-namespaces

# Check for privileged service accounts
kubectl get serviceaccounts --all-namespaces -o yaml | \
grep -A5 -B5 "automountServiceAccountToken: false"

ConfigMap Analysis

# List all configmaps
kubectl get configmaps --all-namespaces

# Extract sensitive information from configmaps
kubectl get configmaps --all-namespaces -o yaml | grep -A20 -B5 -i "password\|token\|key\|secret"

# Check for kubeconfig in configmaps
kubectl get configmaps --all-namespaces -o yaml | grep -A10 -B5 "kubeconfig\|\.kube"

Cluster Discovery

Understanding the cluster’s layout is a critical step in Kubernetes pentesting. Cluster discovery and architecture mapping involve identifying the nodes, services, and overall topology of the environment.

By mapping the cluster, we can determine which nodes host critical workloads, how network traffic flows, and where sensitive resources are located. This information is essential for planning further enumeration and potential lateral movement.

Node Discovery

# List all nodes
kubectl get nodes -o wide

# Get detailed node information
kubectl describe nodes

# Check node labels and taints
kubectl get nodes --show-labels

Network Policy Analysis

# Check for network policies
kubectl get networkpolicies --all-namespaces

# Analyze ingress controllers
kubectl get ingress --all-namespaces

# Check for service mesh components
kubectl get pods --all-namespaces | grep -E "(istio|linkerd|consul)"

Pod Security Analysis

# Check for privileged pods
kubectl get pods --all-namespaces -o yaml | grep -i "privileged: true"

# Find pods with host network
kubectl get pods --all-namespaces -o yaml | grep -i "hostNetwork: true"

# Check for host path mounts
kubectl get pods --all-namespaces -o yaml | grep -A5 -B5 "hostPath"

RBAC Configuration Review

# Analyze cluster admin bindings
kubectl get clusterrolebindings -o yaml | grep -A10 -B10 "cluster-admin"

# Check for wildcard permissions
kubectl get clusterroles -o yaml | grep -A5 -B5 "\*"

# Find service accounts with cluster-admin
kubectl get clusterrolebindings -o yaml | grep -A10 "cluster-admin"

Service Account Token Usage

Once a service account token is retrieved from a compromised pod, it can be used to authenticate directly against the Kubernetes API server. This token allows interaction with all previously described API endpoints, with access limited only by the RBAC permissions assigned to the service account.

Even in the absence of kubectl, we can leverage the token to perform enumeration, query cluster resources, and retrieve sensitive information by sending authenticated HTTP requests directly to the Kubernetes API.

kubectl --token=$TOKEN --certificate-authority=$CERTIFICATE --server=https://<api_server>:6443

Automated Enumeration Tools

# External scanning
kube-hunter --remote <target_ip>

# Internal scanning from pod
kube-hunter --pod

# Network range scanning
kube-hunter --cidr <cidr_range>

# Detailed report
kube-hunter --report json --remote <target_ip>

Detection Evasion Techniques

During reconnaissance, simple traffic obfuscation techniques can be used to blend API requests with legitimate Kubernetes activity. One common approach is to modify the HTTP User-Agent header to mimic standard Kubernetes clients, such as kubectl.

While this does not bypass authentication or authorization controls, it can reduce suspicion in logs and make reconnaissance traffic less distinguishable from normal cluster operations.

# Use different user agents
curl -k -H "User-Agent: kubectl/v1.20.0" https://<target>:6443/

Resources

CLI kubectlkubernetes.io GitHub - cyberark/kubeletctl: A client for kubeletgithub.com GitHub - aquasecurity/kube-hunter: Hunt for security weaknesses in Kubernetes clustersgithub.com trustedsec.comtrustedsec.com

On this page