The evolution of GuLoader

Sep 12th 2022
The evolution of GuLoader
MALWARE ANALYSIS SPOTLIGHT FROM VMRAY LABS

Table of Contents

Introduction

In this Spotlight, we take another look at GuLoader. The malware family is active since at least 2020. It gained some attention because of its evasion techniques and abusing legitimate and popular cloud services to host its malicious payloads. The downloader is commonly used to deliver other malware families such as FormBook, XLoader, and Lokibot. After we took a closer look at GuLoader’s evasion techniques in a Threat Bulletin, we observed some additional behavior later that year.

Recently, we collected samples that are different from the samples we have seen before. The file that executes GuLoader’s shellcode has changed, and the functionality of GuLoader has been extended compared to our last Spotlight. The sample in discussion leads to the execution of Lokibot as indicated by the extracted configurations in Figure 1.

Malware sandbox analysis report example
Figure 1: VMRay Analyzer - VTI highlighting GuLoader's behavior and extracted configurations.

GuLoader’s Delivery

The main functionality of GuLoader is implemented as shellcode, and typically an executable takes care of loading the shellcode into memory and transferring the execution flow to it. So far this executable was written in VB6. However, the executable in this analysis is a signed NSIS installer that leads to the execution of GuLoader.

During the installation process, the installer extracts multiple files to the hard disk including a DLL (Dynamic Link Library) named “System.dll”, and a file named “Gestisk.For” (Figure 2.).

Figure 2: VMRay Analyzer - Dropped files

While the name for the DLL seems to be consistent across similar samples, the name of the second file can vary. After writing “System.dll” to the hard disk, it is loaded by the installer and used to call WinAPI functions to allocate memory where the shellcode will end up alter on. 

Previous samples written in VB6 called the WinAPI functions directly instead of using a separate DLL.

GuLoader’s Evolution

At first glance, we can see the typical behavior of GuLoader. It tries to detect an analysis environment and if none was found it injects the shellcode into another process instance of the executable. 

Next, the second instance downloads and executes the payload from the well-known cloud service Google Drive. When comparing the memory dump of the shellcode with memory dumps from older samples, we can see that GuLoader stopped storing the strings in plaintext. Instead, they are decrypted at runtime and stored in a separate memory region (Figure 3.).

Figure 3: Encrypted strings embedded in shellcode (left), and decrypted strings stored in a separate memory region (right).

VMRay Analyzer uses special triggers that allow obtaining the region which contains the decrypted strings.

Moving on to the observed function calls, we can see that the sample utilizes additional WinAPI functions compared to previous ones. Figure 4. lists additional function calls that we discuss next.

RtlAddVectoredExceptionHandler
 
EnumDeviceDrivers
GetDeviceDriverBaseNameA
 
MsiEnumProductsA
MsiGetProductInfoA
 
OpenSCManagerA
EnumServicesStatusA

Figure 4: List of additional WinAPI functions observed in newer samples.

While we have seen calls to functions related to enumerating products and services in previous samples, the registration of a new exception handler and the examination of device drivers have been added recently. This leads to the assumption that GuLoader is still under active development.

Given the function log, we can see that the address of the exception handler is part of the shellcode (Figure 5.).

Figure 5: VMRay Analyzer - Exception handler registration

This exception handler first checks if the exception was raised because of a software breakpoint. Next, the function inspects the CPU registers to detect the presence of hardware breakpoints. In case no breakpoint is set, the handler continues to change the instruction pointer. The new value depends on the current instruction pointer and the byte followed after the int3 instruction that triggered the exception handler (Figure 6). If a hardware breakpoint is set, the handler doesn’t change the instruction pointer, subsequently executing invalid instructions. 

Additionally, the function checks for int3 instructions between the current and the new instruction pointer value.

Figure 6: Exception handler snippet that modifies the instruction pointer.

By registering the exception handler, GuLoader uses int3 instructions as relative jumps. Because debuggers like WinDbg and x64dbg use int3 instructions for software breakpoints, this approach interferes with debugging if the debugger handles these exceptions first.

A deeper look at the function log reveals that multiple WinAPI functions are called from the same address within the shellcode (Figure 7.). This is an indicator that some kind of wrapper function takes care of calling the WinAPI functions.

Figure 7: VMRay Analyzer - Excerpt from flog.xml revealing the same from address is being used multiple times.

