微軟MS09-002漏洞分析報告
Internet Explorer的CFunctionPointer函數(shù)沒有正確處理文檔對象,如果以特定序列附加并刪除了對象,就可以觸發(fā)內(nèi)存破壞。攻擊者可以構(gòu)造特殊順序的代碼觸發(fā)這個內(nèi)存破壞,同時利用精心構(gòu)造的緩沖區(qū),導(dǎo)致以當(dāng)前登錄用戶的權(quán)限執(zhí)行任意代碼。
該弱點實際存在于mshtml.dll中。CFunctionPointer對象在其構(gòu)造函數(shù)中沒有正確地引用文檔對象(標(biāo)簽對象或其它),導(dǎo)致該文檔對象可能在CFunctionPointer對象釋放前被釋放,而CFunctionPointer會繼續(xù)使用這個已經(jīng)被銷毀的文檔對象。
這是CFunctionPointer的構(gòu)造函數(shù):
public: __thiscall CFunctionPointer::CFunctionPointer(class CBase *, long)
.text:775E7BE9 mov edi, edi
.text:775E7BEB push ebp
.text:775E7BEC mov ebp, esp
.text:775E7BEE push esi
.text:775E7BEF mov esi, ecx
.text:775E7BF1 call ??0CBase@@QAE@XZ ; CBase::CBase(void)
.text:775E7BF6 mov ecx, [ebp+pOwner]
.text:775E7BF9 test ecx, ecx
.text:775E7BFB mov eax, [ebp+pISecurityContext]
.text:775E7BFE mov dword ptr [esi], offset ??_7CFunctionPointer@@6B@ ; const CFunctionPointer::`vftable'
.text:775E7C04 mov [esi+10h], ecx // 設(shè)置關(guān)聯(lián)文檔對象
在設(shè)置文檔對象時,CFunctionPointer的構(gòu)造函數(shù)僅僅是簡單的將其賦給[edi+10h],而沒有對其進(jìn)行引用(AddRef)。
而在CFunctionPointer其他函數(shù)中幾乎都使用了該關(guān)聯(lián)文檔對象指針,例如實現(xiàn)IUnknown::AddRef的CFunctionPointer::PrivateAddRef,實現(xiàn)IUnknown::Release的CFunctionPointer::PrivateRelease。
這是CFunctionPointer::PrivateAddRef函數(shù):
virtual unsigned long CFunctionPointer::PrivateAddRef(void)
.text:775E7A21 arg_0 = dword ptr 8
.text:775E7A21 mov edi, edi
.text:775E7A23 push ebp
.text:775E7A24 mov ebp, esp
.text:775E7A26 push esi
.text:775E7A27 mov esi, [ebp+arg_0] ; this
.text:775E7A2A mov eax, [esi+10h] ;獲得文檔對象指針
.text:775E7A2D test eax, eax
.text:775E7A2F jz short loc_775E7A3D
.text:775E7A31 cmp dword ptr [esi+4], 0
.text:775E7A35 jz short loc_775E7A3D
.text:775E7A37 mov ecx, [eax] ;取第一個DWORD,即虛表指針
.text:775E7A39 push eax
.text:775E7A3A call dword ptr [ecx+4] ;調(diào)用+4位置給出的函數(shù),即AddRef
例如在CFunctionPointer::PrivateAddRef中,如果文檔對象已經(jīng)被銷毀,那么將獲得不可預(yù)知的虛表指針,接下來執(zhí)行call dword ptr [ecx+4]后,將跳轉(zhuǎn)到一個不可預(yù)知地址去執(zhí)行 ,在一般情況下會導(dǎo)致IE崩潰。
攻擊者可以以特定的步驟,使CFunctionPointer對象的關(guān)聯(lián)文檔對象在CFunctio nPointer對象釋放前被釋放,接著再引用該CFunctionPointer對象,致使已經(jīng)被釋放的文檔對象被重新使用。
而攻擊者又可以以特殊的方式,任意設(shè)置被釋放文檔對象原來所在內(nèi)存位置的數(shù)據(jù)(即可構(gòu)造不正確的虛表),導(dǎo)致該弱點被擴(kuò)大到可以被利用于執(zhí)行任意代碼。