HP Security Research Blog
The HP Security Research blog provides a platform for security experts from across HP to discuss innovative research, industry observations, and updates on the threat landscape to help organizations proactively identify and manage risk.

Double-Dip: Using the latest IE 0-day to get RCE and an ASLR Bypass

Overview

 

The last couple of days there has been a big buzz regarding an IE 0-day being exploited in the wild.  The exploit was caught by FireEye. The FireEye blog stated that a Flash bug has been used to bypass ASLR. This caught our attention here in the ZDI, and made us wonder if we can actually bypass ASLR and DEP using the same IE bug without the Flash one.

 

Initial Crash

 

The browser would crash with pageheap on in the following function:

 

initialCrash.png

 

The stack trace at crash time:

 

stacktrace.png

 

The free happened here:

 

free.png

 

 

Control

 

In order to fill up the freed memory, we would need to get the length of the object:

 

size.png

 

Filling up the freed object is relatively easy from there and the crash would look like this:

 

control.png

 

Exploitation

 

According to the online reports, the exploit found in the wild used Flash to bypass ASLR.

Let’s take a look at the ASM around the crash spot to understand the options that we have to gain RCE.  The following was performed on IE11 on 32-bit Windows 8.1.

 

If we take one step backwards to check the functions and instructions around CMarkup::IsConnectedToPrimaryMarkup, we notice that right before returning there’s a CALL instruction that might be controllable:

 

rce.png

 

It seems legit, and definitely in our control:

 

rce1.png

 

So far, we know we can gain RCE from the bug.  Now the question is whether or not we are able to leak out of this bug.

 

ASLR Bypass

 

The plan is to find an instruction that would allow for a controlled:

  1. write-4
  2. write-0
  3. ADD [controlled],X
  4. INC [controlled]
  5. DEC [controlled]
  6. AND [controlled],XXXXXXX
  7. Etc..

 

The above options would allow us to do one of the following:

  1. Change the length of some BSTR in memory to leak memory
  2. Tricking IE into thinking that some number is an actual object , thus triggering a type confusion

 

There are a couple of functions that are called after CMarkup::IsConnectedToPrimaryMarkup.  I won’t cover all the function calls, but I will highlight the ones of interest.

 

CElement::EnsureFormatCacheChange():

 

Inside this function there’s a call to CElement::ClearRunCaches() that we can reach.

And inside CElement::ClearRunCaches() there’s a call to CMarkup::ClearRunCaches().

 

CMarkup::ClearRunCaches() contains interesting instructions that we can reach and control. Some of them allow controlled null writes, and others would allow zero’ing out the least significant bit (LSB) of a controlled address like this AND instruction:

 

AND.png

 

This definitely helps in creating type confusion.

 

Another function of interest, and which I’ve personally used to trigger type confusion, is CView::AddInvalidationTask().

 

CView::AddInvalidationTask():

 

If we check the assembly inside of this function closely we’ll notice that we have something quite interesting:

 

INC.png

 

There’s an INC instruction that we potentially control.

But do we really control it?

 

INC1.png

 

Yep, we do.

 

This gives us two options, either modify some BSTR length or trigger a type confusion by INC’ing a controlled location and setting the LSB to 0.

 

The strategy that I took to trigger a type confusion is the following:

 

  1. Place a value in memory that IE thinks is a Number
  2. INC that value, so then, LSB is 0, and IE then thinks it’s an object
  3. Modify the location that the address points to and craft your fake object
  4. Use that object to read memory and leak a memory address

 

If everything went as planned, we’ll be able to leak base addresses:

 

leak.png

 

 

Exploitation problems

 

There are some problems that I ran through:

  1. Attempting to re-trigger the bug more than once
  2. Crashing on a CLock:CLock
  3. Bypassing the CALL right before the RET

 

In order to re-trigger the bug more than once (which is required to trigger the type confusion), I had to re-build the document again. This can be done easily by re-writing the exact HTML elements required to trigger the bug using a simple document.write().

 

The second problem was crashing on a CLock:CLock making it difficult for us to continue execution.

 

If we step back a bit inside MSHTML!CView::AddInvalidationTask, we will notice that there’s a call to CView::PostCloseView.

 

Inside CView::PostCloseView, there’s a test that we should take and exit pre-maturely:

 

test.png

 

If we don’t take that jump, and exit cleanly, we CLock::CLock will end up being called right after being triggered, thus it won’t allow multiple triggers.

 

The final problem is bypassing the CALL instruction that was used by the attackers to get RCE.

 

This is an easy problem to solve:

 

bypassCALL.png

 

If ECX is 0 at the test, then we can bypass that virtual call, and thus return cleanly.

This is all in our control. So, problem solved.

 

This is the path that I took to exploit the bug (Node in RED should be avoided):

 

overview.png

 

 

It’s pretty expensive to use two bugs when you can actually use one. The Flash bug has been used more than once. Using known bugs increases the chances of detection and thus an attacker would not have been caught as quickly without it.  Investing time and focus into exploit primitives around use-after-free vulnerabilities will be beneficial and will minimize the number of bugs necessary for code execution.

 

Abdul Aziz Hariri

HP ZDI, Senior Security Researcher

Labels: 0day| ASLR| DEP| exploit| IE| IE0day| ZDI
Comments
hikerell | ‎05-06-2014 08:38 AM

Creative way! Could you email me a poc?

am06 | ‎05-06-2014 10:43 AM

can you detail a bit these steps please?

 

  1. Place a value in memory that IE thinks is a Number
  2. INC that value, so then, LSB is 0, and IE then thinks it’s an object
  3. Modify the location that the address points to and craft your fake object
  4. Use that object to read memory and leak a memory address

 

How does that type confusion actually happens?  what changes and where??

Leave a Comment

We encourage you to share your comments on this post. Comments are moderated and will be reviewed
and posted as promptly as possible during regular business hours

To ensure your comment is published, be sure to follow the Community Guidelines.

Be sure to enter a unique name. You can't reuse a name that's already in use.
Be sure to enter a unique email address. You can't reuse an email address that's already in use.
Type the characters you see in the picture above.Type the words you hear.
Search
Showing results for 
Search instead for 
Do you mean 
About the Author
Featured


Follow Us
The opinions expressed above are the personal opinions of the authors, not of HP. By using this site, you accept the Terms of Use and Rules of Participation.