Internet Explorer漏洞分析(五)——CVE-2016-0199

Gcow安全团队

共 3912字,需浏览 8分钟

 ·

2021-04-24 09:15

Internet Explorer漏洞分析(五)——CVE-2016-0199

1.本文一共1233个字26张图预计阅读时间13分钟2.本文作者erfze 属于Gcow安全团队复眼小组未经过许可禁止转载3.本篇文章是CVE-2016-0199漏洞的分析入手详细的阐述漏洞的成因4.本篇文章十分适合漏洞安全研究人员进行交流学习5.若文章中存在说得不清楚或者错误的地方欢迎师傅到公众号后台留言中指出感激不尽

0x01 漏洞信息

0x01.1 漏洞简述

编号:CVE-2016-0199类型:类型混淆(Type Confusion)漏洞影响:远程代码执行(RCE)/拒绝服务攻击 (DoS)CVSS 2.0:9.3

mshtml.dll组件在将CElement—>CAttributeCollection—>CAttrArray—>Attribute.nodeValue复制到CAttribute—>Variant时,并未对其进行校验,以致类型混淆,进而可造成任意代码执行。

0x01.2 漏洞影响

Microsoft Internet Explorer 9 through 11

0x01.3 修复方案

[MS16-063]https://docs.microsoft.com/en-us/security-updates/securitybulletins/2016/ms16-063

0x02 漏洞分析

0x02.1 分析环境

OS版本:Windows 7 Service Pack 1 x86Internet Explorer版本:9.0.8112.16421mshtml.dll版本:9.0.8112.16684jscript9.dll版本:9.0.8112.16684

0x02.2 详细分析

分析用POC来自[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 41  oElement.setAttributeNode(oAttr);// Replace oElement with original value data  oElement.removeAttributeNode(oAttr);CollectGarbage();// Use original value data as address 0x41424344 of a vftable</script>

document.createElement("IMG");语句对应实现为mshtml!CDocument::createElement,其执行流如下:

e4f657496e024a0d51085913ddd81687.webp

图片1

首先分配堆块用于存储CImgElement对象:

71e6b47628bc098437b697f0e19dcb1e.webp

图片2

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

9ad511ea71e41b96a995e0d2ca0de0b1.webp

图片3

完成CImgElement对象创建:

1d7f6194c895df6ad8762f5a7f9920bf.webp

图片4

634891f1e529a60fc6bf610a94c9d0c5.webp

图片5

var oAttr = document.createAttribute("loop");语句对应实现为mshtml!CDocument::createAttribute,其执行流如下:

fc6dc9f98bd9fa3bd538dfc691e9464a.webp

图片6

分配堆块用于存储CAttribute对象,之后由CAttribute::CAttribute完成初始化操作:

b9640e8e31e9efd88a9fc4d4dd7eed02.webp

图片7

CAttribute对象偏移0x24处存储属性名:

aa77898c129b5fdd6f7b7db0ff06ae0f.webp

图片8

eaea41fe2db5429f7525b92e6feb2b24.webp

图片9

oAttr.nodeValue = oElement;语句对应实现为mshtml!CAttribute::put_nodeValue,其调用CAttribute::PutNodeValueVariantHelper完成功能。首先是复制VARIANT类型对象(存储nodeValue值)至偏移0x28处:

e27aad7b1f9faef5cd5346c0fefff078.webp

图片10

之后判断该CAttribute对象是否为Tracked Object,如果不是则将其设为Root Object,并加入CRootTracker中(感兴趣的读者可自行分析CTrackerHelper::SetAsRootCRootTracker::AddRoot函数,此部分与GC机制有关,不在此展开):

748cdea1400b33c84ac97e8a98118a13.webp

图片11

CAttribute对象偏移0x5C处用于判断其是否为Root Object:

e311cc7c6b18e559d984244b31ae2654.webp

图片12

oElement.loop = 0x41424344;语句设定CElement对象属性,其属性使用数组存储,对应实现为CAttrArray::Set。该函数首先判断CElement对象偏移0x10处是否置值,若无则分配内存并将返回值写入该处:

图片13

CImplAry::InsertIndirect函数中对CAttributeCollection(CElement offset 0x10)偏移0x04处值与0x00处值进行比较以检查是否需要调整Attribute Array存储空间:

bfaab24ce7930c272a6fc7532b6ca1c3.webp

图片14

由于是首次设定CElement对象属性,并未开辟Attribute Array空间,故调用HeapAlloc进行分配,具体可分析CImplAry::EnsureSizeWorker函数,完成后内存如下:

b6d6c3fe8bf202657fd519211055a814.webp

图片15

共4个元素(0x10>>2),每个元素占用内存空间为0x10。完成属性赋值,并将Attribute Array当前元素数量加1:

853142e58e637a3842f482e88b9926a3.webp

图片16

CElement对象部分结构含义如下:

+0x10CAttributeCollection+0x00The total size of the AttributeArray<<2+0x04Number of Attributes+0x08CAttrArray+0x0c+0x14CTreeNode

oElement.setAttributeNode(oAttr);语句对应实现为mshtml!CElement::setAttributeNode,其调用CElement::VersionedSetAttributeNode完成功能。首先是执行MSHTML!CAttribute::PrivateQueryInterface+0x920函数,该函数会对esp+30h+var_14处内存置值,此值会决定后续执行CAttrArray::Set函数orCAttrArray::SetAt函数:

bc92a768e4bdef6523687f67f0786233.webp

图片17

之后执行CAttribute::SetElement函数,对CAttribute对象偏移0x3c处及偏移0x08处进行置值,具体流程可自行跟进分析:

c0993beda08aad9fd7160a37869b2ad3.webp

图片18

b639a34148e2f05794fcbdb80d50b968.webp

图片19

CAttrArray::Set函数执行完成:

4339215498679548f17300c52ad8bdc1.webp

图片20

CAttribute对象部分结构含义如下:

+0x24AttributeName(Pointer to BSTR)、+0x28Variant(Save the nodeValue)+0x3cCElement+0x5CIsRootObject

oElement.removeAttributeNode(oAttr);语句对应实现为mshtml!CElement::VersionedRemoveAttributeNode。漏洞发生在将CElement—>CAttributeCollection—>CAttrArray—>Attribute.nodeValue复制到CAttribute—>Variant(0x28)时,并未对其进行校验,以致类型混淆。正常情形下:

<!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>

其执行流如下:

c91a293ce0c6d5f321b99ede5a39e01b.webp

图片21

bddf463b2c75801de93239d3f873d68c.webp

图片22

b459b56e70032827761c4b8e81f13462.webp

图片23

而在POC情形下,其执行流:

a077ae4329488f4d690acb251c81b855.webp

图片24

6796e98b6292e50abfc72dfeea21d173.webp

图片25

如此一来,CAttribute::EnumerateTrackedObjects传递参数给jscript9!ScriptEngine::EnumerateTrackingClient,其在mov ecx, [eax]时便会发生访问错误:

3715a41c1d5cd70f05b551788f69aea1.webp

图片26

0x03 参阅链接

[对CVE-2016-0199的简单分析]https://bbs.pediy.com/thread-212058.htm[CVE-2016-0199 漏洞分析]https://www.jianshu.com/p/38001618bc2d


浏览 49
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报