Skip to main content

IE9/10 information disclosure vulnerability

IE memory garbage collection ( Mark Sweep algorithm ) object address leak vulnerability

Information disclosure, Windows IE9/10

Description:

Since IE9, Javascript date uses 1 bit to mark *num* and *object* pointer. However, in most object structures, there are data field that does not use the bit to mark. IE Mark Sweep algorithm JSCRIPT9!Recycler::ProcessMark will mark the object in the structure. Because this is a general class, it cannot process correctly the num in the object structure that does not have the marked bit. Therefore, JSCRIPT9!Recycler::ProcessMark will wrongly think these num are object pointers and mark the wrong tag. This will cause some objects cannot be released correctly, and may also leak the object address to bypass ASLR. If the garbaby collection contains the code to *defrag* memory blocks, it might lead to potential more serious issues such as buffer overrun due to the incorrect operation of the object pointers (which should be a num).
Details


gc.html:

 
 
   
    
 



Poc creates an object array. Alert is for tracking. JSON.stringify allocates lots of memory to trigger gc. Observe how gc handles object array.

Object array process code:

0:008:x86> u JSCRIPT9!Js::JavascriptArray::NewInstance
JSCRIPT9!Js::JavascriptArray::NewInstance:
63138d83 8bff            mov     edi,edi
63138d85 55              push    ebp
63138d86 8bec            mov     ebp,esp
63138d88 83e4f8          and     esp,0FFFFFFF8h
63138d8b 83ec1c          sub     esp,1Ch
63138d8e 53              push    ebx
63138d8f 56              push    esi
63138d90 8b7508          mov     esi,dword ptr [ebp+8]
63138d93 8b4e04          mov     ecx,dword ptr [esi+4]
63138d96 8b4104          mov     eax,dword ptr [ecx+4]
63138d99 57              push    edi
63138d9a 8b7804          mov     edi,dword ptr [eax+4]
63138d9d 8b8f34020000    mov     ecx,dword ptr [edi+234h]
63138da3 ba00040000      mov     edx,400h
63138da8 e8ac00f7ff      call    JSCRIPT9!ThreadContext::IsStackAvailable (630a8
e59)
63138dad 84c0            test    al,al
63138daf 0f84b77b0c00    je      JSCRIPT9!Js::JavascriptArray::NewInstance+0x37e
(6320096c)
63138db5 8b450c          mov     eax,dword ptr [ebp+0Ch]
63138db8 a900000008      test    eax,8000000h
63138dbd 0f85ba1a1c00    jne     JSCRIPT9!memset+0x31b37 (632fa87d)
63138dc3 25ffffff00      and     eax,0FFFFFFh
63138dc8 83f802          cmp     eax,2
63138dcb 0f82f9000000    jb      JSCRIPT9!Js::JavascriptArray::NewInstance+0x18a
(63138eca)
63138dd1 0f854d030000    jne     JSCRIPT9!Js::JavascriptArray::NewInstance+0x27f
(63139124)
63138dd7 8b5d14          mov     ebx,dword ptr [ebp+14h]
63138dda f6c301          test    bl,1
63138ddd 0f84fc1a1c00    je      JSCRIPT9!memset+0x31b98 (632fa8df)
63138de3 d1fb            sar     ebx,1
63138de5 8b4604          mov     eax,dword ptr [esi+4]
63138de8 0f88c91a1c00    js      JSCRIPT9!memset+0x31b71 (632fa8b7)
63138dee 8b7804          mov     edi,dword ptr [eax+4]
63138df1 68fc760a63      push    offset JSCRIPT9!Recycler::Alloc (630a76fc)
63138df6 ff770c          push    dword ptr [edi+0Ch]
63138df9 6a20            push    20h
63138dfb e86fe9f6ff      call    JSCRIPT9!operator new (630a776f)
63138e00 8bf0            mov     esi,eax
63138e02 83c40c          add     esp,0Ch
63138e05 85f6            test    esi,esi
63138e07 0f843b43feff    je      JSCRIPT9!Js::JavascriptArray::NewInstance+0x3a8
63138e73 8b4604          mov     eax,dword ptr [esi+4]
63138e76 c706c82d0a63    mov     dword ptr [esi],offset JSCRIPT9!Js::JavascriptA
rray::`vftable' (630a2dc8)
63138e7c c7461c00000000  mov     dword ptr [esi+1Ch],0
63138e83 8b4004          mov     eax,dword ptr [eax+4]
63138e86 8b4004          mov     eax,dword ptr [eax+4]
63138e89 8b9064040000    mov     edx,dword ptr [eax+464h]
63138e8f 895e10          mov     dword ptr [esi+10h],ebx
63138e92 85db            test    ebx,ebx




0:008:x86> g  63138e76
Breakpoint 1 hit
JSCRIPT9!Js::JavascriptArray::NewInstance+0xf3:
63138e76 c706c82d0a63    mov     dword ptr [esi],offset JSCRIPT9!Js::JavascriptA
rray::`vftable' (630a2dc8) ds:002b:05384580={JSCRIPT9!Js::DynamicObject::`vftabl
e' (630a27d8)}
0:008:x86> t
JSCRIPT9!Js::JavascriptArray::NewInstance+0xf9:
63138e7c c7461c00000000  mov     dword ptr [esi+1Ch],0 ds:002b:0538459c=00000000

