Anti-Analysis in an Office Document

Please note: This was a blog post I originally authored for Bromium. Due to changes in how they host their blog content, it has fallen into the archives and become somewhat difficult to find. I’m posting this content here mainly as an archive.

Office documents have been a favorite method of distribution for malware authors for several years. While most malware authors go to great lengths to hide the intention of their macros through obfuscation, it is seldom that I’ve encountered macros that also exhibit anti-analysis techniques. I recently examined an office document that contained such capabilities. You can find this sample on VirusTotal.

Finding the Macros

What first stood out about this document was that when it was opened in a virtual environment, no malicious activity was observed. The content of the document used social engineering to get the user to enable macros.

Further inspection of the document revealed that it contained several macro streams:

The macros were obfuscated as can be seen in the Document_Open() function, which will execute when the document is opened.

Along with using obfuscated variable and function names, strings were also obfuscated and stored in the text property of numerous labels in a user form.

At this point it was clear that the document was malicious, but where was the follow on behavior? To find that out I began by de-obfuscating the macros. This was to determine the lack of observed activity when enabled – was it due to anti-analysis techniques or simply errors in the code?  What I determined is that the code was looking for a sandbox environment and, if detected, would not download and execute malware.

Tracing Macro Functionality

The code begins in the Document_Open function by invoking a function in a different stream. This function sets up an error handler and then invokes a function that performs several checks for virtualization.

The call to check_virtualization will check for several artifacts in the environment, if none are found then application_run() is called, which will download an executable from hxxp://chienenforme.[com]/img/doc.exe, write it to “C:\Users\%USER%\AppData\Local\Temp/0.7055475” and execute it. 

What’s interesting in this sample is the anti-analysis techniques employed.  Following the code into check_virtualization reveals several distinct checks.

Checking the Host

To begin, we can look into check_host_and_environ, which obtains the current user and domain and compares them to the hard-coded string values “USER” and “HOST” respectively:

In order to obtain the current user name and user domain, the script uses an instance of the WScript.Shell object.

If the user and domain do not match the hard-coded values, then another function is called. This function is responsible for checking for the following strings in the environment:

This is performed in the is_virtual_environ function:

The outer loop begins by creating an instance of the Win32_ComputerSystem WMI class, which, according to Microsoft, “represents a computer system running windows.” This is done by creating an object using the string “winmgmts:” and then using the CallByName method to obtain an instance of the Win32_ComputerSystem WMI class.

The Manufacturer and Model properties are then compared to a list of hard-coded string values referenced above. If the sub-string match is found, the loop terminates and the function returns. If no match is found then another check is performed, this time to check for the presence of any common monitoring tools.

This function performs similar to the previous and initially obtains a list of all running processes. It does this by using winmgmts in order to execute a query to obtain a list of running processes:

The process name is compared to a hard-code list of string values:

If a match is found, the function returns TRUE otherwise FALSE. If either check_host_and_environ or check_tools returns TRUE then an additional function is called – check_path.  This function gets the current path of the Word document and does a string comparison to see if it contains the string “1461771256_us”:

Conclusion

The anti-analysis techniques observed in this document were effective. I performed several tests using both a virtual environment and some of the targeted tools and in each instance the anti-analysis code was able to detect their presence.