Internet Explorer漏洞分析(五)——CVE-2016-0199
Internet Explorer漏洞分析(五)——CVE-2016-0199
1.本文一共1233個(gè)字26張圖預(yù)計(jì)閱讀時(shí)間13分鐘2.本文作者erfze 屬于Gcow安全團(tuán)隊(duì)復(fù)眼小組未經(jīng)過(guò)許可禁止轉(zhuǎn)載3.本篇文章是CVE-2016-0199漏洞的分析入手詳細(xì)的闡述漏洞的成因4.本篇文章十分適合漏洞安全研究人員進(jìn)行交流學(xué)習(xí)5.若文章中存在說(shuō)得不清楚或者錯(cuò)誤的地方歡迎師傅到公眾號(hào)后臺(tái)留言中指出感激不盡
0x01 漏洞信息
0x01.1 漏洞簡(jiǎn)述
?編號(hào):CVE-2016-0199?類(lèi)型:類(lèi)型混淆(Type Confusion)?漏洞影響:遠(yuǎn)程代碼執(zhí)行(RCE)/拒絕服務(wù)攻擊 (DoS)?CVSS 2.0:9.3
mshtml.dll組件在將CElement—>CAttributeCollection—>CAttrArray—>Attribute.nodeValue復(fù)制到CAttribute—>Variant時(shí),并未對(duì)其進(jìn)行校驗(yàn),以致類(lèi)型混淆,進(jìn)而可造成任意代碼執(zhí)行。
0x01.2 漏洞影響
Microsoft Internet Explorer 9 through 11
0x01.3 修復(fù)方案
[MS16-063]https://docs.microsoft.com/en-us/security-updates/securitybulletins/2016/ms16-063
0x02 漏洞分析
0x02.1 分析環(huán)境
?OS版本:Windows 7 Service Pack 1 x86?Internet Explorer版本:9.0.8112.16421?mshtml.dll版本:9.0.8112.16684?jscript9.dll版本:9.0.8112.16684
0x02.2 詳細(xì)分析
分析用POC來(lái)自[exploit-db]https://www.exploit-db.com/exploits/39994:
<!DOCTYPE html><metahttp-equiv="X-UA-Compatible"content="IE=7"><script>oElement = document.createElement("IMG");var oAttr = document.createAttribute("loop");oAttr.nodeValue = oElement;oElement.loop =0x41424344;// Set original value data to 44 43 42 41oElement.setAttributeNode(oAttr);// Replace oElement with original value dataoElement.removeAttributeNode(oAttr);CollectGarbage();// Use original value data as address 0x41424344 of a vftable</script>
document.createElement("IMG");語(yǔ)句對(duì)應(yīng)實(shí)現(xiàn)為mshtml!CDocument::createElement,其執(zhí)行流如下:

首先分配堆塊用于存儲(chǔ)CImgElement對(duì)象:

之后由CElement::CElement完成初始化操作:

完成CImgElement對(duì)象創(chuàng)建:


var oAttr = document.createAttribute("loop");語(yǔ)句對(duì)應(yīng)實(shí)現(xiàn)為mshtml!CDocument::createAttribute,其執(zhí)行流如下:

分配堆塊用于存儲(chǔ)CAttribute對(duì)象,之后由CAttribute::CAttribute完成初始化操作:

CAttribute對(duì)象偏移0x24處存儲(chǔ)屬性名:


oAttr.nodeValue = oElement;語(yǔ)句對(duì)應(yīng)實(shí)現(xiàn)為mshtml!CAttribute::put_nodeValue,其調(diào)用CAttribute::PutNodeValueVariantHelper完成功能。首先是復(fù)制VARIANT類(lèi)型對(duì)象(存儲(chǔ)nodeValue值)至偏移0x28處:

之后判斷該CAttribute對(duì)象是否為T(mén)racked Object,如果不是則將其設(shè)為Root Object,并加入CRootTracker中(感興趣的讀者可自行分析CTrackerHelper::SetAsRoot及CRootTracker::AddRoot函數(shù),此部分與GC機(jī)制有關(guān),不在此展開(kāi)):