0:008:x86> t
JSCRIPT9!Js::JavascriptArray::NewInstance+0x100:
63138e83 8b4004          mov     eax,dword ptr [eax+4] ds:002b:05388aa4=00b0fb03

0:008:x86> t
JSCRIPT9!Js::JavascriptArray::NewInstance+0x103:
63138e86 8b4004          mov     eax,dword ptr [eax+4] ds:002b:03fbb004=98a9b502

0:008:x86> t
JSCRIPT9!Js::JavascriptArray::NewInstance+0x106:
63138e89 8b9064040000    mov     edx,dword ptr [eax+464h] ds:002b:02b5adfc=f0b1b
502
0:008:x86> t
JSCRIPT9!Js::JavascriptArray::NewInstance+0x10c:
63138e8f 895e10          mov     dword ptr [esi+10h],ebx ds:002b:05384590=000000
00
0:008:x86> t
JSCRIPT9!Js::JavascriptArray::NewInstance+0x10f:
63138e92 85db            test    ebx,ebx


0:008:x86> d esi l 20
05384580  c8 2d 0a 63 a0 8a 38 05-00 00 00 00 03 00 00 00  .-.c..8.........
05384590  40 23 01 00 00 00 00 00-00 00 00 00 00 00 00 00  @#..............

0:008:x86> u poi(esi)
JSCRIPT9!Js::JavascriptArray::`vftable':
630a2dc8 89750a          mov     dword ptr [ebp+0Ah],esi
630a2dcb 6389750a6389    arpl    word ptr [ecx-769CF58Bh],cx
630a2dd1 750a            jne     JSCRIPT9!Js::JavascriptArray::`vftable'+0x15 (6
30a2ddd)
630a2dd3 63857d0a637a    arpl    word ptr [ebp+7A630A7Dh],ax
630a2dd9 2028            and     byte ptr [eax],ch
630a2ddb 63642028        arpl    word ptr [eax+28h],sp
630a2ddf 634312          arpl    word ptr [ebx+12h],ax
630a2de2 1963a2          sbb     dword ptr [ebx-5Eh],esp
0:008:x86> u poi(poi(esi))
JSCRIPT9!JsUtil::BackgroundJobProcessor::AssociatePageAllocator:
630a7589 c20400          ret     4

