Malware Analysis
Malware Analysis
When we perform static analysis on the malware, we can observe that it includes an export function named “installer,” which indicates it may be responsible for installing the malicious software.
By searching the hash of the malware in some threat intelligence sources below, we can gain some insights into its behavior.
During the static analysis process, we carefully examine various string values found within the malware. We take note of any strings that appear suspicious or seem to be potentially related to the malicious activity. These identified strings can be valuable and utilized in subsequent stages of our analysis to gain a deeper understanding of the malware’s behavior and functionality.
The presence of strings such as wsock32.dll and send suggests that this malware is likely to use sockets for communication with a Command and Control server. Since the send function is not listed in the Imports and wsock32.dll is not among the imported libraries, it is probable that the malware will dynamically resolve and import this function during its execution.
When the malware is executed, it has been observed to copy itself into the System32 directory under the name spoolvxxx32.dll.
When examining the command line outputs after the malware is executed, it becomes evident that the malicious DLL file is triggered by the “installer” function using the rundll command. This observation indicates that the rundll command is used to initiate the malware’s activities, specifically calling the “installer” function within the DLL file. This step is crucial in understanding how the malware begins its execution process.
With static analysis and the Autoruns tool, we can identify the added or modified registry keys. The registry key shown below has been used to achieve persistence on the systems.
The AppInit_DLLs registry key has been used to achieve persistence on the systems.Proceeding to Basic Dynamic Analysis and running the malware using rundll32.exe, we observe, as anticipated from the string analysis, that the malware gains persistence through the AppInit_DLLs registry key. This method ensures that the DLL is loaded by every process that loads User32.dll, a very common occurrence.
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Windows\AppInit_DLLs : “spoolvxx32.dll”
This is how the malware establishes persistence, utilizing the AppInit_DLLs registry key. By doing this, the DLL gets loaded by any process that loads User32.dll. Now, let’s examine the DLL Main to understand what occurs when it is loaded by another process.
When using IDA Pro’s flow visualization, we can focus our analysis on the most frequently called function in the DLL main.
The malicious DLL file operates within these executable files.
The DLL file calls the following subroutines.
–> sub_100013BD –> sub_100012A3 –> sub_10001499
GetModuleHandleA is a function that is part of the Windows API, used to retrieve a handle to the specified module (DLL or EXE file).GetModuleHandleA retrieves a handle to a loaded module without loading it if it is not already loaded. It is typically used to obtain a handle to another module within an application or library. For example, it can be used within a DLL to access another DLL.
Example of usageGetModuleHandleA:
#include
int main() {
1
2
3
4
5
6
7
8
9
HMODULE hModule = GetModuleHandleA("kernel32.dll");
if (hModule != NULL) {
printf("Module handle: %p\n", hModule);
} else {
printf("Failed to get module handle. Error: %lu\n", GetLastError());
}
return 0; }
LoadLibraryA loads the specified DLL into memory and returns a handle to the loaded module. This function is useful when an application needs to load a DLL at runtime. Once loaded, the handle obtained with this function can be used with GetProcAddress to access functions within the DLL. When the module is no longer needed, FreeLibrary should be called to release it.
#include
int main() {
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
HMODULE hModule = LoadLibraryA("user32.dll");
if (hModule != NULL) {
printf("DLL loaded successfully. Module handle: %p\n", hModule);
FARPROC pMessageBoxA = GetProcAddress(hModule, "MessageBoxA");
if (pMessageBoxA != NULL) {
printf("Address of MessageBoxA: %p\n", pMessageBoxA);
} else {
printf("Failed to get the address of MessageBoxA. Error: %lu\n", GetLastError());
}
FreeLibrary(hModule);
} else {
printf("Failed to load DLL. Error: %lu\n", GetLastError());
}
return 0; }
GetProcAddress allows you to get the address of a function or variable in a DLL, enabling you to call the function or access the variable dynamically. This is particularly useful for creating flexible and extensible applications where the specific functions to be used may not be known until runtime.
#include
typedef int (WINAPI *MESSAGEBOXA)(HWND, LPCSTR, LPCSTR, UINT);
int main() {
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
HMODULE hModule = LoadLibraryA("user32.dll");
if (hModule != NULL) {
printf("DLL loaded successfully. Module handle: %p\n", hModule);
MESSAGEBOXA pMessageBoxA = (MESSAGEBOXA)GetProcAddress(hModule, "MessageBoxA");
if (pMessageBoxA != NULL) {
printf("Address of MessageBoxA: %p\n", pMessageBoxA);
pMessageBoxA(NULL, "Hello, world!", "MessageBoxA", MB_OK);
} else {
printf("Failed to get the address of MessageBoxA. Error: %lu\n", GetLastError());
}
FreeLibrary(hModule);
} else {
printf("Failed to load DLL. Error: %lu\n", GetLastError());
}
return 0; }
From this, it seems that the program employs inline hooking through this DLL as a type of user-space rootkit. The hooking code appears to be mainly set up within ‘sub_10001203’.
Since the file is encrypted, it will need to be decrypted later on. The function called after reading the file could potentially be used for decrypting this encrypted file. By setting a breakpoint at the address where the function is called, we can intercept its cleartext version in memory.
By loading the malicious file into OllyDebug program and placing a breakpoint at the memory address where the function is called, we can obtain the encrypted data in cleartext.
Afterwards, during dynamic analysis, if we redirect the traffic from our target machine to the INetSim traffic on our REMnux installed machine, we can view the SMTP traffic passing through as described above.