Internet Explorer漏洞分析(四)——CVE-2016-0199
字数 2656 2025-08-05 13:25:32

CVE-2016-0199 Internet Explorer类型混淆漏洞深入分析

漏洞概述

漏洞编号: CVE-2016-0199
漏洞类型: 类型混淆(Type Confusion)
影响范围: Microsoft Internet Explorer 9至11版本
危害等级: CVSS 2.0评分9.3,可导致远程代码执行(RCE)或拒绝服务攻击(DoS)
受影响组件: mshtml.dll
修复方案: 微软安全更新MS16-063

漏洞原理

该漏洞存在于mshtml.dll组件中,当处理CElementCAttributeCollectionCAttrArrayAttribute.nodeValueCAttributeVariant的复制过程时,缺乏必要的类型校验机制,导致类型混淆(Type Confusion)漏洞。

环境准备

分析环境配置:

  • 操作系统: Windows 7 Service Pack 1 x86
  • Internet Explorer版本: 9.0.8112.16421
  • 关键DLL版本:
    • mshtml.dll: 9.0.8112.16684
    • jscript9.dll: 9.0.8112.16684

漏洞详细分析

POC代码分析

<!DOCTYPE html>
<meta http-equiv="X-UA-Compatible" content="IE=7">
<script>
    oElement = document.createElement("IMG");
    var oAttr = document.createAttribute("loop");
    oAttr.nodeValue = oElement;
    oElement.loop = 0x41424344; // 设置原始值数据为44 43 42 41
    oElement.setAttributeNode(oAttr); // 用原始值数据替换oElement
    oElement.removeAttributeNode(oAttr);
    CollectGarbage(); // 使用原始值数据作为vftable的地址0x41424344
</script>

关键函数调用链

  1. document.createElement("IMG")

    • 对应实现: mshtml!CDocument::createElement
    • 执行流程:
      • 分配堆块存储CImgElement对象
      • 通过CElement::CElement完成初始化
  2. document.createAttribute("loop")

    • 对应实现: mshtml!CDocument::createAttribute
    • 执行流程:
      • 分配堆块存储CAttribute对象
      • 通过CAttribute::CAttribute完成初始化
      • CAttribute对象偏移0x24处存储属性名
  3. oAttr.nodeValue = oElement

    • 对应实现: mshtml!CAttribute::put_nodeValue
    • 调用CAttribute::PutNodeValueVariantHelper完成功能:
      • 复制VARIANT类型对象(存储nodeValue值)至偏移0x28处
      • 判断CAttribute对象是否为Tracked Object
      • 如果不是则设为Root Object并加入CRootTracker
  4. oElement.loop = 0x41424344

    • 对应实现: CAttrArray::Set
    • 执行流程:
      • 检查CElement对象偏移0x10处是否置值
      • 若无则分配内存并将返回值写入该处
      • 通过CImplAry::InsertIndirect检查是否需要调整Attribute Array存储空间
      • 首次设定属性时调用HeapAlloc分配空间(4个元素,每个0x10字节)
      • 完成属性赋值并将Attribute Array当前元素数量加1
  5. oElement.setAttributeNode(oAttr)

    • 对应实现: mshtml!CElement::setAttributeNode
    • 调用CElement::VersionedSetAttributeNode完成功能:
      • 执行MSHTML!CAttribute::PrivateQueryInterface+0x920函数
      • 执行CAttribute::SetElement函数,对CAttribute对象偏移0x3c及0x08处置值
  6. oElement.removeAttributeNode(oAttr)

    • 对应实现: mshtml!CElement::VersionedRemoveAttributeNode
    • 漏洞触发点: 将CElementCAttributeCollectionCAttrArrayAttribute.nodeValue复制到CAttributeVariant(0x28)时未进行类型校验

关键数据结构

CElement对象结构:

  • +0x10: CAttributeCollection
    • +0x00: Attribute Array总大小<<2
    • +0x04: 属性数量
    • +0x08: CAttrArray
    • +0x0c+0x14: CTreeNode

CAttribute对象结构:

  • +0x24: 属性名(指向BSTR的指针)
  • +0x28: Variant(保存nodeValue)
  • +0x3c: CElement
  • +0x5C: IsRootObject标志

漏洞触发流程

  1. 正常流程:

    • 创建元素和属性
    • 设置属性值为合法值(如0x41424344)
    • 添加和移除属性节点
    • 垃圾回收
  2. 漏洞利用流程(POC):

    • 创建IMG元素和loop属性
    • 将属性值设置为元素对象本身(oAttr.nodeValue = oElement)
    • 设置元素的loop属性值为0x41424344
    • 添加属性节点到元素
    • 移除属性节点
    • 触发垃圾回收

关键差异在于类型混淆后,CAttribute::EnumerateTrackedObjects传递参数给jscript9!ScriptEngine::EnumerateTrackingClient时,mov ecx, [eax]指令会尝试访问错误的内存地址(0x41424344),导致访问违例。

漏洞利用思路

通过精心构造的JavaScript代码,攻击者可以:

  1. 利用类型混淆漏洞控制内存中的对象布局
  2. 通过垃圾回收机制重用已释放的内存
  3. 最终实现任意代码执行

