4878) from poc to utilization

Posted by trammel at 2020-02-29

This is the [5th] article of 360 A-Team

In this article, 360 A-Team will introduce how to use flash 0day (cve-2018-4878) from POC.

Statement: This article was originally created by ze0r @ 360 A-Team and is only used for technical research. Improper use will cause harm. Illegal use is strictly prohibited, or the consequences will be borne by yourself.

0 * 00 Preface

This article has no foreword. It's simple and rough. It's full of dry goods. Let's start~

0 × 01 in the field exp

At the beginning, we downloaded to exp which was in the field at that time, and used ffdec to view as script. The key trigger points are as follows:

From the decompiled script, it can be found that these two methods are in addition to layout memory. The main method is to initialize a drmmanager object with a § \ X05??? Parameter, and then assign a value of § \ X05??? To null, while § \ X05??? Is:

Later, it was found that POC had been published on GitHub, and the code was completely consistent, just making the random variable name meaningful, and it could also be compiled and generated directly. Therefore, the analysis is carried out according to the POC.

As mentioned earlier, in addition to the code for layout memory, a listener is created after initialization and assignment. In POC, only this code is left in the exploit method. Compile and run:

Open it and wait for a moment to crash to the debugger. Check:

It can be seen that an object is passed directly using ECX, which is also confirmed as a virtual function call in IDA.

According to the assembly code, it can be concluded that the ECX offset 0x0c is an object pointer, and this object has been all 0, causing a hanging pointer. In AS3 script, a mylistener (drmoperationcompletelistener interface implemented) type object is assigned null. So we can guess that ECX - > 0x0c is the mylistener object. The construction process of ECX is as follows:

There are five methods to judge this object. Trigger vul is the method to trigger crash. There are 2 references to view:

The disassembly confirmation assignment method is 1037a150:

In WinDbg, you can view the object memory after a few steps:

Confirm that the drmoperationcompletelistener instance pointer is at 0x0c of this object, that is, the drmoperationcompletelistener instance is garbage collected after being set to null, and the instance pointer remains in the object, causing the hanging pointer problem.

0 × 02 POC utilization

In POC exploitation, double free memory is used to exploit this vulnerability. As follows:

In the code, a new mylistener object is added after an exception occurs. Because the size of the same mylistener object is the same, the memory manager will still allocate the memory of the original mylistener object to the new object (as long as it is not occupied). After that, the code drmmanager has never been used, so garbage collection will release the drmmanager object, and also release the drmmanager object members (reduce the reference count), so 0x068c0100 will be cleared and recycled again:

After clearing, the danglingpointer variable in AS3 still points to this area, so in POC, it is also necessary to check whether the member variable of danglingpointer has been changed regularly to determine whether the memory release has been completed. After that, a large amount of memory is requested to be allocated by the memory manager again. Write the breakpoint at offset 0x70 (because the debugger is restarted, the address in the following screenshot is not exactly the same):

You can see that the MEM? Arr has occupied the bit successfully and is writing the default value of the variable. After completion, the memory layout can be obtained:

It can be seen that the data area of MEM pur is 0x054a815c-0x054a819c (position = 0x31). Where 0x38383838 is the overridden modify object tag, that is:

In AS3 code, pwnbuffer mainly sets the member variable value of member O1, and writes the breakpoint to get the layout:

From POC comments, we know that danglingpointer.a14 is the address of M ﹤ buffer, and A31 is the object of O1. Looking at the layout above, we find that there is an obvious intentional error (0x54a818c has been wrongly rewritten as 0xfffff0). After correction: "this. Danglingpointer. A30 = this. Danglingpointer. A14 - 0x10;". Revised layout:

After the O1 pointer is correctly rewritten, the ARR [0] property is changed by calling pwnbuffer, and then the memory can be read successfully:

At this time, since the length of arr [0] has been set to 0xFFFFFFFF, the memory of any address of the read-write process is as follows: