Between August and October 2025, IBM X-Force observed several emails targeting likely Colombian, Spanish-speaking individuals with themes relating to the Attorney General’s office of Colombia. The emails entice the user to download an “official document” from the judicial information system, which starts the infection chain of executing a Hijackloader executable that leads to the PureHVNC Remote Access Trojan (RAT).
Between August and October 2025, X-Force observed several emails targeting users likely residing in Colombia with emails imitating the Attorney General’s office of Colombia with official document downloads. The emails aim to use Hijackloader to deliver several payloads, including PureHVNC. Hijackloader itself has not been widely used in campaigns targeting users within Latin America (LATAM), and previously, there were no observable campaigns by X-Force where LATAM users have been targeted to deliver PureHVNC. In 2024, there are details of Hijackloader being used to load RemcosRAT in campaigns targeting CrowdStrike customers, likely from LATAM countries (based on Spanish filenames and instructions). The delivery of PureHVNC RAT is interesting in that X-Force has not previously observed any campaigns where PureHVNC was delivered to Spanish-speaking users. PureHVNC RAT is part of a set of tools sold by PureCoder. The malicious tools are readily for sale on the dark web on underground forums, as well as on Telegram.
Users are presented with an email purporting to be an official correspondence related to the Attorney General’s office of Colombia. The email states that a lawsuit has been filed by a former employee, and is being processed before the labor courts. Attached to the email is an SVG file, which is opened by the victim in Google Drive. In most instances, the document preview is visible and is ready for download by clicking on the download button. In one instance, the victim was presented with a “Couldn’t preview file” and a download button, which opened the file in Google Drive. In any case, while in Google Drive, clicking anywhere on the document will download a ZIP archive file, and the victim is now presented with a “Download Complete” page containing a password such as “KC4SX87”. The ZIP file contains several additional files, one being an executable file for which the user needs the password in order to execute it if clicked. Clicking on the EXE file will initiate the infection chain, whereby Hijackloader is used to deploy several different payloads, including PureHVNC.
Malware stage 1: DLL side-loading
Hijackloader uses a technique called DLL side-loading, which abuses the search order Windows uses to locate required libraries to execute a malicious DLL. Hijackloader uses a legitimate javaw.exe file that has been renamed with a judiciary-themed name (02 BOLETA FISCAL.exe). Since one of the dependencies of javaw.exe is JLI.dll, Hijackloader places a modified version of JLI.dll in the same directory. When the renamed javaw.exe is launched, the operating system also loads the malicious DLL from the local directory.
The primary function of the malicious JLI.dll is to load the 2nd stage payload, MSTH7EN.dll. It does this by calling the LoadLibraryW() API, which loads MSTH7EN.dll into the process’s address space. The API call returns the image base address of the newly loaded DLL. This address is then added to a specific offset to calculate the entry point of the malicious code in MSTH7EN.dll.
Malware stage 2: Loading phase
The second-stage payload begins with initialization. To avoid detection, it dynamically loads and resolves all necessary libraries and APIs. Once complete, it verifies that the current working directory matches the Hijackloader’s location, ensuring the third-stage payload can be referenced and loaded properly.
The third-stage payload contains an encrypted malware configuration with the following components:
Upon decryption, the malware configuration contains information, such as the following:
The shellcode is then loaded into vssapi.dll, which is the DLL specified in the malware’s configuration. This is done by calling VirtualProtect() to change the memory protection of the DLL’s .text section to PAGE_EXECUTE_READWRITE. Finally, the shellcode is copied to this writable address, and the flow of execution is transferred to it.
The shellcode acts as a loader, but first, it hashes running process names in the system and compares them to the values specified in the malware configuration. If a match is found, the malware uses the NtDelayExecution() API to stall its own execution.
Next, it reads the content of Plagkeg.zk. The content of this file is another encrypted malware configuration and HijackLoader’s modules. The data is split into multiple chunks, with the initial chunk containing the following information:
The subsequent chunks follow this structure:
To assemble these chunks, HijackLoader iterates through the encrypted data searching for the “????IDAT“ pattern, where the question marks act as wildcards. Once a match is found, it checks if the four bytes immediately following the pattern are equal to 0xC6A579EA. This confirms that the initial chunk has been found, which is important because it contains the total size of the shellcode and the decryption key. If the value matches, HijackLoader stores the shellcode bytes into a buffer. The process is repeated for all subsequent chunks, with their shellcode bytes being appended to the same buffer, until no more matching patterns are found.
Once done, the buffer containing the encrypted shellcode is decrypted using an XOR cipher and then decompressed using the LZNT1 algorithm. The result is a structure that contains various information, such as the final payload, the module structure, etc.
Malware stage 3: ti64 - main module
HijackLoader’s functionality is divided into modules. Some contain executable code, while others are simply information used for reference. An example of this is the COPYLIST module, which contains the list of filenames related to this variant of HijackLoader. As per Trellix’s report, some variants of HijackLoader support up to 40 modules, but the sample analyzed for this report only supports 35. Not all modules are executed, and their use depends on flags specified in the malware configuration.
The table below summarizes the name of each module and its purpose:
HijackLoader loops through these structures and converts each module name to a hash using a custom algorithm. Once the match for the “ti64” module is found, it calculates a pointer to the module’s code by adding the offset of the data to the base of the module data array. This pointer is then returned and used as a reference to shellcode of “ti64”.
Next, the malware performs another DLL hollowing operation to inject the “ti64” module’s shellcode. The target is a DLL specified in the previously decrypted configuration, which in this case is pla.dll.
Module Name | Hash | Purpose |
AVDATA | 0x78B783CA | Contains hashes of security product-related processes |
ESAL | 0x757C9405 | Cleans the in-memory data of hijackloader and executes the final payload |
ESLDR | 0xE7794E15 | Used to inject and execute shellcode related to HijackLoader |
ESWR | 0x93EB1CB1 | Clears out the shellcode data and executes the rshell module |
FIXED | 0x699D0C82 | Legitimate PE file used for injecting code into its process |
LauncherLdr64 | 0xF4F141C2 | Decrypts configuration files that are stored on the disk |
modCreateProcess | 0x696F778F | Used to execute a file |
modTask | 0x3115355E | Creates persistence using scheduled task |
modUAC | 0xC64EBFDA | Used for privilege escalation |
modWriteFile | 0xFCE82FC1 | Handles file creation on disk |
rshell rshell64 | 0x74984889 | Executes the final payload |
ti ti64 | 0x3EE477F1 | Serves as the main shellcode that executes all the other modules |
TinyCallProxy | 0x455CBBC3 | Acts as a proxy to execute API calls |
tinystub | 0x4EACE798 | Contains dummy executable file, which is used for patching during the final payload execution process |
tinyutilitymodule.dll | 0xA1D724FC | Overwrites the PE headers of a specified file with null bytes |
SM | 0xD8222145 | Contains the name of the system DLL used in call stack spoofing or shellcode injection |
COPYLIST | 0x1AE7700A | A list of files names for copying or deletion |
CUSTOMINJECT | 0x6703F815 | Contains a legitimate executable file which is used for injecting code into its process memory. The process is created in a custom path specified by the CUSTOMINJECTPATH module |
CUSTOMINJECTPATH | 0x192A4446 | Contains a file path used to create the legitimate file in the CUSTOMINJECT module |
X64L | 0xCB5B9F3F | Module that is injected into a process to serve as an injection proxy |
WDUACDATA | 0x4D75088D | Contains the string used for executing commands via cmd |
WDDATA | 0xB718A6AE | Contains a PowerShell command to add a Windows Defender Antivirus exclusion |
PERSDATA | 0xA2E0AB5D | Contains the configuration used by the modTask module to create scheduled tasks |
MUTEX | 0x1999709F | Contains the name of mutex to check |
The modUAC module, similar to the other modules, uses TinycallProxy to call APIs. If the first DWORD of the UACDATA module is 2, it uses the “runas” to elevate its privilege. Otherwise, it uses the CMSTPLUA COM interface to bypass UAC.
In some variants, HijackLoader uses a technique called “stack spoofing“ to mask the origin of API and system calls. It does this by using the base pointer register (EBP) to navigate the stack, following the chain of EBP pointers to retrieve the return address from each stack frame. If a return address is not within the .text section of ntdll.dll or kernelbase.dll, HijackLoader stores it for later. This process is repeated until the stack limit is reached or until three consecutive return addresses are found within those system libraries.
Next, it performs call stack spoofing by overwriting the saved, legitimate return addresses with fake ones. Each fake address is generated by selecting a random export from a DLL specified by the SM module (in this case, dcd9.dll) and adding a random offset, ensuring the final pointer lands within that module’s .text section. Heaven’s Gate is then used to perform the syscall. Immediately after the call completes, the original stack addresses are restored.
More recent variants, however, use a different technique. Instead of stack spoofing, HijackLoader loads the target DLL specified by the SM module via LoadLibraryW(). It then saves the code from a random offset within that DLL to a temporary buffer and replaces it with the TinyCallProxy64 module’s shellcode, which is designed to call the specified API. Once the call is finished, the original, clean code is restored.
HijackLoader uses these techniques for a select number of functions that are likely to be monitored by AV software, such as ZwProtectVirtualMemory and ZwGetContextThread.
Technique | Description |
Time-based anti-debugging check | Uses a timing-based evasion technique by measuring the latency of the cpuid instruction. It wraps the cpuid call with rdtsc instructions inside a loop, and if the execution time exceeds a specified threshold, it detects the presence of a debugger or virtual machine. |
Hypervisor check | Performs a standard anti-VM check by executing the cpuid instruction and checking the “hypervisor bit” (bit 31) in the returned ECX register. If this bit is set to 1, it indicates the presence of a hypervisor. |
Vendor ID check | Performs an anti-VM check by querying the hypervisor information leaf (0x40000000). A return value in EAX that is greater than or equal to 0x40000000 indicates the presence of active hypervisor-specific CPUID leaves. |
Checks total RAM | Performs an anti-sandbox check by querying the total physical RAM. It calls NtQuerySystemInformation to calculate the total memory in gigabytes (by right-shifting the byte count by 30) and terminates if the result is below 4GB. |
Checks number of processors | Performs an anti-sandbox check by querying the number of CPU cores. It calls NtQuerySystemInformation to get the NumberOfProcessors and compares it against the value specified in the configuration of the ANTIVM module. |
Username checking | Compares the current user’s username to the specified value in the ANTIVM module. |
Computer name checking | Checks if the computer name consists of only numbers. |
Checks current working directory | Checks if the current module path is on the desktop. |
A failed anti-virtualization check results in process termination via a call to ZwTerminateProcess().
The unhooking routine compares the .text section of the currently loaded ntdll.dll against a clean, mapped copy. It scans for call (0xE8) and jmp (0xE9) instructions and detects a hook if the instruction type or destination address differs between the two versions. If a hook is found, the malware patches the in-memory ntdll.dll by restoring the original, clean bytes.
HijackLoader’s persistence mechanism is also controlled by its configuration. The behavior is dictated by a flag:
In addition to these flags, HijackLoader can create another persistence mechanism by checking for a PERSDATA module. This module contains the necessary configuration data, such as the task name, to create a second scheduled task.
Injection Type | Description |
If the file to inject is a DLL or injection flags is less than 0x3 | the final payload will be executed under the same process, so the DLL payload will be mapped in the hollowed DLL. |
If the final payload is not a .NET/CLR file, injection flags 0x20 is false and 0x80 is true | Hides the rshell payload in a dummy tinystub PE using a rolled-back NTFS transaction. It then maps this hidden PE into a suspended process (FIXED), where the ESWR module hijacks the main thread’s context to execute the rshell code. |
If the final payload is not a .NET/CLR file, injection flags 0x20 and 0x80 are both false | The FIXED module is dropped to disk and created as a suspended process. The ESWR module is then used to trigger the rshell payload’s execution within the FIXED process. |
The injection flags 0x100 is set to true and 0x20 is false | Injects rshell into a suspended legitimate system executable (e.g., MSBuild.exe) located by parsing the .NET header for the CLR path. The payload is patched in-memory before being executed via thread context hijacking and clears its own PE headers. |
Injection flags 0x4 and 0x80 are both true. | Conditionally drops the FIXED module, then stores the rshell payload in a rolled-back transacted file (tinystub). It injects this into the suspended FIXED process via section mapping. Execution is triggered via thread context hijacking, followed by optionally erases its PE header. |
Injection flags 0x4 is true and 0x80 is false. | HijackLoader launches a suspended process, creates and maps a new memory section directly within it, and then writes the patched rshell module into this section. Execution is triggered by hijacking the main thread’s context to run the rshell code. |
Injection flags 0x4 is false and 0x10 is true. | Performs Process Hollowing by launching its FIXED module, wiping its main memory section, and then copying in the payload. It writes the “MZ” header in two separate calls. Finally, it injects the patched rshell module, modifies the PEB, and optionally erases the payload’s PE header. |
Injection type is set to 4 | Injects the main payload and rshell module via section mapping. A section is created and populated locally with the patched rshell and payload, then mapped into a suspended target process (a system native binary or CUSTOMINJECT module). Execution is triggered by hijacking the main thread’s context to point to the rshell entry point. |
Users within LATAM regions are increasingly targets of emails impersonating government or judicial entities, with themes often creating a sense of urgency. X-Force observes campaigns that routinely involve an embedded link or ZIP attachments that lead victims to malicious downloaders. Between August and October 2025, X-Force observed several emails targeting users likely residing in Colombia with emails imitating the Attorney General’s office of Colombia with official document downloads. Hijackloader is a modular malware with evasion and persistence mechanisms, primarily delivered to users as a ZIP or RAR archive file. The archives contain a malicious DLL that is sideloaded and used to deliver additional payloads. These emails, likely a part of a single campaign, are significant in that the actors utilize the Hijackloader to deliver PureHVNC RAT, a combination not previously observed by X-Force.
Indicator | Indicator Type | Context |
troquelesmyj[@]gmail.com | Sender email | |
nuevos777[.]duckdns[.]org | Domain | C2 Domain |
7octubredc[.]duckdns[.]org | Domain | C2 Domain |
dckis13[.]duckdns[.]org | Domain | C2 Domain |
dckis7[.]duckdns[.]org | Domain | C2 Domain |
enviopago[.]mysynology[.]net | Domain | C2 Domain |
maximo26[.]duckdns[.]org | Domain | C2 Domain |
sofiavergara[.]duckdns[.]org | Domain | C2 Domain |
hxxps[:]//drive[.]google[.]com | URL | SVG Host |
hxxps[:]//drive[.]google[.]com/ | URL | SVG Host |
e7120d45ee357f30cb602c0d93 | SHA256 | ZIP |
7e64102405459192813541448c8 | SHA256 | RAR |
14becb3a9663128543e1868d09 | SHA256 | Hijackloader |
57c49cff3e71bc75641c78a5a72d | SHA256 | Hijackloader |
7c3d9ad3f1bd890e3552dc6709 | SHA256 | Hijackloader |
ce42377d3d26853fd1718f69341 | SHA256 | Hijackloader |
a0e4979b4e4a706286438d48f | SHA256 | Hijackloader |
6d93a486e077858b75eb814e | SHA256 | Hijackloader |
bdca9849d7263d508b7ed4db | SHA256 | Hijackloader |
1ae61edf35127264d329b7c0e2 | SHA256 | Hijackloader |
2ec31a8a36d73fa8354a7ac0c | SHA256 | Hijackloader |
776bbaa44c7788e0ccd5945 | SHA256 | Hijackloader |
9e9997b54da0c633ffcf0a4fb | SHA256 | Hijackloader |
b2f733b67f1ef06d9e5ce76d3 | SHA256 | Hijackloader |
c93e70d20ba2948a6a8a013 | SHA256 | Hijackloader |
d550a2a327394148c0c3d05 | SHA256 | Hijackloader |
e668ca17fcdfa818aac35f1206 | SHA256 | Hijackloader |
fe6d0ee45a70359008b2916 | SHA256 | Hijackloader |
977f2f18ff13c93406c5702f83 | SHA256 | Hijackloader |
768ca38878c5bb15650343ce | SHA256 | Hijackloader |
47245b7d2d8cb6b92308deb | SHA256 | Hijackloader |
4484b0ac51536890301a0e6 | SHA256 | Hijackloader |
0113d9f3d93069a29458b3b4 | SHA256 | Hijackloader |
22d474e729d600dcd84ce139 | SHA256 | Hijackloader |
2cbfc482e27a2240a48d2fb6f | SHA256 | Hijackloader |
96ee786c5b6167c0f0f770efba | SHA256 | Hijackloader |
33d0c63777882c9ec514be06 | SHA256 | PureHVNC |
afecefa6d9bd1e6d1c9214420 | SHA256 | PureHVNC |
85641c8fb94e8e4c5202152dc | SHA256 | PureHVNC |
1bf3a1cf9bc7eded0b8994d44 | SHA256 | PureHVNC |
IBM X-Force Premier Threat Intelligence is now integrated with OpenCTI by Filigran, delivering actionable threat intelligence about this threat activity and more. Access insights on threat actors, malware, and industry risks. Install the X-Force OpenCTI Connector to enhance detection and response, strengthening your cybersecurity with IBM X-Force’s expertise. Get a 30-Day X-Force Premier Threat Intelligence trial today!
Think Newsletter
Join security leaders who rely on the Think Newsletter for curated news on AI, cybersecurity, data and automation. Learn fast from expert tutorials and explainers—delivered directly to your inbox. See the IBM Privacy Statement.
Your subscription will be delivered in English. You will find an unsubscribe link in every newsletter. You can manage your subscriptions or unsubscribe here. Refer to our IBM Privacy Statement for more information.