In the course of our research, we constantly encounter the simple but harsh truth that malware authors can easily bypass popular security products with small variations to their code. In this technical analysis, we present the inner details of a very specific attack that was identified several years back, and which has security patches, but which embodies the new sophistication which makes it invisible to almost every security product.
CVE-2012-0158 is an ActiveX vulnerability patched by Microsoft back in 2012, but it remains one of the most popular CVEs to be used in document exploits. Just a few days ago, uanalysis.com discovered an Excel-transmitted version, which is able to evade almost all popular security solutions. [MD5: / see Twitter communication in the image above]
The good news is that Morphisec’s Moving Target Defense once more proved itself and prevented the attack immediately like expected. Watch the short screen capture I prepared.
Attack Analysis
This analysis does not cover the exploitation and the vulnerability, which have already been explored thoroughly (see this post). Instead, we go deep into the shellcode, demonstrating how the exploit successfully evades most of the security solutions today.
The general steps of the shellcode execution are as follows (see the following section for the technical details):
- The shellcode initiated after activation of gadget from MSCOMCTL -> JMP ESP (RET)
- The shellcode has two sequential decryption routines which activate second stage shellcode + a few sophisticated anti-debugging techniques.
- Second stage shellcode locates functions by traversing the PEB and kernel32 module, locates the .xls file handle by iterating over existing handles, reading from it and locating its magic number, and decrypts the main 3rd stage shellcode.
- 3rd stage shellcode again locates many more functions from the PEB but this time it holds the pointers + small offset (0x5) -> to JMP over hooks (Bypass hooking).
- Its next step is to load MSVBVM60.dll which is the (32-bit) runtime component of VB6, although the reason for loading the module is different.
- Next it locates the function PutMemVar from this module and replaces it with a homemade function that is capable of receiving any function pointer (+0x5) as a parameter and activating it from the code (bypass of control flow analysis).
- Next the shellcode uses PutMemVar extensively by decrypting a new section from the .xls file -> this section is actually a propagative password stealer malware.
- To evade any whitelisting or AV which can scan the executable, the shellcode creates a duplicate Excel child process in a suspended state, overrides its memory with the executable, and resumes the process.
Summary:
The creators of this attack worked extensively to evade existing advanced protections.
It can be seen from the advanced methods used in the shellcode (replacing existing dll functions to fool control flow analysis; bypassing hooking by executing the targeted functions with a small offset +0x5; staying fileless to bypass whitelisting and AV’s; locating main modules like Kernel32 only by checking the length of the module name; locating functions by hashing the names, which usually fools static analysis; the same is true for the file handles).
Although all of these techniques are well known and not new, such combination is rarely found. Similar shellcode technique can be found in the newer CVE-2015-2545 samples of malicious EPS Word documents (sha256 - 9c6dc1c2ea5b2370b58b0ac11fde8287cd49aee3e089dbdf589cc8d51c1f7a9e), although in that case the RAT is not fileless.
The Technical Details
1. The shellcode initiated after activation of gadget from MSCOMCTL -> JMP ESP (ret)12. As a closure of this investigation, I uploaded the embedded Trojan (saving the memory dump into an executable file) to VirusTotal Detection. In this case, of course, many AVs are effective. Too bad that attackers are well aware of this, and are now using the new evasive and stealthy methods described above.
Recommendation for debugging
If you are using Windbg, execute “childdbg 1” and change the opcode marked in the next image from “ja” (JMP ABOVE) to “jb” (JMP BELOW), or instead, just progress the EIP so that the JMP will not happen.