HP Threat Research Blog Do You Speak Multiple Languages? Malware Does.

August 10, 2023 Category: Threat Research By: Patrick Schläpfer Comments: 0

Do You Speak Multiple Languages? Malware Does.

Over the last few months, we’ve seen a flurry of finance-themed malicious spam campaigns spreading malware through batch scripts (.bat). The campaigns use a wide variety of programming languages to achieve different objectives within the infection chain – from batch scripts, PowerShell, Go, shellcode to .NET. The infection starts with simple batch scripts that download a second stage of malware from the web using PowerShell. The malware is packed twice to evade detection, including by a Go crypter called ShellGo that decrypts and executes shellcode in memory. The shellcode bypasses two Windows security features, decrypting the payload and running it in memory. The payload in the campaign we analyzed below was AsyncRAT, a popular remote access trojan (RAT) developed in .NET. Notably, the malware author used a clever technique to run the RAT in memory through a complex sequence of function calls. These campaigns show how easy it is for threat actors to combine tools to achieve a considerable range of functionality like anti-analysis and anti-detection, even those with few resources. HP Sure Click protects users from this type of attack, and its containment-based approach enabled us to capture the malware execution trace. In this blog we outline HP’s analysis of the attack and we offer possible mitigation approaches for organizations that aren’t protected.

It Begins with a Batch Script

Figure 1 – Threat identified by HP Sure Click

The filenames of the batch scripts were crafted to look like invoices, payment confirmations or similar – a classic phishing lure. In some cases, the threat actor used double file extensions like “.pdf.bat” to trick users into running the scripts. Since Windows File Explorer hides file extensions by default, this simple technique means the user sees the file ending with “.pdf” and might mistake the script for a document.

Figure 2 – Email headers spoofing sender address

The threat actor crafted the emails to make them look like they originated from a legitimate sender by spoofing the sender address. Many email clients display this sender address without scrutiny, which could lead the recipient to open the attachment.

If the user opens the script, it downloads, extracts and runs a payload. Figure 3 shows the download command in the behavioral analysis of a threat within HP Sure Click, our threat containment solution. In this case, we filtered for the PowerShell execution responsible for downloading the payload.

Figure 3 – HP Sure Click behavioral analysis inside a micro-virtual machine

Mitigation opportunities:

  • Block risky file types like script files from being sent to your users as email attachments. Additionally, block risky file types compressed inside archives.
  • Check the Sender Policy Framework (SPF) result in the email’s header to see if the received email was sent from an authorized email server.
  • Consider changing the default file type handler of script files to Notepad. If a user then double clicks a script file, it will open in Notepad without being executed.

A Bloated Binary

The script downloads a ZIP archive, unpacks it and runs an executable (.exe) stored inside. Using binary padding, the threat actor artificially inflated the file to almost 2GB. This method bypasses some on-access malware scanners.

Figure 4 – Archive file containing padded executable

Since the sections of the portable executable (PE) file are still in their original state, we can calculate and restore the correct size of the executable. We do this to make it easier to analyze the file in a dynamic sandbox, debugger and disassembler. The correct size of the executable is the sum of the raw size of all sections and the size of the header.

In [1]: headers = 0x600
In [2]: sections = [0x64c00, 0x72c00, 0x18600, 0x600, 0x1a00, 0x200]
In [3]: headers + sum(sections)
Out[3]: 992768

Figure 5 – The section headers to recover the original file size

The executable’s entropy is high, which indicates the threat actor may have packed the file. Packing is a popular way of evading detection that relies on static signatures. The malware payload is stored encrypted within the binary and is decrypted and loaded when the binary runs.

The ShellGo Crypter

Our static analysis of the program suggests that it is partly written in Go. Since most Go programs are statically linked, they include all their dependencies, producing larger binaries than when dynamically linked. This makes analyzing and reverse engineering such malware more complex. However, here the threat actor only wrote the first part of the malware in Go: a crypter named ShellGo.

Figure 6 – String extracted from Go module information

Analyzing the malware using a debugger can be time consuming as lots of library code must run before reaching the main function. To speed up our analysis, we can locate the main function using static analysis tools. In this case, we used GoReSym, a symbol parser for Go that extracts useful program metadata. This way, we identify the address of the user code and the main function. Figure 7 shows the addresses and the names of the user functions:

Figure 7 – User function information extracted using GoReSym

