混淆漏洞CVE-2017-0213技術分析
1. 引言
CVE-2017-0213 是一個比較冷門的COM 類型混淆 (Type Confusion)漏洞。巧妙的利用該漏洞,可以實現本地的提權。該漏洞由著名的Google Project zero 發現。漏洞信息原文可參見【1】
然而原文對漏洞的描述有些過於任性,儘管筆者熟悉好幾國英文J,反覆讀了好幾遍還是覺得雲山霧罩。因此決定親自分析下,和讀者共同分享一下。
2. 技術分析
2.1 DCOM 簡介
這個漏洞要從DCOM 談起了。相信大家對Windows的組件對象模型(COM) 都已經非常熟悉了。而DCOM可能相對來說要陌生一些。DCOM是 分散式的COM, 類似於CORBA, 也就是說調用的COM 可以在遠程主機上。
https://msdn.microsoft.com/en-us/library/cc226801.aspx
在COM模型中,我們知道所有的COM 介面都要繼承 IUnkown 介面。通過QueryInterface函數,可以查詢任意介面。
而在DCOM模型中,對應於IUnknown的介面為IRemunkown 和IRemUnkown2 兩個遠程介面。
相應的,QueryInterface對應的方法為:
和
兩者的主要區別在於返回的對象類型上。
IRemUnknown::RemQueryInterface 通過最後一個參數[out,size_is(,cIids)] PREMQIRESULT* ppQIResults 來返回對象。
看一下PREMQIRESULT的定義
STDOBJREF 通常包含OXID,IPID, OID 這些信息。
而IRemUnknown2::RemQueryInterface2
通過最後又一個參數PMInterfacePointerInternal來返回對象.
而PMInterfacePointerInternal的定義
根據MSDN的解釋(https://msdn.microsoft.com/en-us/library/cc226826.aspx)
MInterfacePointer是一個NDR裝組(marshal)的對象引用。
不難看出,IRemUnknown::RemQueryInterface 只是返回了對象的部分信息,而IRemUnknown2::RemQueryInterface2返回了整個對象的信息。
2.2 漏洞分析
CVE-2017-0213的問題出現在 IRemUnknown2::RemQueryInterface2的 代碼中。
代碼調用CStdMarshal::Finish_RemQIAndUnmarshal2來完成對返回對象解組(Unmarshal)。
對於每一個MInterfacePointer指針,函數CStdMarshal::UnmarshalInterface對其進行解組,即從IStream的數據中解組出相應的介面。問題出現在這裡,解組的時候,解組代理是根據IStreamde數據中的OBJREF(IID)來解組的,而並非IRemUnknown2::RemQueryInterface2中指定的IID。也就是說,這裡沒有對OBJREF的IID和IRemUnknown2::RemQueryInterface2中指定的IID進行一致性檢查。,如果在IStream中的IID和調用IRemUnknown2::RemQueryInterface2時指定的IID不一致的時候,就會發生類型混淆。
2.3 漏洞利用
類型混淆的漏洞通常可以通過內存損壞的方式來進行利用.然而漏洞發現者在利用時,並未採用內存損壞的方式來進行漏洞利用。按照漏洞發現者的說法,內存損壞的利用方式需要對內存進行精心布局,即便如此,在Windows 10上也可能會觸發CFG(Control Flow Guard)。
漏洞發現者另闢其徑,採用了一種基於LoadTypeLibrary來利用的方法。
背景知識:
如果將COM 介面註冊PSOAInterface或者PSDispatch後,oleaut32.dll 會查找註冊的Type Library信息(存放在註冊表中),如果找到的話,將調用LoadTypeLibrary 來載入 Type Library. TypeLibrary在載入的時候,有個很有趣的行為: 首先會按GUID查找,如果查找失敗的話,會按文件名來查找。如果按文件名查找也失敗的話,這時會按照Moniker 來查找。這時,我們只需將包含scriptlet的Moniker注入到一個Type Library 文件中。就可以執行這段scriptlet。漏洞發現者採用的ScriptLet如下圖所示。
現在我們知道,可以利用這個漏洞來成功載入JS, 從而達到執行任意文件的目的。
那麼如何來利用這個漏洞來進行提權呢? 我們注意到,BITS 服務運行在 SYSTEM 完整性等級(IntegrityLevel)上。如果調用其
並傳入一個精心構造的COM 介面,引發類型混淆,便可利用該漏洞來載入一個TypeLibrary。這裡,漏洞利用程序選擇了COM 介面 IID_ITMediaControl(GUID ),其TypeLibGUID為 , 註冊的DLL為 tapi3.dll。那麼如何才能達到載入自己定義的tapi3.dll的目的呢?Tapi3.dll位於 %system32%目錄下,覆蓋此文件顯然不可能。漏洞利用程序使用了這樣一個技巧:利用NtCreateSymbolicLink重定向C: 到當前目錄。在當前目錄下創建windowssystem32 api3.dll即可。具體過程可參見漏洞利用源代碼【2】
最後上一張成功利用的截圖。Windows 7 SP1 下成功彈出一個admin許可權的cmd窗口。
3. 總結
「天下漏洞,唯冷不破」。CVE-2017-0213的無論從挖掘和利用,感覺都有些劍走偏鋒,正屬於這種比較冷門的一類。這種漏洞似乎難以通過fuzzing的方式來發現。通常這種漏洞的發現,需要對Windows的代碼非常熟悉。而從漏洞的利用的角度來看,思路亦是非常巧妙。從這個漏洞的發現到利用,可見漏洞發現者在Windows 操作系統方面的造詣非同一般。
4. 參考文獻
1.https://bugs.chromium.org/p/project-zero/issues/detail?id=1107
2.https://github.com/WindowsExploits/Exploits/blob/master/CVE-2017-0213/Source/CVE-2017-0213.cpp
*本文作者:蘭雲科技銀河實驗室,轉子請註明來自 FreeBuf.COM
※Discuz!任意文件刪除漏洞重現及分析
※黑帽SEO剖析之手法篇
※IDS和IPS的部署細節科普
※「臟牛漏洞」惡意Root軟體分析報告
※雅虎承認其30億用戶信息全部被黑
TAG:FreeBuf |