Analysis of a Dridex Downloader with Locked Excel Macros


I came across a fairly interesting Dridex maldoc the other day, and I figured it was worth doing a quick write-up on the obfuscation and anti-analysis techniques I saw. This was an Excel document that had its VBA macro project “locked” by the threat actor to disrupt analysis. Further anti-analysis included a heavy dose of multi-layered DOSfuscation, also designed to disrupt analysis and evade sandboxes. In this post, I will provide a brief overview of Dridex and then shift into a discussion of these anti-analysis techniques and how you can use some open-source tooling and Python scripts to overcome them. Let’s go!

Dridex Overview

The Dridex malware is a modular banking trojan and infostealer operated by a financially motivated criminal group referred to as “Indrik Spider” amongst other aliases. Dridex has the capability to perform web injects to steal banking credentials that may be monetized as a commodity themselves or leveraged in support of further wire fraud activities. Recently, these threat actors have also been known to leverage Dridex infections to move laterally within network environments and manually deploy the BitPaymer ransomware on high value targets. Indrik Spider typically distributes Dridex malware via spam email phishing campaigns.

The Document Phishing Lure

The “INV_984748.xls” attachment was a Microsoft Excel document with an invoice theme in its naming convention, which is typical of many similar campaigns. The document’s content also employs an Intuit tax theme, which is intended to take advantage of end-user curiosity related to current events, another popular tactic of financially motivated criminals. The document is weaponized with VBA macros, which is also common, however, the actors utilized a few interesting techniques in this document as we shall see.

  • Filename: INV_984748.xls
  • SHA256: 7F8F24884E26B4B508D5147F8F54269E452D1200904323544EF36E30400190B1
Figure 1. Intuit-themed Dridex lure

The “Locked” Macros

A Microsoft Office document weaponized with macros is nothing new, we see these all day, everyday. These macros are executed when an unsuspecting user clicks “Enable Content” kicking off the infection chain and leading to the download of next-stage payloads. Usually, analysts can quickly review these macros by simply opening up the onboard VBA project editor within the MS Office or Excel program. Obfuscation and anti-analysis techniques are commonly employed to evade detection and avoid complete analysis by automated sandboxes. In this case, however, the VBA project itself was locked, and could not be viewed.

Figure 2. Locked VBA project

I have never had trouble dropping into the editor and getting access to the malicious code, but alas, it was not the case in this instance. Since I had not previously encountered this error message before, you may be able to imagine that I was quite stymied.

Figure 3. Analyst Reaction

So, in case you are wondering, this isn’t simply a password protected project which is common with developers and legitimate users who would like to protect their code. Those can be fairly easily brute-forced. Something else was going on here and it took a little googling before I found the solution. I stumbled across a Medium Post by Carrie Roberts who pointed me in the right direction. I can’t be certain that the actors in this case were using an open-source program called “EvilClippy” to lock these macros, but that is what I ended up using to unlock them, so that at least provides some minimal supporting evidence that this was indeed the tool used to lock the project. It was trivial to download EvilClippy and then simply run the program against the file with the “-uu” option.

Figure 4. Unlocking the project

With the EvilClippy tool, opening up the project to access the VBA code was a snap. The application output a file into my working directory with “_EvilClippy” appended to the filename and a new freshly unlocked macro project. Behold:

Figure 5. We’re In!

The Obfuscated Macro

Unfortunately, simply accessing the macro code turned out to be just the first stage of this battle. This particular macro has many, many layers of obfuscation that is intended to complicate analysis and evade detection by sandbox applications. At this stage, it is often better to rely on these automation tools to dump the code via dynamic analysis with a sandbox or VBA emulator, but I often prefer to take a static analysis approach and manually decode these macros to divine the underlying subtleties of their operation. It is also just a fun exercise, akin to putting together a puzzle or deciphering a riddle. This type of approach may also provide some insight into adversary tactics, techniques, and procedures (TTPs) that would otherwise be lost (or at least glossed over) when employing dynamic analysis.

Figure 6. Mankind

The primary obfuscation technique utilized in this document appears to be a series of DOSfuscation layers. These layers use a confusing series of nested arrays, indexed by variable assignments, along with a bewildering series of character substitutions and compression/decompression operations to boot. But first, we need to figure out where all of this code is hidden. A cursory review of the macro above does not show much that would raise too many eyebrows.

Figure 7. The base macro

There is not a lot to go on here, but we should zero in on line 7. The range “C192:HA310” sure does look like a basic formula for a range of cells, so this indicates to us we need to hop out of the VBA project and take a peek at the actual XLS document sheet. You should know the threat actors definitely changed the font color to white, so we can just restore the default and scroll down to the range of cells in question. Line 8 gives us a clue that these values might be character codes, and also that we need to add 1 to each of the values as noted above in Figure 7.

Figure 8. The cell range

