熟悉 Kubernetes 架构的同学可能知道,管理员管理 Kubernetes 无论是使用 kubectl 或 Kubernetes dashboard 的 UI 功能,其实都是间接在和 APIServer 做交互。
参考官方的架构图:
那么如果需求需要在 Kubernetes 原本的能力上做开发的话,很有可能产品后端就是请求了 APIServer 的 Rest API 实现的。
攻击者破坏程序原本想对 APIServer 所表达的语义,注入或修改 Rest API 请求里所要表达的信息,就可以达到意想不到的效果。
例如下面的代码,用户传入 namespace、pod 和容器名即可获取相应容器的日志:
相似的需求和 API 还有例如:
- 到用户自己的容器内创建一个 web console 供用户进行远程调试, POST https:/apiserver:
8443/api/v1/namespaces/default/pods/nginx/exec?command=bash&container=nginx&stdin=true&stdout=true&tty=true
- 给用户销毁自己 POD 的能力, DELETE https://apiserver:
8443/api/v1/namespaces/default/pods/sleep-75c6fd99c-g5kss
这类型的需求在多租户的集群设计里比较常见。渗透测试选手看到这样的代码或 API,首先想到的就是越权,把 namespace、pod 和容器名修改为他人的,就可以让二次开发的代码去删除其他用户的 POD、进入其他用户的容器里执行命令、获取其它 POD 的日志等。
除了上述的功能点,这里比较容易出问题且影响较大的功能和业务逻辑是多租户集群平台的自研 Web Console 功能,Web Console 的越权问题可以直接导致任意容器登录和远程控制,也是非常值得关注的一个点。
其实我们甚至可以修改获取日志、删除 POD、执行命令的 Rest API 语义:
例如在上述 namespace 命名空间处插入 “default/configmaps/istio-ca-root-cert?ingore=”,
原本请求的
“https://apiserver:6443/api/v1/namespaces/istio-dev/pods/service-account-simple/lo g?container=test-container”
就会转变为
“https://apiserver:6443/api/v1/namespaces/default/configmaps/istio-ca-root-cert?ingore=/pods/service-account-simple/lo g?container=test-container”,
实际就是请求了
https://apiserver:6443/api/v1/namespaces/default/configmaps/istio-ca-root-cert,从获取日志转变了为获取 configmap。