Pentesting Kubernetes Services

支持 HackTricks

Kubernetes 使用多个特定的网络服务,您可能会发现这些服务暴露在互联网上或者在一旦您入侵了一个 pod 后暴露在内部网络中

使用 OSINT 查找暴露的 pods

一种方法是在 crt.sh 中搜索 Identity LIKE "k8s.%.com" 以查找与 Kubernetes 相关的子域。另一种方法可能是在 github 中搜索 "k8s.%.com" 并查找包含该字符串的 YAML 文件

Kubernetes 如何暴露服务

了解 Kubernetes 如何可以公开暴露服务可能对您有所帮助,以便找到它们:

Exposing Services in Kubernetes

通过端口扫描查找暴露的 pods

在 Kubernetes 集群中可能会打开以下端口:

端口进程描述

443/TCP

kube-apiserver

Kubernetes API 端口

2379/TCP

etcd

6666/TCP

etcd

etcd

4194/TCP

cAdvisor

容器指标

6443/TCP

kube-apiserver

Kubernetes API 端口

8443/TCP

kube-apiserver

Minikube API 端口

8080/TCP

kube-apiserver

不安全的 API 端口

10250/TCP

kubelet

允许完全访问的 HTTPS API

10255/TCP

kubelet

无需身份验证的只读 HTTP 端口:pods、运行中的 pods 和节点状态

10256/TCP

kube-proxy

Kube Proxy 健康检查服务器

9099/TCP

calico-felix

Calico 的健康检查服务器

6782-4/TCP

weave

指标和端点

30000-32767/TCP

NodePort

服务的代理

44134/TCP

Tiller

Helm 服务监听

Nmap

nmap -n -T4 -p 443,2379,6666,4194,6443,8443,8080,10250,10255,10256,9099,6782-6784,30000-32767,44134 <pod_ipaddress>/16

Kube-apiserver

这是管理员通常使用工具 kubectl 与之交互的 API Kubernetes 服务

常见端口:6443 和 443,但在 minikube 中也有 8443,并且 8080 是不安全的。

curl -k https://<IP Address>:(8|6)443/swaggerapi
curl -k https://<IP Address>:(8|6)443/healthz
curl -k https://<IP Address>:(8|6)443/api/v1

查看以下页面以了解如何获取敏感数据并与此服务交互执行敏感操作:

Kubernetes Enumeration

Kubelet API

此服务在集群的每个节点上运行。这是控制节点内的pod的服务。它与kube-apiserver通信。

如果您发现此服务暴露,可能已找到一个未经身份验证的RCE

curl -k https://<IP address>:10250/metrics
curl -k https://<IP address>:10250/pods

如果响应是 Unauthorized,则需要进行身份验证。

如果您可以列出节点,则可以使用以下命令获取 kubelet 终端节点列表:

kubectl get nodes -o custom-columns='IP:.status.addresses[0].address,KUBELET_PORT:.status.daemonEndpoints.kubeletEndpoint.Port' | grep -v KUBELET_PORT | while IFS='' read -r node; do
ip=$(echo $node | awk '{print $1}')
port=$(echo $node | awk '{print $2}')
echo "curl -k --max-time 30 https://$ip:$port/pods"
echo "curl -k --max-time 30 https://$ip:2379/version" #Check  also for etcd
done

kubelet(只读)

curl -k https://<IP Address>:10255
http://<external-IP>:10255/pods

etcd API

etcd API

curl -k https://<IP address>:2379
curl -k https://<IP address>:2379/version
etcdctl --endpoints=http://<MASTER-IP>:2379 get / --prefix --keys-only

Tiller

Tiller

helm --host tiller-deploy.kube-system:44134 version

你可以滥用这项服务来在 Kubernetes 内部提升权限:

cAdvisor

用于收集指标的有用服务。

curl -k https://<IP Address>:4194

NodePort

当通过 NodePort 在所有节点上公开端口时,相同的端口将在所有节点上打开,将流量代理到声明的 Service。默认情况下,此端口将位于 30000-32767 范围内。因此,新的未经检查的服务可能可以通过这些端口访问。

sudo nmap -sS -p 30000-32767 <IP>

可能存在的配置错误

Kube-apiserver 匿名访问

kube-apiserver API 端点不允许匿名访问。但您可以检查一些端点:

检查 ETCD 的匿名访问

ETCD 存储集群机密、配置文件和更多敏感数据默认情况下,ETCD 不允许匿名访问,但最好进行检查。

如果可以匿名访问 ETCD,您可能需要使用 etcdctl 工具。以下命令将获取所有存储的密钥:

etcdctl --endpoints=http://<MASTER-IP>:2379 get / --prefix --keys-only

Kubelet RCE

Kubelet文档解释说,默认情况下允许对服务进行匿名访问:

启用对Kubelet服务器的匿名请求。未被其他身份验证方法拒绝的请求将被视为匿名请求。匿名请求的用户名为system:anonymous,组名为system:unauthenticated

要更好地了解Kubelet API的身份验证和授权工作原理,请查看此页面:

Kubelet Authentication & Authorization

Kubelet服务API未记录,但可以在此处找到源代码,并且查找暴露的端点就像运行这样简单:

curl -s https://raw.githubusercontent.com/kubernetes/kubernetes/master/pkg/kubelet/server/server.go | grep 'Path("/'

Path("/pods").
Path("/run")
Path("/exec")
Path("/attach")
Path("/portForward")
Path("/containerLogs")
Path("/runningpods/").

你可以使用Kubeletctl工具与Kubelets及其端点进行交互。

/pods

此端点列出了Pods及其容器:

kubeletctl pods

/exec

此端点允许非常容易地在任何容器内执行代码:

kubeletctl exec [command]

为避免此攻击,kubelet 服务应该以 --anonymous-auth false 参数运行,并且该服务应该在网络层面进行隔离。

检查 Kubelet(只读端口)信息泄露

kubelet 只读端口暴露时,未经授权的用户可能从 API 中检索信息。该端口的暴露可能导致各种集群配置元素的泄露。尽管信息,包括pod 名称、内部文件位置和其他配置,可能并不关键,但其暴露仍构成安全风险,应该避免。

一个利用这种漏洞的示例涉及远程攻击者访问特定 URL。通过访问 http://<external-IP>:10255/pods,攻击者可能从 kubelet 中检索到敏感信息:

https://www.cyberark.com/wp-content/uploads/2019/09/KUbe-Pen-2-fig-6.png

参考资料

支持 HackTricks

Last updated