k8s攻防-窃取Service Account令牌获取集群权限及对应检测方式
字数 2272 2025-08-20 18:18:16
Kubernetes攻防:窃取Service Account令牌获取集群权限及防御措施
1. Kubernetes安全基础
1.1 Kubernetes架构组件
Kubernetes组件分为两大类:
Master (控制面板)组件:
- 协调集群中的所有活动
- 负责调度pods、处理进程、与云环境交互
- 存储所有集群数据
- 公开Kubernetes API供访问
Node组件(Worker Node):
- 通过kubelet、kube-proxy和container-runtime运行Kubernetes pod
1.2 RBAC(基于角色的访问控制)
RBAC控制用户或服务账户可以访问哪些API资源及授权操作:
- 操作(Actions/Verbs):get, create, apply, update, patch, delete, proxy, list, watch
- 角色:定义verbs作用于哪些API
- 角色绑定:将用户/服务账户与角色关联
2. 服务账户(Service Accounts)与令牌
2.1 服务账户基础
- 从Kubernetes v1.22开始,pods包含projected volumes,其中包含API访问token
- 未指定服务账户时,每个pod会添加默认服务账户(最小权限)
- 许多应用程序会创建和挂载高权限服务账户
2.2 服务账户令牌位置
容器内路径:
/var/run/secrets/k8s.io/serviceaccount
主机路径:
/var/lib/kubelet/pods/**/volumes/k8s.io~projected/**
包含CA证书、namespace和token,用于身份验证
3. 攻击方法:窃取服务账户令牌
3.1 攻击流程
- 攻击者获得k8s主机文件系统访问权限
- 枚举主机上的服务账户令牌
- 识别高权限服务账户
- 利用服务账户权限提升集群权限
- 实现集群完全控制
3.2 枚举脚本示例
for mydir in $(find /var/lib/kubelet/pods -name namespace -exec dirname {} \;); do
echo "Checking $mydir"
export cert=$mydir/ca.crt
export token=$mydir/token
export namespace=$mydir/namespace
export apiserver=$(netstat -n | grep 6443 | awk '{print $5}' | uniq)
echo "$cert $namespace $token $apiserver"
kubectl --certificate-authority=$cert --token=$(cat $token) \
--namespace=$(cat $namespace) --server=https://$apiserver auth can-i --list
done
4. 权限提升技术
4.1 利用Kubernetes Secrets
高风险Secret类型:
Opaque:用户自定义数据,常包含应用程序凭据kubernetes.io/service-account-token:服务账户令牌
攻击步骤:
- 攻击者获得有权在kube-system命名空间create和list secrets的服务账户
- 为高权限服务账户创建新的service account token secret
- 获取并使用该令牌进行身份验证
- 实现集群控制
创建ServiceAccount token secret的YAML:
apiVersion: v1
kind: Secret
metadata:
name: research-argo-token
annotations:
kubernetes.io/service-account.name: "argocd-application-controller"
type: kubernetes.io/service-account-token
4.2 利用Pod创建工作负载
攻击步骤:
- 获得可创建pod的服务账户
- 使用高权限服务账户创建Pod
- 在pod中执行命令获取令牌或运行其他命令
- 使用新令牌进行身份验证
- 实现集群管理
高权限Pod配置示例:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: research-pod
name: research-pod
spec:
serviceAccountName: argocd-application-controller
automountServiceAccountToken: true
containers:
- image: nginx
name: research-pod
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
4.3 利用持久卷(PersistentVolumes)
攻击步骤:
- 获得创建PersistentVolumes、PersistentVolumeClaim和Pod的权限
- 创建挂载hostPath的持久卷
- 创建绑定到该持久卷的持久卷申领
- 在pod配置中指定该卷,获取主机文件系统访问权限
4.4 利用角色和集群角色
关键权限:
Escalateverb:允许绕过Kubernetes对权限提升的限制Bindverb:允许绑定到高权限角色
攻击步骤:
- 获得有提升权限的服务账户
- 获取
clusterrole-aggregation-controller服务账户的secret - 利用该角色的升级权限实现集群管理
5. 后渗透技术
5.1 System:Masters组
- 在
system:masters组中创建用户可实现不受限的API访问 - 即使删除所有角色和角色绑定,该组用户仍保持完全管理权限
5.2 通过DaemonSets控制节点
- 创建DaemonSets确保pod在集群每个节点上运行
- 可用于大规模主机控制
5.3 控制ETCD
- ETCD存储所有集群数据
- 访问ETCD证书可监控和修改集群数据,绕过RBAC
6. 防御措施
6.1 Pod安全标准
三种策略:
- 特权策略(Privileged):无限制,不应用于生产
- 基线策略(Baseline):提供基本保护,防止容器逃逸
- 受限策略(Restricted):最高安全级别
应用示例:
kubectl label --overwrite ns --all \
pod-security.kubernetes.io/audit=baseline \
pod-security.kubernetes.io/warn=baseline
6.2 限制服务账户自动挂载
- 仅当服务账户或pod配置明确要求时才挂载令牌
- 不需要API访问的应用程序不应挂载令牌
6.3 RBAC权限审查
关键实践:
- 遵循最小权限原则
- 定期审查应用程序请求的权限
- 使用权限枚举脚本检查服务账户权限
增强版枚举脚本:
for mydir in $(find /var/lib/kubelet/pods -name namespace -exec dirname {} \;); do
echo "Checking $mydir"
export cert=$mydir/ca.crt
export token=$mydir/token
export namespace=$mydir/namespace
export apiserver=$(netstat -n | grep 6443 | awk '{print $5}' | uniq)
export whoami=$(kubectl whoami --token=$(cat "$token"))
export tokenexpiration=$(jq -R 'split(".")[0:2] | map(@base64d) | map(fromjson)' <<< $(cat "$token") | jq '.[1].exp')
echo -e "\n"
echo "Checking privileges for --- $whoami ---"
echo "Service account expires @ $(date -d @"$tokenexpiration")"
echo "$cert $namespace $token $apiserver"
mv /root/.kube/config /root/.kube/enum-config
kubectl --certificate-authority="$cert" --token=$(cat "$token") \
--namespace=$(cat $namespace) --server=https://"$apiserver" auth can-i --list
echo -e "\n"
echo "Does this service account have full cluster-admin privileges?"
kubectl --certificate-authority="$cert" --token=$(cat "$token") \
--namespace=$(cat $namespace) --server=https://"$apiserver" auth can-i "*" "*" --all-namespaces
echo "Can this service account list secrets in kube-system (Quick way to get cluster admin)?"
kubectl --certificate-authority="$cert" --token=$(cat "$token") \
--namespace=$(cat $namespace) --server=https://"$apiserver" auth can-i list secrets -n kube-system
mv /root/.kube/enum-config /root/.kube/config
echo -e "\n"
done
6.4 加密Secrets
- 默认情况下Kubernetes secrets不加密
- 启用静态加密可防止攻击者直接读取secret数据
- 确保不将secret以明文形式存储在配置或代码仓库中
6.5 网络策略
- 使用Calico等网络插件限制命名空间、pod间通信
- 在多租户环境中特别重要
6.6 审计日志与威胁检测
- 启用Kubernetes审计日志记录
- 配置审计策略(注意避免记录敏感数据)
- 使用Falco等工具进行威胁检测
- 监控异常API访问模式
7. 总结
Kubernetes安全事件常源于配置错误和对环境理解不足。关键防御措施包括:
- 严格实施和定期审查RBAC权限
- 遵循Pod安全标准限制容器逃逸
- 仅挂载必要的服务账户令牌
- 加密敏感数据
- 实施网络分段
- 启用全面的审计日志和威胁检测
通过多层次的防御策略,可以有效降低服务账户令牌被盗带来的风险,在攻击者渗透集群前检测并阻止恶意活动。