Exploiting CVE-2019-1208 in IE from BinDiff to 0day

foreword

As mentioned above, CVE-2019-1208it is UAFa vulnerability, this type of security hole can destroy valid data, cause process crash, and can be carefully exploited to eventually lead to arbitrary code execution. For CVE-2019-1208 introduced in this article, an attacker who successfully exploits this vulnerability can obtain the current user privileges of the system. If the current user has admin privileges, an attacker can hijack the system—from installing or uninstalling programs, viewing and modifying data, to creating users with full privileges.

potential impact

There is also a more tangible attack scenario where an attacker sends phishing emails to unsuspecting users and tricks them into visiting a malicious website through IE (CVE-2019-1208 exists).

Alternatively, an attacker could send a spam email with an attachment containing an exploit for the vulnerability. These attachments can be Microsoft Office documents with the IE rendering engine enabled, or applications that embed ActiveX controls that contain exploits.

Attackers can also place attack code on some legitimate websites, such as those that accept user input.

The following figure VbsJoinshows the code flow:

 

How was the vulnerability discovered?

My research started BinDiffwhen I was trying to compare vbscript.dllthe May and June versions, looking for functions that were changed, and this module contains API functions for the VBScript engine. Eventually I found some fixes via SafeArrayAddRef , SafeArrayReleaseData and SafeArrayReleaseDescriptor functions

However, inspired by the vulnerability CVE-2018-8373 I found before , after further analysis, I used VBScriptClass to trigger the UAF vulnerability through the following steps:

  1. arr = Array(New MyClass), create a SafeArray and save it at arr[0]VBScriptclass: MyClass

  2. Callback: arr = Array(0), Join(arr)will trigger the callback function of MyClass Public Default Property Get. In this callback, a new SafeArray is created for the variable, as shown in the figure below and this new SafeArray is not SafeArrayAddRefprotected by the function. Therefore, the normal code flow assumption is broken by this callback

     

  1. arr(0) = Join(arr), when Public Default Property Getreturning from, the code in VBsJoin will call SafeArrayReleaseDataand SafeArrayReleaseDescriptorto decrement the reference count of SafeArrayDataand SafeArrayDescriptor. However, the new SafeArray is not SafeArrayAddRefprotected, and SafeArrayDatahas SafeArrayDescriptora reference count of 0.

    SafeArrayDataTherefore, the sum of the new SafeArray will be freed SafeArrayDescriptorin the function sum SafeArrayReleaseData, as shown in the following figure:SafeArrayReleaseDescriptor

     

where the code snapshot shows in-memory arr = Array(New MyClass)(top), in-memory arr = Array(0)and callbackat the bottom

When saving the return value of VbsJoin to arr(0), PoC vbscript!AccessArraycrashes in (see the figure below), because SafeArrayDescriptorit is free, Variant arr still saves the released SafeArrayDescriptorpointer.

 

Code snapshot showing how the PoC vbscript!AccessArraytriggers the crash in

Did the PoC successfully trigger UAF?

In a way, the answer is yes

To demonstrate how to fully trigger UAF, I used basic string/binary string(BSTR)as data structure. SafeArray is a multidimensional array, but since VBsJoin can only handle one-bit arrays, I changed the dimensions of the SafeArray in the callback.

Unfortunately, it still doesn't work, it throws a runtime error stating that the array type doesn't match in the Join. But it doesn't matter, I use On Error Resume Next to bypass this runtime error, the following picture shows the modified PoC:

 

After getting 0x20 bytes of freed memory, I use a BSTR of size 0x20 bytes to fake a larger size SafeArray.

By using heap feng shui , this BSTR can stably reuse 0x20 bytes of freed memory, as shown in the following figure:

 

I finally got a fake one-dimensional array SafeArray, with a total of 0x7fffffff elements, each element size is 1 byte, as shown below:

Fake SafeArray (top) and fixed address for read/write (bottom)

 

So far I've been able to fake a SafeArray that can be used to read/write memory from 0x00000000 to 0x7fffffff

In order to leak some read/write addresses for exploitation, I refer to Simon Zuckerbraun's previous research and use heap spraying to get some fixed read/write addresses (0x28281000)

From UAF to RCE

As described in Simon Zuckerbraun's blog, I used the Scripting.Dictionary object to accomplish remote code execution, but used another method to fake a fake Dictionary. This time, I used a BSTR and brought them out

The memory layout of Faked Dictionary is as follows:

 

  1. Use the memory read/write functions to read the original Dictionary memory, save its data to a BSTR, and replace it VBADictionary::Existswithkernel32!Winexec
  2. WinexecWrite the parameters used later \..\clac.exeinto this BSTR
  3. Save this BSTR to util_memory+0x1000, and modify util_memory + 0x1000 – 8 = 9to fake_array(util_memory + 0x1000)make an object
  4. Use fake_array(util_memory + &h1000), use dummyto trigger Winexecthe function

Finally, using the result, the calculator pops up successfully:

 

What does this vulnerability mean for IE?

On August 13, 2019, VBScript, which was disabled in Windows 10, was also disabled in Windows 7 and 8 for IE. Therefore, the PoC detailed above was developed in local mode. But as Microsoft says, this setting can still be enabled through the registry or group policy. Likewise, users and organizations should always adopt best practices: keeping systems patched and updated, disabling components that are not needed (or limiting use), and promoting cybersecurity awareness, such as spam and other social engineering threats

Full details of the study are in this technical brief

Guess you like

Origin blog.csdn.net/weixin_55436205/article/details/130659577