作者:yyjb@360高級攻防實驗室
原文鏈接:http://noahblog.#/cve-2022-21907-httpxie-yi-yuan-cheng-dai-ma-zhi-xing-lou-dong-fen-xi-zong-jie/

背景:

2021年最近的上一個http遠程代碼執行漏洞CVE-2021-31166中,由于其UAF的對象生命周期的有限性,似乎并不太可能在實際場景中實現利用。今年一月的安全更新中包含另一個http的遠程代碼執行漏洞CVE-2022-21907,根據官方更新說明這仍是一個非常嚴重的漏洞,我們有必要對他在實際環境中是否可能被利用進行進一步的判斷。

開始準備分析之前的兩點說明:

在開始分析之前,這里有兩點分析過程中的思路提示需要提前說明。可以排除其他研究人員在理解這個漏洞可能產生的一些歧義。

A,最合適的補丁對比文件。

通常來說,我們在最開始選擇對比的補丁文件時,盡量選擇時間間隔最小的補丁文件。但是有時候,對于補丁文件的系統版本也非常重要。本例中,如果研究者使用server2019的http文件去分析,你會發現代碼有太多改動是針對一些舊版代碼的相對改動,并不是所有版本系統的某一模塊都是一樣的。

B,漏洞產生的方向。

這里我們說的方向主要指協議過程中,服務端和客戶端的數據請求方向。通常來說一個可互聯網蠕蟲級別的漏洞,我們首先想到的觸發方式可能是客戶端向服務端發送請求,之后服務端在解析請求時發生的漏洞。如cve-2019-0708RDP代碼執行漏洞以及永恒之藍。但近年來隨著這類漏洞發現的越來越困難,研究人員開始向將漏洞挖掘方向偏向于協議客戶端的一些接收解析模塊。但該漏洞似乎更加特殊,雖然它存在于服務端,卻并不是解析處理客戶端的具體數據內容模塊,而是處于服務端接收客戶端請求之后,進行的響應發送模塊。

我們似乎并不能在最簡單默認的http服務端系統配置中觸發此漏洞,需要服務端包含一些特定的代碼邏輯,該漏洞才會有比較大的威脅。具體來說,我們的poc代碼是一個普通的http服務端代碼,在其上加入有一些較小改動的特殊邏輯代碼。只要客戶端發起正常訪問,即可觸發服務端崩潰。

補丁分析:

我們使用最新的windows11的補丁文件進行分析。可以比較清晰的發現漏洞可能存在于這些代碼中:ULpFastSendCompleteWorker,UlPFreeFastTracker,以及UlFastSendHttpResponse.中指針使用完之后清零的操作。另外有兩處不太明顯的代碼即是申請FastTracker對象內存的函數:UlAllocateFastTracker和UlAllocateFastTrackerToLookaside.時,初始化部分頭部內存。

通過梳理http快速響應包發送流程,我們可以發現這些補丁的作用都是針對FastTracker對象中的一些指針地址所進行的。

其中主要有以下三個對象指針。

FastTracker中的LogDatabuffer對象,UriCacheEntry對象以及一個FastTrackerMDL指針。

失敗的嘗試:

通常來說,根據此漏洞的官方描述嚴重性,我們通常會先考慮這些對象是否存在UAF的情況。

我們優先分析了LogDatabuffer對象,UriCacheEntry對象的生命周期,如果僅從這兩個對象的申請和釋放過程判斷,我們并沒有找到較容易發現的觸發可能的UAF錯誤方式。

img

之后開始考慮第三個FastTracker的MDL指針。

剩下的可能:

通過前面的測試結果以及分析思路,我們有留意到FastTracker本身在申請釋放過程中其內存的一些變化,大致上,FastTracker對象的申請有兩種情況,首先查看http響應結構中一些數據長度是否滿足最低需求,以及http Tailers長度是否為空,滿足條件則直接使用http內部鏈表對象,否則申請新的內存。問題在這里開始出現,補丁之前的代碼,如果申請新內存,有一些關鍵偏移是沒有初始化內存的。其中就包括FastTracker的MDL幾個相關判斷標志以及MDL本身的地址指針。

