記一次VMware的崩潰除錯分析過程

ADLab發表於2020-09-14

1.研究背景


VMware Workstation是一款主流的虛擬機器軟體,近期啟明星辰ADLab安全研究員在使用VMware虛擬機器的過程中遇到虛擬機器異常崩潰的問題,當從7zip中直接將檔案拖拽到VMware虛擬機器中,會造成虛擬機器異常關閉。目前已測試過VMware 15.5.0、15.5.2、15.5.5 以及7zip 19.0、20.02等版本。本文將通過對VMware和7zip程式進行跟蹤分析,最終定位虛擬機器異常關閉原因。
2.VMware端除錯分析

使用WinDbg-I指令將WinDbg設定為即時偵錯程式,VMware-vmx.exe程式崩潰後自動彈出WinDbg。堆疊資訊如下:


記一次VMware的崩潰除錯分析過程


除錯資訊顯示stack buffer overrun異常,最初推斷可能是緩衝區溢位漏洞。


記一次VMware的崩潰除錯分析過程


通過查詢資料後發現,從Windows 8開始,Windows設計了一個新的中斷INT 29H,用以快速丟擲失敗,在sdk中被宣告為__fastfail, __fastfail內部函式不會返回。


體系結構指令程式碼引數的位置x86int 0x29ecxx64int 0x29rcxARM操作碼 0xDEFBr0


在上圖中,程式終止於int 29h,而它的引數為0xa,對應FAST_FAIL_GUARD_ICALL_CHECK_FAILURE,由此推斷問題可能出現在CFG的檢查過程中。


記一次VMware的崩潰除錯分析過程


從函式呼叫棧中vmware_vmx+0x58b21地址向上追溯,動態除錯程式,比較程式正常執行與異常崩潰的函式呼叫區別,定位到與程式崩潰相關的函式sub_1400965A0。


使用Windbg Attach vmware-vmx.exe程式,在sub_1400965A0函式設定斷點,開始動態除錯。從7z開啟的壓縮檔案中拖拽cdp.pcapng的檔案,程式在斷點處停下。通過動態除錯可知該函式中calloc分配了三個堆空間,分別用於存放:主機臨時檔案路徑temp_path、目標檔名file_name以及VMware中的快取目錄名vm_cache_dir_name。


記一次VMware的崩潰除錯分析過程


但是開啟主機Temp目錄下卻沒有發現該檔案,於是初步斷定這是程式崩潰原因。繼續往下看,3個檔案相關引數全都傳入了sub_140579b30函式。


記一次VMware的崩潰除錯分析過程


進入函式sub_140579b30,定位temp_path引數的處理。其中,sub_14057FF90函式對傳入的temp_path進行了逐一遍歷,sub_1405B2080函式對傳入的temp_path進行了非法性檢查。下面重點分析sub_140576460函式。


記一次VMware的崩潰除錯分析過程


sub_140576460函式將路徑引數temp_path傳入了sub_14049DA50。


記一次VMware的崩潰除錯分析過程


首先,函式sub_14049DA50通過sub_140477C70對字串進行了處理。然後,呼叫wstat64獲取相應路徑的檔案狀態,如果成功獲取則儲存到一個結構體中,否則返回0xffffffff。由於Temp目錄下並未發現備份檔案,導致獲取狀態失敗,從而返回0xffffffff。


記一次VMware的崩潰除錯分析過程

記一次VMware的崩潰除錯分析過程


返回0xffffffff後,重新回到sub_140579b30函式中,程式跳出while迴圈到達如下位置,輸出錯誤資訊並跳轉至sub_140572A70。


記一次VMware的崩潰除錯分析過程


從sub_140572A70最終執行到sub_1400960C0,到達如下位置將vmware_vmx+0xb1ed90處的值賦給了rsi,即為0。


記一次VMware的崩潰除錯分析過程


繼續往下執行,將rsi中0值賦值到rax中,然後呼叫0x7ff8fab0c510處,即ntdll!LdrpDispatchUserCallTarget。


記一次VMware的崩潰除錯分析過程


此處與靜態下的過程有一點不同,靜態下該處呼叫如下:


記一次VMware的崩潰除錯分析過程


如果按照靜態過程執行,應當到達sub_1407C7650,即如下位置:


記一次VMware的崩潰除錯分析過程

