您好,登錄后才能下訂單哦!
如何實現微軟“照片”應用Raw 格式圖像編碼器漏洞 CVE-2021-24091的技術分析,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
2020年12月和2021年2月,微軟兩次針對“照片”應用的Raw格式圖像編碼器發布安全更新,其中2月9日修復的是CVE-2021-24091。筆者從事文件格式方面的安全研究工作,找到研究人員提供的poc 后,對該漏洞進行了漏洞驗證和分析。
根據MSRC 和漏洞發現者公開的信息,該漏洞存在于Windows Imaging Component解碼Olympus E300 相機拍攝的原始圖像的相關函數中。由于互聯網并沒有過多公開資源介紹 E300 RAW 格式(筆者僅找到一份公開資料,見https://myolympus.org/E300/#RAW),所以本文將從漏洞產生機制的角度,分析漏洞產生的原因。
1、在Win10 1903 x64系統上,使用gflags工具為圖片app開啟頁堆,雙擊圖片文件打開(圖片默認應用為照片App)。一段時間后,App退出進程。
2、使用Windbg附加照片App(Windbg 調試UWP方法詳見微軟文檔),敲擊g運行程序。一段時間后,進程崩潰。如下圖所示:
使用ida pro 加載崩潰的dll,可以確認崩潰發生在一個將數據寫入緩沖區的循環之中。
通過這段代碼,可初步大致判斷循環體條件語句導致循環次數過多,造成越界寫入。函數部分變量的初始化如下:
結合函數開始時局部變量的初始化和變量交叉引用的情況來看,可以得出:
1、代碼通過讀取某個類型對象的成員值,并加以運算,計算結果即為需要申請的緩沖區的大小;
2、緩沖區分為兩部分,一部分為size 為*(this+12320*4) * 2的數據塊(chunk2)另一部分數據塊(chunk1)的大小為*(this+0x12320*4) * 16 / 10個字節。
3、執行初始化后,代碼首先執行一個for循環,在這個循環體的內部執行另一個for循環,向chunk2內寫入數據。
所以,這段代碼的偽代碼如下:
chunk2_size = this->mem_12320;chunk1_size = chunk2_size * 16 / 10;char * data = (char *)malloc(chunk1_size + 2 * chunk2_size);for (char *i = data+chunk1_size; v12 < this->mem_12325; a5 = v12){…expresions;…for (char *pdata = data, char *j = i; j < chunk+chunk1_size+2*chunk2_size; pdata += 3, j += 4){if ((pdata – data) %15) pdata++;*(word *)j = pdata[1] << 8 | pdata[0]; //寫入兩個字節*(word *)(j+1) = pdata[2] << 4 | pdata[1] >> 4; //寫入兩個字節 }…expressions;…}
按照上面的偽代碼,每次循環都寫入四個字節,循環次數應該是(chunk2_size * 2 / 4)向上取整的值。在第一個for循環中,當 i = &data[chunk1_size],即從第二個chunk頭部開始循環寫入字節時,如果chunk2_size為奇數,循環次數 * 4 將大于chunk2_size。也就是說,最后一次循環中,寫入后兩個字節時,將造成越界,產生訪問違例。
使用windbg 附加App進程,并在崩潰函數設置斷點:
bu WindowsCodecsRaw!COlympusE300LoadRaw::olympus_e300_load_raw
圖片App 加載poc 文件時,獲取的chunk2_size為0xd79,是一個奇數。
通過上文的偽代碼可得:
chunk1_size = 0x158e
data 指向的內存區域是一個大小為0x3080的緩沖區。
代碼執行到第二個for循環時,需要寫入數據的指針存放在r15中,即為chunk2 緩沖區的起始地址(r15 == data + chunk1_size):
所以,在這種情況下,循環次數應為? (0xd79 * 2 / 4) ?,即為1725 次。而緩沖區只有2 * chunk2_size, 共6898個字節,不能支持1725*4 = 6900個字節的寫入。由此可知,最后一次循環將產生兩個字節的越界。至此,漏洞分析完畢。
循環次數記錄如下:共命中725次,與分析無誤。
該漏洞的發現者提到:通過函數名查找,這段代碼與LibRaw Lite庫的同名函數有較大的相似性,但是這個庫目前已經停止維護和更新了,源代碼下載地址失效,所以筆者在github上找到了類似的代碼片段。(https://github.com/coolshou/DIR-850L_A1/blob/92b64054ac75795429b9a6678baef5b3e69dfc10/progs.gpl/image_tools/netpbm-10.35.81/converter/other/cameratopam/camera.c)
對比可知,這段代碼與漏洞函數在實現上基本一致,所以微軟的代碼應該是在此基礎上重新實現了一遍。
因此,基于代碼供應鏈安全的考量,建議使用LibRaw Lite 庫函數的代碼,由相關人員自行更新補丁。
微軟官方在2月9日推出的補丁內容如下:
這個補丁比較簡單粗暴,即:復制第二個像素(第二次寫入雙字節)時,判斷指針是否指向緩沖區末端。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。