淺談雲上攻防——CVE-2020-8562漏洞為k8s帶來的安全挑戰

雲鼎實驗室發表於2021-10-25

前言

2021年4月,Kubernetes社群披露了一個編號為CVE-2020-8562的安全漏洞,授權使用者可以透過此漏洞訪問 Kubernetes 控制元件上的私有網路。

透過查閱此漏洞披露報告可發現,這個漏洞擁有較低的CVSS v3評分,其分值僅有2.2分,與以往披露的Kubernetes高危漏洞相比,這個擁有較低評分的漏洞極其容易被安全研究人員以及運維人員所忽視。但經過研發測試發現,在實際情況中,這個低風險的漏洞卻擁有著不同於其風險等級的威脅:在與雲上業務結合後,CVE-2020-8562漏洞將會為雲廠商帶來不可忽視的安全挑戰。

在這篇文章中,雲鼎實驗室將為大家帶來業內首個CVE-2020-8562漏洞分析報告,一同來看一下這個被忽視的低風險漏洞引發的“血案”。

CVE-2020-8555漏洞簡述

Kubernetes為了緩解CVE-2020-8555等歷史漏洞帶來的安全問題,對APIServer Proxy請求進行域名解析以校驗請求的IP地址是否處於本地鏈路 (169.254.0.0/16) 或 localhost (127.0.0.0/8) 範圍內,Kubernetes透過此方式禁止由使用者觸發的對Services,Pods,Nodes,StorageClass物件的內網Proxy訪問許可權。

但是在完成校驗並透過校驗之後,Kubernetes立即進行第二次域名解析,此次域名解析後並不再進行IP地址的校驗,這將導致上述校驗存在繞過問題,如果一個DNS伺服器不斷返回不同的非快取解析請求,攻擊者可以利用此方式繞過Kubernetes的API Server Proxy IP地址限制,並訪問內網ControlPlane管控元件。

詳細的漏洞細節可參見如下圖Issue所示:

淺談雲上攻防——CVE-2020-8562漏洞為k8s帶來的安全挑戰

圖 1 CVE-2020-8562漏洞細節

Issue地址如下:

https://github.com/kubernetes/kubernetes/issues/101493

在正式開始介紹這個漏洞是如何對Kubernetes叢集帶來危害之前,我們先來看看這個漏洞中應用到主要攻擊技巧:DNS重繫結攻擊(DNS Rebinding)。

DNS重繫結攻擊

DNS重繫結攻擊技術的實現主要依賴於攻擊者可將其自建的DNS伺服器中DNS TTL配置為設定為0或者極小值。DNS TTL表示DNS記錄的生存時間,數值越小, DNS記錄在DNS伺服器上緩衝的時間越小。

在攻擊者將DNS TTL數值設定為一個極小值時,當受害目標第一次訪問惡意域名時併發起域名解析請求時,惡意DNS伺服器會返回一個ip地址A;當受害目標第二次發起域名解析請求時,卻會得到ip地址B的解析結果。具體的原理,我們可以透過一道CTF題目,深入瞭解一下:

$dst = @$_GET['KR'];


$res = @parse_url($dst);


$ip = @dns_get_record($res['host'], DNS_A)[0]['ip'];


...


$dev_ip = "54.87.54.87";


if($ip === $dev_ip) {    $content = file_get_contents($dst);    echo $content;}

這道CTF題目需要參賽者訪問內網127.0.0.1地址並獲取儲存於其中的Flag。

從程式碼中可見,題目將會判斷參賽者傳入的域名解析後的ip,並僅允許訪問54.87.54.87地址的內容。

如何繞過題目中的條件語句,利用到的就是DNS重繫結攻擊技術。

從上文程式碼段可見,程式透過以下程式碼來執行第一次DNS解析以獲取ip:

$ip = @dns_get_record($res['host'], DNS_A)[0]['ip'];

假設此時參賽者傳入的域名為www.a.com,將會進行如下的解析:

