CVE-2012-0158 is a buffer overflow vulnerability in the ListView / TreeView ActiveX controls in the MSCOMCTL.OCX library. The malicious code can be triggered by a specially crafted DOC or RTF file for MS Office versions 2003, 2007 and 2010. Although this vulnerability was patched by Microsoft more than a year ago, it seems that not everyone cared to install the updates. And those who didn't may be at risk of getting all their documents, pictures and databases encrypted by a new version of the Gimemo ransomware (detected by our products as Trojan-Ransom.Win32.Gimemo.beic).
As the binary is still being analyzed, in this article we will focus only on the delivery part. Even if the exploit is not a zero-day, it's pretty interesting because of the code complexity (it consists of 4 stages!) and the simple-yet-effective anti-heuristic techniques it uses.
The ransomware is dropped and executed by a malicious RTF file ("Указ Президента от 12.06.2013.doc", which translates to "Presidential Decree 12.06.2013.doc") attached to mass-mailed messages. The outbreak seems to have taken place on 18 June 2013 when Kaspersky Security for Linux Mail Server detected hundreds of such messages as malicious (identifying them as Exploit.Generic.Dropper.a). So far, it seems that only Russian-speaking users are being targeted and most of the emails we've seen were sent from an IP address in Germany, with the header that's the same or similar to this one:
"Received: from bersar by 24-host.com with local (Exim 4.69)(envelope-from )id"
The RTF file contains three embedded objects. The first one is a package consisting of a 12-byte signature and the malicious binary followed by the final (4th) stage of shellcode (both "encrypted" with XOR 0x9D) .
This signature is used later by the stage 3 shellcode to find the rest of the shellcode and the binary in memory.
The second object is an OLE object - that contains a malformed DOC file, which triggers the buffer overflow and executes shellcode. Embedding this document using Object Linking and Embedding technology means that in the source of the original RTF file we will see the ASCII representation of malicious hex code, rather than the hex code itself. This is a primitive technique that may result in bypassing some simple heuristic mechanisms. Furthermore, the malware writer also took care to obfuscate all of the constant values that are used in processing the ListView ActiveX control. The idea here was to inject brackets and whitespaces into these values, making them harder to recognize, while they are fully ignored during the processing of the OLE compound document.
If we open the malicious RTF file in the hex editor, it's not so easy to spot the exploit code at first glance. But once we've figured out the location of the ListView CLSID, things become a little bit easier. But no point in looking for the most popular exploit opcodes, like 0xEB (JMP instruction) or 0xE8 (CALL instruction); this exploit aims higher. Firstly, it tries to bypass Data Execution Prevention by using a ROP chain build upon the instructions from the vulnerable version of MSCOMCTL.OCX library. Secondly, it uses FLDZ + FSTENV instructions to get the instruction pointer, which is an old but fairly uncommon technique and might overlooked, especially if surrounded by some fake, legitimate-looking mathematical operations.
ROP (Return Oriented Programming) is a method invented a couple of years ago against Data Execution Prevention. Instead of trying to directly execute code in memory that might be marked as non-executable, the exploit makes use of appropriate instruction sequences from one of shared libraries, assuming that this library was loaded in memory at some predictable address. In this case, the ROP chain is designed to allocate space on a heap, copy the second stage of shellcode from the stack to this executable memory and simply call it.
The second part of the shellcode is obfuscated with lots of junk instructions, which have no significant effect, but are here to fool the heuristics and impede analysis. When we exclude these meaningless instructions (marked with "-----" comment on the screenshot below), we can clearly see that this part is responsible for decrypting the third stage of the shellcode. Again, the decryption routine is very simple - just a XOR with 0x3D.
The next part of the code implements the technique called "egg hunting" to find and execute the final payload. What is worth noticing here, is that the exploit doesn't contain any strings, or even hashes, that might be easlily identified as suspicious. Instead, it uses the name length to find the kernel32.dll library base, and the difference between the first and the second word of the name to find the IsBadReadPtr API.
As we already know, the stage 4 shellcode and the malicious binary are located in the first OLE object of the RTF document. By checking subsequent memory blocks with IsBadReadPtr() function, the exploit identifies all the memory areas that the current process is able to read. Then it searches through these readable blocks for a sequence of bytes which matches the signature of the beginning of the encrypted malicious package. After the decryption routine, the exploit allocates some memory on the heap then copies the stage 4 shellcode into it, saves the pointer to the decrypted MZ, and jumps to the routine that performs the actual attempt to drop and execute the binary.
The last part of the shellcode drops the binary to %TEMP%WINWORD.EXE and deletes the registry keys that MS Word uses to store information about the files that might need recovery. Then it uses the WMI interfaces (WMI stands for Windows Management Instrumentation) to finally execute the MZ file. Why the attackers used WMI is not clear yet. We haven't seen this technique in exploits very often.
Although the shellcode contains a long list of IIDs and CLSIDs related to other WMI interfaces, it only makes use of the IWbemLocator interface. The purpose of the rest of them is unknown. It's possible that the malware writer included this list in the shellcode just to obfuscate it, or maybe they are used at some point by the malicious binary.
This particular exploit sample doesn't really invent anything new and the techniques it uses are either old or very simple. However, this amount of obfuscation and anti-heuristic tricks is somewhat impressive in a single file:
- multilayered OLE objects
- brackets + whitespaces obfuscation
- ROP chain to bypass DEP
- FSTENV instruction to get EIP
- junk instructions
- XOR obfuscation
- egg hunting technique
- unusual hashing routine for API names
- use of WMI to execute the binary
- list of unused WMI UIDs
Malware writers made a lot of effort to avoid detection, yet it seems they focused on systems with some particular configuration and/or running some particular AV software. There was a limited amount of targets, most of them based in Ukraine. Kaspersky Security for Linux Mail Server detected several hundreds of infected messages - all of them were sent during the first day of outbreak. On the other hand, our KSN data shows, that between June 18 and July 30 there were merely 55 detections of Trojan-Ransom.Win32.Gimemo.beic, exclusively in Ukraine. Starting from July 31 we've been seeing the same (or very similar) exploit, dropping the different binary (detected as Trojan-Spy.Win32.Zbot.nxdk). We will investigate this further and keep you updated. In the meanwhile, please make sure that you have installed all available security patches. Even if in this case we are dealing with a relatively small-scale targeted attack, other CVE-2012-0158 exploits are still extremely widespread and used by cybercriminals to drop hundreds of different malicious files.