ViperMonkey: VBA maldoc deobfuscation

Published: 2018-11-26
Last Updated: 2018-11-26 17:57:09 UTC
by Russ McRee (Version: 1)
0 comment(s)

ViperMonkey: a VBA Emulation engine written in Python, designed to analyze and deobfuscate malicious VBA Macros contained in Microsoft Office files.

Related reads:

Problem Statement:

“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

ViperMonkey Installation:

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

sudo -H pypy -m ensurepip

will not work on Ubuntu 18.04.

sudo apt-get install pypy
sudo apt-get install python-pip

Download the archive from the repository: Extract it in the folder of your choice, and open a shell/cmd window in that folder. Install dependencies by running

sudo -H pypy -m pip install -U -r requirements.txt

Confirm that Vipermonkey runs without errors:


Ideally, install the dependencies for PyPy, you can download them individually then install them as follows:

sudo pypy ~/Downloads/setuptools-40.6.2/ install
sudo pypy ~/Downloads/colorlog-3.1.4/ install
sudo pypy ~/Downloads/olefile-0.46/ install
sudo pypy ~/Downloads/prettytable-0.7/ install
sudo pypy ~/Downloads/pyparsing-2.3.0/ install

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?

pypy -s <file>

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

pypy ~/vipermonkey/ -s samples/4aff

Maldoc samples:

I logged in to my favorite malware sample repository,, searched for VBA, and selected three samples.

  • Trojan:Win32/Tiggre!rfn, MD5 cbdcc830345b99d94aa624e57689fd7b
  • Trojan:Win32/Occamy.C, MD5 0dc208ad5f0768fe99b75528dc97321b
  • Trojan:Win32/Bluteal.B!rfn, MD5 8ef62c0737f219e3e57a9f1ed1adcfb9

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:

  • Runs other files, shell commands, or applications
  • Contains deobfuscation code
  • Makes use of macros
  • Create OLE objects

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:

  • Contains deobfuscation code
  • Makes use of macros
  • Automatically runs commands or instructions when the file is opened
  • Create OLE objects

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:

  • Downloads additional files from the Internet
  • Executes code from Dynamically Linked Libraries
  • Opens a file
  • Automatically runs commands or instructions when the file is opened
  • Makes use of macros
  • Enumerates open windows
  • Executes PowerShell commands
  • Tries to hide the viewer or other applications
  • Creates OLE objects

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.

Russ McRee | @holisticinfosec 

0 comment(s)


Diary Archives