CAttribute對(duì)象偏移0x5C處用于判斷其是否為Root Object:

oElement.loop = 0x41424344;語(yǔ)句設(shè)定CElement對(duì)象屬性,其屬性使用數(shù)組存儲(chǔ),對(duì)應(yīng)實(shí)現(xiàn)為CAttrArray::Set。該函數(shù)首先判斷CElement對(duì)象偏移0x10處是否置值,若無(wú)則分配內(nèi)存并將返回值寫(xiě)入該處:
于CImplAry::InsertIndirect函數(shù)中對(duì)CAttributeCollection(CElement?offset 0x10)偏移0x04處值與0x00處值進(jìn)行比較以檢查是否需要調(diào)整Attribute Array存儲(chǔ)空間:

由于是首次設(shè)定CElement對(duì)象屬性,并未開(kāi)辟Attribute Array空間,故調(diào)用HeapAlloc進(jìn)行分配,具體可分析CImplAry::EnsureSizeWorker函數(shù),完成后內(nèi)存如下:

共4個(gè)元素(0x10>>2),每個(gè)元素占用內(nèi)存空間為0x10。完成屬性賦值,并將Attribute Array當(dāng)前元素?cái)?shù)量加1:

CElement對(duì)象部分結(jié)構(gòu)含義如下:
+0x10CAttributeCollection+0x00The total size of the AttributeArray<<2+0x04Number of Attributes+0x08CAttrArray+0x0c+0x14CTreeNode
oElement.setAttributeNode(oAttr);語(yǔ)句對(duì)應(yīng)實(shí)現(xiàn)為mshtml!CElement::setAttributeNode,其調(diào)用CElement::VersionedSetAttributeNode完成功能。首先是執(zhí)行MSHTML!CAttribute::PrivateQueryInterface+0x920函數(shù),該函數(shù)會(huì)對(duì)esp+30h+var_14處內(nèi)存置值,此值會(huì)決定后續(xù)執(zhí)行CAttrArray::Set函數(shù)orCAttrArray::SetAt函數(shù):

之后執(zhí)行CAttribute::SetElement函數(shù),對(duì)CAttribute對(duì)象偏移0x3c處及偏移0x08處進(jìn)行置值,具體流程可自行跟進(jìn)分析:


CAttrArray::Set函數(shù)執(zhí)行完成:

CAttribute對(duì)象部分結(jié)構(gòu)含義如下:
+0x24AttributeName(Pointer to BSTR)、+0x28Variant(Save the nodeValue)+0x3cCElement+0x5CIsRootObject
oElement.removeAttributeNode(oAttr);語(yǔ)句對(duì)應(yīng)實(shí)現(xiàn)為mshtml!CElement::VersionedRemoveAttributeNode。漏洞發(fā)生在將CElement—>CAttributeCollection—>CAttrArray—>Attribute.nodeValue復(fù)制到CAttribute—>Variant(0x28)時(shí),并未對(duì)其進(jìn)行校驗(yàn),以致類(lèi)型混淆。正常情形下:
<!DOCTYPE html><metahttp-equiv="X-UA-Compatible"content="IE=7"><script>oElement1 = document.createElement("IMG");var oAttr1 = document.createAttribute("loop1");oAttr1.nodeValue =0x41424344;oElement1.setAttributeNode(oAttr1);oElement1.removeAttributeNode(oAttr1);CollectGarbage();</script>
其執(zhí)行流如下:



而在POC情形下,其執(zhí)行流:


如此一來(lái),CAttribute::EnumerateTrackedObjects傳遞參數(shù)給jscript9!ScriptEngine::EnumerateTrackingClient,其在mov ecx, [eax]時(shí)便會(huì)發(fā)生訪問(wèn)錯(cuò)誤:

0x03 參閱鏈接
?[對(duì)CVE-2016-0199的簡(jiǎn)單分析]https://bbs.pediy.com/thread-212058.htm?[CVE-2016-0199 漏洞分析]https://www.jianshu.com/p/38001618bc2d