img

之后,思路就比較清晰了,我們需要做的就是構造這樣的一個邏輯:當FastTracker申請內存成功之后,并在完全初始化MDL指針之前,故意觸發一個HTTP快速響應流程中的任意一個錯誤,使http提前釋放FastTracker對象。而這時,如果FastTracker對象中,未初始化的MDL相關指針位置包含申請內存時包含的一些隨機數據,則可能導致這些隨機數據被當作MDL指針進行引用。

說明:

這里需要提出一個特別注意的地方。即該漏洞與http Tailers的聯系。

從表面上看,該漏洞的直接原因是新FastTracker對象重新從系統內存申請時,未初始化導致的。這樣,Tailers長度是否為空作為FastTracker從系統內存申請的判斷條件之一,則直接影響該漏洞是否能觸發。但是如果繼續分析,會發現,即使沒有http Tailers的判斷條件,該漏洞仍然是可以被觸發的。

具體存在以下邏輯:如FastTracker對象申請流程圖中,如果發現該http響應結構中不包含http Tailers,會先查詢http內部鏈表,如有空閑對象,則使用空閑對象。這種情況下,這里仍有可能存在一種特殊情況,即內部鏈表被耗盡,仍需繼續通過另一個UlAllocateFastTrackerToLookaside申請新的內存。不過微軟已經注意到這里,同樣修補了這里的FastTracker的初始化工作。但這意味著,即使http服務端沒有開啟支持 Tailers特性,該漏洞仍然是可能被觸發的。測試之一,僅僅是增加對服務端的訪問頻率即可做到這一點。

poc:

如該漏洞開始分析之前的描述,該漏洞poc主要為我們自己編寫的一個http服務端。該服務端唯一不同的地方,是在http響應包發送流程中,在申請FastTracker之后,在FastTracker中的UriCacheEntry對象初始化之前,使http響應流程失敗,并開始銷毀FastTracker對象即可。(作為示例,其中一種方式,我們在服務端代碼的響應包中,加入了一個超過http限制長度的固定頭字符數據使得系統認為該固定頭數據無效而丟棄)。

當然,要達到這個目的還有很多方式,還有另外的判斷可以選擇,。只要在這些響應包結構生成流程中(即UlFastSendHttpResponse),在如:UlGenerateMultipleKnownHeaders,UlGenerateFixedHeaders相應包結構生成的流程中出現判斷失敗,則該服務器代碼就可能觸發該漏洞。

然后觸發該漏洞的方式只需要在客戶端訪問該端口并進入到我們服務端對應流程即可。因為我們沒有刻意進行內存布局,并不是每次訪問都能導致崩潰,這需要未初始化內存剛好符合FastTracker的MDL指針的一個標志判斷。如下,滿足v118+10的標志位為1.

img

漏洞觸發堆棧如下:

img

總結:

最后,該http遠程代碼執行漏洞雖然在類型上仍屬于UAF(use after free),但該漏洞實現exp有兩個比較重要的前提條件待解決。1是該漏洞的觸發原理,需要服務端的http代碼中,包含一個流程錯誤的構造操作使HTTP FastTracker因為意外而提前釋放,這需要http服務端開發人員在他的代碼中剛好包含這樣的一個邏輯。2另外則是該漏洞的利用實現方式,即通過布局HTTP FastTracker的未初始化的內存,通過漏洞觸發去操作我們自己偽造的MDL指針結構。為了要執行代碼,除了我們可能需要繼續分析一種可能的信息泄露方式(如構造讀寫源語或者利用MDL本身的一些機制),但我們仍有大量的后續代碼執行方式上的嘗試工作要做。所以,就目前短時間來說,該漏洞被利用的困難程度可能較大。

但是對于那些未啟用http Tailers支持的服務器,也需要盡快更新此補丁。

參考:

https://piffd0s.medium.com/patch-diffing-cve-2022-21907-b739f4108eee

https://msrc.microsoft.com/update-guide/vulnerability/CVE-2022-21907


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1899/