您好,登錄后才能下訂單哦!
這篇文章主要介紹“VMware ESXi OpenSLP堆溢出漏洞如何解決”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“VMware ESXi OpenSLP堆溢出漏洞如何解決”文章能幫助大家解決問題。
該漏洞編號為CVE-2021-21974,由 OpenSLP 服務中的堆溢出問題引起,未經身份驗證的攻擊者可以此進行低復雜度攻擊。
該漏洞主要影響6.x 版和 6.7、7.0版本之前的 ESXi 管理程序,2021年2月23日 ,VMware曾發布補丁修復了該漏洞。(在此之后發布的版本不影響)
該漏洞啟動之后,主要破壞行為為停止所有虛擬機,并加密所有數據文件。
因為不會加密大文件,所以有很大可能性進行恢復操作。
大于以下版本則不受影響
ESXi versions 7.x prior to ESXi70U1c-17325551
ESXi versions 6.7.x prior to ESXi670-202102401-SG
ESXi versions 6.5.x prior to ESXi650-202102101-SG
服務定位協議是一種服務發現協議,它允許連接設備通過查詢目錄服務器來識別局域網內可用的服務。這類似于一個人走進購物中心并查看目錄列表以查看商場中有哪些商店。為了保持簡短,設備可以通過發出“服務請求”并指定要使用 URL 查找的服務類型來查詢服務及其位置。
例如,要從目錄服務器查找 VMInfrastructure 服務,設備將使用“service:VMwareInfrastructure”作為 URL 發出請求。服務器將回復類似“service:VMwareInfrastructure://localhost.localdomain”的內容。
設備還可以通過發出提供相同 URL 的“屬性請求”來收集有關服務的其他屬性和元數據。要添加到目錄中的設備可以提交“服務注冊”。此請求將包括發布公告的設備的 IP、服務類型以及要共享的任何元數據等信息。SLP 可以執行更多功能,但我感興趣的最后一個消息類型是“目錄代理通告”,因為這是漏洞所在。“目錄代理通告”是由服務器發送的廣播消息,讓網絡上的設備知道如果他們想要查詢服務及其位置,應該聯系誰。要了解有關 SLP 的更多信息,請參閱此處和該內容。
雖然不同 SLP 消息類型之間的 SLP 結構布局略有不同,但它們通常遵循標頭 + 正文格式。
“服務請求”數據包如下所示:
“屬性請求”數據包如下所示:
“服務注冊”數據包如下所示:
最后,“目錄代理通告”數據包如下所示:
該問題出在“SLPParseSrvURL”函數中,該函數在處理“目錄代理通告”消息時被調用。
在第 18 行,URL 的長度與數字相加 0x1d 以形成從內存中“calloc”的最終大小。在第 22 行,調用 'strstr' 函數來查找子字符串 “:/” 的位置在網址中。在第 28 行,子字符串“:/”之前的 URL 內容將從第 18 行復制到新的 ‘calloced’內存中。
另一件需要注意的事情是,如果子字符串“:/”,'strstr'函數將返回0不存在或函數命中空字符。
我推測VMware測試用例只嘗試長度小于256的“范圍”。如果我們查看以下“目錄代理通告”布局代碼段,我們會看到示例 1 的“范圍”長度包含一個空字節。這個空字節意外地充當了“URL”的字符串終止符,因為它緊隨其后。如果 'scopes' 的長度高于 256,則長度的十六進制表示形式將沒有空字節(如示例 2 所示),因此 'strstr' 函數將讀取傳遞的 'URL' 并繼續查找子字符串 “:/”在“范圍”中。
因此,“memcpy”調用將導致堆溢出,因為源包含來自“URL”的內容+“范圍”的一部分,而目標只有空格來容納“URL”。
在這里,我將介紹相關的 SLP 組件,因為它們是利用的構建塊。
連接到“slpd”守護程序的所有客戶端都將在堆上創建一個“slpd-socket”對象。此對象包含有關連接的當前狀態的信息,例如它是處于讀取狀態還是寫入狀態。此對象中存儲的其他重要信息包括客戶端的 IP 地址、用于連接的套接字文件描述符、指向此特定連接的“recv-buffer”和“send-buffer”的指針,以及指向從先前和將來建立的連接創建的“slpd-socket”對象的指針。此對象的大小固定為 0xd0,無法更改。
來自OpenSLP源代碼的_SLPDSocket結構
_SLPDSocket對象的內存布局
從服務器接收的所有 SLP 消息類型將創建至少兩個 SLPBuffer 對象。一個稱為“recv-buffer”,它存儲服務器從客戶端接收的數據。由于我可以控制從客戶端發送的數據的大小,因此我可以控制“recv-buffer”的大小。另一個SLPBuffer對象稱為“send-buffer”。此緩沖區存儲將從服務器發送到客戶端的數據。“發送緩沖區”具有固定的0x598大小,我無法控制其大小。此外,SLPBuffer 具有元數據屬性,指向所述數據的起始位置、當前位置和結束位置。
從 OpenSLP 源代碼_SLPBuffer
_SLPBuffer對象的內存布局
SLP 套接字狀態定義特定連接的狀態。狀態值在_SLPSocket對象中設置。連接將調用“recv”或“發送”,具體取決于套接字的狀態。
OpenSLP 源代碼中定義的套接字狀態常量
了解_SLPSocket、_SLPBuffer和套接字狀態的屬性非常重要,因為利用過程需要修改這些值。
客戶端 1 發送“目錄代理通告”請求,以準備此特定請求可能發生的任何意外內存分配。我觀察到當“slpd”守護進程在啟動時運行時運行時,請求會進行額外的內存分配,但在通過 /etc/init.d/slpd start 運行它時不會。任何意外的內存分配最終都會被釋放并最終出現在自由列表中。假設這些獨特的釋放插槽將被未來的“目錄代理通告”消息再次使用,只要我沒有顯式分配會劫持它們的內存。
客戶端 2–5 發出“服務請求”,每個接收緩沖區的大小為 0x40。這是為了填充自由列表中存在的一些初始釋放插槽。如果我不占用這些釋放的插槽,它將劫持未來的“URL”內存分配,用于未來的“目錄代理通告”消息并破壞堆整理。
客戶端 6–10 設置客戶端 7 以向服務器發送“服務注冊”消息。服務器僅接受來自本地主機的“服務注冊”消息,因此需要覆蓋客戶端 7 的“slpd-socket”以更新其 IP 地址。發送消息后,客戶端 7 的套接字對象將再次更新,以保存偵聽文件描述符以處理未來的傳入連接。如果跳過此步驟,將來的客戶端將無法與服務器建立連接。
客戶端 11–21 通過覆蓋客戶端 15 的“發送緩沖區”位置指針來設置任意讀取基元。由于我不知道首先要泄漏哪些地址,因此我將使用空值對“start”位置指針的最后兩個有效字節執行部分覆蓋。這需要將擴展的空閑塊設置為標記為“IS_MAPPED”,以避免被“calloc”調用歸零。更新的“發送緩沖區”屬于“屬性請求”消息。由于我無法了解將泄漏多少數據,因此我可以通過在步驟 3 中記錄的“服務注冊”消息中包含標記值來大致了解泄漏的位置。如果泄漏的內容包含標記,我知道它正在從“屬性請求”“發送緩沖區”對象泄漏數據。這告訴我是時候停止從泄漏中讀取了。最后,我必須更新客戶端 15 的“slpd-socket”,使其狀態為“STREAM_WRITE”,這將向我的客戶端發出“發送”調用。
我能夠從泄漏中收集堆地址和libc地址,我可以得出其他所有內容。我的目標是用libc的系統地址覆蓋libc的__free_hook。我將需要一個小工具將我的堆棧放置在應用程序不會更改的位置。我從 libc-2.17.so 中找到了一個小工具,它將堆棧提升堆棧地址0x100。
使用收集的libc地址,我可以計算存儲堆棧地址的libc環境地址。我使用客戶端 22–31 來設置任意讀取原語以泄漏堆棧地址。我必須在“slpd-socket”中更新客戶端 25 的文件描述符以保存偵聽文件描述符。
客戶端 32–40 設置任意寫入基元。這需要覆蓋客戶端 33 的“recv-buffer”對象的位置指針。它首先將 shell 命令存儲到客戶端 15 的“發送緩沖區”對象中,這是我控制下的一大塊空間。然后,它會在執行堆棧提升后將 libc 的系統地址、虛假返回地址和 shell 命令的地址寫入預測的堆棧位置。之后,它會覆蓋 libc 的__free_hook以保存堆棧提升小工具地址。最后,每次任意寫入都需要將相應的“slpd-socket”對象狀態更新為“STREAM_READ”。如果跳過此步驟,服務器將不接受位置指針的覆蓋值。
完成上述所有步驟后,將執行所需的 shell 命令。
關于“VMware ESXi OpenSLP堆溢出漏洞如何解決”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。