The cells appear pretty clearly, but they seem to just be a very large, very random block of numbers that doesn’t really tell us much. For our next trick, we should copy out this range into a CSV or similar so that we can get some output that we can work with. CSV is a good choice because that preserves the individual values, values that we don’t want to concatenate just yet. We want to decode these values before joining them together. However, just opening up the file in our favorite text editor is initially a little perplexing while attempting to make sense of the data.

Figure 9. The cell range now

Again, this appears to just be a random series of numbers that have also brought in a bunch of extra “,” characters that are unnecessary. We can do a quick find/replace with some regex: ([,\s]{2,500}). This removes the long comma strings, but preserves the single commas that separate our values. The output now looks like this:

Figure 10. The cell range cleaned up

Ok, so this is much better and starting to look like something we can work with, but let’s not get too excited. We haven’t even gotten to the DOSfuscation bits yet. We can now take this code block and pivot over to CyberChef to help decode the values. This is one of my all-time favorite tools, and honestly, if you aren’t using it, what are you even doing? Kidding aside, CyberChef is amazing and decodes this block like a champ:

Figure 11. Cooked recipe

This embarrassingly simple recipe takes our code block and dumps out our next phase. Turns out….that that insane code block was just a bunch of UTF-8 encoded values that make up the document’s downloader code. This code is what will ultimately be passed to the interpreter and executed on the target host. Right away we can easily see that a WMIC process is going to call an obfuscated PowerShell cradle that will attempt to download the initial Dridex binary payload. Classic.

So we could pack it in right here and go about our business, but if you have the time and inclination, you could also be fascinated by this interesting obfuscation scheme and want to delve just a bit further. I also previously mentioned something about learning about attacker TTPs. Earlier I also mentioned arrays and indexes and we can now see this clearly here:

Figure 12. DOSfuscation

I won’t go into everything going on here because there is so much, but we can clearly see the index of numbers, followed by a large block of strings. The numbers of the index represent the position of the corresponding strings for the order of the array. There are also several other smaller arrays/indices that operate on the same concept that obfuscate shorter strings. We can also see several variable assignments such as the “${0L4}” variable which is assigned the character code 44, which is the comma (“,”) in ascii. So our array is simply a comma separated series of strings that can be easily decoded. I’m not sure what the fastest method of decoding these arrays are, but I do know that manual decoding is completely out of the question, so I wrote up a quick Python script to help us out here with this task.

Figure 13. Python decoder

All you have to do is drop in your strings and index and execute and it will print the reordered array to screen. I’m not much of a Python scripter, so YMMV, but you can get the script on my GitHub here. Ultimately, as some may have guessed, this array of strings is another long base64 encoded string that must also be decoded. The next screenshot shows the decoded array along with more cleanup of the various obfuscations.

Figure 14. Further down the rabbit hole

At this point it is obvious the obfuscated array is an encoded base64 string. Again, we should pivot towards CyberChef to help with the task of decoding the base64.

Figure 15. Level 2

Once we’ve decoded the base64 string, we see that we have, checks notes, another script with a base64 encoded string broken up out of order and indexed with a key. We will have to decode and reorder this array same as the last with my Python script. Next stop is another visit to CyberChef to decode the base64 output from the script.

Figure 16. Level 3

After decoding the the third level, we can see the output in Figure 16 includes more base64 encoding, but thankfully its additional obfuscation is simple compression and not the indexed arrays of the previous two layers.

Figure 17. Level 4

Here we go again. Forget about that point in time mere seconds ago when I was just thankful for no more indices. At least this time instead of one big array, there are dozens of shorter ones all mixed in together, which make scripting these problematic. In this obfuscation layer, we also see very many character substitutions with variable assignments. On top of all of that, we also have several split string functions, character replacements, and of course several escape characters which are a hallmark of DOSfuscation.

Figure 18. A better view of Level 4

The good news is that this is the final layer in our descent down the rabbit hole. Unless we are being particularly masochistic, we do not need to exhaustively decode this layer. We primarily are wanting to get to the IOCs, in this case the URL hxxp[:] which is the attacker controlled C2 location that the script will download the main Dridex DLL loader and execute it via regsvr32.

Figure 19. Fifth and final layer


So that’s it, my take on conducting analysis on a recent Dridex sample. This variant of Dridex was fairly different than many I’ve seen before, but it’s been awhile since I’ve really dug in on this malware so that could certainly be attributed to my own ignorance. Either way the usage of locked macros is intriguing and I hope this post at least helps others that may need to overcome similar analytical roadblocks. The obfuscation techniques observed here are extensive and mostly effective at evading detection and absolutely effective at frustrating manual analysis. I’ve provided some ATT&CK tagging below, if you’re into that sort of thing. Thanks for reading!



ATT&CK Tagging



















Leave a Reply

Your email address will not be published. Required fields are marked *