BH 笔记 - Kubernetes 从容器逃逸到集群权限控制

  • 容器逃逸在前几年是一个非常火的话题,有很多不同的方法进行容器逃逸。基于这些已有的技术,我们可以预见到,容器逃逸(提权/容器控制blahblah)是一个必然的攻击入口。那么通过这个入口,我们又可以在k8s中取得什么样的突破呢?

  • 在k8s中一个显著的利用就是:compromised node(受陷节点)。攻击者可以通过控制某个已有的容器或pod取得对整个节点的控制。

  • 那么如何通过单个节点获取整个集群的管理权限,就是本次讨论的问题。

  • 如何确认拥有admin权限?

    # admin
    kctl auth can-i "*" "*" --all-namespaces
    # yes
    
    # admin-equivalent (few trivial steps, almost admin)
    kctl auth can-i list secrets -n kube-system
    # yes
    

前置知识

  • 什么是 k8s?

    结构化的pod/容器组,现阶段的开发架构中非常常见。

  • k8s Authentication

    用户和各个节点可以通过证书进行通讯

    各个pod可以通过 service account tokens 进行通讯

  • K8s Authorization

    Perms: 决定当前用户是否有权限对节点中的对象进行操作,对应值可能是:list secrets, create pods等

    perms 组合后形成roles,如果想要获得xx权限,需要将与roles绑定,而非直接通过添加perms进行操作。

    • 例子 获取 list service/ list pods 权限

权限拓展

  • 在一个受陷节点中,攻击者可以获得什么?

    • 没有kubelet credentials → 无法直接admin!

    • 邻近pod的service account → 权限可大可小,每个节点的权限可能都是不同的

  • Trampoline Pod → 什么权限都有的pod

    我们的目标:拿到Trampoline Pod!

  • 节点中都存在什么类型的pod?

    • 应用程序pod:自己写的golang/python 代码,起的乱七八糟的服务,数据库啊之类的

    • 插件pod:用于辅助的插件,prometheus、lstio,它们不是由用户主动建立的,而是通过package manager安装时,由系统自动配置的权限。

    • 系统pod:kube-proxy、coredns,在集群建立的时候就存在了。根据平台不同,有不同的权限。(系统pod、少数的插件pod会节点中作为DaemonSets在所有节点中存在)

  • 当一个Trampolines pod 作为DaemonSets存在时,它就会在所有节点中出现。也就是说,攻击者可以直接通过控制手中的节点,获取对于整个集群的掌控。

Spotting Trampolines

  • 寻找trompoline pod:什么才算是一个trampoline pod?有什么样权限的pod才算trampoline pod?

总结一些可以修改AuthN和AuthZ的危险操作:

  • 身份伪装

  • Service Account Token获取

  • RCE

  • Pod窃取(后续演示)

    • 设置其他节点的PodCapacity=0

    • 删除operator pod

    • 由于只有当前节点可以有pod,operator pod会被在受陷节点创建

  • Trampoline pod

实践

  • Trampoline DaemonSets → 直接就能获取集群的admin权限

  • Cillium演示

(跳过demo……)

Rbac-police

用于检测k8s上的pod危险权限