In this example, GuLoader uses such a function to partially overwrite its code before calling the actual WinAPI function. Figure 8. shows the part of the wrapper function that overwrites the code by xoring it with the return address before and after the call instruction.

Figure 8: Partially overwriting code before WinAPI function calls.

By overwriting code before the calls, GuLoader avoids being extracted correctly by analysis tools that use WinAPI functions as memory dump trigger.

Looking at the list of called functions, we can see that GuLoader gathers information about the

  • name of installed drivers EnumDeviceDrivers and GetDeviceDriverBaseNameA)
  • publisher of installed products (MsiEnumProductsA and MsiGetProductInfoA)
  • services in the SERVICES_ACTIVE_DATABASE

The resulting strings are then hashed using a customized djb2 algorithm and compared against a block list of pre-computed values of analysis environment artifacts.

Device names:
    0x0A4F1B4F0
    0x0D277D8C6
    0x06E5A1CF8
    0x0966FE6F7
    0x0EC7C85F9

Product publisher:
    0x07630654D
    0x0A80331E9
    0x0F8727F49
    0x060FAFADD

Services:
    0x0C749257D
    0x0CC359518
    0x0C55733D2
    0x0A0F0EF16
    0x0BA252FC4
    0x02DC0E42A
    0x077C8F76A

Figure 9: Blocklist of pre-computed values of analysis environment artifacts

If the calculated value is present in the block list, GuLoader stops its execution and therefore evades the analysis.

This technique was used earlier with the original djb2 algorithm. In this particular sample, the djb2 algorithm is customized in a way that the hash is xored with the key 0x0C93EB2D8 in each iteration (Figure 9.)

def djb2_custom(s: bytes) -> int:
    hash = 5381
    for in s:
        hash = ((hash << 5+ hash) + x
        hash = (hash ^ 0x0C93EB2D8) & 0xFFFFFFFF
    return hash

Figure 10: Customized djb2 algorithm in Python

In general, values of the block list are indicators analysts can take advantage of for detection and identification as long as the algorithm remains the same across samples. GuLoader prevents this by slightly changing the algorithm.

Finally, GuLoader creates another process of the installer, injects code, and delivers the payload. In this case, the payload is Lokibot and hosted on Google Drive.

VMRay Analyzer extracts the malware configuration for both malware families, which eases the detection and identification of infected systems.

Extracted Payload URLs

In addition to Google Drive being abused to host the malicious payload, we have seen other services in our extracted configurations.

Figure 10. shows the distribution of hostnames. While Google Drive remains the most common one, other cloud services like Microsoft OneDrive are used a well.

Figure 11: Distribution of host names

Conclusion

In this post, we took another look at GuLoader with a focus on behavioral differences compared to past samples. We have seen that not only the executable, which leads to GuLoader’s shellcode has been changed but also its functionality has been further extended.

While GuLoader utilizes new techniques to search for artifacts revealing an analysis environment, some of the existing logic changed to further thwart detection and analysis attempts. Given VMRay Analyzer’s unique monitoring approach, GuLoader can’t detect the presence of the sandbox and reveal its malicious behavior leading to the delivery of Lokibot. The extracted malware configuration for both families allows analysts and incident responders to quickly take actions to prevent the infection and identify already compromised machines.

IOCs

Initial Sample:

e7ee8ff4872d57b2fba736ee6556e3f92a3fc1c3c8738c50cc8b1e6acbb4379f

GuLoader Payload URL:

hxxps://drive[.]google[.]com/uc?export=download&id=1SrbfkJ9_Bx7Q9qhzb5JeLy5TlBRjWwjF

Lokibot C&Cs:

alphastand[.]trade/alien/fre.php

alphastand[.]top/alien/fre.php

alphastand[.]win/alien/fre.php

kbfvzoboss[.]bid/alien/fre.php

hxxp://198[.]187[.]30[.]47/p.php?id=67243588715181780

Pascal Brackmann

Pascal is a Threat Researcher at VMRay Labs. His recent projects cover in-depth analysis of emerging and evolving malware.

Subscribe

Stay current on the threat landscape with industry-leading insights.

See Analyzer in action.
Solve your own challenges.

Calculate how much malware false positives are costing your organization:
Malware False Positive Cost Calculator