Summary
The malware extracts configuration information about the machine that it infects using the systeminfo command, and then it retrieves the list of processes by spawning a tasklist process. The content of the following directories, along with the processes’ output, is base64-encoded and exfiltrated to the C2 server updaterweb[.]com:
- Desktop folder
- C:\Program Files
- C:\Program Files (x86)
- C:\Users\<User>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Administrative Tools
- C:\Users\<User>\AppData\Roaming
- C:\Users\<User>\AppData\Roaming\Microsoft\Windows\Templates
- C:\WINDOWS
- C:\Users\<User>\AppData\Local\Temp
The user agent used during the network communication is set to “Opera”, and the following is the structure of the POST request: “id=<hostname>#Username#<Serial number in decimal>¤t=1&total=1&data=<data to be exfiltrated>”. The “cmd=y” command is used to download a DLL file from the C2 server, which is loaded using the LoadLibraryW API, and the first ordinal function is executed.
Analyst: @GeeksCyber
Technical analysis
SHA256: ae0bc3358fef0ca2a103e694aa556f55a3fed4e98ba57d16f5ae7ad4ad583698
The DLL has 2 exports (DllEntryPoint and RunMod). We have used rundll32.exe to run the DLL by calling the RunMod function:
The malware creates an unnamed event object by calling the CreateEventW API:
Two new threads are created by the process using the CreateThread function:
The GetMessage routine is utilized to retrieve a message from the thread’s message queue:
The malicious process enumerates all the messages, and it breaks the loop if the message is equal to 0x16 (WM_ENDSESSION – inform the application whether the session is ending):
Thread activity – StartAddress function
The malware creates an anonymous pipe using the CreatePipe API:
GetStartupInfoA is used to retrieve the content of the STARTUPINFO structure from when the calling process was created:
The binary creates a new process that runs the systeminfo command, which displays configuration information about the computer and its OS:
The pipe created earlier is used as an inter-process communication mechanism. The output of the systeminfo command is read via a ReadFile function call:
The list of processes is retrieved by creating a new process that runs the tasklist command:
The output of the tasklist command is transmitted to the main process using the ReadFile API:
The binary gets the path of the Desktop folder using the SHGetFolderPathW routine:
The process enumerates the files/directories from the Desktop directory using the FindFirstFileW and FindNextFileW functions:
The binary adds 18 characters of “#” before and after the folder name, as following:
The list of files and directories extracted before is concatenated with the above string, as shown in figure 19:
The following directories are also targeted by the backdoor: “C:\Program Files”, “C:\Program Files (x86)”, “C:\Users\<User>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Administrative Tools”, “C:\Users\<User>\AppData\Roaming”, “C:\Users\<User>\AppData\Roaming\Microsoft\Windows\Templates”, “C:\WINDOWS” and “C:\Users\<User>\AppData\Local\Temp”. The SHGetFolderPathW function is utilized to obtain some of these folder names (0x2a = CSIDL_PROGRAM_FILESX86, 0x30 = CSIDL_ADMINTOOLS, 0x1a = CSIDL_APPDATA, 0x15 = CSIDL_TEMPLATES and 0x24 = CSIDL_WINDOWS):
The GetTempPathW API is utilized to retrieve the path of the %TEMP% directory:
The file initializes the use of the WinINet functions using the InternetOpenW API (the user agent is hard-coded as “Opera”):
The send and receive timeouts are set to 600 seconds using the InternetSetOptionW routine (0x6 = INTERNET_OPTION_CONTROL_RECEIVE_TIMEOUT and 0x5 = INTERNET_OPTION_CONTROL_SEND_TIMEOUT):
The malicious process establishes a connection to the C2 server updaterweb[.]com on port 443:
The NetBIOS name of the local computer is retrieved using the GetComputerNameA API:
GetUserNameA is utilized to extract the name of the user associated with the current thread:
The malware extracts the volume serial number of the root of the current directory via a function call to GetVolumeInformationW:
The process decrypts some important strings using the XOR algorithm, the keys being “CEJ&V%$84k839y92m” and “qpzoamxiendufbtbf3-#$*40fvnpwOPDwdkvn”. The strings “id=%s#%s#%u&cmd=y” and “id=%s#%s#%u¤t=%s&total=%s&data=” have been computed:
The output of the systeminfo command + output of the tasklist command + the list of targeted directories and their content are base-64 encoded using the CryptBinaryToStringA API (0x1 = CRYPT_STRING_BASE64):
The HttpOpenRequestW routine is utilized to create an HTTP POST request handle:
The malware adds one HTTP request header (“application/x-www-form-urlencoded”) to the HTTP request handle:
The request is sent to the HTTP server using the HttpSendRequestExW API, as displayed in figure 39:
In the case of failing to connect to the C2 server on port 443, the process tries to connect on port 80:
The information extracted before is exfiltrated to the C2 server (id=<hostname>#Username#<Serial number in decimal>¤t=1&total=1&data=<base-64 encoded data computed above>):
The thread sets the event created earlier to the signaled state:
Thread activity – sub_6BD71960 function
This thread sets the event created earlier now to the nonsignaled state using the ResetEvent routine:
There is a similar workflow starting with calling the InternetOpenW function up until connecting to the C2 server on port 443 (or port 80 if the first one is unsuccessful). The POST request is different this time because it contains the “cmd=y” command that is used to download a DLL file:
The malware queries the server to determine the amount of data available using the InternetQueryDataAvailable routine:
The potential DLL file is read from the handle using the InternetReadFile API (the first 4 bytes would represent the data size and there will also be 32 bytes that represent the SHA256 hash value of the content, as we’ll describe in the upcoming paragraphs):
The expected DLL is base64-encoded because the process tries to decode it using the CryptStringToBinaryA function (0x1 = CRYPT_STRING_BASE64):
CryptAcquireContextA is utilized to acquire a handle to the Microsoft RSA and AES Cryptographic Provider (0x18 = PROV_RSA_AES):
The CryptCreateHash routine is used to create a handle to a CSP (cryptographic service provider) hash object (0x800c = CALG_SHA_256):
After the base64-encoded DLL file is decoded, then the malware hashes the buffer that is supposed to contain a DLL file using the SHA256 algorithm:
The hash value is extracted by calling the CryptGetHashParam API, as shown in figure 52 (0x2 = HP_HASHVAL):
The malicious process verifies if the hash value computed above coincides with a 32-byte buffer that comes with the DLL file (of course that the response is emulated in our case, but we can adjust it to pass the comparison):
GetTempPathW is utilized to retrieve the path of the %TEMP% directory:
The malicious process creates a file called fvjoik.dll in the %TEMP% directory, as shown below:
The newly created file is populated with the potential DLL downloaded from the C2 server:
The DLL file is loaded into the address space of the current process using the LoadLibraryW routine:
The malware will execute the exported function with ordinal 1, as highlighted in the next figure:
After the function finishes, there is a call to WinExec that deletes the DLL file created earlier:
The process communicates again with the C2 server, and we believe that it transmits the result of the DLL execution (we won’t go into too much details here because it’s pretty much the same activity described so far). The parameters of the request are again as follows: “id=<hostname>#Username#<Serial number in decimal>¤t=1&total=1&data=<data to be transmitted>”.
Main thread activity
The main thread sets the event created before to the signaled state:
The malware retrieves the termination status of the 2 threads using the GetExitCodeThread API:
References
MSDN: https://docs.microsoft.com/en-us/windows/win32/api/
Fakenet: https://github.com/fireeye/flare-fakenet-ng
Cluster25: https://cluster25.io/wp-content/uploads/2021/05/2021-05_FancyBear.pdf
INDICATORS OF COMPROMISE
C2 server: updaterweb[.]com
SHA256: ae0bc3358fef0ca2a103e694aa556f55a3fed4e98ba57d16f5ae7ad4ad583698
User-Agent: Opera