Threat Research

RATicate: an attacker’s waves of information-stealing malware

In a series of malspam campaigns dating back to November of 2019, an unidentified group sent out waves of installers that drop remote administration tool (RAT) and information stealing malware on victims’ computers.

We’ve identified five separate campaigns between November, 2019 and January, 2020 in which the payloads used similar packing code and pointed to the same command and control (C&C) infrastructure. The campaigns targeted industrial companies in Europe, the Middle East, and the Republic of Korea. This leads us to believe that they are all the work of the same actors—a group we’ve dubbed RATicate.

A new campaign we believe connected to the same actors leverages concern about the global COVID-19 pandemic to convince victims to open the payloads. This is a shift in tactics, but we suspect that this group constantly changes the way they deploy malware—and that the group has conducted campaigns prior to this past November.

In this post, we’ll focus on the initial wave of campaigns, which all used Nullsoft Scriptable Install System (NSIS) installers. NSIS is an open source tool for creating Windows installers, designed for Internet-based software distribution. But it has also been abused for a long time to disguise and deploy malware. (We’ll discuss newer campaigns using other installers, and the group’s shift in phishing tactics, in an upcoming follow-up report.)

Plugged in for malware

One of the interesting features of NSIS installers is their plug-in architecture, which allow installers to communicate with other software components—including components of the Windows operating system. (A list of available plug-ins can be found here.) These plug-ins are deployed as Windows DLL files. If selected during the installer build, they will be automatically added to the final compiled NSIS installer’s packaged files inside the “$PLUGINS” folder.

Some of the capabilities these plugins can provide include:

The installers we looked at caught our attention because they all drop the same set of “junk files” (files that are never used by the installed malware) across the initial sample set. We’ve seen the tactic of packing NSIS installers with garbage files to conceal malware in the past; the junk files are intended to confuse analysts and create “noise” during sandbox analysis. So this behavior caught our attention, and we started to analyze it in more detail.

We found that all the samples use the System.dll plugin, which allows you to load a DLL and call its exported functions. The DLL called by these malicious installers injects a payload into memory (in most cases by using cmd.exe).

For purposes of illustration, this report focuses primarily on the analysis of one sample NSIS installer from the first group we discovered:

The output of the Exeinfo PE tool identifies the sample as an NSIS installer

NSIS installers contain compressed components, including executable code, which can be loaded into memory by the installers. These components can be extracted using file decompression tools, such as 7zip.

Output of 7zip after list the files contained on the analyzed sample

The files dropped by this sample included the following types:

    • ASCII text
    • C source files, in ASCII text
    • data
    • Executable and Linkable Format (ELF) 64-bit
    • GIF image data
    • JPEG image data
    • PC bitmap, Windows 3.x format, 164 x 314 x 4
    • PE32 executable (DLL)
    • PE32 executable (GUI)
    • POSIX shell script, ASCII text executable
    • Python 3.6 byte-compiled
    • XML 1.0 document

The installer drops the junk files into the %TEMP%/careers/katalog/_mem_bin/page1/W3SVC2 folder.

Junk files created by analyzed sample.

There are only two components dropped by the installer that are important to the malware installation, which are dropped into the $TEMP folder. In the case of the NSIS installer we analyzed for this report, these two components are:

  • aventailes.dll (the Initial Loader)
  • Cluck (Encrypted data)

The payloads of the installers we examined vary. During analysis of the samples we collected—conducted both manually and with the aid of sandboxing tools—we found several different families of RATs and infostealers. These included Lokibot, Betabot, Formbook, and AgentTesla. But all of them followed the same multi-stage unpacking process when executed.

First stage: initial loader and shellcode

In the first stage, the installer deploys the initial loader, a malicious DLL. The DLL is then used to begin decryption of the malicious payload, and then finally to inject malicious payload into memory while the NSIS layer drops the junk files. The following images show how the analyzed sample creates a cmd.exe process, which is used to inject the Final Payload.

Output of Procmon which shows how the analyzed sample creates a child process
The memory of created child process by the analyzed sample. The final payload is loaded at the address 0x400000.

The malicious DLL deployed with the RATicate installers (in this case, aventailes.dll) is a custom loader, likely developed by the threat actor, stored in the $TEMP folder of the file package. All of the analyzed initial loaders are DLL files with only one export, though the name of the loader and the export function vary across the samples. In this case, the export was named Inquilinity.

Export of Initial Loader

This export is called using the NSIS System plugin as explained previously. The export loads and executes a shellcode, located in the initial loader’s .rdata section. The shellcode is initially encrypted using a basic arithmetic operation. This operation varies across the initial loaders we analyzed.

The shellcode dropped by the initial loader then reads the Encrypted data (Cluck file) where other loaders and payloads are stored. These PE files and shellcodes are decrypted on demand during the next two stages of malware deployment. In the first stage of the decryption, done by the shellcode called by initial loader, contains an xor key, a second shellcode (shellcode 2), and a PE file (Loader 2).

The xor key is used to decrypt shellcode2 and Loader 2.

Here’s how the workflow of Stage 1 breaks down in depth:

Stage 1 workflow:

  1. NSIS exe file is executed.
  2. System.dll plugin loads and calls to Initial Loader (aventailes.dll)
  3. The export of Initial Loader decrypts shellcode1 and jumps to it.
  4. shellcode1 reads Cluck file which is loaded in a memory buffer.
  5. shellcode1 decrypts both shellcode2 and Loader2 and maps shellcode2 then jumps to it.
  6. shellcode2 maps Loader2 into memory (Reflective loading).

Second stage: second shellcode and loader DLL

The second stage of decryption begins when Loader 2 is loaded in memory by shellcode2. Loader 2 reads the Cluck file in order to decrypt more artifacts. The data for this stage is decrypted with a dynamically generated xor key based on the name of the file which contains the encrypted data (which in this case is Cluck). As shown below, after this xor is applied, there is another xor key (xor_key2) stored in the second part of the file, which is used to decrypt different artifacts like strings, shellcodes, and PE files.

Stage 2 workflow

  1. Loader2 starts executing its DllEntryPoint.
  2. Loader2 reads again Cluck file.
  3. Loader2 decrypts from Cluck some shellcodes which are never used.
  4. Loader2 decrypts shellcode3 from read data from Cluck.
  5. Loader2 executes shellcode3, which decrypts the Final Payload (a PE file).

Third stage: injection

After the decryption, shellcode3 injects the final payload in a child process. It accomplishes this using cmd.exe with the NtCreateSection + NtMapViewOfSection code injection technique.

These are the extracted artifacts during the analysis.

Loader 2 c2cdb371d3394ff71918ac2422a84408644fa603f1b45e3fb1a438dbce9dcad0
Final Payload 46c6fa90acdf651e99620c257ae4e9ed9d1cfcb31fd676dc9b570bb3f9720ac8

Hints of a single actor

We found 38 NSIS installer samples in total that shared very similar characteristics:

Identical junk files. Not only their name, but also their content. When generating the installer from NSIS Script, the actor who is packing the payload would have to have all these random files in their possession on their hard drive.

The loader is the same: All the loaders across analyzed NSIS installers are the same, not in terms of their hash value but in terms of their functionality.

  •  All initial loaders have just one export, which is called by the NSIS installer
  •  The Initial Loader reads from Encrypted Data in order to decrypt a shellcode which loads the Loader 2.
  •  Loader 2 across all samples extracts and decrypts shellcode 3 from Encrypted Data.
  • Shellcode 3, responsible for decrypting the final payload and injecting it into a remote process, is binary-equal between all analyzed samples.

However, each NSIS installer we looked at dropped different malware payloads. We considered two possible scenarios: either the malicious NSIS package is a generic packer sold on dark forums; or, the same threat actor is using a custom loader to deploy different payloads in a variety of their attacks.

While there are many packers sold in dark forums, we found this scenario unlikely, as one should expect the junk files to change along with the payloads, if different actors were using the same generic packer. So, we continued our investigation with the hypothesis the attacks come from the same actor.

Given the evidence we have in hand, we can’t prove that a single actor was responsible for all of them, but we at least knew from the identical packing strategy and artifacts that we could find a way to connect all of them. We performed further analysis in search of a definitive link, turning to the infection chain that delivered them.

Based on Sophos telemetry, we found a set of NSIS installers dropping these same junk files as part of an email campaign seen between December 8 and December 13, 2019. (We later designated this wave Campaign 3, after discovering other sets of NSIS installers, discussed later.) In the email attacks we observed, the targets appeared to all be critical infrastructure providers (or businesses related to critical infrastructure). We analyzed the observed attacks using VirusTotal’s graphing feature, gathering open-source information about other victims.

The graph above shows the infection chain for some of the analyzed NSIS installers. It reveals two common patterns used to infect a victim:

Superimposing the distinct infection chains over the graph shows that both chains were used for the same target company revealed by VT data. It is likely the same approach is taken for any targeted company.

We were able to retrieve some of the emails associated with this campaign from VT. With these emails, we were able to identify some of the installers’ targets.


One of the Campaign 3 emails, presenting the installer as a “banking confirmation.”

Many of the the emails we found in VirusTotal data did not show recipients’ addresses, or the “To” address was filled with the same email address that appeared in the “From” field. In these cases, we analyzed the email headers—since the headers hold more information related to the email, like the original recipients.

During the analysis of the NSIS installers we found with identical junk files to our initial sample, we identified at least 5 different malware families used as final payload—all of them InfoStealer or RAT malware:

  • ForeIT/Lokibot
  • BetaBot
  • Formbook
  • AgentTesla
  • Netwire

We then looked at the Command and Control (C&C) infrastructure used for these payloads, to check for any relationship between them and to see if the C&Cs were used to send the stolen data points to same or similar servers.

These are some of the families identified in this campaign and their C&Cs:

Info Stealer Betabot
Info Stealer Formbook
Info Stealer Lokibot
RAT Netwire
RAT AgentTesla

Almost all of the malware samples of each type connected to the campaign share the same C&C. And in some cases, even different families—such as Lokibot and Betabot—share same domain for their C&C.

Identifying more campaigns

Following this pattern—looking for other groups of NSIS installers which drop identical junk files during the same range of dates—we were able to identify 5 distinct NSIS campaigns that took place between November 16, 2019 and January 8, 2020. While the junk files for each of these campaigns were different from our first samples, their behavior was identical (or at least similar) to those observed in Campaign 3.

Campaign 1 2019-11-16/2019-11-20
Campaign 2 2019-11-25/2019-11-26
Campaign 3 2019-12-08/2019-12-13
Campaign 4 2019-12-20/2019-12-31
Campaign 5 2020-01-03/2020-01-08


Campaign 1 (November 16-20, 2019)

These are the dropped junk files for all NSIS installers that belong to Campaign 1:

Output of 7z after list the files contained on a sample that belongs to campaign 1

These are some of the payloads identified for Campaign 1 on a first triage of the installers.

Info Stealer Betabot
Info Stealer Lokibot
Info Stealer Formbook
RAT Netwire

Here is a sample of the emails we collected from VirusTotal connected to Campaign 1:

Used emails on Campaign 1

The following graph shows the relation and infection chain for campaign 1 (based on available data on VT)


Campaign 2 (November 25, 2019 to November 26, 2019)

These are the dropped junk files for all NSIS installers that belong to campaign 2:

Output of 7z after list the files contained on a sample that belongs to campaign 2

Some of the payloads identified for campaign 2 on a first triage included the following:

Info Stealer Betabot
Info Stealer Formbook
RAT Bladabindi
RAT Blackrat
RAT Remcos

We found no emails for this campaign, so we were unable to map its intended targets. The graph below shows the relationship between the similar payloads.

Data from VirusTotal

Campaign 4 (December 20, 2019 to December 31, 2019)

These are the dropped junk files for all NSIS installers that belong to campaign 4:


Some of the payloads observed associated with campaign 4 included:

Info Stealer Betabot
Info Stealer Lokibot
Info Stealer Formbook
RAT Netwire
RAT AgentTesla


Emails collected from VirusTotal tied to campaign 4.


Campaign 5 (January 3, 2020 to January 8, 2020)

These are the dropped junk files for all NSIS installers that belong to campaign 5:

Output of 7z after list the files contained on a sample that belongs to campaign 5

Some of the payloads of campaign 5:

Info Stealer Betabot
Info Stealer Lokibot
Info Stealer Formbook
RAT Netwire
RAT AgentTesla

Sample emails we collected tied to campaign 5:

The following graph shows the relation and infection chain for campaign 5 (based on available data on VT)

Profiling the threat actor

Looking across all the campaigns we discovered during this analysis, we saw frequent duplications in C&C infrastructure, as shown in the table summarizing the campaigns below:

1 2019-11-16/2019-11-20 Info Stealer Betabot
Info Stealer Lokibot
Info Stealer Formbook
RAT Netwire
2 2019-11-25/2019-11-26 Info Stealer Betabot
Info Stealer Formbook
RAT Bladabindi
RAT Blackrat
RAT Remcos
3 2019-12-08/2019-12-13 Info Stealer Betabot
Info Stealer Formbook
Info Stealer Lokibot
RAT Netwire
RAT AgentTesla
4 2019-12-20/2019-12-31 Info Stealer Betabot
Info Stealer Lokibot
Info Stealer Formbook
RAT Netwire
RAT AgentTesla
5 2020-01-03/2020-01-08 Info Stealer Betabot
Info Stealer Lokibot
Info Stealer Formbook
RAT Netwire
RAT AgentTesla

We also found that some of the different payloads from each campaign (mostly Betabot, Lokibot, AgentTesla and Formbook) shared the same C&C. This suggests that the same actor/group was managing the web panels behind these malware campaigns.

There was also a distinct clustering of the campaign timelines—there was never any overlap between them, suggesting that they were operated serially by the same threat actors (including a sixth campaign we observed, to be covered in our next report):

These campaigns didn’t just share command and control infrastructure across different payloads within the same campaign. Some of the infrastructure was also shared across multiple campaigns, which also suggests the same actor was involved across all of them.

The following tables show some interesting relations between campaigns.

Targeting and motivation

Based on the payloads used by RATicate, it’s clear that the campaigns run by the group are intended to gain access to and control of computers on the targeted companies’ networks. The targets identified from the collected emails sent by these campaigns include:

  • An electrical equipment manufacturer in Romania;
  • A Kuwaiti construction services and engineering company;
  • A Korean internet company;
  • A Korean investment firm;
  • A British building supply manufacturer;
  • A Korean medical news publication;
  • A Korean telecommunications and electrical cable manufacturer;
  • A Swiss publishing equipment manufacturer;
  • A Japanese courier and transportation company.

We know that the targets overlapped on at least two campaigns: Campaign 1 and 2 both targeted the electrical equipment manufacturer. There are likely more targets that were common across multiple campaigns (we looked only at publicly-available data from VirusTotal, and have not explored non-public databases). And many (but not all) of the companies that have been targeted-up are related to critical infrastructure.

We’ve detected one more recent campaign using these NSIS installers (from January 13-16). However, as we’ve continued to research this actor group, we’ve been studying other campaigns that we believe are being run by the the same actor—and we believe that since January, the actor has moved to using other loaders and packers.

One of those campaigns is an email campaign we detected in March that uses the COVID-19 global pandemic as a lure to get victims to open the payload. The most recent detected samples are delivered with a variety of Visual Basic loaders —including the Guloader malware dropper discovered by Proofpoint on December 2019. 

We believe these campaigns are run by the same actor fro a number of reasons:

  •  The email targets the same companies seen in previous campaigns.
  • Some of the detected payloads are Betabot and Lokibot, families observed in previous campaigns.
  • This Betabot’s C&C are similar to observed in these previous campaigns—it uses same domain as Campaign 3 for Betabot (stngpetty[.]ga) and uses a similar path (/~zadmin/{NAME1}/{NAME2}/logout.php).

Based on their behavior, we’re unsure of whether the RATicate group is focused on corporate espionage or is simply acting as a malware-as-a-service provider to other actors. It could simply be that they are dropping malware on targeted companies in order to provide paid access to others, or are using InfoStealer and RAT malware as part of a larger malware distribution effort. We continue to analyze the new attacks and hope to get deeper insight into their motivations.

Anti-sandboxing by dumb luck

During our analysis of the first RATicate sample, we discovered that the Shellcode3 dropped by the installer uses a number of interesting techniques to make it difficult to analyze API calls, as well as a number of anti-debugging tricks to further hinder analysis. But we also found a strange behavior in these samples: if the sample is executed with its SHA256 hash as its filename, the program will crash.

Analyzed sample crashing when the file name size is its SHA256 hash.

This sort of behavior might be seen as an anti-analysis trick. Since sandboxes usually run the samples with their hash as a filename, this technique could avoid the execution of the payload in sandbox environments. But in this case, the behavior is actually because of a bug in the code.

The error occurs during the execution of shellcode 3.

A snippet of shellcode 3’s code as viewed in IDA Pro.

Shellcode3 uses a known technique to get the address of loaded modules (such as libraries and the executable’s image itself) by searching against the LDR_DATA_TABLE_ENTRY data structure within the Windows operating system’s Process Environment Block (PEB). The LDR structure contains information that includes the names and addresses of loaded modules. The shell code checks this structure against hashes of the desired function names, providing a silent way to dynamically resolve the memory address of a function to be called.

Shellcode 3 function to get module base addresses based on LDR_DATA_TABLE, which contains a bug that causes the sample to crash.

This feature is implemented in the code’s get_dll_base_addres_from_ldr_by_hash(dll_hash) function, which is where the crash happens. The function walks through the LDR data structure, hashing the names of loaded modules in order to try to match the hash passed as argument.

The function puts the contents of ldr_data_table->BaseDllName.Buffer into vulnerable_buffer in order to convert the ANSI string to a UNICODE string.

But since the size of the vulnerable_buffer string is 104 and it’s storing a Unicode string, which means its size limit is really just 52 ANSI characters. The consequences of that are if the filename has a length of 53 or more characters, a buffer overflow will occur. To make the program crash, you simply need to give the sample a 57-character-long filename (such as “this_is_57_length_filename_in_order_to_do_a_crash_PoC.exe”).

Once analyzed, we determined this was a programming error, rather than an anti-sandbox technique.

Indicators of Compromise (IOCs)

Hashes for the files associated with the RATicate campaigns can be found on SophosLabs’ GitHub here.


Leave a Reply

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