ViperMonkey: a VBA Emulation engine written in Python, designed to analyze and deobfuscate malicious VBA Macros contained in Microsoft Office files.
“Macro malware hides in Microsoft Office files and are delivered as email attachments or inside ZIP files. These files use names that are intended to entice or scare people into opening them. They often look like invoices, receipts, legal documents, and more. Macro malware was fairly common several years ago because macros ran automatically whenever a document was opened. However, in recent versions of Microsoft Office, macros are disabled by default. This means malware authors need to convince users to turn on macros so that their malware can run. They do this by showing fake warnings when a malicious document is opened.” ~Macro malware
Download and installation guidance is available on ViperMonkey’s GitHub repository. Be advised installation success and an optimized deployment can vary wildly depending on the OS you chose to install on. The most important takeaway is that you want to use PyPy to run ViperMonkey, the performance improvements in doing so are significant. While Philippe’s disclaimer is warranted, I found ViperMonkey to be quite performant, even on a virtual machine, when utilized with PyPy. I had the most success installing as follows on Ubuntu 18.04 Bionic Beaver, your experience may vary and you’ll likely want or need to experiment. There are definite nuances between Windows and Linux/Mac. Most importantly, note that
will not work on Ubuntu 18.04.
Download the archive from the repository: https://github.com/decalage2/ViperMonkey/archive/master.zip Extract it in the folder of your choice, and open a shell/cmd window in that folder. Install dependencies by running
Confirm that Vipermonkey runs without errors:
Ideally, install the dependencies for PyPy, you can download them individually then install them as follows:
Again, “ViperMonkey can be sped up considerably (~5 times faster) by running ViperMonkey using pypy rather than the regular Python interpreter.”
Once you’ve conquered the installation, usage is particularly straightforward. Ready for it?
Use the -s flag to strip out useless statements from the Visual Basic macro code prior to parsing and emulation, again contributing to efficiency and speed. I enabled an example run via the likes of
I logged in to my favorite malware sample repository, VirusShare.com, searched for VBA, and selected three samples.
The first sample, a Word doc with malicious macros disguised as a Citi Bank document, yielded immediately interesting results. A typical ViperMonkey run should result in the likes of Figure 1 as it starts parsing.
Figure 1: Initial ViperMonkey run
This sample is noted for commonly abused properties such as:
This is all immediately noted via ViperMonkey. Of particular interest, take note of Figure 2 as derived in ViperMonkey’s Recorded Actions for this sample.
Figure 2: Recorded Actions
Looks like someone popped a shell to me. This sample also utilizes the GetNetworkCredential().password function, for what I hope are overtly obvious reasons. In all, ViperMonkey identified the VBA Builtins Called as [‘Chr’, ‘CreateObject’, ‘Mid’, ‘Run’, ‘StrReverse’]. Mid returns a variant containing a specified number of characters from a string, and StrReverse returns a string in which the character order of a specified string is reversed. Carrie’s above mentioned article, Evasive VBA - Advanced Maldoc Techniques, states that StrReverse() can be “used to demonstrate that the strings do not need to be stored in the form required by GetObject() anywhere in the VBA.”
Our next sample is malicious Excel document with equally interesting attributes including the fact that it:
Let’s see what ViperMonkey has to say. Yep, popped another shell (see Figure 3).
Figure 3: Malicious Excel macro
Note that the CLng function is an Excel a built-in function that converts a value to a long integer and can be used as a VBA function (VBA) in macro code. Additionally, the CallByName function is used to get or set a property, or invoke a method at run time using a string name.
Our last sample is another Word variant, and I definitely save the best for last. This little gem treats victims to:
There are no surprises in the VBA calls identified by ViperMonkey, but if you read the VirusTotal community page for this sample, you’ll note that THOR APT Scanner (thank you, Florian @cyb3rops) rule, SUSP_Base64_Encoded_URL, from the Suspicious Indicators ruleset, detects a Base64 encoded URL. ViperMonkey proves that out as seen in Figure 4.
Figure 4: Spawned PowerShell
ViperMonkey is again consistent in its identification of the malicious behaviors in our selected sample. Note the process call [‘winmgmts:\\.\root\cimv2:Win32_Process’] as well as the PowerShell invocation: powershell -noP -sta -w 1 -enc SQBmACgAJABQAFMAVg. This is better exemplified in the VBA code as parsed by ViperMonkey in Figure 5.
Figure 5: VBA code for malicious Macro
Of interest, the Macro references an external library of libc.dylib, allowing execution of system commands as should be familiar to Empire users. I know Philippe considers this very much work in progress, but I’m pretty impressed and hope he continues development on the project. I really enjoyed putting this walkthrough together, I look forward to hearing about your experiments in maldoc analysis via russ @ holisticinfosec dot io or @holisticinfosec. Cheers…until next time.
Nov 26th 2018
8 months ago