CRIL recently identified an active malicious campaign utilizing a malicious LNK file as the initial infection vector, delivered within a ZIP archive, potentially through spam emails. This LNK file is cleverly disguised as a PDF, tricking users into thinking they are opening a legitimate document.
Based on the lure document observed in this campaign, CRIL has concluded that the campaign is likely targeting business professionals across the United States.
When executed, the LNK file runs a command via cmd.exe to invoke the legitimate certutil.exe tool on the compromised system. This process decodes and prepares the next-stage payload embedded within the LNK file. The decoded payload is identified as a malicious HTML Application (HTA) file, which is executed using the legitimate mshta.exe utility. Upon execution, the HTA file opens a PDF lure document to trick the victim and simultaneously drops a malicious DLL file embedded within its content. The DLL is then executed using regsvr32.exe.
The DLL functions as a loader, decrypting both the shellcode and another encrypted DLL file from its resource section, and then executing the shellcode. Once the shellcode is executed, it loads the decrypted DLL, which subsequently loads another embedded malicious DLL identified as Ursnif—a notorious banking trojan. Ursnif then establishes a connection to its Command and Control (C&C) server and retrieves additional payloads designed to steal sensitive information from the victim’s machine. The below image shows the infection chain of this campaign.
The ZIP archive contains an LNK file disguised as a PDF. Once extracted, the file appears as “staplesds02_23.pdf,” but it is actually an LNK file with a dual extension (.pdf.lnk) crafted to mislead users into believing it is a legitimate PDF document. When the user opens the disguised LNK file, it triggers cmd.exe and leverages certutil.exe to decode and execute malicious content embedded within the file. The following image shows the command line configured within the malicious LNK file.
Certutil is a Windows command-line utility primarily used for managing certificates. However, it is frequently abused by TAs to decode files encoded in Base64 format. In this case, the malicious LNK file contains Base64-encoded data, enclosed within the “—–BEGIN CERTIFICATE—–” and “—–END CERTIFICATE—–” tags, as shown in the figure below.
The decoded content results in an .hta file (HTML Application), which is saved in the system’s temporary directory (C:\Users\userprofile\AppData\Local\Temp) and executed using mshta.exe. The image below shows the content of the dropped HTA file.
The initial section of the HTA file contains a VBScript designed to retrieve data from a remote server at hxxps://docusign-staples[.]com/api/key via an HTTP GET request. Once a response is received, the script verifies that the HTTP status code is 200 (OK) and that no errors occurred before executing further actions. If an error occurs or the status code is not 200, the script terminates its execution.
Upon receiving the response from the remote server, the VBScript decodes the response body into a readable string. It then extracts the first five characters from the decoded data and compares them to the hardcoded string “QG099.” If the strings do not match, the script terminates execution; otherwise, it continues with further actions.
When the first five characters of the decoded response body match the hardcoded string, the VBScript extracts a portion of the file’s content, starting at byte offset 7956 (1F14h) with a length of 138617 bytes. The image below displays a portion of the extracted content at this offset.
The extracted content, identified as a PDF, is saved in the temporary folder as staplesds.pdf. The script then opens this PDF, presenting it as a lure document to the victims. The figure below shows the lure document.
The Figure below shows another lure document observed in this campaign.
Then, the VBScript disables Windows Defender protection by adding the C:\ drive to the exclusion list through PowerShell commands.
After adding the exclusion path, the VBScript extracts another large chunk of data from the file, starting immediately after the PDF content, and retrieves a block of 1,416,704 bytes. As shown below, this extracted data corresponds to a PE (Portable Executable) file.
The retrieved PE file is then saved as a DLL file named “x.dll” in the temporary location. Additionally, the script pads the newly created DLL file with empty spaces by writing 35 blocks, each containing 10 million space characters.
Finally, the HTA script sets the current working directory to the user’s Desktop and executes a command to use regsvr32, registering the newly created DLL file as a system component.
Upon execution, the DLL calls the ntdll.LdrFindResource API to access a resource named “FAMILY.” This resource contains two encrypted pieces of content, which are stored within the executable, as shown below.
The DLL reads the encrypted contents and decrypts them using a hardcoded key present in the file. The following figure shows the code snippet responsible for decrypting the encoded data.”
The first encrypted content is a shellcode that, when decrypted, is responsible for mapping another PE (Portable Executable) file into memory, as illustrated below.
The second encrypted content is a PE DLL file, which acts as another loader for executing the core module of the Ursnif component. This core component is responsible for establishing a connection to the C&C server and downloading additional Ursnif modules to steal sensitive information from the victim’s machine. The figure below shows the decrypted file, with control being transferred to the shellcode after decryption.
Next, the shellcode copies the hardcoded API strings that are necessary for dynamically resolving the required APIs.
The shellcode then passes the hardcoded checksum “0xBDBF9C13” of the “LdrLoadDll” to a custom function. This function scans the loaded DLLs in memory that have export functions. If an export function is found, it calculates the checksum based on the DLL name, then iterates through the APIs associated with that DLL, calculating the checksum for each API.
It adds the checksum of each API name to the DLL name checksum and compares the result with the hardcoded checksum. If there is a match, the shellcode identifies the corresponding address to dynamically resolve the “LdrLoadDll” function. Similarly, it resolves the “LdrGetProcedureAddressEx” API by passing the checksum “0x5ED941B5.”
After resolving, it uses LdrLoadDll and LdrGetProcedureAddressEx to resolve the following APIs:
The shellcode then uses the VirtualAlloc API to allocate a new memory region. Afterward, it copies the decrypted DLL (previously extracted from the resource section) into this newly allocated memory, excluding the DOS header. To ensure the DLL can be executed properly, the shellcode modifies the memory protection of the allocated space using the VirtualProtect API, as shown below.
Finally, the shellcode calls the RtlAddFunctionTable API to add a dynamic function table to the list of function tables in memory. Afterward, it uses the FlushInstructionCache API to ensure that the changes made to the memory are permanently written and reflected in the processor’s cache. Once the necessary memory modifications are made, it proceeds to execute the loaded DLL by invoking the DllRegisterServer function, which typically registers the DLL with the system and allows its functions to be used for further malicious activities.
The second-stage DLL contains another embedded DLL, which is the core component of the Ursnif malware. This DLL holds encrypted configuration data, including crucial information such as the C&C server address, user agent, bot-details, and more. Upon execution, the second-stage DLL loads the embedded DLL found in the .data section, maps it into memory, and modifies its protection using the VirtualProtect API. It then transfers control to the entry point of the DLL, as illustrated below.
The final DLL file now reads the encrypted configuration details stored in the .bss section, passes it through a decryption loop, and retrieves the C&C server details from the decrypted configuration, as shown below.
The decrypted configuration file also contains additional information, such as the user agent details and the structure used for communication with the C&C server, as shown below.
After decrypting the configuration file, the malware calculates a checksum based on the creation time of pagefile.sys or hiberfil.sys present on the system. It then generates a checksum of the victim’s username. To ensure that only one instance of the malware is running at any given time, it creates a mutex named “Global\DbEls,” as shown below.
After creating the mutex, the malware uses GetCurrentThreadId, OpenThread, and QueueUserAPC APIs to launch a new thread. This new thread is responsible for handling communication with the C&C server.
The malware constructs a specific format for its C&C communication, which is shown in the figure below. This structure is designed to facilitate the exchange of data between the infected machine and the C&C server.
Filed | Description |
version | Bot Version |
user | Checksum calculated previously based on the victim’s username |
group | Bot ID |
System | Checksum created based on the creation time of pagefile.sys or hiberfil.sys |
file | Checksum of the filename |
arc | File architecture |
crc | File checksum |
size | File size |
The malware then prepends a random string “emst=urxll&” to the created format, as shown below.
The malware then utilizes the following APIs to encrypt the format it generated for its C&C communication, using AES encryption:
After encryption, the malware invokes the CryptStringToBinaryA API to convert the encrypted content into a BASE64-encoded format, as shown below.
Finally, the malware generates a boundary and uses the following boundary and User-Agent string to communicate with its C&C server at “budalixt.top/index.html.” In this instance, the malware utilizes an outdated User-Agent for its communication, as shown below.
In the next stage, the malware receives a response from the C&C server, which is intended to download and execute additional malware to carry out malicious activities. Unfortunately, we were unable to retrieve any response from the C&C server as it was down, preventing us from fully analyzing the next stage of the attack.
The Ursnif malware campaign exemplifies the growing sophistication in cyber threats. By utilizing advanced techniques such as dynamic API resolution, encrypted payloads, and memory manipulation, Ursnif successfully evades detection and establishes secure communication with its C&C server. Each stage of the malware’s execution, from initial resource loading to the final encrypted C&C communication, is designed to ensure persistence, data exfiltration, and the ability to adapt to changing environments.
Yara rule to detect the latest ursnif loader, available for download from the Github repository.
Tactic | Technique | Procedure |
Initial Access (TA0001) | Phishing (T1566) | This campaign is likely to reach users through spam emails |
Execution (TA0002) | Command and Scripting Interpreter: Windows Command Shell (T1059.003) | Executes Certutil,exe to decode the next stage payloads |
Defense Evasion (TA0005) | Masquerading: Masquerade File Type (T1036.003) | The .lnk file is named to appear as a PDF file to deceive users. |
Defense Evasion (TA0005) | System Binary Proxy Execution: Mshta (T1218.005) | Abuse mshta.exe to proxy execution of malicious hta file |
Defense Evasion (TA0005) | Deobfuscate/Decode Files or Information (T1140) | Deobfuscate/Decode Files or Information |
Command and Control (TA0011) | Application Layer Protocol: Web Protocols (T1071.001) | sends HTTP POST requests to communicate with its C&C server. |
Exfiltration (TA0010) | Exfiltration Over C2 Channel (T1041) | System information and potentially other data are exfiltrated over the established C&C channel. |
Indicator | Indicator Type | Comments |
fdc240fb8f4a17e6a2b0d26635d8ab613db89135a5d95834c5a888423d2b1c82 | SHA-256 | Zip File |
dd20336df4d95a3da83bcf7ef7dd5d5c89157a41b6db786c1401bf8e8009c8f2 | SHA-256 | Malicious LNK file |
13560a1661d2efa15e58e358f2cdefbacf2537cad493b7d090b5c284e9e58f78 | SHA-256 | HTA file |
hxxps://docusign-staples[.]com/api/key hxxps://betterbusinessbureau-sharefile[.]com/api/key | URL | Remote server |
aea3ffc86ca8e1f9c4f9f45cf337165c7d0593d4643ed9e489efdf4941a8c495 | SHA-256 | DLL file |
budalixt[.]top/index.html | URL | C&C |
11a16f65bc93892eb674e05389f126eb10b8f5502998aa24b5c1984b415f9d18 | SHA-256 | Similar LNK file |
468d7a8c161cb7408037797ea682f4be157be922c5f10a812c6c5932b4553c85 | SHA-256 | Similar ZIP file |
https://www.sonicwall.com/blog/emotet-campaign-with-bloated-file
https://cloud.google.com/blog/topics/threat-intelligence/rm3-ldr4-ursnif-banking-fraud