Recently, Google’s Threat Analysis Group published a blog post about a campaign targeting security researchers, which they attribute to an entity backed by the North Korean government.
Using social engineering the attackers try to convince victims to download and open a Visual Studio Project file.
This file contains commands that are executed during the build process of the project. For example, in Figure 1, the command starts a new Powershell instance that first verifies that the operating system is Windows 10, and then executes the malicious payload using Microsoft’s rundll32, which indicates that the payload is a DLL (dynamic-link library).
Analyzing a DLL in a sandbox can be a challenging task. In contrast to applications that have only one entry point, a DLL can export additional functions besides its entry point. One of the main purposes of a DLL is to share code among applications. Hence, an application can load a DLL into its process memory and use a subset of its exported functions.
The behavior of a malicious DLL can depend on the context in which it was loaded and executed. To trigger the malicious behavior, we need to call the right exports with the right arguments.
Another obstacle for automated dynamic analysis is function arguments. Exported functions may require function arguments. The absence of these can cause errors during the execution that may lead to the crash of the process. In this case, the malicious behavior may not be reached at all even if the right function was called.
This use case reinforces why analysts need the ability to provide custom function arguments to DLLs, so they can trigger and observe the potential malicious behavior. In this Malware Analysis Spotlight, we will take a closer look at the malicious DLL from the campaign targeting security researchers
If we submit the malicious DLL to VMRay Analyzer without customizing the submission options, Analyzer uses heuristics to attempts to reach the malicious behavior.
For each exported function and each guess of arguments, it spawns a new process that loads the DLL and calls the function accordingly (Figure 2).
We refer to this approach as VMRay Fuzzer. As mentioned before, calling a function without knowing its calling conditions including its dependencies can lead to a crash. The breakdown into several processes has the advantage that if one process crashes, the behavior of the remaining processes are still monitored.
In we can see that at least one process has crashed during the analysis (Figure 3).
The process crash indicates that something went wrong. This means the function was called in an unexpected way.
The crash didn’t happen for all function calls. We want to check what happened in the cases where the function didn’t crash. To check, we will go to the function log.
First, when opening the function log, we search for the exported function CMS_dataFinal
. Next, we see that the function gets resolved with the GetProcAddress
call. The DLL is unloaded right after this call and no suspicious API calls occur.
As a next step, we need to figure out the correct arguments for the function to be called.
Luckily, there is another option that allows us to tweak the calls to exported functions to our needs. We can manually select the exported functions that are called during the analysis and provide arguments for each exported function separately.
By default, all function calls are called in a separate process. This is good because if one of the crashes one the rest of the processes can still work. In certain cases, we want to establish a function call chain within the same process. To allow this we can also select ‘Run in single process’, which executes all of the function calls in the same process.
For this sample, you only need to call one function with two parameters. We can select the function with the correct arguments.
In the wild, the DLL was distributed with a Visual Studio Project file. This file contains the parameters (“Bx9yb37GEcJNK6bt 4901”) that we need to execute the function successfully.
This allows us to resubmit the sample with the expected arguments (Figure 5).
By providing these arguments, we observe more behavior in the new analysis (Figure 6).
The sample drops and executes another DLL (vmnat-update.bin) using rundll32
. This behavior can be easily observed in the sandbox (Figure 7).
It is also notable that the dropped file performs web requests during the analysis, which we have already seen in Figure 6. According to Google’s Threat Analysis Group, these domains are either compromised or owned by the attackers.
Now that we have the secondary DLL, we are able to perform a deeper investigation focusing on the behavior of the dropped file and the connection to the C&Cs.
In this Malware Analysis Spotlight, we have seen how challenging the analysis of a DLL in a sandbox can be. Without meeting the right calling conditions, the malicious behavior might not be triggered. On the other hand, a complete manual analysis of a DLL without using a sandbox can be a . Given VMRay Analyzer’s capability of customizing the analysis of a DLL, an analyst can reduce this investigation by finding the right calling conditions and let the sandbox handle the rest.
Sample DLL
4c3499f3cc4a4fdc7e67417e055891c78540282dccc57e37a01167dfe351b244