Pentesting Kubernetes Services

支持 HackTricks

Kubernetes 使用几个 特定的网络服务,你可能会发现它们 暴露在互联网上 或在 内部网络中,一旦你攻破一个 pod

使用 OSINT 查找暴露的 pods

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

Kubernetes 如何暴露服务

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

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

在 Kubernetes 集群中,以下端口可能是开放的:

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 与之交互的 Kubernetes API 服务

常用端口: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

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

Kubelet API

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

如果您发现此服务暴露,您可能发现了未认证的 RCE

Kubelet API

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

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

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

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

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

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 服务 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 中检索敏感信息:

References

支持 HackTricks

Last updated