淺談雲上攻防——CVE-2020-8562漏洞為k8s帶來的安全挑戰

圖 2首次DNS解析流程

此時www.a.com域名解析出來的ip為54.87.54.87。

程式繼續往下執行,執行到了如下程式碼塊:

$dev_ip = "54.87.54.87";

if($ip === $dev_ip){}

此時ip引數為54.87.54.87,滿足條件分支判斷,程式執行進入if條件分支。

隨後,程式執行到如下語句:

$content = file_get_contents($dst);

注意,此時file_get_contents方法內的引數為參賽者控制的域名dst,而非ip地址。

也就是說,程式執行file_get_contents方法時,需要獲取此域名的ip地址解析。由於攻擊者將DNS TTL設定的數值極其小,從程式第一次獲取ip到執行file_get_contents方法處時,DNS快取早已失效,CTF伺服器此時需要重新發起域名解析請求以獲取www.a.com的ip,此時參賽者修改DNS解析結果以完成DNS重繫結攻擊,見下圖:

淺談雲上攻防——CVE-2020-8562漏洞為k8s帶來的安全挑戰

圖 3重繫結DNS解析

此時獲取到的解析ip值為127.0.0.1,參賽者透過此方式繞過限制並訪問127.0.0.1資源,實現重繫結攻擊。

KuBernetes中DNS重繫結攻擊的應用

Kubernetes為了防止使用者對Services,Pods,Nodes,StorageClass物件的內網Proxy進行非法訪問,採用了域名解析的方式解析並校驗Proxy請求的IP地址是否位於本地鏈路 (169.254.0.0/16) 或 localhost (127.0.0.0/8) 範圍內。

Kubernetes透過此方式防止惡意內網資源的Proxy訪問行為,但是Kubernetes在校驗透過之後,會進行第二次域名解析,獲取IP地址訪問而不再進行IP地址的校驗。

聯想到上一章節的DNS重繫結攻擊方式:攻擊者可以控制DNS解析的IP地址,在第一次校驗時返回一個合法值,隨後在第二次獲取IP地址時,返回一個本地鏈路或 localhost地址,詳見下圖:

淺談雲上攻防——CVE-2020-8562漏洞為k8s帶來的安全挑戰

圖 4 Kubernetes中DNS重繫結流程

透過這個技術方式,攻擊者可以繞過apiserver proxy的內網限制,構造惡意請求訪問叢集中的資源。

這種攻擊技術將為雲服務商帶來了極大的安全問題:大多數雲服務商提供Kubernetes託管版叢集服務,採用此服務的使用者Master節點將由雲廠商建立並託管,如果攻擊者透過方式訪問到本地鏈路 (169.254.0.0/16) 或 localhost (127.0.0.0/8)地址,則有可能訪問同為託管模式下其他使用者的apiserver。

CVE-2020-8562漏洞原理

首先,使用雲廠商提供的Kubernetes託管版叢集服務建立一個叢集。在此場景下,我們建立的叢集的Master節點將與其他採用託管服務的使用者一併,由雲廠商建立並託管管理,這為後續的利用提供了先決條件。

淺談雲上攻防——CVE-2020-8562漏洞為k8s帶來的安全挑戰

圖 5 Kubernetes託管版叢集服務

在叢集建立完畢後,透過編寫如下yaml來建立一個名為cve-2020-8562的node,見下圖:

淺談雲上攻防——CVE-2020-8562漏洞為k8s帶來的安全挑戰

圖 6 使用yaml建立node

透過上圖可見,在此yaml中,將只能在叢集內進行路由的節點的IP地址InternalIP設定為攻擊者可控的www.attacker.com。

建立完畢後,可以透過kubectl get nodes檢視到此節點:

淺談雲上攻防——CVE-2020-8562漏洞為k8s帶來的安全挑戰

圖 7 透過kubetctl檢視cve-2020-8562節點

