Addressing CVE-2014-6332 SWF Exploit

Continuing a recent trend in which Internet Explorer vulnerabilities are exploited using Flash, samples of an SWF purportedly used in conjunction with CVE-2014-6332 have appeared in several places. The most famous examples of this trend are the exploits for CVE-2014-0322 and CVE-2014-1776.

We have yet to encounter the SWF sample with its original exploit attached, but by looking at the SWF, it is clear that it is constructed to function with several forms of memory corruption, making the vulnerability itself less interesting. That is a great example of why our Advanced Endpoint Protection approach, which focuses on the core techniques used in attacks, works well. It will prevent uses of this SWF framework, regardless of the vulnerability it is used with.

The interesting part in this exploit is the Flash component. At first glance at the decompiled ActionScript shown here, it seems fairly straightforward, sharing much of its code with the previously seen exploits:

cve 1

This post will not go into detail regarding the spray mechanisms since they are almost identical to the ones seen in previous exploits, but in short:

  1. A 0x18180 element vector is sprayed, each vector 0x3FE bytes in size.
  2. A timer routine is started, with the browser vulnerability is triggered via an ExternalInterface call to a JavaScript/VBScript function.
  3. Once the timed routine detects that the corruption has occurred by scanning the vector for a longer vector, it stops and continued to the next phase.
  4. The following vector is corrupted to span the entire memory and read/write abstracts are defined
  5. A pointer from Flash_*.ocx is leaked and its base is determined by scanning backwards.

After that, addresses of VirtualAlloc and GetProcAddress are resolved from the import table, for later use in assembling the ROP and shellcode.

The ROP chain is triggered by overriding the previously created Sound object's vtable and calling the toString method, leading to the first ROP gadget.

cve 2

At this point it’s worth mentioning one particular behavior. Prior to the shellcode, after the stack pivot, the original stack address (now in eax) is preserved in esi, and then put back into esp as part of the shellcode's prologue, enabling the shellcode to run on the original stack.

The shellcode

The interesting part starts with the shellcode, which seems to be tailor made to bypass Microsoft EMET protections, and possibly other security products as well.

The first reference to EMET can be seen when the shellcode sets up its data section (containing mostly hashes of functions to later be resolved):

cve 3

The shellcode then starts off by resolving the address of NtSetContextThread by calling GetProcAddress, the address of which was previously written into the heap spray (pointed to by ecx) by the ActionScript code.

cve 4

The shellcode sets up a CONTEXT structure and calls NtSetContextThread, overriding the debug registers and eliminating EMET's EAF feature, as per the method demonstrated by Piotr Bania in 2012.

Once this is accomplished, the challenges faced by the shellcode are greatly reduced.
It then proceeds to resolve the previously entered hashes into functions:

cve 5

It resolves the following functions from kernel32 and ntdll in two separate loops:

  • LoadLibraryA
  • GetProcAddress
  • VirtualAlloc
  • IsBadReadPtr
  • WriteProcessMemory
  • GetModuleHandleA
  • Sleep
  • VirtualProtect
  • CreateThread
  • GetProcessHeap
  • CreateFileA
  • WriteFileA
  • CloseHandle
  • WinExec
  • GetTempPathA
  • SetUnhandledExceptionFilter
  • RtlAllocateHeap
  • Memcpy
  • ZwGetContextThread
  • ZwSetContextThread

Once all functions are resolved, it proceeds to read a payload PE that was concatenated to the end of the shellcode by the Flash component. The payload PE itself arrives via a file named "shadow.jpg", and is marked by the magic value 0xDEADBEEF41414141 and another DWORD containing its overall size.

It is copied into memory and then written into a file called "windump.exe" in the Local\Temp directory (retrieved using GetTempPathA).

At this point another piece of evasive code is introduced:

cve 6

The shellcode checks if EMET.dll is present in the process.

If so it simply calls WinExec normally, and the payload is run. Otherwise, it resets the UnhandledExceptionFilter, saves the current esp value, and calls a wrapper function which first takes control of the last SEH handler (pointed to by the TEB) and jumps into WinExec.
Upon returning it will reset esp to its preserved value and exit cleanly.

Either way, normal execution is restored after having returned from the corrupted sound object's toString method.

Conclusion

This exploit is interesting because it is the first display of an in-the-wild attack targeting machines protected by EMET (specifically, EMET 4.1).

Oddly enough, the bypass is unfinished – this exploit would be caught by EMET's stack pivot check on VirtualAlloc.

Disable or bypass this single test – and the exploit will succeed in bypassing EMET 4.1.

In fact, a fairly small set of customizations could be made to enable this exploit to bypass EMET 5.1 as well.

Albeit half-baked, this exploit shows a significant step toward in-the-wild exploits which bypass EMET, whereas in previous exploits of this nature, exploiters actively avoided machines running EMET by using a since patched information disclosure vulnerability in IE (CVE-2014-7331).

Worth noting: Palo Alto Networks Traps stopped this exploit with several layers of redundancy. We will continue to examine these exploits and update as appropriate.