防护措施

  1. 及时安装微软安全更新MS16-063
  2. 升级到更高版本的Internet Explorer
  3. 考虑使用更现代的浏览器替代IE
  4. 在企业环境中可通过组策略限制ActiveX控件和脚本执行

参考链接

  • 微软安全公告: https://docs.microsoft.com/en-us/security-updates/
  • Exploit-DB上的POC: https://www.exploit-db.com/
  • 类型混淆漏洞原理: https://cwe.mitre.org/data/definitions/843.html
CVE-2016-0199 Internet Explorer类型混淆漏洞深入分析 漏洞概述 漏洞编号 : CVE-2016-0199 漏洞类型 : 类型混淆(Type Confusion) 影响范围 : Microsoft Internet Explorer 9至11版本 危害等级 : CVSS 2.0评分9.3,可导致远程代码执行(RCE)或拒绝服务攻击(DoS) 受影响组件 : mshtml.dll 修复方案 : 微软安全更新MS16-063 漏洞原理 该漏洞存在于mshtml.dll组件中,当处理 CElement → CAttributeCollection → CAttrArray → Attribute.nodeValue 到 CAttribute → Variant 的复制过程时,缺乏必要的类型校验机制,导致类型混淆(Type Confusion)漏洞。 环境准备 分析环境配置 : 操作系统: Windows 7 Service Pack 1 x86 Internet Explorer版本: 9.0.8112.16421 关键DLL版本: mshtml.dll: 9.0.8112.16684 jscript9.dll: 9.0.8112.16684 漏洞详细分析 POC代码分析 关键函数调用链 document.createElement("IMG") 对应实现: mshtml!CDocument::createElement 执行流程: 分配堆块存储 CImgElement 对象 通过 CElement::CElement 完成初始化 document.createAttribute("loop") 对应实现: mshtml!CDocument::createAttribute 执行流程: 分配堆块存储 CAttribute 对象 通过 CAttribute::CAttribute 完成初始化 CAttribute 对象偏移0x24处存储属性名 oAttr.nodeValue = oElement 对应实现: mshtml!CAttribute::put_nodeValue 调用 CAttribute::PutNodeValueVariantHelper 完成功能: 复制VARIANT类型对象(存储nodeValue值)至偏移0x28处 判断 CAttribute 对象是否为Tracked Object 如果不是则设为Root Object并加入 CRootTracker 中 oElement.loop = 0x41424344 对应实现: CAttrArray::Set 执行流程: 检查 CElement 对象偏移0x10处是否置值 若无则分配内存并将返回值写入该处 通过 CImplAry::InsertIndirect 检查是否需要调整Attribute Array存储空间 首次设定属性时调用 HeapAlloc 分配空间(4个元素,每个0x10字节) 完成属性赋值并将Attribute Array当前元素数量加1 oElement.setAttributeNode(oAttr) 对应实现: mshtml!CElement::setAttributeNode 调用 CElement::VersionedSetAttributeNode 完成功能: 执行 MSHTML!CAttribute::PrivateQueryInterface+0x920 函数 执行 CAttribute::SetElement 函数,对 CAttribute 对象偏移0x3c及0x08处置值 oElement.removeAttributeNode(oAttr) 对应实现: mshtml!CElement::VersionedRemoveAttributeNode 漏洞触发点: 将 CElement → CAttributeCollection → CAttrArray → Attribute.nodeValue 复制到 CAttribute → Variant (0x28)时未进行类型校验 关键数据结构 CElement对象结构 : +0x10: CAttributeCollection +0x00: Attribute Array总大小< <2 +0x04: 属性数量 +0x08: CAttrArray +0x0c+0x14: CTreeNode CAttribute对象结构 : +0x24: 属性名(指向BSTR的指针) +0x28: Variant(保存nodeValue) +0x3c: CElement +0x5C: IsRootObject标志 漏洞触发流程 正常流程: 创建元素和属性 设置属性值为合法值(如0x41424344) 添加和移除属性节点 垃圾回收 漏洞利用流程(POC): 创建 IMG 元素和 loop 属性 将属性值设置为元素对象本身( oAttr.nodeValue = oElement ) 设置元素的 loop 属性值为0x41424344 添加属性节点到元素 移除属性节点 触发垃圾回收 关键差异在于类型混淆后, CAttribute::EnumerateTrackedObjects 传递参数给 jscript9!ScriptEngine::EnumerateTrackingClient 时, mov ecx, [eax] 指令会尝试访问错误的内存地址(0x41424344),导致访问违例。 漏洞利用思路 通过精心构造的JavaScript代码,攻击者可以: 利用类型混淆漏洞控制内存中的对象布局 通过垃圾回收机制重用已释放的内存 最终实现任意代码执行 防护措施 及时安装微软安全更新MS16-063 升级到更高版本的Internet Explorer 考虑使用更现代的浏览器替代IE 在企业环境中可通过组策略限制ActiveX控件和脚本执行 参考链接 微软安全公告: https://docs.microsoft.com/en-us/security-updates/ Exploit-DB上的POC: https://www.exploit-db.com/ 类型混淆漏洞原理: https://cwe.mitre.org/data/definitions/843.html