從上圖紅框處可以發現,此時我們建立的cve-2020-8562節點的狀態為NotReady,但即使此時cve-2020-8562節點的狀態為NotReady,也並不影響後續的利用流程。

使用如下命令啟動Kubernetes API 伺服器的代理:

kubectl proxy &

淺談雲上攻防——CVE-2020-8562漏洞為k8s帶來的安全挑戰

圖 8 透過kebuectl開啟代理

在成功啟動Kubernetes API 伺服器的代理之後,透過如下命令使用apiserver proxy來訪問cve-2020-8562節點的apiserver:

淺談雲上攻防——CVE-2020-8562漏洞為k8s帶來的安全挑戰

圖 9訪問cve-2020-8562節點的apiserver

透過上文來看,cve-2020-8562節點處於NotReady,我們可以正常的訪問其apiserver嗎?

我們來看一下Kubernetes是如何完成接下來的訪問:

首先,為了可以訪問cve-2020-8562節點,Kubernetes首先需要獲取cve-2020-8562節點的InternalIP,我們透過如下指令檢視一下cve-2020-8562 的InternalIP:

淺談雲上攻防——CVE-2020-8562漏洞為k8s帶來的安全挑戰

圖 10 檢視cve-2020-8562節點詳情

透過上圖可知,cve-2020-8562節點的InternalIP值與生成此節點yaml中配置項一致,為我們配置的www.attacker.com。

由於InternalIP為域名而非IP地址,Kubernetes需要對其進行域名解析,隨後校驗獲取到的IP地址是否位於本地鏈路 (169.254.0.0/16) 或 localhost (127.0.0.0/8) 範圍內,如果獲取到的IP屬於此範圍,則禁止訪問。

在第一次DNS解析時,攻擊者自建的DNS伺服器將會返回一個合法的IP地址(非本地鏈路或 localhost範圍),例如172.x.x.x,流程見下圖:

淺談雲上攻防——CVE-2020-8562漏洞為k8s帶來的安全挑戰

圖 11 第一次DNS解析

透過此方式,可以繞過k8s的本地鏈路/localhost範圍IP校驗。

在透過安全校驗之後,K8s將會發起第二次域名解析。由於攻擊者將DNS TTL設定的數值極其小,此時DNS快取已失效,k8s需要重新發起域名解析請求以獲取www.attacker.com的ip地址,流程見下圖:

淺談雲上攻防——CVE-2020-8562漏洞為k8s帶來的安全挑戰

圖 12 DNS重繫結攻擊

從上圖可見,此時攻擊者可以將 www.attacker.com域名的IP解析為一個localhost範圍內的IP地址並返回,在此例中,我們返回一個127.x.x.x地址。

此時,k8s apiserver proxy訪問情況可以類比於下圖情況:

淺談雲上攻防——CVE-2020-8562漏洞為k8s帶來的安全挑戰

圖 13當前訪問可抽象成此情況

如果127.x.x.x這個節點的apiserver 存在未授權訪問情況,我們就可以透過此方式直接訪問其apiserver,見下圖:

淺談雲上攻防——CVE-2020-8562漏洞為k8s帶來的安全挑戰

圖 14 攻擊者訪問託管服務中Master

透過此方式,可以訪問其他使用Kubernetes託管叢集服務的租戶的apiserver。

總結

在安全研究以及運維中,一些低風險的叢集漏洞極其容易被安全以及運維人員所忽略,但是這些漏洞在一些特定場景中仍為雲上安全帶來了極大的安全挑戰,正如本文中所舉例的CVE-2020-8562安全漏洞,這個僅有2.2評分的Kubernetes安全漏洞,在與實際業務結合後,仍可為業務帶來極大的安全風險。因此與雲上安全相關的漏洞,無論嚴重與否,都應得到安全人員以及運維人員的相應重視。

參考連結

https://github.com/kubernetes/kubernetes/issues/101493

https://zhuanlan.zhihu.com/p/89426041

https://cloud.tencent.com/developer/article/1400018


相關文章