[原創]360網盾 廣告攔截模組崩潰分析
仙果發表於2012-12-10
360網盾 廣告攔截模組崩潰分析
宣告:此Bug不是本人發現的,所做的工作是對Bug成因進行分析,分析的過程中自己學到了很多東西,
在此感謝提供此Bug的壇友:xuecniao,是你讓我有了這次鍛鍊的機會。
分析過程是逆向分析的,希望能和大家多多交流。其中有錯誤之處歡迎指正。
1.分析環境:
Windwos XP SP3_CN(虛擬機器)
360安全衛士8.7.2002(最新版)
備用木馬庫版本:2012.11.3.1
工具:
IDA 5.5
Windbg
OD
2.分析過程
樣本程式碼如下:
xp3系統,ie8,360安全衛士-7.6.0.1130
<a> 標籤的 href 屬性用於指定超連結目標的 URL。
首先這是一個惡意的URL連結,正常情況下IE處理這個請求但不會崩潰,開啟360安全衛士以後,IE崩潰,使用Windbg除錯,發現以下地址報錯
ecx為0,自然程式在讀取[eax]的內容,觸發一個記憶體不可讀的異常,IE發生崩潰。
檢視這個Adfilter的相關資訊:
確認是360網盾的一個DLL檔案,並且DLL檔案屬性資訊可以檢視到“360網盾 廣告攔截模組”,
使用IDA載入Adfilter.dll進行靜態分析,跳轉到崩潰程式碼,發現如下資訊:
顯然IDA已經把函式名提示出來:wcslen(const wchar_t *Str),檢視引數可以發現,只有一個引數,為wchar_t 型的字串指標,
反彙編中,ecx是一個字串指標,指向一串字元,而在程式中,
65448f26 8b4c2404 mov ecx,dword ptr [esp+4]
ecx為空,即空指標,空指標引用出錯導致的IE崩潰。
使用VC程式碼進行演示:
上述程式碼肯定會觸發一個異常。
現在為止,知道了是什麼地方導致的IE崩潰,但是傳遞給wcslen()函式空指標的原因何在,之前為什麼沒有檢測到空指標,這些疑問需要解決,
分析的過程中也繞了一個彎路,以下是繞的彎路的分析過程:
從00d615e4 函式處呼叫Adfilter.dll中程式碼
繼續往上分析發現。。。
下這個斷點,然後得到當 eax=0時跳轉到錯誤處理流程。
當eax=oxfa時,執行.text:65405CB4 sub eax, 0FAh 後eax=0,跳轉到錯誤的執行流程。。。
以下為除錯時使用的一些命令
如下地址寫入了0xfa
呼叫關係:
找到的相關資訊:
http://www.sonic.net/~undoc/comes_v_microsoft/Supp_Rpt_Andrew_Schulman.pdf
Connection Point APIs: A “connection point” is a mechanism related to
receiving callback notifications of given events. Microsoft has a
documented ConnectionPoint class, and in 2004 Microsoft documented
ConnectToConnectionPoint. However, there remain connection-point
related shell APIs, implemented by shlwapi.dll, and used by the IE
component shdocvw.dll, that are not documented:
IConnectionPoint_InvokeWithCancel and
IConnectionPoint_SimpleInvoke. See e.g.:
最終找到如下的一個地址,寫入了0xfa這個整數。。
函式宣告:
由於以上函式都是微軟未文件化的函式,所以具體含義只能從語義上來判斷,引數等結構資訊無法得到。
上面的分析過程花費了我很長時間來跟蹤除錯,最終發現是一個錯誤的判斷。過程是這樣的,本來以為自己找到了關鍵點,但是有一個疑問是這樣的:
既然找到了0xfa的出處,但是什麼樣的原因導致程式走到了這個流程中來,與點選的超連結有什麼樣子的一個關係,超連結是如何影響程式執行流程的,
這個疑問是始終沒有解決,也不敢妄下結論。
下面就開始驗證自己的想法,把虛擬機器除錯環境克隆了一份出來,進行兩臺虛擬機器一起除錯,一臺是IE正常的環境,另一臺就是IE崩潰環境,
跟蹤除錯那一條指令出現了差異導致程式的執行流程發生了變化。這個時候就發現正常情況與崩潰情況下都會出現0xfa,程式都會執行到Adfilter.dll中程式碼,
區別只有傳遞給wcslen()函式的指標是否是空指標的差別。
以下即是過程:
現在開始查詢惡意字串是如何影響到oxfa這個流程的。。。。
可以明顯的看出來,執行到eip=00d28fb9後0211e424的這個地址又了明顯的變化。。。
正常情況下是又指標的,異常情況下沒有寫入字串的指標。。。
poi(poi(esi)+58)+8
現在來看00d28fb9是在執行什麼操作:
接著找寫入資料的地方
正常情況下,跟蹤到這個處理函式
異常情況下,不會走到這個流程中。。。
堆疊資訊如下:
發現都會呼叫0211f568 63776ac8 mshtml!CWebOCEvents::BeforeNavigate2+0x29f函式,在這個函式上下斷點,跟蹤處理流程上的變化
最終是 call _IEGetDisplayName@12 此函式正常情況下與崩潰情況下的返回值不同,導致了執行流程的不同,最終導致Adfilter.dll呼叫wcslen()函式出錯。。。
IEGetDisplayName最終呼叫:
至此此次360網盾 廣告攔截模組 的bug才算分析完畢,其中也有一些不太明白的地方,但程式基本的處理流程就是這樣的。現在可以總結一下這個360bug的觸發原因了。。。
三.總結
前前後後花了很長時間來分析這個bug,也走了很長的彎路。
360網盾的廣告攔截模組給IE註冊了很多個回撥函式,但在處理回撥的資料時存在問題,直接引用並下發IE ieframe.dll的GetEventURL()函式的返回值,
並沒有判斷返回值是否為空情況的情況存在,傳遞給了wcslen()函式,導致IE崩潰。
Assay_Bug.txt
宣告:此Bug不是本人發現的,所做的工作是對Bug成因進行分析,分析的過程中自己學到了很多東西,
在此感謝提供此Bug的壇友:xuecniao,是你讓我有了這次鍛鍊的機會。
分析過程是逆向分析的,希望能和大家多多交流。其中有錯誤之處歡迎指正。
1.分析環境:
Windwos XP SP3_CN(虛擬機器)
360安全衛士8.7.2002(最新版)
備用木馬庫版本:2012.11.3.1
工具:
IDA 5.5
Windbg
OD
2.分析過程
樣本程式碼如下:
xp3系統,ie8,360安全衛士-7.6.0.1130
<A href="file:///c:\windows\system32\BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB">按一下</A>
<a> 標籤的 href 屬性用於指定超連結目標的 URL。
首先這是一個惡意的URL連結,正常情況下IE處理這個請求但不會崩潰,開啟360安全衛士以後,IE崩潰,使用Windbg除錯,發現以下地址報錯
65448f26 8b4c2404 mov ecx,dword ptr [esp+4] 65448f2a 66833900 cmp word ptr [ecx],0 ds:0023:00000000=???? 65448f2e 8d4102 lea eax,[ecx+2] 65448f31 740a je Adfilter!OnTrayMsg+0x2119b (65448f3d) 0:008> r eax=00000000 ebx=00000000 ecx=00000000 edx=000000c0 esi=0211e354 edi=02b24c14 eip=65448f2a esp=0211e170 ebp=0211e1ac iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 Adfilter!OnTrayMsg+0x21188: 65448f2a 66833900 cmp word ptr [ecx],0 ds:0023:00000000=????
ecx為0,自然程式在讀取[eax]的內容,觸發一個記憶體不可讀的異常,IE發生崩潰。
檢視這個Adfilter的相關資訊:
0:008> !lmi Adfilter Loaded Module Info: [adfilter] Module: Adfilter Base Address: 65400000 Image Name: C:\Program Files\360\360safe\safemon\Adfilter.dll Machine Type: 332 (I386) Time Stamp: 4f558bc0 Tue Mar 06 12:00:00 2012 Size: ab000 CheckSum: b1275 Characteristics: 210e Debug Data Dirs: Type Size VA Pointer CODEVIEW 45, 0, a8000 [Debug data not mapped] - Can't validate symbols, if present. Image Type: FILE - Image read successfully from debugger. C:\Program Files\360\360safe\safemon\Adfilter.dll Symbol Type: EXPORT - PDB not found Load Report: export symbols
確認是360網盾的一個DLL檔案,並且DLL檔案屬性資訊可以檢視到“360網盾 廣告攔截模組”,
使用IDA載入Adfilter.dll進行靜態分析,跳轉到崩潰程式碼,發現如下資訊:
.text:65448F26 ; =============== S U B R O U T I N E ======================================= .text:65448F26 .text:65448F26 ; Attributes: library function .text:65448F26 .text:65448F26 ; size_t __cdecl wcslen(const wchar_t *Str) .text:65448F26 _wcslen proc near ; CODE XREF: sub_654012C5+61p .text:65448F26 ; sub_65402AB1+D4p ... .text:65448F26 .text:65448F26 Str = dword ptr 4 .text:65448F26 .text:65448F26 mov ecx, [esp+Str] .text:65448F2A cmp word ptr [ecx], 0 .text:65448F2E lea eax, [ecx+2] .text:65448F31 jz short loc_65448F3D .text:65448F33 .text:65448F33 loc_65448F33: ; CODE XREF: _wcslen+15j .text:65448F33 mov dx, [eax] .text:65448F36 inc eax .text:65448F37 inc eax .text:65448F38 test dx, dx .text:65448F3B jnz short loc_65448F33 .text:65448F3D .text:65448F3D loc_65448F3D: ; CODE XREF: _wcslen+Bj .text:65448F3D sub eax, ecx .text:65448F3F sar eax, 1 .text:65448F41 dec eax .text:65448F42 retn .text:65448F42 _wcslen endp
顯然IDA已經把函式名提示出來:wcslen(const wchar_t *Str),檢視引數可以發現,只有一個引數,為wchar_t 型的字串指標,
反彙編中,ecx是一個字串指標,指向一串字元,而在程式中,
65448f26 8b4c2404 mov ecx,dword ptr [esp+4]
ecx為空,即空指標,空指標引用出錯導致的IE崩潰。
使用VC程式碼進行演示:
#include <Windows.h> int _tmain(int argc, _TCHAR* argv[]) { WCHAR* p = NULL; wcslen(p); return 0; }
上述程式碼肯定會觸發一個異常。
現在為止,知道了是什麼地方導致的IE崩潰,但是傳遞給wcslen()函式空指標的原因何在,之前為什麼沒有檢測到空指標,這些疑問需要解決,
分析的過程中也繞了一個彎路,以下是繞的彎路的分析過程:
從00d615e4 函式處呼叫Adfilter.dll中程式碼
Breakpoint 0 hit eax=65461620 ebx=00175c90 ecx=00000001 edx=000000c0 esi=0211e260 edi=02b24bf8 eip=00d615e4 esp=0211e1b4 ebp=0211e1e0 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 IEFRAME!IEIsProtectedModeProcess+0x580b: 00d615e4 ff5018 call dword ptr [eax+18h] ds:0023:65461638=65405c64
繼續往上分析發現。。。
下這個斷點,然後得到當 eax=0時跳轉到錯誤處理流程。
bp 65405cb9 "r eax;gc" .text:65405CA3 mov edi, [ebp+8] .text:65405CA6 mov ecx, edi .text:65405CA8 call sub_65405AA8 .text:65405CAD test eax, eax .text:65405CAF jz short loc_65405C9C .text:65405CB1 mov eax, [ebp+0Ch] .text:65405CB4 sub eax, 0FAh .text:65405CB9 jz loc_65405F75 ; eax=0x0,在這裡跳轉到錯誤處理流程 .... .text:65405F75 loc_65405F75: ; CODE XREF: .text:65405CB9j .text:65405F75 mov eax, [ebp+8] .text:65405F78 push dword ptr [eax+1Ch] .text:65405F7B lea edi, [eax+1Ch] .text:65405F7E call sub_654026F7 .text:65405F83 push dword ptr [edi] .text:65405F85 call sub_65402612 .text:65405F8A mov eax, [esi] .text:65405F8C pop ecx .text:65405F8D pop ecx .text:65405F8E mov eax, [eax+58h] .text:65405F91 push ebx .text:65405F92 mov [ebp+1Ch], eax .text:65405F95 mov al, [ebp+0Bh] .text:65405F98 lea ecx, [ebp-28h] .text:65405F9B mov [ebp-28h], al .text:65405F9E call ?_Tidy@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@AAEX_N@Z ; std::basic_string<ushort,std::char_traits<ushort>,std::allocator<ushort>>::_Tidy(bool) .text:65405FA3 mov eax, [ebp+1Ch] .text:65405FA6 mov [ebp-4], ebx .text:65405FA9 test byte ptr [eax+1], 40h .text:65405FAD mov eax, [eax+8] ; 正常情況兄下[eax+8]儲存有字串的指標 .text:65405FB0 jz short loc_65405FC4 .text:65405FB2 mov eax, [eax] .text:65405FB4 push eax ; Str .text:65405FB5 mov [ebp+1Ch], eax .text:65405FB8 call _wcslen ; 這裡呼叫出錯函式
當eax=oxfa時,執行.text:65405CB4 sub eax, 0FAh 後eax=0,跳轉到錯誤的執行流程。。。
breakpoint 9 redefined eax=ffffff6f eax=ffffff6f eax=ffffff6f eax=ffffff6f eax=ffffff6f eax=ffffff6f eax=ffffff6f eax=ffffff6c eax=ffffff6f eax=00000000 Breakpoint 8 hit eax=00000000 ebx=00000000 ecx=0211e1a0 edx=000000c0 esi=0211e354 edi=02b24d08 eip=65405f75 esp=0211e178 ebp=0211e1ac iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 Adfilter!IsInWhiteList+0x7ef: 65405f75 8b4508 mov eax,dword ptr [ebp+8] ss:0023:0211e1b4=02b24d08
以下為除錯時使用的一些命令
bp 65405C64 "r ‘poi(ebp+0x0c)’;'gc'" bp 65405C64 ".echo begin ######### ;dd poi(ebp+0c);.echo end ##############;gc" bp 65405CA8 ".echo begin ######### ;dd poi(ebp+0c);.echo end ##############;gc"
bp 65405CA8 ".echo begin ######### ;dd poi(ebp+0c);.echo end ##############;gc" begin ######### 000000fa ???????? ???????? ???????? ???????? 0000010a ???????? ???????? ???????? ???????? 0000011a ???????? ???????? ???????? ???????? 0000012a ???????? ???????? ???????? ???????? 0000013a ???????? ???????? ???????? ???????? 0000014a ???????? ???????? ???????? ???????? 0000015a ???????? ???????? ???????? ???????? 0000016a ???????? ???????? ???????? ???????? bp 65405CA6 ".echo begin ######### ;dd poi(ebp+0c);.echo end ##############;gc" bp 65405C7B ".echo begin ######### ;dd poi(ebp+0c);.echo end ##############;gc" bp 65405C64 ".echo begin ######### ;dd poi(ebp+0c);.echo end ##############;gc" begin ######### 0211e260 00000003 000000fa 00d61078 00000000 0211e270 e3540001 00000211 00000000 00000000 0211e280 d4af0000 021100d5 0211e430 00000000 0211e290 0211e368 00d5d454 001758d0 000000fa 0211e2a0 0211e354 0211e430 00000000 0000400c 0211e2b0 0000400b 0000400b 00000000 0211e430 0211e2c0 00000000 0000400c 00000000 0211e40c 0211e2d0 00000000 0000400c 00000000 0211e3ec end ############## Breakpoint 8 hit eax=00000000 ebx=00000000 ecx=0211e1a0 edx=000000c0 esi=0211e354 edi=02b24d08 eip=65405f75 esp=0211e178 ebp=0211e1ac iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 Adfilter!IsInWhiteList+0x7ef: 65405f75 8b4508 mov eax,dword ptr [ebp+8] ss:0023:0211e1b4=02b24d08
如下地址寫入了0xfa
.text:00D5D46C ; __stdcall IConnectionPoint_InvokeWithCancel(x, x, x, x, x) .text:00D5D46C _IConnectionPoint_InvokeWithCancel@20 proc near .text:00D5D46C ; CODE XREF: DoInvokeParamHelper(IUnknown *,IConnectionPoint *,int *,void * *,long,uint,...)+7Ap .text:00D5D46C .text:00D5D46C var_30 = dword ptr -30h .text:00D5D46C var_2C = dword ptr -2Ch .text:00D5D46C var_1E = dword ptr -1Eh .text:00D5D46C var_E = dword ptr -0Eh .text:00D5D46C var_8 = dword ptr -8 .text:00D5D46C var_4 = dword ptr -4 .text:00D5D46C arg_0 = dword ptr 8 .text:00D5D46C arg_4 = dword ptr 0Ch .text:00D5D46C arg_8 = dword ptr 10h .text:00D5D46C arg_C = dword ptr 14h .text:00D5D46C arg_10 = dword ptr 18h .text:00D5D46C .text:00D5D46C mov edi, edi .text:00D5D46E push ebp .text:00D5D46F mov ebp, esp .text:00D5D471 sub esp, 30h .text:00D5D474 mov eax, [ebp+arg_4] .text:00D5D477 mov [ebp+var_2C], eax ; 寫入0xfa .text:00D5D47A mov eax, [ebp+arg_8] .text:00D5D47D mov [ebp+var_1E], eax .text:00D5D480 mov eax, [ebp+arg_C] .text:00D5D483 mov [ebp+var_8], eax .text:00D5D486 mov eax, [ebp+arg_10] .text:00D5D489 mov [ebp+var_4], eax .text:00D5D48C lea eax, [ebp+var_30] .text:00D5D48F push eax .text:00D5D490 push [ebp+arg_0] .text:00D5D493 mov [ebp+var_30], 3 .text:00D5D49A mov [ebp+var_E], offset ?InvokeWithCancelProc@@YGJPAUIDispatch@@PAUSHINVOKEPARAMS@@@Z ; InvokeWithCancelProc(IDispatch *,SHINVOKEPARAMS *) .text:00D5D4A1 call _IConnectionPoint_InvokeIndirect@8 ; IConnectionPoint_InvokeIndirect(x,x) .text:00D5D4A6 leave .text:00D5D4A7 retn 14h .text:00D5D4A7 _IConnectionPoint_InvokeWithCancel@20 endp
呼叫關係:
WARNING: Stack unwind information not available. Following frames may be wrong. 0211e290 00d5d454 IEFRAME!IEIsProtectedModeProcess+0x16a1 0211e368 00d29054 IEFRAME!IEIsProtectedModeProcess+0x167b 0211e45c 00d365b0 IEFRAME!Ordinal218+0x2c1f 0211e4a4 63777bcb IEFRAME!Ordinal303+0x4052 0211f568 63776ac8 mshtml!CWebOCEvents::BeforeNavigate2+0x29f 0211f750 63776610 mshtml!CDoc::DoNavigate+0xab5 0211f870 637788a2 mshtml!CDoc::FollowHyperlink2+0xda7 0211f8f0 636b6de9 mshtml!CDoc::FollowHyperlink+0x9d
找到的相關資訊:
http://www.sonic.net/~undoc/comes_v_microsoft/Supp_Rpt_Andrew_Schulman.pdf
Connection Point APIs: A “connection point” is a mechanism related to
receiving callback notifications of given events. Microsoft has a
documented ConnectionPoint class, and in 2004 Microsoft documented
ConnectToConnectionPoint. However, there remain connection-point
related shell APIs, implemented by shlwapi.dll, and used by the IE
component shdocvw.dll, that are not documented:
IConnectionPoint_InvokeWithCancel and
IConnectionPoint_SimpleInvoke. See e.g.:
最終找到如下的一個地址,寫入了0xfa這個整數。。
函式宣告:
.text:00D28EB9 ; int __stdcall FireEvent_BeforeNavigate(struct IUnknown *punk, int, int, struct _ITEMIDLIST_ABSOLUTE *, int, int, int, void *Src, ULONG Size, int, int) .text:00D28EB9 _FireEvent_BeforeNavigate@44 proc near ; CODE XREF: CBaseBrowser2::_FireBeforeNavigateEvent(_ITEMIDLIST_ABSOLUTE const *,int *)+172p .text:00D28EB9 ; CBaseBrowser2::FireBeforeNavigate3(IHTMLWindow2 *,IDispatch *,ushort const *,ulong,ushort const *,uchar *,ulong,ushort const *,int,int *)+88p ... .text:00D28EB9 .text:00D28FFC xor eax, eax .text:00D28FFE cmp [ebp+var_10], eax .text:00D29001 mov [ebp+var_80], 3 .text:00D29007 mov [ebp+var_60], 8 .text:00D2900D mov [ebp+var_70], si .text:00D29011 mov [ebp+var_50], 8 .text:00D29017 mov edi, 0FAh ; 0xfa是從這裡來的 .text:00D2901C jz short loc_D29059 .text:00D2901E lea ecx, [ebp+var_2C] .text:00D29021 push ecx .text:00D29022 push ebx .text:00D29023 lea ecx, [ebp+var_50] .text:00D29026 push ecx .text:00D29027 push esi .text:00D29028 lea ecx, [ebp+var_70]
由於以上函式都是微軟未文件化的函式,所以具體含義只能從語義上來判斷,引數等結構資訊無法得到。
上面的分析過程花費了我很長時間來跟蹤除錯,最終發現是一個錯誤的判斷。過程是這樣的,本來以為自己找到了關鍵點,但是有一個疑問是這樣的:
既然找到了0xfa的出處,但是什麼樣的原因導致程式走到了這個流程中來,與點選的超連結有什麼樣子的一個關係,超連結是如何影響程式執行流程的,
這個疑問是始終沒有解決,也不敢妄下結論。
下面就開始驗證自己的想法,把虛擬機器除錯環境克隆了一份出來,進行兩臺虛擬機器一起除錯,一臺是IE正常的環境,另一臺就是IE崩潰環境,
跟蹤除錯那一條指令出現了差異導致程式的執行流程發生了變化。這個時候就發現正常情況與崩潰情況下都會出現0xfa,程式都會執行到Adfilter.dll中程式碼,
區別只有傳遞給wcslen()函式的指標是否是空指標的差別。
以下即是過程:
現在開始查詢惡意字串是如何影響到oxfa這個流程的。。。。
s -a 0 l fffffff "file:///c:" 0378934b 66 69 6c 65 3a 2f 2f 2f 63 3a 5c 77 69 6e 64 6f 77 73 file:///c:\windows 0378935d 5c 73 79 73 74 65 6d 33 32 5c 42 42 42 42 42 42 42 42 \system32\BBBBBBBB 0378936f 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 BBBBBBBBBBBBBBBBBB 03789381 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 BBBBBBBBBBBBBBBBBB 03789393 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 BBBBBBBBBBBBBBBBBB s -u 0 l?fffffff "file:///c:" ba w1 0211e424 "r eip;.echo check mem;dd 0211e424;.echo changed;gc" Normal:正常情況 eip=00d28fa8 check mem 0211e424 02110000 0211e518 00000064 00000000 0211e434 00000000 00000000 00000000 ffffffff 0211e444 00000000 00000000 00175d70 00000000 0211e454 03c4afd4 00175d4c 0211e4a4 00d365b0 0211e464 00175d04 002901d0 00175d04 00c4c408 0211e474 00000000 00000040 00000000 00000000 0211e484 00000000 00000000 0211f5c8 0211f5c8 0211e494 002239d4 00202020 00000000 00175d04 changed eip=00d28fb9 check mem 0211e424 03c4adac 00000000 00000064 00000000 03c4adac為字串指標 0211e434 00000000 00000000 00000000 ffffffff 0211e444 00000000 00000000 00175d70 00000000 0211e454 03c4afd4 00175d4c 0211e4a4 00d365b0 0211e464 00175d04 002901d0 00175d04 00c4c408 0211e474 00000000 00000040 00000000 00000000 0211e484 00000000 00000000 0211f5c8 0211f5c8 0211e494 002239d4 00202020 00000000 00175d04 changed BUG:崩潰情況 eip=00d28fa8 check mem 0211e424 02110000 0211e518 00000064 00000000 0211e434 00000000 00000000 00000000 ffffffff 0211e444 00000000 00000000 00175ea8 00000000 0211e454 00000000 00175e84 0211e4a4 00d365b0 0211e464 00175e3c 000c025e 00175e3c 00c4ec48 0211e474 00000000 00000040 00000000 00000000 0211e484 00000000 00000000 0211f5c8 0211f5c8 0211e494 002231d4 00201820 00000000 00175e3c changed eip=00d28fb9 check mem 0211e424 00000000 00000000 00000064 00000000 這裡沒有字串指標存在。。。。 0211e434 00000000 00000000 00000000 ffffffff 0211e444 00000000 00000000 00175ea8 00000000 0211e454 00000000 00175e84 0211e4a4 00d365b0 0211e464 00175e3c 000c025e 00175e3c 00c4ec48 0211e474 00000000 00000040 00000000 00000000 0211e484 00000000 00000000 0211f5c8 0211f5c8 0211e494 002231d4 00201820 00000000 00175e3c changed
可以明顯的看出來,執行到eip=00d28fb9後0211e424的這個地址又了明顯的變化。。。
正常情況下是又指標的,異常情況下沒有寫入字串的指標。。。
poi(poi(esi)+58)+8
現在來看00d28fb9是在執行什麼操作:
.text:00D28FAB mov [ebp+var_40], 8 .text:00D28FB1 call _SysAllocString@4 ; SysAllocString(x) .text:00D28FB6 mov [ebp+SystemTimeAsFileTime], eax //這裡寫入字串指標。。。。 .text:00D28FB9 xor eax, eax .text:00D28FBB lea edi, [ebp+var_7E] 此時的堆疊呼叫如下: 0:008> k ChildEBP RetAddr WARNING: Stack unwind information not available. Following frames may be wrong. 0211e45c 00d365b0 IEFRAME!Ordinal218+0x2b76 0211e4a4 63777bcb IEFRAME!Ordinal303+0x4052 0211f568 63776ac8 mshtml!CWebOCEvents::BeforeNavigate2+0x29f 0211f750 63776610 mshtml!CDoc::DoNavigate+0xab5 0211f870 637788a2 mshtml!CDoc::FollowHyperlink2+0xda7 0211f8f0 636b6de9 mshtml!CDoc::FollowHyperlink+0x9d 0211f994 636b6c68 mshtml!CHyperlink::ClickAction+0x31c 0211f9a4 636b57da mshtml!CAnchorElement::ClickAction+0x10 0211f9d8 636b2be9 mshtml!CElement::DoClick+0x155 0211fa08 636b2b5a mshtml!CAnchorElement::DoClick+0x6d 0211faa4 635f1fea mshtml!CDoc::PumpMessage+0xf10
接著找寫入資料的地方
ba w1 0211e454 "r eip;.echo check mem;dd 0211e454;.echo changed;gc"
正常情況下,跟蹤到這個處理函式
.text:00D284AE ; int __stdcall ATL__CComBSTR__operator_(OLECHAR *psz) .text:00D284AE ??4CComBSTR@ATL@@QAEAAV01@PBG@Z proc near .text:00D284AE ; CODE XREF: CDataList::SetTitle(ushort const *)+Ep .text:00D284AE ; CDocObjectHost::_PublishParsedData(int)-32DD9p ... .text:00D284AE .text:00D284AE psz = dword ptr 8 .text:00D284AE .text:00D284AE mov edi, edi .text:00D284B0 push ebp .text:00D284B1 mov ebp, esp .text:00D284B3 push esi .text:00D284B4 mov esi, ecx .text:00D284B6 push dword ptr [esi] ; bstrString .text:00D284B8 call _SysFreeString@4 ; SysFreeString(x) .text:00D284BD push [ebp+psz] ; psz .text:00D284C0 call _SysAllocString@4 ; SysAllocString(x) .text:00D284C5 mov [esi], eax .text:00D284C7 mov eax, esi .text:00D284C9 pop esi .text:00D284CA pop ebp .text:00D284CB retn 4 .text:00D284CB ??4CComBSTR@ATL@@QAEAAV01@PBG@Z endp
異常情況下,不會走到這個流程中。。。
堆疊資訊如下:
0:008> k ChildEBP RetAddr WARNING: Stack unwind information not available. Following frames may be wrong. 0211d34c 00d288b9 IEFRAME!Ordinal218+0x2079 0211e3b0 00d28ef2 IEFRAME!Ordinal218+0x2484 0211e45c 00d365b0 IEFRAME!Ordinal218+0x2abd 0211e4a4 63777bcb IEFRAME!Ordinal303+0x4052 0211f568 63776ac8 mshtml!CWebOCEvents::BeforeNavigate2+0x29f 異常情況下的堆疊呼叫關係如下: 0:008> k ChildEBP RetAddr WARNING: Stack unwind information not available. Following frames may be wrong. 0211d34c 00d288b9 IEFRAME!Ordinal218+0x2079 0211e3b0 00d28ef2 IEFRAME!Ordinal218+0x2484 0211e45c 00d365b0 IEFRAME!Ordinal218+0x2abd 0211e4a4 63777bcb IEFRAME!Ordinal303+0x4052 0211f568 63776ac8 mshtml!CWebOCEvents::BeforeNavigate2+0x29f
發現都會呼叫0211f568 63776ac8 mshtml!CWebOCEvents::BeforeNavigate2+0x29f函式,在這個函式上下斷點,跟蹤處理流程上的變化
63776a99 ff74247c push dword ptr [esp+7Ch] 63776a9d 52 push edx 63776a9e ff742428 push dword ptr [esp+28h] 63776aa2 8b542428 mov edx,dword ptr [esp+28h] 63776aa6 ffb42484000000 push dword ptr [esp+84h] 63776aad ffb42480000000 push dword ptr [esp+80h] 63776ab4 51 push ecx 63776ab5 ff30 push dword ptr [eax] 63776ab7 8b8c24d4000000 mov ecx,dword ptr [esp+0D4h] 63776abe 8d442454 lea eax,[esp+54h] 63776ac2 50 push eax 63776ac3 e8010f0000 call mshtml!CWebOCEvents::BeforeNavigate2 (637779c9) //斷在這裡 此時ECX中儲存了 超連結的路徑 0:008> du ecx 037c67b0 "file:///c:/windows/system32/BBBB" 037c67f0 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 037c6830 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 037c6870 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 037c68b0 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 037c68f0 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 037c6930 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 037c6970 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 037c69b0 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 037c69f0 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 037c6a30 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 037c6a70 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 求得字串長度 63777a51 8d5002 lea edx,[eax+2] 63777a54 668b08 mov cx,word ptr [eax] 63777a57 40 inc eax 63777a58 40 inc eax 63777a59 663bce cmp cx,si 63777a5c 75f6 jne mshtml!CWebOCEvents::BeforeNavigate2+0x8b (63777a54) 63777a5e 2bc2 sub eax,edx //計算結果為字串長度 63777a60 d1f8 sar eax,1 計算結果 nromal: 0:008> r eax eax=0000010b Bug: 0:008> r eax eax=00000255 .... 63777ab9 ffb580efffff push dword ptr [ebp-1080h] //壓棧,把字串指標壓棧 源地址 63777abf 8bb58cefffff mov esi,dword ptr [ebp-1074h] ss:0023:0211e4f4=0211f5c8 63777ac5 832600 and dword ptr [esi],0 63777ac8 53 push ebx 63777ac9 8d85b0efffff lea eax,[ebp-1050h] 63777acf 50 push eax //目的地址 63777ad0 e871e2e7ff call mshtml!StringCchCopyW (635f5d46) 字串複製函式, ..... 63777bbb 8b8598efffff mov eax,dword ptr [ebp-1068h] 63777bc1 8b08 mov ecx,dword ptr [eax] 63777bc3 83c714 add edi,14h 63777bc6 57 push edi 63777bc7 50 push eax 63777bc8 ff510c call dword ptr [ecx+0Ch] ds:0023:00d2b850=00d36523 這裡進入iframe.dll中的處理流程 .text:00D36592 push edi ; int .text:00D36593 push [ebp+arg_20] ; int .text:00D36596 push [ebp+Size] ; Size .text:00D36599 push [ebp+Src] ; Src .text:00D3659C push eax ; int .text:00D3659D push [ebp+arg_10] ; int .text:00D365A0 push ebx ; int .text:00D365A1 push ecx ; struct _ITEMIDLIST_ABSOLUTE * .text:00D365A2 push [ebp+ppvOut] ; int .text:00D365A5 push dword ptr [esi+48h] ; int .text:00D365A8 push [ebp+ppvOut] ; punk .text:00D365AB call _FireEvent_BeforeNavigate@44 ; FireEvent_BeforeNavigate(x,x,x,x,x,x,x,x,x,x,x) //這個函式中進入不同的處理流程。。。。 .text:00D28ED4 lea eax, [ebp+pcszURL] .text:00D28ED7 push eax ; int .text:00D28ED8 push [ebp+arg_C] ; struct _ITEMIDLIST_ABSOLUTE * .text:00D28EDB mov [ebp+var_4.lpVtbl], esi .text:00D28EDE mov [ebp+ppvOut], esi .text:00D28EE1 mov [ebp+var_10], esi .text:00D28EE4 mov [ebp+bstrString], esi .text:00D28EE7 mov [ebp+var_14], esi .text:00D28EEA mov [ebp+pcszURL], esi .text:00D28EED call ?GetEventURL@@YGXPBU_ITEMIDLIST_ABSOLUTE@@AAVCComBSTR@ATL@@@Z ; GetEventURL(_ITEMIDLIST_ABSOLUTE const *,ATL::CComBSTR &) .text:00D2887D mov esi, [ebp+arg_4] .text:00D28880 push edi .text:00D28881 jz loc_C482EE .text:00D28887 and [ebp+psz], 0 .text:00D2888F push 8000h ; __int16 .text:00D28894 lea ecx, [ebp+psz] .text:00D2889A push ecx ; unsigned __int16 * .text:00D2889B push eax ; struct _ITEMIDLIST_ABSOLUTE * .text:00D2889C call _IEGetDisplayName@12 ; 函式返回值在正常與異常情況下不同。。。 .text:00D288A1 mov edi, eax .text:00D288A3 test edi, edi .text:00D288A5 jl loc_C482EE .text:00D288AB lea eax, [ebp+psz] .text:00D288B1 push eax ; psz .text:00D288B2 mov ecx, esi .text:00D288B4 call ??4CComBSTR@ATL@@QAEAAV01@PBG@Z ; ATL::CComBSTR::operator=(ushort const *) .text:00D288B9 cmp dword ptr [esi], 0 .text:00D288BC jz loc_D776E4
最終是 call _IEGetDisplayName@12 此函式正常情況下與崩潰情況下的返回值不同,導致了執行流程的不同,最終導致Adfilter.dll呼叫wcslen()函式出錯。。。
IEGetDisplayName最終呼叫:
.text:00C3589B push [ebp+cwchBuf] ; cwchBuf .text:00C3589E push esi ; pwszDst .text:00C3589F push [ebp+arg_4] ; int .text:00C358A2 push [ebp+ppidlLast] ; int .text:00C358A5 push [ebp+ppv] ; int .text:00C358A8 call _DisplayNameOfW@20 ; DisplayNameOfW(x,x,x,x,x) .text:00C35784 mov eax, [ebp+arg_0] .text:00C35787 mov esi, [ebp+pwszDst] .text:00C3578A and word ptr [esi], 0 .text:00C3578E mov ecx, [eax] .text:00C35790 lea edx, [ebp+var_10C] .text:00C35796 push edx .text:00C35797 push [ebp+arg_8] .text:00C3579A push [ebp+arg_4] .text:00C3579D push eax .text:00C3579E call dword ptr [ecx+2Ch] ; 這裡返回了0x8007006f錯誤,執行的函式是SHELL32!ILRemoveLastID() ILRemoveLastID()函式解釋如下: Removes the last SHITEMID structure from an ITEMIDLIST structure,
至此此次360網盾 廣告攔截模組 的bug才算分析完畢,其中也有一些不太明白的地方,但程式基本的處理流程就是這樣的。現在可以總結一下這個360bug的觸發原因了。。。
三.總結
前前後後花了很長時間來分析這個bug,也走了很長的彎路。
360網盾的廣告攔截模組給IE註冊了很多個回撥函式,但在處理回撥的資料時存在問題,直接引用並下發IE ieframe.dll的GetEventURL()函式的返回值,
並沒有判斷返回值是否為空情況的情況存在,傳遞給了wcslen()函式,導致IE崩潰。
Assay_Bug.txt
相關文章
- win10 360攔截在哪裡找_win10怎麼找360攔截器2020-05-16Win10
- Mac騰訊截圖閃退崩潰2020-12-13Mac
- 360瀏覽器總是崩潰是為什麼 360瀏覽器經常崩潰怎麼解決2022-05-13瀏覽器
- 360瀏覽器總是崩潰是為什麼 360經常崩潰解決修復方法介紹2022-08-27瀏覽器
- IOS 崩潰日誌分析2018-08-08iOS
- Invalid double崩潰分析2017-11-25
- Wipr for mac(瀏覽器廣告攔截)2021-11-02Mac瀏覽器
- WkWebView 令人崩潰的崩潰2017-07-05WebView
- win10 360瀏覽器崩潰如何解決_win10開啟360瀏覽器就崩潰處理方法2020-07-09Win10瀏覽器
- 攔截廣告Yuki Ad Blocker,超實用2020-12-23BloC
- 喵趣漫畫 + Adguard 攔截廣告2024-06-09
- 圖形化還原崩潰地址 iOS的crash檔案分析2018-12-05iOS
- win10qq聊天廣告怎樣攔截_win10電腦qq聊天廣告攔截怎麼設定2020-08-03Win10
- XSS 前端防火牆 —— 可疑模組攔截2014-07-23前端防火牆
- Facebook反廣告攔截 惹怒德國外掛公司2016-08-10
- Opera新瀏覽器整合廣告攔截功能2016-03-11瀏覽器
- MySQL 崩潰恢復過程分析2022-11-29MySql
- 記一次 Windows10 記憶體壓縮模組 崩潰分析2023-04-26Windows記憶體
- win10 microsoft edge網址被攔截如何取消攔截2020-03-18Win10ROS
- WKWebView崩潰2017-09-26WebView
- Redis崩潰2012-12-03Redis
- 華為手機使用 appium 截圖後,app 崩潰2020-12-10APP
- XSS 前端防火牆(2):可疑模組攔截2014-06-18前端防火牆
- SponsorBlock for YouTube mac(YouTube訂閱廣告攔截器)2022-02-27ORBBloCMac
- axios原始碼分析——攔截器2018-06-18iOS原始碼
- 攔截器,攔截器棧總結2014-09-15
- Crittercism:KitKat崩潰率0.7% iOS 7.1崩潰率1.6%2014-03-28iOS
- crash日誌符號化,以分析崩潰2017-08-22符號
- APP防崩潰2018-08-07APP
- okhttp3 攔截器原始碼分析2018-02-27HTTP原始碼
- WWDC 2018:理解崩潰以及崩潰日誌2018-06-11
- win10經常網頁崩潰怎麼解決 win10網頁崩潰如何修復2020-12-04Win10網頁
- iOS13 Safari 廣告為何增多?蘋果將淘汰廣告攔截擴充套件2019-09-24iOS蘋果套件
- AdGuard 最高階的(廣告攔截軟體)功能介紹2020-09-24
- 新版Windows10開始支援瀏覽器廣告攔截2016-05-09Windows瀏覽器
- TestBird 崩潰分析(Artisan) Android SDK 使用指南2016-08-23Android
- 多起網路釣魚攻擊借勢新冠疫情!360安全大腦強力攔截2020-03-13
- SpringBoot攔截器及原始碼分析2021-07-11Spring Boot原始碼