In our recent blog post “Blinding Malware Analysis with COM Objects” we talked about the steady trend of malware using Microsoft’s Component Object Model (COM) for evading sandbox analysis. The reason why COM can be used to perform stealth operations is that traditional dynamic analysis systems monitor program behavior by intercepting calls on the WinAPI-, the NativeAPI-, or the system call-layer. Unfortunately, none of these calls directly reflect COM method invocations. Furthermore, the actual execution of COM methods can be happening within different (remote) processes and it is very hard to associate back to the issuing thread. This makes it extremely difficult for traditional sandboxes to monitor COM activity and, especially, to reconstruct the original high-level semantic of the analyzed piece of code. In our first posting on COM Evasion we gave a brief introduction into COM and presented VMRay Analyzer’s capability to generate fine-granular function logs that comprise each single COM activity. In this blogpost we now illustrate the power of this unique monitoring methodology by taking a deeper look at different COM utilization by in-the-wild malware.
We thank Adam from Hexacorn for providing us with additional information and samples on COM malware in-the-wild. He already addressed some of our COM examples before in a related blog post.
Generic Representation of COM activity
VMRay Analyzer generates extensive analysis data for each analyzed malware. For example, it provides screenshots, memory dumps, network PCAPs, and copies of all dropped or modified files. However, the most important information is the monitored behavior data, which contains information about every single interaction between the malware and any other part of the system, e.g., the operating system itself or one of the other running process. This behavior data is provided at various different abstraction layers and in different formats. On the lowest level it comprises a comprehensive function log that contains every single function call plus its input and output parameters. From that fine-granular low-level data, a generic log is created, that abstracts away from specific API and parameter formats. Instead, everything is standardized and normalized, allowing the creation and application of flexible rules that no longer need to take into account any system specifics. The part of these generic logs that is relevant to this blog post covers the monitored COM activity. The three available operations in this context are shown in the following figure and described in the table below.
CREATE: Before using a COM object, it needs to be instantiated. By calling an appropriate API (like CoCreateInstance), an uninitialized COM object of the specified class is returned and an interface to it is provided. The generic log displays the class name (or the CLSID if the class name is unknown), the specified interface, and additional information about the applied COM context.
QUERY: Since COM classes may provide multiple interfaces, one can query additional interfaces, e.g., by using the API QueryInterface. Unsurprisingly, the generic log shows the class name, the origin interface and the new queried one.
METHOD: All other COM activity is covered by the generic METHOD operation. For each invocation, the log presents the name of the COM class, the name of the interface, and the called method. Further details (such as the used method parameters) can be obtained by referring to the corresponding low-level data within the function log. Note that some method invocations also return an additional interface, which then can be used to access the result of the method call.
In-the-wild COM Utilization by Malware
The utilization of COM by malware is increasingly popular and is used to achieve different tasks. We present here some in-the-wild examples and provide details on how they work and how VMRay Analyzer can be used to quickly analyze them.
The ShellLink COM class
A key goal for almost any malware is gaining persistence, i.e. to be able to automatically restart after reboot. This can be done in several ways, and one way is to place a shortcut into the user’s autostart folder that links to the malware file. To implement this via COM, the ShellLink class can be employed. The following figure gives a high-level overview of the necessary operations:
After creating the object, the destination path for the shortcut needs to be specified by calling the SetPath method. After that, SetDescription is used to specify the name of the resulting shortcut. Finally, the IPersistFile interface is queried and then used to actually store the shortcut in the user’s autostart folder by calling the Save Method. The Figure below displays the detailed function calls with all the parameters. One can easily see how the malware creates the shortcut C:UsersUserAppDataRoamingMicrosoftWindowsStart MenuProgramsStartupTest.lnk that links to C:WindowsSystem32calc.exe. Please note that this first example was taken from a PoC sample that only demonstrates the functionality without actually performing any malicious payload.
The TaskScheduler COM class
Another way to achieve persistence is to use the Windows Task Scheduler, which provides the ability to automatically launch programs or scripts at pre-defined times or after specified time intervals. The Qadars Banking Trojan makes use of this technique. The high-level representation of the COM related operations is shown in the next Figure, which is a good overview of the intended functionality.
In the following low-level view of the performed COM operations, one can see how the malware:
- creates a trigger that is activated on each bootup (type 0x9 = TASK_TRIGGER_LOGON),
- sets the user that is associated with the task, and finally sets the file to be started to C:UsersUserAppDataRoamingiPsdqsZHlCzZPdrTXhGsQzeUDbAKwUrgQ.exe
- A more detailed description of this persistence technique is described on MSDN.
The WMI COM Class
One very powerful approach for malware to ‘blind’ sandboxes is the utilization of the Windows Management Instrumentation (WMI). WMI provides an interface to the operating system for the purpose of scripting administrative tasks and querying various systems settings. On the implementation side, WMI can be used in many different ways, e.g. directly from VBasic Scripts, Javascripts, and also via COM.
In our final example we show a malware employing WMI to get a list of the installed anti-virus software on the underlying system. IWbemServices class is the primary interface to access WMI and its ExecQuery method is used to request more specified services or information. The general procedure of the WMI approach and the actual query performed (“SELECT * FROM AntiVirusProduct“) can be easily gathered from the generic and detailed low-level outputs respectively:
COM Interface Inheritance
Due to inheritance it is possible to use certain COM methods via one interface which are originally provided by any of its parents. Within the generated analyses VMRay Analyzer always refers to the interface that actually implements a certain method and not the one that was used at runtime. This provides a much better view on how the system internally works and eases understanding of the originally intended semantic. For demonstration purposes take a look at the following code snippet:
First four different instances of the InternetExplorer class with different interfaces (IWebBrowser, IWebBrowser2, IWebBrowserApp, and IShellLink) are created.
Then the IWebBrowser interface is used to navigate to http://speedtest.netcologne.de/test_500k.bin, and then IWebBrowser2 is used to navigate to http://speedtest.netcologne.de/test_1mb.bin. In both cases the internally called Navigate method is implemented by IWebBrowser and only inherited from it by IWebBrowser2 in the second case. Accordingly, in the generic log below you see two calls of the Navigate method, both with the IWebBrowser interface (note the amount of 2 in the corresponding line). Afer that, the get_Visible and put_Visible methods are called via IWebBrowser2. Again, both functions are inherited and originally provided by the IWebBrowserApp interface. The corresponding calls of get_Visible and put_Visible in the log below again indicate this accordingly: