Malware

Weaponization of Excel Add-Ins Part 2: Dridex Infection Chain Case Studies

Clock Icon 8 min read

This post is also available in: 日本語 (Japanese)

Executive Summary

In Part 1 of this two-part blog series, we discussed briefly how XLL files are exploited to deploy Agent Tesla. During December 2021, we continued to observe Dridex and Agent Tesla exploiting XLL in different ways for initial payload delivery. A more in-depth look at the Dridex infection chain follows.

Threat actors behind Dridex have been using various delivery mechanisms over the years. In early 2017, we observed plain VBScript and JavaScript were being used. In later years, we observed many variations, including Microsoft Office files (DOC, XLS) compressed in zip. In 2020, we found the malware using Discord and other legitimate services to download the final payload. More recently, during December 2021, we received various Dridex samples, which were exploiting XLL and XLM 4.0 in combination with Discord and OneDrive to download the final payload.

In our previous blog focused on XLL files and Agent Tesla, we saw the abuse of the legitimate Excel-DNA framework. In this blog post, we will look into other infection chains. We will discuss different stages of the XLL and Excel 4 (XLM) droppers that deliver Dridex samples. We will also briefly look at the Dridex Loader.

Palo Alto Networks customers receive protections against the attacks discussed here through Cortex XDR or the WildFire cloud-delivered security subscription for the Next-Generation Firewall.

Types of Attacks Covered Malware, Dridex
Related Unit 42 Topics Agent Tesla, Macros

XLM Dropper

While XLM 4.0 is not new, there has been a lot of evolution in how malware has abused it since early 2020 Threat actors have gone from using simple, non-obfuscated macro formulas to creating complex hidden variants which finally utilize native services such as rundll32 to run a payload.

As the malicious usage of XLM 4.0 macros is quite new, vendors are striving hard to provide coverage in such cases.

The XLM document in this case comprises two spreadsheets – one contains formulae and the other simply contains some random data. See Figures 1-2 below.

The XLM document comprises two spreadsheet. The one shown here contains formulae. The red 1 indicates the macro 4.0 responsible for dumping an HTML application file. The red 2 at the top of the screenshot shows the output of the highlighted formulae.
Figure 1. The red “1” in the right side of the screenshot shows the macro 4.0 responsible for dumping an HTML application file (HTA). The red “2” at the top shows the output of highlighted formulae.
The red box indicated by the number 1 shows an HTA script stored in ASCII values.
Figure 2. The red box indicated by the number 1 shows an HTA script stored in ASCII values.

It can be seen that one of the formulae in the spreadsheet shown in Figure 1 tries to run with Mshta, so we can assume it is not really an RTF. Upon further analysis, we found that indeed it is an HTA. XLM 4.0 code in Sheet1 is responsible for reading ASCII values from Sheet2 (Figure 2) and generating the HTA file that downloads Dridex from Discord.

VBScript to download Dridex from Discord.
Figure 3. VBScript to download Dridex from Discord.
Encoded Discord URL in HTA file.
Figure 4. Encoded Discord URL in HTA file.

It is difficult to say anything about the XLS itself until it finally downloads a malicious payload. Furthermore, the HTA is being dropped as RTF. This might confuse some security products because they could analyze the HTA as an RTF file and might lose detection. Additionally, the usage of Discord URLs makes the samples more evasive. (Though the examples given here involve Discord URLs, we have also observed similar usage of OneDrive URLs. See the GitHub link in the Indicators of Compromise section for specific examples of OneDrive URLs.)

XLL Dropper

In comparison to the malicious XLL files that we discussed in Part 1 of this blog series, this dropper is rather simple. An XLL file is just a DLL, but it must be executed using Excel. The proper detonation is important for detection.

We extracted around 1,400 URLs from XLM adn XLL files, though at the time of analysis, only a few were still up.
Figure 5. Discord URLs found in XLL.
The screenshot shows, among other things, the commands that run the downloaded payload.
Figure 6. XLL running Dridex Loader.

Active Directory Check

We think that both the XLL and VBScript downloaders are associated with the same actor because, as we can see, both perform a check to see whether the LOGONSERVER and USERDOMAIN environment variables are set. This would mean a system is on Active Directory.

HTA dropper checking for the environment variables LOGONSERVER and USERDOMAIN.
Figure 7. HTA dropper checking for the environment variables LOGONSERVER and USERDOMAIN.
XLL dropper checking for the environment variables LOGONSERVER and USERDOMAIN.
Figure 8. XLL dropper checking for the environment variables LOGONSERVER and USERDOMAIN.

Discord URLs

We extracted around 1,400 URLs (see Indicators of Compromise section at the end of this post) from XLM and XLL files, however, at the time of analysis, only a few of them were still up and were found downloading only Dridex. An interesting thing to note is that DLL files are being downloaded as MKV. We saw that at the start of the infection chain that HTA was being dropped as RTF.

Brief Loader Analysis

As can be seen in Figure 6, the downloaded payload is being run with the command

rundll32.exe * DirSyncScheduleDialog. However, as we opened the file for further analysis, the method DirSyncScheduleDialog is not found in the export directory. It is interesting to note that that function name belongs to a legitimate Windows DLL.

The left side of the screenshot shots the missing method, DirSyncScheduleDialog. The right side shows the legitimate Windows loghours.dll with exported function DirSyncScheduleDialog.
Figure 9. The missing method(left) is shown, compared to the legitimate Windows loghours.dll with exported function DirSyncScheduleDialog (right).

Unpacking Stages

  1. Decrypt and Load second-stage DLL from rdata section.
  2. Second DLL further unpacks the final Dridex Loader.
  3. Jumps to DirSyncScheduleDialog.

First Stage

The first stage is fairly simple in terms of functionality; its only job is to decrypt a small DLL from the rdata section and move it to allocated memory and run it.

However, there are a few anti-analysis tricks.

  1. Usage of junk code.
  2. A Large Loop with INT3 instructions.
  3. Usage of undocumented functions such as ldrgetprocedureaddress and LdrLoadDll to avoid common hooks.

While junk code might hinder manual analysis, large loops containing INT3 breakpoints might delay the execution in some cases.

The first stage has a handful of functions. We renamed them to reflect trivial loader behavior.

enamed functions (left); jump to allocated memory (center); anti-VM function, CC bytes replaced with NOP (right).
Figure 10. Renamed functions (left); jump to allocated memory (center); anti-VM function, CC bytes replaced with NOP (right).

Second Stage

Once the first stage passes control to the in-memory DLL (Figure 8), it further unpacks the final payload and transfers control to it. The second stage is also trivial. However, the stage does include a few interesting anti-analysis tricks to note.

  1. Calls Disablethreadlibrarycalls to increase invisibility of final DLL.
  2. Checks LdrLoadDll for hooks.
Renamed functions (left), check for LdrLoadDll hook (center), disableThreadLibraryCalls in imports (right).
Figure 11. Renamed functions (left), check for LdrLoadDll hook (center), disableThreadLibraryCalls in imports (right).

Final Dridex Loader

Finally, we are able to see a call to DirSyncScheduleDialog. It is interesting to note that Dridex Loader is not performing DLL side loading. However, the final payload is loaded as loghours.dll, a legitimate windows DLL.

The export table from the Dridex Loader is shown on the left, and the one from the legitimate loghours.dll is shown on the right. A red box highlights the particular line to compare side by side, showing DirSyncScheduleDialog.
Figure 12. A side-by-side comparison of the Export table from the Dridex Loader (left) and the legitimate loghours.dll (right).
Dridex Loader EP; anti-VM loop can be noticed in start.
Figure 13. Dridex Loader EP; anti-VM loop can be noticed in start.

Micro VM

Dridex implements a micro VM, which adds an exception handler using AddVectoredExceptionHandler to emulate the call eax instruction.

Call to get_proc_address_by_hash function and CC CC bytes (call eax).
Figure 14. Call to get_proc_address_by_hash function and CC CC bytes (call eax).
As can be seen here, in the case of EXCEPTION_BREAKPOINT, the "call eax" instruction is being emulated.
Figure 15. Exception handler emulating call eax.

As can be seen in Figure 15, in the case of EXCEPTION_BREAKPOINT, the call eax instruction is being emulated. For the sandbox, this should not be a problem; however, it can hinder manual analysis. As can be seen, the exception handler only emulates one instruction. Patching these two INT3 instructions with call eax should not be a big deal. A simple IDA script to patch all CC CC instructions with FF D0 should do the trick.

An IDA script to patch all CC CC instructions with FF D0 can patch the two INT3 instructions, as shown.
Figure 16. Patched INT3 instruction with “call eax”.

API Hashing

API Hashing is trivial, however, we observed a few obfuscations and variations in this Dridex Loader.

  1. Multiple hashing functions.
  2. Masqueraded Prolog for hashing function.

We observed that, in order to hinder analysis further, this Dridex Loader is using multiple hashing functions. We observed at least two hashing functions and one masqueraded Prolog function, as can be seen below.

API hashing function sub_744102D4
Figure 17. API hashing function sub_744102D4
Masqueraded Prolog function used by Dridex Loader to hinder analysis.
Figure 18. Masqueraded Prolog function.

It can be seen that the Prolog of the get_proc_address_1 function is not normal. The registers eax and edx are being used to pass module hash and API hash to the get_proc_address_1_mas function. It is possible to call get_proc_address_1 to set eax and edx. Alternatively, they can be set before calling get_proc_address_1_mas. If a researcher is writing an automation for resolving APIs – such as using AppCall – it is important to watch out for this trick.

We used the IDA AppCall feature to extract all APIs used in the loader. Based on extracted APIs, this Dridex Loader is not different from the Dridex Loader that was observed in early 2021.

Key functions of the Dridex Loader:

  1. Check process privileges.
  2. AdjustToken privileges.
  3. GetSystemInfo
  4. Uses the “Atomic Bombing” injection technique to load core payload downloaded from command and control server.

The Dridex Loader has been extensively analyzed. Here, we focused mainly on small tricks used across the infection chain to avoid detection and slow down analysis.

Conclusion

We observed a continued evolution of the infection chain. We saw how malware authors can evade detection engines using legitimate services such as Discord and OneDrive. We analyzed how malware authors continue to add more stages in the infection chain.

Lastly, we briefly looked into the Dridex payload. Although the final payload was similar to the previous Dridex version in terms of behaviour, we noticed an additional unpacking stage and a couple of new changes in the API hashing function. These simple yet powerful tricks that can be challenging for malware analysts, helping the malware avoid detection and slow down analysis.

Palo Alto Networks customers receive protections against the attacks discussed here through Cortex XDR or the WildFire cloud-delivered security subscription for the Next-Generation Firewall.

If you think you may have been compromised or have an urgent matter, get in touch with the Unit 42 Incident Response team or call:

  • North America Toll-Free: 866.486.4842 (866.4.UNIT42)
  • EMEA: +31.20.299.3130
  • APAC: +65.6983.8730
  • Japan: +81.50.1790.0200

Indicators of Compromise

Indicators of compromise related to the malware discussed here can be found on GitHub.

Enlarged Image