Unit 42研究人員調查了Azure的無服務器架構,發現他們能夠破壞底層主機的無服務器函數。研究人員還發現,他們的主機實際上是一個HyperV虛擬機,它託管了其他幾個無服務器函數。 Hyper-V是微軟的一款虛擬化產品,是微軟第一個採用類似Vmware ESXi和Citrix Xen的基於hypervisor的技術。
Azure serverless functions(通常稱為Azure Functions)是一種無服務器解決方案,可以使用戶減少代碼編寫、減少需要維護的基礎結構並節省成本。無需擔心部署和維護服務器,雲基礎結構提供保持應用程序運行所需的所有最新資源。你可以專注於使用你認為最高效的語言編寫最重要的代碼,而Azure Functions 處理其餘代碼。作為一個基於觸發器的服務,它運行代碼以響應各種事件。在本文中,這個事件是一個網頁請求。
研究人員發現,對於每個函數,主機都會生成一個新的容器。每個容器將在幾分鐘後終止並刪除,以將無服務器函數與傳統的容器即服務區分開來。
問題主機只託管研究的Azure用戶有權訪問的函數,因此不會造成真正的攻擊。很明顯,微軟竭盡全力阻止人們訪問主機,因此可能還有其他問題尚未被發現。虛擬機上可能有不應該顯示的重要信息,這些信息可能會被動機充分的攻擊者發現。
微軟經常使用容器來加強安全性,但由於容器本質上不如虛擬機那樣安全,因此通常不會將其視為安全邊界。在本文的示例中,他們實現了額外的安全層,這被證明是有效的。
Prisma的無服務器解決方案為大多數雲提供商提供了函數發現和漏洞掃描功能。這些功能會作用於無服務器函數上,並在發現這些函數中存在已知漏洞時提醒你。
什麼是無服務器函數無服務器函數是無服務器計算(通常簡稱為“無服務器”)的一個特點,雲提供商按需為其客戶提供所有計算資源,並管理所有架構,包括雲基礎設施。
無服務器理想應用程序的一個很好的例子是聊天機器人。例如,Slack使用名為marbot的無服務器應用程序通過Slack向DevOps團隊發送通知。
“serverless”這個名字有點誤導人。不管它的名字意味著什麼,無服務器計算仍然需要物理服務器來執行代碼。與傳統計算的主要區別在於,無服務器抽象了與代碼本身無關的任何東西,從代碼運行的操作系統到實際運行代碼的設備硬件。
無服務器函數的內部結構你可能會問自己的第一個問題是如何開始研究無服務器平台。任何使用過Azure Serverless Functions的人都知道,可研究的地方不是很多。你可以上傳一些代碼或更改一些設置,如下圖所示,但僅此而已。
通過Azure函數提供的所有不同運行時
研究人員決定從一個HTTP請求觸發的Linux上的Python函數開始研究,對於某些運行時,Windows也可用。
下一步是在函數中獲得一個有效的交互式shell,以更好地理解研究人員正在處理的內容,並獲得有關運行代碼的設備的一些信息。為了便於使用,研究人員決定使用逆向shell。研究人員還決定使用數據傳輸工具socat而不是netcat,因為它支持更廣泛的協議。
研究人員使用的socat二進製文件
研究人員只是將socat二進製文件放在Visual Studio代碼中的項目目錄中,並將整個文件部署到研究人員之前創建的無服務器函數中。實際啟動逆向shell的代碼非常簡單,因為整個邏輯都在socat應用程序中,如下圖所示。
連接到逆向shell偵聽器的簡單函數代碼
執行逆向shell後,研究人員進入了一個名為app的用戶下的函數目錄。研究人員使用
cat/proc/1/cgroup_last_cap命令,以SandboxHost開頭的設備主機名也暗示了這一點。
無服務器函數內部的shell
在研究人員登錄的工作目錄中沒有太有趣的東西。這個目錄包括他們上傳的所有文件,外加一個額外的lib文件夾,其中包含Python與Azure通信所需的庫。
容器這項研究一開始並沒有明確的目標,只是為了改善Prisma的無服務器保護。然而,在了解了更多關於架構的知識後,研究人員渴望探索一下容器。
在熟悉了容器及其文件以及用戶權限等之後,研究人員決定檢查環境變量,因為它們通常包含一些有趣的信息。這一次沒有什麼不同。在其他有趣的事情中,研究人員注意到環境變量洩露了映像名稱。
環境變量中的映像名稱
在網上搜索這個映像名稱,研究人員找到了一個顯示映像名稱的微軟官方目錄,該目錄指向一個提供所有Microsoft映像(包括我們正在查看的映像)的官方存儲庫。
研究人員的第一個方法是獲取映像“源代碼”(如果你使用Docker,則為Dockerfile)。經過一番搜索,研究人員發現有一個叫做Whaler的實用工具,它可以將Docker映像逆向工程到創建它們的Dockerfile中。該過程如下所示。
使用Whaler對微軟映像進行逆向工程
Whaler有大量的映像,從而產生一個易於使用的單行命令。使用這個方法,研究人員成功地生成了一個足夠好的Dockerfile版本,如下圖所示。文件中最有趣的部分是最後一行。
逆向之後的Dockerfile版本
網格文件夾似乎包含一些有趣的文件,特別是launch.sh腳本,它似乎是容器內執行的第一件事。此時,研究人員只需從映像內部複製整個網格文件夾,以進一步研究它。
還有一些腳本在不同的場景中調用了一些其他腳本,該文件夾中有趣的部分是一個名為init的二進製文件,它在每個Azure無服務器容器的後台運行。對研究人員來說幸運的是,這個二進製文件也包含了符號,所以逆向工程很容易。
在研究了函數和字符串列表之後,有一個函數特別有趣:init_server_pkg_mount_BindMount。在對其進行逆向工程之後,研究人員發現該函數將容器內的一條路徑綁定到另一條路徑,該路徑也位於容器內。此函數也不要求用戶具有特權,但它在root上下文中運行!要將一個文件綁定到任何其他文件,你所需要做的就是在容器中使用正確的參數在正確的端口上執行HTTP查詢。
init_server_pkg_mount_BindMount函數簽名
init_server_pkg_mount_BindMount函數解析來自HTTP請求的sourcePath和targetPath
在這部分調查的過程中,研究人員還發現了許多關於Azure無服務器架構如何在幕後工作的信息。雖然這超出了本文的範圍,但可以在本文中深入探討這一問題。
升級權限簡而言之,雖然在一個沒有特權的用戶的容器中研究,但研究人員能夠將任何一個文件作為根文件綁定到任何其他文件。此時,研究人員的目標是在容器內將特權升級到根權限。可能有幾種方法可以實現這一點,但研究人員選擇用生成的文件替換/etc/shadow文件,然後將用戶更改為root。
使用OpenSSL生成/etc/shadow
為了實現這一點,研究人員執行了以下步驟:
為root用戶生成一個密碼已知的/etc/shadow文件;
將該文件上傳到Function容器的本地目錄;
使用正在運行的init服務和BindMount函數通過查詢http://localhost:6060將本地陰影文件綁定到實際的/etc/shadow文件;
使用su-root命令將用戶更改為root。
不斷升級權限
利用root權限規避容器可以利用新獲得的根訪問來規避容器,通過研究,研究人員選擇了菲利克斯马云惹不起马云威廉姆(Felix Wilhelm)多年前發現的一個舊漏洞。
不過要使用此漏洞也不是一件簡單的事情,要使其正常工作,需要滿足以下幾個要求:
研究人員必須在容器內以root身份運行;
容器需要具有SYS_ADMIN函數;
容器要么沒有AppArmor配置文件,要么允許掛載系統調用;
cgroup v1虛擬文件系統必須在容器內以讀寫方式安裝;
研究人員已經在早些時候實現了第一個需求。令人驚訝的是,其餘的需求在我們的容器中也可用。這是令人驚訝的,因為在默認情況下,容器啟動時具有一組受限的函數,並且沒有啟用SYS_ADMIN函數。此外,Docker通常在默認情況下使用AppArmor策略啟動容器,這防止了在容器使用SYS_ADMIN運行時使用mount sycall。通過在/proc/PID/status下的shell狀態文件上運行capsh命令,研究人員確認了所有必要的函數,如下圖所示。
使用capsh和一些sed腳本來打印特權用戶函數
關於此漏洞的詳細解釋已超出了本文範圍,我們建議閱讀'Digging into cgroups Escape' 以更好地理解此技術。簡而言之,研究人員將通過以下步驟描述該漏洞:
查找或創建對cgroup控制器的訪問權限(大多數版本的漏洞利用使用RDMA);
在該控制器中創建一個新的cgroup;
將該cgroup的notify_on_release設置為1;
將發布代理設置為容器和主機都可以訪問的文件;
在該cgroup中啟動一個快速完成流程,該流程將在終止時觸發發布代理的執行。
研究人員決定通過運行ps aux並將其與容器的ps aux進行比較來演示實現主機執行上下文。在本節開頭的視頻中,你可以看到漏洞的整個利用過程。需要注意的是,託管容器的設備是HyperV虛擬機,而不是物理服務器。
總結不管怎樣,Azure的用戶都可以訪問虛擬機託管的所有資源,因此,這種防禦沒有什麼意義。這是雲提供商緩解措施按預期工作的一個示例。在本文的示例中,他們選擇不依賴容器作為安全邊界,並實現另一種保護,這被證明是一個聰明的舉動。
但是,如果在虛擬機本身中發現另一個漏洞,這個漏洞可能會產生巨大的影響。此外,微軟在過去已經修復了類似的問題,即使他們本身沒有將其稱為漏洞。
虛擬機可能包含對無服務器函數用戶或可能的攻擊者不可見的重要信息或秘密。在與微軟分享該調查結果後,他們考慮了以下防禦措施,以更好地保護客戶:
對綁定裝載API進行額外驗證,以防止裝載過度;
盡可能從二進製文件中刪除符號。