概述
近日經過Rancher Labs實驗室報告,谷歌開源的知名容器編排平臺K8S(Kubernetes)爆重大安全漏洞(CVSS 9.8分)CVE-2018-1002105用戶特權提升漏洞。
通過精心設置的Web請求,使得任何用戶都可以通過K8s API服務器與後端服務器建立連接。一旦建立,攻擊者就可以通過網絡連接直接向該後端發送任意請求。K8s API服務器的傳輸通過TLS憑證對用戶請求進行身份驗證。 在默認配置中,未對該特權提升API進行限制,允許所有用戶(經過身份驗證和未經身份驗證的用戶)執行操作,可以實現對K8s集群中所有節點機器的所有控制操作,包括ROOT權限。
目前還沒有簡單的方法來審計該漏洞是否已被漏洞。由於未經授權的請求是通過已建立的連接進行的,因此它們不會出現在Kubernetes API服務器審計日誌。只會出現在kubelet或聚合的API服務器日誌中,但是在這些日誌中,無法與正確授權和代理的請求進行區分。
影響範圍
· Kubernetes V1.0.x-1.9.x
· Kubernetes vV1.10.0-1.10.10 (V1.10.11修復)
· Kubernetes V1.11.0-1.11.4 (V1.11.5修復)
· Kubernetes V1.12.0-1.12.2 (V1.12.3修復)
漏洞分析
從kube-api服務器到kubelet 的連接是依靠 kube-api服務器的 TLS(SSL) 憑證實現的,只要擁有已經建立的TLS連接, 那麼kubelet 就會認可來自kube-api服務器的請求並且完成相應的操作。默認情況下kubelet是允許執行所有API權限的操作。
漏洞的產生是在k8s apimachinery/pkg/util/proxy/upgradeaware.go 接口的權限沒有嚴格判斷,使得用戶對該接口訪問後就可以獲得對應特權的TLS連接。
涉及的函數為(h *UpgradeAwareHandler) tryUpgrade(w http.ResponseWriter, req *http.Request):
通過ServeHTTP調用tryUpgrade函數處理代理響應請求,在 UpgradeRequestRoundTripper接口描述中,所有有關Upgrade的響應都會經由代理(Proxy)處理。在用戶通過API向後端發起請求時,API Server 會預先進行一次判斷,通過函數 httpstream.IsUpgradeRequest判斷 Http請求的頭部是否包含 Upgrade 字段進,如果不包含Upgrade,則判斷失敗結束。該處理過程中,使用了 http.Hijacker包, Golang常用於對Http請求消息進行轉發。而此刻 Proxy服務器具有全訪問權限,由於處理邏輯漏洞,致使轉發任意的請求(正常特權請求和非特權請求)也附上了所有權限。
漏洞修補中,新增加了一個函數getResponseCode函數來獲取請求狀態碼?轉發之前對rawResponseCode進行判斷,對非特權請求予以關閉:
新增加的getResponseCode函數返回狀態碼:
對rawResponseCod狀態碼判斷:
當客戶端請求和服務端狀態不一致則關閉該連接,就不會獲得相應的特權憑據了。
修復建議
由於該漏洞影響巨大,屬於嚴重漏洞,建議即刻升級到對應系列的最新版本:
Kubernetes V1.10.11
Kubernetes V1.11.5
Kubernetes V1.12.3
Kubernetes V1.13.0-rc.1
安全設置建議:
針對匿名用戶通過一些安全設置限制提對應權限:
暫停使用聚合的API服務器(影響使用聚合服務器API的用戶)
設置 --anonymous-auth = false傳遞到kube-apiserver禁用匿名請求(影響kube-apiserver的負載均衡器或kubelet運行狀況檢查,並中斷kubeadm join設置流程)
刪除對所有聚合API的所有匿名訪問;對非聚合API的完全訪問權限的用戶刪除對所有聚合API訪問權限;
非特權kubelet API 用戶中刪除pod exec/attach/ portforward權限
閱讀更多 蟲蟲安全 的文章