這似乎又是一個0 day漏洞,這個漏洞與pif文件有關,是我在研究pif文件的時候發現的。
實驗環境
Microsoft Windows 2000 5.00.2195 Service Pack 4
用到的軟件工具
010Editor
ollydbg
IDA pro
一 漏洞簡述
首先,win 2000系統里存在一個文件_default.pif,它的結構如下:

我在這個文件的基礎上添加了一個名為WINDOWS VMM 4.0的塊,如下圖:

把這個文件放在U盤根目錄下,插入win 2000系統后,瀏覽U盤時,資源管理器崩潰閃退。

二 對崩潰的逆向跟蹤,找到溢出點
我們可以確定的是,崩潰的出現是由于我們構造的pif文件里新的內容,而且應該出現在對文件內容的處理的過程中。
而根據pif文件的格式:

可以看到每個數據塊都有一個名字,猜測在對這些數據塊處理的代碼里可能包含這些名字的字符串常量,也許可以由此定位到數據塊處理相關代碼。
于是在explorer.exe和其調用的動態鏈接庫中搜索這些字符串,最終發現只有系統shell32.dll中存在這些字符串:

然后在ollydbg里追蹤崩潰。
由于windows系統只允許存在一個explorer.exe進程實例,我們用ollydbg打開新的explorer.exe進程進行動態調試時,系統會自動關閉該進程,從而阻止了調試的繼續進行。所以需要通過File ->Attach菜單項將系統當前的explorer.exe進程附加ollydbg中的方式進行調試。
在調用這些字符串常量的函數里下大量斷點,通過函數執行后崩潰是否發生判斷溢出點的大致位置:

最后跟蹤到這個函數:

也就是函數sub_7909062B
整個跟蹤過程如下:

動態分析函數sub_7909062B(上圖中藍色筆的部分),觀察堆棧,發現在某次執行lstrcpyA后,堆棧里的返回地址和其它數據被覆蓋。
執行lstrcpyA前后堆棧里的變化:


三 不太成功的漏洞利用
函數的返回地址被覆蓋,在Windows 2000系統上的漏洞利用應該是毫無難度的簡單勞動,但是這回的不太一樣。
在sub_79057E1D函數開始的地方將this指針保存在堆棧里:

在堆棧被覆蓋后的代碼里又使用到this指針。

造成程序沒有執行到函數返回指令的機會,所以按照常規方法通過返回地址得到程序執行權的方法在這里不適用。
但是this指針被覆蓋也為我們提供了獲得執行的機會,我們在溢出this指針的數據處設置為堆棧地址硬編碼,在溢出數據中構造出索引虛函數地址的數據,可以概率性的實現計算器的啟動。下面是我構造的pif文件:

程序執行到this指針索引到的虛函數調用時,數據區里包含了我們的shellcode,啟動的程序路徑,和用來索引虛函數的鏈表結構。如下圖:

其中包含了我寫的shellcode:

最終效果如下:

概率性成功的原因是,exploere.exe進程每次啟動的其棧地址都是動態變化的,溢出發生時真實的堆棧可能沒在我們提前設定的地址處。我這里測試平均每5次會有一次成功啟動計算器,最終的頻次體驗應該和電腦有關。
進一步研究,發現程序運行到調用虛函數地址時的寄存器EAX,EBX,ESI的值是溢出數據的某個位置的地址,所以理想的做法應該是尋找一個與JMP EAX,JMP EBX,JMP ESI類似的指令,假如這個指令的地址為A,設this的值為x,[ ]表示在進程地址空間里尋址后取值;我們可以將被覆蓋的this指針設定為滿足下面的公式的值:
[[(x+4)]+0x1c] = A
顯然,找到滿足上式的x是不容易的,我做了嘗試,但失敗了。不知道有沒有更好的技巧來利用這種漏洞。
四 Windows XP及其他版本系統里存在該漏洞嗎
進一步的,我對Windows XP的shell32.dll進行了逆向分析,發現同樣的位置與windows 2000的代碼極為相似,但是它用安全的_StringCopyWorker函數代替了lstrcpy,如下圖:

所以有理由相信,在后續的windows系統中微軟已經發現了這個漏洞,并修補了它。
我的安全夢
上官雨寶
FreeBuf
007bug
Anna艷娜
cayman
上官雨寶
安全牛
安全俠
FreeBuf
Anna艷娜
X0_0X