Esi is the pointer of object array. 0x630a2dc8 points to vtable Js::JavascriptArray::`vftable'

poi(esi+0x10) is the array length, which can be controlled by the attacker. We can see later that in GC’s collection algorithm, it marks the entire objects when doing marking, instead of check details inside object layout.



0:008:x86> ba r4 esi
0:008:x86> ba r4 esi+10

Set breakpoint of array object vtable and length, run g, ignore intermediate breakpoint till alert pops up.

You can see GC algorithm try to mark the vtable and length and other num values to be object type.


Breakpoint 0 hit
JSCRIPT9!Recycler::ProcessMark+0x82:
631026b5 895c2418        mov     dword ptr [esp+18h],ebx ss:002b:07e0f9d8=d01f03
01

GC algorithm reads the vtable pointer

0:017:x86> u eip-4
JSCRIPT9!Recycler::ProcessMark+0x79:
631026b1 8bc3            mov     eax,ebx
631026b3 8b1f            mov     ebx,dword ptr [edi]
631026b5 895c2418        mov     dword ptr [esp+18h],ebx
631026b9 81fb00000100    cmp     ebx,10000h
631026bf 726b            jb      JSCRIPT9!Recycler::ProcessMark+0xf9 (6310272c)
631026c1 f7c30f000000    test    ebx,0Fh
631026c7 7563            jne     JSCRIPT9!Recycler::ProcessMark+0xf9 (6310272c)
631026c9 8bc3            mov     eax,ebx


0:017:x86> d edi l 20
05384580  c8 2d 0a 63 a0 8a 38 05-00 00 00 00 03 00 00 00
05384590  40 23 01 00 10 00 e9 02-10 00 e9 02 00 00 00 00

You can see Recycler::ProcessMark now handle the object array





0:017:x86> g
Breakpoint 1 hit
JSCRIPT9!Recycler::ProcessMark+0x82:
631026b5 895c2418        mov     dword ptr [esp+18h],ebx ss:002b:07e0f9d8=030000
00
0:017:x86> r
eax=053845a0 ebx=00012340 ecx=02b5b1f0 edx=00000400 esi=02ba3660 edi=05384590
eip=631026b5 esp=07e0f9c0 ebp=07e0f9f0 iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000287
JSCRIPT9!Recycler::ProcessMark+0x82:
631026b5 895c2418        mov     dword ptr [esp+18h],ebx ss:002b:07e0f9d8=030000
00

Continue, GC algorithm processes the array length field which is totally controlled by the attacker.

Analyze Recycler::ProcessMark

Check if it is object pointer (0x10000, lower 4 bit is 0). If it is object pointer, check list till the mark table of the object and mark the object. If it is marked, then it means there are pending references so the sweep would release the object.


0:017:x86> u JSCRIPT9!Recycler::ProcessMark
JSCRIPT9!Recycler::ProcessMark:
63102638 8bff            mov     edi,edi
6310263a 55              push    ebp
6310263b 8bec            mov     ebp,esp
6310263d 83e4f8          and     esp,0FFFFFFF8h
63102640 83ec24          sub     esp,24h
63102643 807d0c00        cmp     byte ptr [ebp+0Ch],0
63102647 53              push    ebx
63102648 56              push    esi
63102649 57              push    edi
6310264a 0f859e210000    jne     JSCRIPT9!Recycler::ProcessMark+0x42b (631047ee)
63102650 f6058053336320  test    byte ptr [JSCRIPT9!Microsoft_JScriptEnableBits
(63335380)],20h
63102657 0f85e99a1000    jne     JSCRIPT9!memset+0x15667 (6320c146)
6310265d 8b4d08          mov     ecx,dword ptr [ebp+8]
63102660 8b99506f0000    mov     ebx,dword ptr [ecx+6F50h]
63102666 895c242c        mov     dword ptr [esp+2Ch],ebx
6310266a 8b81306f0000    mov     eax,dword ptr [ecx+6F30h]
63102670 85c0            test    eax,eax
63102672 0f8408010000    je      JSCRIPT9!Recycler::ProcessMark+0x1a8 (63102780)
63102678 8b91286f0000    mov     edx,dword ptr [ecx+6F28h]
6310267e 3bd0            cmp     edx,eax
63102680 0f84ee000000    je      JSCRIPT9!Recycler::ProcessMark+0x19c (63102774)
63102686 8b4208          mov     eax,dword ptr [edx+8]
63102689 8b78f8          mov     edi,dword ptr [eax-8]
6310268c 8b70fc          mov     esi,dword ptr [eax-4]
6310268f 8bc2            mov     eax,edx
63102691 834008f8        add     dword ptr [eax+8],0FFFFFFF8h
63102695 8b91286f0000    mov     edx,dword ptr [ecx+6F28h]
6310269b 8d4210          lea     eax,[edx+10h]
6310269e 394208          cmp     dword ptr [edx+8],eax
631026a1 0f84e6350000    je      JSCRIPT9!Recycler::ProcessMark+0x2f1 (63105c8d)
631026a7 c1ee02          shr     esi,2
631026aa 8d1cb7          lea     ebx,[edi+esi*4]
631026ad 895c2410        mov     dword ptr [esp+10h],ebx
631026b1 8bc3            mov     eax,ebx

631026b3 8b1f            mov     ebx,dword ptr [edi]
631026b5 895c2418        mov     dword ptr [esp+18h],ebx
631026b9 81fb00000100    cmp     ebx,10000h
631026bf 726b            jb      JSCRIPT9!Recycler::ProcessMark+0xf9 (6310272c)

/*
  > 0x10000
*/
631026c1 f7c30f000000    test    ebx,0Fh
631026c7 7563            jne     JSCRIPT9!Recycler::ProcessMark+0xf9 (6310272c)
/*
  Lower 4 bit is not 0?object pointer
*/
631026c9 8bc3            mov     eax,ebx
631026cb c1e814          shr     eax,14h
631026ce 8bb481bc000000  mov     esi,dword ptr [ecx+eax*4+0BCh]
631026d5 85f6            test    esi,esi
631026d7 0f84c3000000    je      JSCRIPT9!Recycler::ProcessMark+0x195 (631027a0)
/*
  Level-1 table

*/
631026dd 8bc3            mov     eax,ebx
631026df c1e80c          shr     eax,0Ch
631026e2 25ff000000      and     eax,0FFh
0:017:x86> u
JSCRIPT9!Recycler::ProcessMark+0xb4:
631026e7 8b748604        mov     esi,dword ptr [esi+eax*4+4]
631026eb 89742414        mov     dword ptr [esp+14h],esi
631026ef 85f6            test    esi,esi
631026f1 7435            je      JSCRIPT9!Recycler::ProcessMark+0xf5 (63102728)

/*
  Level-2 table
*/

631026f3 0fbf4604        movsx   eax,word ptr [esi+4]
631026f7 83f801          cmp     eax,1
631026fa 7540            jne     JSCRIPT9!Recycler::ProcessMark+0x1c8 (6310273c)
/*
  Object pool type
*/

631026fc 8bc3            mov     eax,ebx
631026fe c1e804          shr     eax,4
63102701 25ff000000      and     eax,0FFh
63102706 8bc8            mov     ecx,eax
63102708 83e11f          and     ecx,1Fh
6310270b ba01000000      mov     edx,1
63102710 89442428        mov     dword ptr [esp+28h],eax
63102714 d3e2            shl     edx,cl
63102716 c1e805          shr     eax,5
63102719 8d0486          lea     eax,[esi+eax*4]
6310271c 855038          test    dword ptr [eax+38h],edx
6310271f 0f840d050000    je      JSCRIPT9!Recycler::ProcessMark+0x109 (63102c32)
63102725 8b4d08          mov     ecx,dword ptr [ebp+8]

63102728 8b442410        mov     eax,dword ptr [esp+10h]
6310272c 83c704          add     edi,4
/*
  Next pointer
*/
6310272f 3bf8            cmp     edi,eax
63102731 7580            jne     JSCRIPT9!Recycler::ProcessMark+0x80 (631026b3)
0:017:x86> u
JSCRIPT9!Recycler::ProcessMark+0x100:
63102733 8b5c242c        mov     ebx,dword ptr [esp+2Ch]
63102737 e92effffff      jmp     JSCRIPT9!Recycler::ProcessMark+0x32 (6310266a)

6310273c 83e802          sub     eax,2
6310273f 0f8557040000    jne     JSCRIPT9!Recycler::ProcessMark+0x25b (63102b9c)
63102745 c1eb04          shr     ebx,4
63102748 81e3ff000000    and     ebx,0FFh
6310274e 0fb7c3          movzx   eax,bx
63102751 8bc8            mov     ecx,eax
63102753 83e11f          and     ecx,1Fh
63102756 ba01000000      mov     edx,1
6310275b d3e2            shl     edx,cl
6310275d 8b4d08          mov     ecx,dword ptr [ebp+8]
63102760 c1e805          shr     eax,5
63102763 8d0486          lea     eax,[esi+eax*4]
63102766 855038          test    dword ptr [eax+38h],edx
63102769 75bd            jne     JSCRIPT9!Recycler::ProcessMark+0xf5 (63102728)
6310276b 095038          or      dword ptr [eax+38h],edx
/*
  mark
*/
6310276e 66ff462c        inc     word ptr [esi+2Ch]
63102772 ebb4            jmp     JSCRIPT9!Recycler::ProcessMark+0xf5 (63102728)



0:017:x86> u  63102c32
JSCRIPT9!Recycler::ProcessMark+0x109:
63102c32 095038          or      dword ptr [eax+38h],edx

/*
  mark
*/

63102c35 66ff462c        inc     word ptr [esi+2Ch]
63102c39 8b4c2428        mov     ecx,dword ptr [esp+28h]
63102c3d 8b461c          mov     eax,dword ptr [esi+1Ch]
63102c40 0fb70448        movzx   eax,word ptr [eax+ecx*2]
63102c44 8a843088000000  mov     al,byte ptr [eax+esi+88h]
63102c4b 0fb74e24        movzx   ecx,word ptr [esi+24h]
63102c4f 8844240f        mov     byte ptr [esp+0Fh],al


Other objects, the object reference area inside object such as the value of the array, during object’s own processing, it would mark the lower bits of these values to be object pointer (last bit 0) or num (last bit 1). However, object itself does not differentiate the object reference area and internal member. GC mark algorithm mistakenly marks the object internal member as object type. The attacker can control directly or indirectly the object member variable, via Fuzz, so that GC will not mark correctly. This will cause some objects cannot be released correctly, and may also leak the object address to bypass ASLR. If the garbaby collection contains the code to *defrag* memory blocks, it might lead to potential more serious issues such as buffer overrun due to the incorrect operation of the object pointers.

Popular posts from this blog

LibrePlanet 2017: Liberating your open source experience

LibrePlanet is a yearly gathering of free software activists, users, and contributors—and, it's my favorite conference of the year. Here's why.
LibrePlanet is run by the Free Software Foundation, and has steadily evolved from a yearly members' meeting with presentations from staff and board members to a full blown two-day conference with speakers and attendees from all over the world. The event brings people who care about free software together to talk about the future of the movement, address current challenges, and celebrate successes.
PreludeI was invited to give a talk at LibrePlanet 2017 on 25th March at MIT, in Cambridge, Massachusetts representing Mozilla as a Tech Speaker. I reached Boston on 25th early morning. Around 1 AM. The journey itself was awesome till I realized that you don't get Uber or Lyft at Boston Airport.

Not that the apps don't function there. They work! Just no driver will be ready to pick you up from Airport at that time. After trying to b…

Bringing the Focus back : Firefox Focus (Builds) for Android

Firefox Focus – A Free, Fast Private Browser for....android! On 17th November 2016 Mozilla announced Firefox Focus. A free fast and easy to use private browser for iOS. Firefox Focus was filled with goodies. From inbuilt tracker blocking, content blockers to making privacy the first class citizen. It was all of that. Wrapped in a nice package, but only for Apple Ecosystem. The argument for having focus was to make privacy dead simple and default experience for most people out there. An excellent read is this article "Privacy made simple with Firefox Focus".
And while this was all fine, a lot of us were severely disappointed that we don't have an android version. That all changes now.
Mozilla has released a port of the Firefox Focus source code and I decided to build a port from it. And this is how it looks in my One Plus One.
If you notice it looks almost similar to its iOS counterpart. Focus blocks tracking cookies by default in its system. But there are small design c…

LinuxCon China 2017: Trip Report

Linux Foundation held a combination of three events in China as part of their foray into Asia early this year. It was a big move for them since this was supposed to be the first time Linux Foundation would hold an event in Asia. I was invited to present a talk on Hardening IoT endpoints. The event was held in Beijing, and since I have never been to Beijing before I was pretty excited for the talk. However, it turned out the journey is pretty long and expensive. Much more than a student like me can hope to bear. Normally I represent Mozilla in such situations, but the topic of the talk was too much into security and not aligned much with the goals of Mozilla at that moment. Fortunately, Linux Foundation gave me a Scholarship to come and speak at LinuxCon China which enabled me to attend LinuxCon and the awesome team at Mozilla TechSpeakers including Michael Ellis and Havi helped me get ready for the talk.

The event was held at China National Convention Center. It's a beautiful and …