After adobe flash’s June patch, we noticed that adobe has introduced a new exploit mitigation technique in the latest flash player, which is the Memory Protector. This new mitigation is aimed to fight against UAF exploits.
Memory protector mitigation for UAF exploit is not a brand-new technique, we had already seen this technique being used in Microsoft’s Internet Explorer as well as the Edge Browser. These years we have seen many flash use-after-free zero days exploited in the wild. We also used 3 UAF 0days in our chrome and flash exploits in this year’s pwn2own contest. So we are not surprised to see that adobe finally decided to add this technique into flash player to fight against flash use-after-free exploits.
In this blog we will take a look at how this technique is implemented in flash player and how it will help to raise the difficulty of exploiting use after free bugs in flash.
A quick reverse engineering at the new added memory protector functions suggests that it is almost the same with Microsoft’s memory protector. Most of the basic data structures and work flows of the two memory protectors are the same.
The most import data structure is the CMemoryProtector object (since we do not have signature of flash player we cannot know what its’ real name is, so we just use the same name in Internet Explorer here).
Figure 1. The CMemoryProtector Structure
Each fixed memory allocator in flash may has its’ own memory protectors, one protector per thread. When a memory block is going to be freed, if the memory protector of the corresponding allocator exists, then CMemoryProtector::ProtectedFree will be used to free this memory.
Figure 2. Free with MemoryProtector
In the ProtectedFree function, instead of freeing the memory block directly, memory protector will put the block to the end of the block array. Also, if current item count or total size reaches the threshold, the memory protector will try to call the Mark & Reclaim functions to free all memory blocks that do not have any references on the stack.
Figure 3. ProtectedFree
As you can see in the above code, in the mark & reclaim functions, if a memory block still has a reference on the stack, it will never be freed. This is the key point of the MemoryProtector mitigation. It is very effective for the following traditionally use-after-free case:
In the above case, now with the memory protected, the memory of object A will never be actually freed as long as there is still some reference to it on the stack. So an attacker will not be able to reuse and control the content of A (since it’s not freed) to complete the exploit.
The memory protector mitigation technique has already been proved to be effective for many use-after-free bugs and there is no doubt that the new flash memory protector will help flash player to become more secure.
However we believe there are still some issues in current memory protector implementation in the flash player.
Currently flash memory protector is only used for part of the objects in flash player. The objects in fixed heap allocators are protected by memory protector, while the gc objects are still not. So if you have a use-after-free vulnerability in the gc heap (e.g. a use-after-free on an ActionScript object), it will still not be mitigated by memory protector.
In CMemoryProtector::MarkBlocks, when checking references on the stack, it increases the stack pointer by 0x10 (0x40 on 64-bit build) bytes (4 pointers) each time.
.text:10724BDD add edi, 10h // stack pointer increased by 0x10 each loop .text:10724BE0 cmp edi, [esi] .text:10724BE2 jb short loc_10724BB6
This means the MarkBlocks function will only scan 4-pointers aligned references on the stack. This means in certain cases that the reference to the use-after-free object on the stack are not 4-pointres aligned, the memory of the object will still be freed and the memory protector will be useless. We have already found such case with real world use-after-free bug. Also, in certain cases an attacker can even adjust the stack layout to force the reference on the stack to be misaligned by 4-pointers.
I’m not sure why adobe implements the stack search algorithm in this way. I guess maybe it is due to performance concern.
- While the purpose of memory protect is to protect the software against exploits. It can also help the exploit in some way such as bypassing ASLR. There already have some attack techniques on this:
And we have also made a poc and proved such attack also works with flash memory protector:
The introduction of the Memory Protector in flash player certainly raises the bar for the exploitation of flash UAF vulnerabilities. However it is not 100% perfect and an attacker can still find his way to bypass the memory protector with a right bug. Also the memory protector may help the attacker to exploit the target under certain circumstances.