在ntdll.dll被載入之前,該處資料依舊為上圖所示地址:


記一次VMware的崩潰除錯分析過程


後來在ntdll.dll中實施CFG(ControlFlowGuard)保護機制,將vmware_vmx+0x7c9668地址處資料進行了改寫,從而執行到ntdll!LdrpDispatchUserCallTarget中。


記一次VMware的崩潰除錯分析過程


在ntdll!LdrpDispatchUserCallTarget函式中,取r11+r10*8處的值賦值給r11時出現了問題,該地址為空,就造成了空指標引用,從而執行了int 29h,造成異常。然而,即使沒有CFG機制,程式也會在執行“jmp rax”處崩潰,通過下圖可以看出,CFG機制僅僅是在原本程式跳轉指令前新增了一些檢查。


記一次VMware的崩潰除錯分析過程

記一次VMware的崩潰除錯分析過程


至此,VMware崩潰的原因基本分析清楚了。另一個疑問是,為什麼7zip已經在系統Temp下生成了檔案,並且VMware也已經獲取到了路徑引數,卻在移動前自動刪除了檔案呢。這就需要從7zip中尋找答案。


3.7zip端除錯分析

由上一節分析可知,Vmware crash原因是Temp目錄下檔案被刪除。閱讀7zip原始碼,鎖定了CPP/Windows/FileDir.cpp中的檔案刪除函式。


記一次VMware的崩潰除錯分析過程


使用WinDbg載入7zip,然後在Remove函式位置進行下斷,程式執行後進行拖拽操作,在Remove函式中斷後對應的呼叫堆疊如下所示。


記一次VMware的崩潰除錯分析過程


堆疊中7zFM+0x5b212地址位於函式CPanel::OnDrag中,該函式為滑鼠拖拽操作函式。當檢測到對7zip開啟的目錄進行操作時,便會在Temp目錄下生成一個以7zE開頭的隨機命名資料夾。


記一次VMware的崩潰除錯分析過程


然後,將該資料夾設定為目標目錄,並且設定了一些資料及IpDropSourse結構體。


記一次VMware的崩潰除錯分析過程


繼續往下可以看到一個DoDragDrop函式,該函式功能是進行OLE拖放相關操作,通過檢測游標的行為分別呼叫一些方法並返回對應的數值。


記一次VMware的崩潰除錯分析過程


然後,根據DoDragDrop函式的返回值來判斷游標的拖拽是否有效,從而執行對應的操作。


記一次VMware的崩潰除錯分析過程


從7zip中拖拽檔案到虛擬機器,由於無法獲知檔案拖拽的目標路徑,因此DoDragDrop會返回DRAGDROP_S_CANCEL(0x40101),不會執行拷貝操作的分支,而是直接將Temp目錄下生成的臨時目錄刪除。


記一次VMware的崩潰除錯分析過程


4.小 結


7zip壓縮包中檔案拖拽操作會觸發DoDragDrop函式呼叫,該函式會獲取檔案資料及游標停止的位置。但是將檔案拖拽到VMware視窗時,DoDragDrop函式不能獲取準確的目標路徑,因此無法將檔案拷貝到目標位置,從而直接刪除臨時檔案,最終導致VMware無法獲取檔案狀態造成崩潰。


參考連結:

[1]https://0cch.com/2016/12/13/int29h/

[2]https://docs.microsoft.com/en-us/windows/win32/api/ole2/nf-ole2-dodragdrop

[3]https://github.com/kornelski/7z/tree/20e38032e62bd6bb3a176d51bce0558b16dd51e2



啟明星辰積極防禦實驗室(ADLab)


ADLab成立於1999年,是中國安全行業最早成立的攻防技術研究實驗室之一,微軟MAPP計劃核心成員,“黑雀攻擊”概念首推者。截止目前,ADLab已通過CVE累計釋出安全漏洞近1100個,通過 CNVD/CNNVD累計釋出安全漏洞900餘個,持續保持國際網路安全領域一流水準。實驗室研究方向涵蓋作業系統與應用系統安全研究、移動智慧終端安全研究、物聯網智慧裝置安全研究、Web安全研究、工控系統安全研究、雲安全研究。研究成果應用於產品核心技術研究、國家重點科技專案攻關、專業安全服務等。


記一次VMware的崩潰除錯分析過程


相關文章