The start address corresponds to the Virtual Address (VA) in decimal format. To find the correct address of the “Main” function within the binary when loaded in the debugger, we must calculate the Relative Virtual Address (RVA). We then add this to the Base Address of the loaded image and get the address of the “Main” function. To jump directly to the user code, we set a breakpoint at this address and let the program run up to this point.

Figure 8 – Breakpoint set on the main function

Since we assume the Go program is a packer, we set a few more breakpoints on memory-related Windows API functions commonly used by malware, such as VirtualAlloc and RtlMoveMemory.

ShellGo uses these two functions to copy encrypted data from the “.data” section into a newly allocated memory region. It then decodes this data in a loop with a simple add instruction. The result of this procedure is executable shellcode.

Figure 9 – Decrypted shellcode in debugger

Shellcode can run using different Windows API functions. Often a function is chosen which takes the address of a callback function as an argument. In this case, ShellGo uses the EnumPageFilesW function and passes the address of the shellcode as a callback function. Once the callback function is triggered, the shellcode runs.

The Shellcode Packer

The shellcode now loads various Windows dynamic-link libraries (DLLs) and resolves its desired API functions. The malware uses the well-known Windows API hashing anti-analysis technique to make analysis more difficult. The desired API functions are resolved based on hashes stored in the malware. Moreover, to evade detection, the shellcode disables Windows security features: the Anti-malware Scan Interface (AMSI) and Windows Lockdown Policy (WLDP).

In the first step, the shellcode loads the AMSI DLL. The shellcode then resolves the functions AmsiScanBuffer and AsmiScanString, changes the Page Protection to Read-Write-Execute using VirtualProtect and overwrites the function with code from the shellcode. Finally, the shellcode sets the Page Protection back to Read-Execute. With this method, the malware prevents buffers and strings from being scanned for malware using AMSI, an interface used by many anti-virus programs. The shellcode uses same method for disabling the WLDP DLL. In this case, the WldpQueryDynamicCodeTrust and WldpIsClassInApprovedList functions are overwritten and thus disarmed.

With these security features bypassed, the shellcode decrypts more encrypted data. Among them is a PE file that is the malware payload.

Figure 10 – PE payload in memory

The payload is a .NET binary, so it cannot run directly in memory without relying on .NET dependencies. The malware author overcomes this challenge by cleverly executing the payload through a complex sequence of function calls to mscoreei.dll and clr.dll. Since the malware runs in memory and is not saved to disk, the attack creates less “noise”, increasing the chance of remaining undetected by security tools that rely on detection. Below is a description of the sequence of function calls the malware uses to execute the .NET payload in memory:

Figure 11 – Sequence of functions to execute the .NET payload in memory

.NET Payload

The payload of the malware is practically not obfuscated. Perhaps the threat actor assumed two packers would be sufficient to evade detection. Next, we extract the PE file from memory for further analysis and save it to disk. Since .NET is an intermediate language, some form of the code is recoverable using publicly available decompilers.

Figure 12 – Decompiled main function of AsyncRAT payload

In this case, the threat actor deployed AsyncRAT, a popular open-source remote access trojan with keylogging and stealer functionalities. When the malware launches, it loads the configurations for this specific sample. Since the decompiler did an excellent job recovering the code, we can easily debug it, set breakpoints and extract the malware’s most important configuration variables. Interestingly, the IP address configured as the command and control (C2) server (45.81.243[.]217) matches the same address the threat actor used to send the malicious emails.

Figure 13 – Configuration extracted from AsyncRAT

Conclusion

These campaigns show an intriguing interaction of programming languages used at different stages of the infection chain. The infection starts with simple batch scripts that download additional malware from the web using PowerShell. The malware is packed twice to evade detection. One of the packers, ShellGo, was written in Go and decrypts and executes shellcode in memory. The shellcode disarms AMSI and WLDP security features in Windows, decrypts the AsyncRAT payload and runs it in memory.

Based on the threat actor’s tooling and configuration choices, namely using a freely available RAT and using one server for sending spam and for C2, we think the threat actor represents low capability and resources. The components the threat actor used to evade detection, such as the two packers, are probably commodity tools available within the cyber underground. Despite this, the campaigns show how attackers can easily combine tools to achieve a considerable range of functionality like anti-analysis and anti-detection. The variety of programming languages used in the infection chain makes the analysis somewhat more complex since the analyst needs to understand how each language works or spend time acquiring this knowledge. Fortunately, the security community is an excellent resource for network defenders, offering support through public reporting, sharing within trust groups and publishing open-source analysis tools.

2023-08-10T15:51:32+01:00August 10th, 2023|Threat Research|