Dynamic-link library (DLL) hijacking is one of the oldest techniques that both threat actors and offensive security professionals continue to use today. DLL hijacking is popular because it grants threat actors a stealthy way to run malware that can be very effective at evading detection. At its core, DLL hijacking tricks an operating system into running a malicious binary instead of a legitimate DLL.
This article explains how threat actors use DLL hijacking in malware attacks, and it should help readers by providing:
This article also provides ideas for how to better detect DLL hijacking, and we share best practices on how to reduce the risk of attack.
Palo Alto Networks customers are better protected from the threats discussed in this article through our Next-Generation Firewall, as well as Advanced WildFire, DNS Security, and Advanced URL Filtering. Cortex XDR and XSIAM detect known and novel DLL hijacking attacks. The Prisma Cloud Defender agent can assist in identifying malware that uses DLL hijacking techniques. If you think you might have been compromised or have an urgent matter, contact the Unit 42 Incident Response team.
What Is DLL Hijacking?
Windows DLL Search Order
Special Search Locations
Standard Search Locations
Common DLL Hijacking Implementations
DLL Side-Loading
DLL Search Order Hijacking
Phantom DLL Loading
Uncovering Threat Actors and Campaigns
Examples of DLL Hijacking by Nation-State APT Threat Actors
ToneShell’s Triple DLL Side-Loading
PlugX RAT Leverages DLL Side-Loading to Remain Undetected
Examples of DLL Hijacking by Cybercrime Threat Actors
Uncovering AsyncRAT Phishing Campaign Targeting South American Organizations
Phantom DLL Loading for CatB Ransomware
Abuse of Microsoft DLLs Leads to Dridex
Principles for Efficient DLL Hijacking Detection
Malicious DLL
Vulnerable Application
Loading Event
Mitigating the DLL Hijacking Attack Surface
Conclusion
Protections and Mitigations
Indicators of Compromise
DLL files are programs that are meant to be run by other programs in Microsoft Windows. DLL hijacking allows attackers to trick a legitimate Windows program into loading and running a malicious DLL. Adversaries leverage DLL hijacking for multiple purposes, including defense evasion, privilege escalation and persistence.
DLL hijacking has evolved, with many variations over the past several years. To understand DLL hijacking, we must first understand the DLL search order mechanism, which is a crucial function in Microsoft Windows.
DLL hijacking relies on the DLL search order that Windows uses when loading DLL files. This search order is a sequence of locations a program checks when loading a DLL. The sequence can be divided into two parts: special search locations and standard search locations. You can find the search order comprising both parts in Figure 1.
Special search locations are taken into account before the standard search locations, and they contain different factors that can control the locations to be searched and used to load a DLL. These locations are based on the application and the system configurations.
The standard search locations are the ones most associated with the DLL hijacking technique, and they will usually be used by adversaries. Windows will use the following order to search for the desired DLL.
Hijacking this whole DLL search order will grant an adversary the option to load their malicious DLL within the context of a legitimate application and achieve stealthy execution. They can do this by triggering a malicious DLL to load before the valid one, replacing the DLL or by altering the order (specifically the PATH environment variable).
The prevalence of DLL hijacking has been on the rise in recent years, and DLL hijacking continues to gain popularity. This is because discovering and exploiting the vulnerability in legitimate executables isn't considered to be particularly difficult. However, detecting an attacker loading malicious, camouflaged DLLs within legitimate executables remains a complex undertaking.
As the concept of DLL hijacking continues to evolve over time, threat actors have evolved as well, using different approaches to perform this kind of attack. The three most common techniques we have observed are DLL side-loading, DLL search order hijacking and phantom DLL loading. The most common technique is DLL side-loading.
In this most commonly used DLL-hijacking technique, an attacker obtains a legitimate executable that loads a specifically named DLL without specifying the DLL file's full directory path. DLL side-loading uses a malicious DLL renamed to the same filename of a legitimate DLL, one normally used by a legitimate executable. Attackers drop the legitimate executable and a malicious, renamed DLL within a directory they have access to.
In DLL side-loading, the attackers rely on the fact that the executable’s directory is one of the first locations Windows searches for.
We have studied examples of attackers employing this technique in recent Unit 42 posts, including an instance by the APT Cloaked Ursa (aka APT29), and as part of our Threat Hunting series.
This implementation exemplifies the core abuse of the entire Windows DLL search order. It is used by adversaries, red teamers and security validation solutions.
This technique simply leverages the Windows DLL search order to drop a malicious DLL in any of its searched locations that would cause a vulnerable, legitimate program to execute a malicious DLL. An attacker can place a malicious DLL in a location prioritized by the DLL search order before the location of a valid DLL. This can happen at any point in the DLL search order, including the PATH environment variable, which attackers can modify by adding a path directory with a malicious DLL.
An example of this type of attack is to drop a malicious DLL in a Python installation directory to hijack the DLL search order. This is an implementation that different security practitioners have already demonstrated.
When Python is installed on a Windows machine, it often adds its installation directory to the PATH environment variable, usually in one of the first searched locations, as shown in Figure 2.
Installing Python on a Windows host creates a directory with relaxed permissions, allowing any authenticated user (including unprivileged ones) to write to this location. This gives attackers the best conditions to execute their DLL search order hijack attack and infect the targeted machine.
In this technique, adversaries look for a vulnerable executable that attempts to load a DLL that simply doesn't exist (or is missing) due to an implementation bug. Then, attackers will plant a malicious DLL with the non-existent DLL’s filename in its expected location.
A familiar example of this technique is the abuse of the Windows Search (WSearch) Service. This service is responsible for search operations and it launches with SYSTEM privileges upon system startup.
When this service starts, it executes SearchIndexer.exe and SearchProtocolHost.exe, which both attempt to load msfte.dll from System32. In default Windows installations, the file does not exist in this location.
An adversary can plant their malicious DLL if they can write to the System32 folder or an alternate DLL search order location, or insert another attacker-controlled location into the PATH environment variable. This allows them to gain a stealthy pathway for execution with SYSTEM privileges, and a means to maintain persistence on the machine.
Using our telemetry, we set out to hunt for DLL hijacking attacks, which revealed a large volume of attempted DLL hijacking attacks – including their variations. The following section provides real-world examples of how various threat actors, both cybercrime and nation-state APT groups, use DLL hijacking.
In September 2023, Unit 42 researchers discovered attackers using DLL side-loading to install the ToneShell backdoor. Attacks using a ToneShell variant were linked to Stately Taurus, in a campaign that built upon three DLL components working in tandem as shown in Figure 3. In the image, each component has been paired with its associated Image Load event in Cortex. The action type shows that the malicious DLLs were loaded to each legitimate process.
Each DLL component holds a different purpose:
The persistence components (nw.dll, nw_elf.dll) are side-loaded by PwmTower.exe, a component of a password manager, which is a legitimate security tool.
The networking component (rw32core.dll) is side-loaded by Brcc32.exe, the resource compiler of Embarcadero, an app development tool.
The functionality component (secur32.dll) is side-loaded by Consent.exe, which is a Windows binary described as “Consent UI for administrative applications.”
Another recent example of a DLL side-loading alert that caught our attention was an attack using the infamous PlugX backdoor.
PlugX is a modular backdoor that is predominantly used by various Chinese APT groups like PKPLUG. PlugX developers circulate in underground hacking communities, and the malware binaries can be found online, so non-Chinese threat actors can also use PlugX.
In the following example, PlugX infected a machine via a compromised USB device. Figure 4 shows the contents of the USB device. This device contained a directory named History and a Windows Shortcut (LNK) file. The History folder’s name and icon were disguised as the Windows History folder, and the LNK file uses an icon to appear as a removable disk.
The fake History folder contains three files:
Once the victim clicks the removable disk LNK, it launches the 3.exe process. Then 3.exe loads the PlugX component named Acrobat.dll via DLL side-loading.
Next, the malware creates a directory at C:\ProgramData\AcroBat\AcrobatAey and copies the three files to this location as Acrobat.exe, Acrobat.dll and AcrobatDC.dat, respectively.
To achieve persistence, this PlugX sample creates a scheduled task named InternetUpdateTask, which it sets to run every 30 minutes.
Figure 5 shows the initial process tree of the infection in Cortex XDR.
By hunting for DLL side-loading alerts in Cortex XDR Analysis, we discovered a phishing campaign targeting victims mainly in Colombia and Argentina, aiming to deliver AsyncRAT.
AsyncRAT is open-source malware that is very popular among cybercriminals. It gives attackers a range of capabilities such as executing commands, screen capturing and key logging.
The infection starts with phishing emails written in Spanish that contain descriptions of required legal actions, as shown in Figure 6.
The emails also contain links to a Google Drive URL hosting a malicious ZIP archive.
These archive files contain an executable with the same name as the ZIP filename and a malicious DLL file named http_dll.dll.
The executable is actually a renamed legitimate component of the ESET HTTP Server service process, originally named EHttpSrv.exe. When the victim executes the renamed EHttpSrv.exe, it loads the malicious http_dll.dll file from the same directory via DLL side-loading. After the executable loads http_dll.dll, the DLL unpacks in memory and loads the AsyncRAT malware.
Figure 7 shows the infection chain as seen in Cortex XDR. The malicious ZIP archive is downloaded, extracted with 7-Zip (7zG.exe) and the renamed EHttpSrv.exe is executed.
Figure 8 shows the “Possible DLL Side-Loading” alert Cortex XDR raised for this chain of events.
CatB ransomware was first seen in December 2022. In at least one campaign since then, threat actors have abused the Distributed Transaction Coordinator (MSDTC) service to achieve phantom DLL loading for CatB ransomware.
The core of this CatB ransomware campaign consists of two components: a dropper DLL and a ransomware DLL. The dropper DLL performs different anti-sandbox and anti-virtual machine (VM) checks to ensure the environment is safe to drop its ransomware payload.
After the dropper DLL is satisfied the environment is clear, it writes a second DLL named oci.dll under the C:\Windows\System32 directory. Then, the dropper kills the MSDTC process by msdtc.exe as shown below in Figure 9.
This is done to implement phantom DLL loading. When msdtc.exe launches, it attempts to load a DLL named oci.dll, which does not usually exist in the System32 folder. When msdtc.exe relaunches, it loads the malicious oci.dll, which is the ransomware payload, as shown in Figure 10. In the image, the process msdtc.exe is paired with the Image Load event in Cortex for the malicious oci.dll.
Cortex XDR alerts on phantom DLL loading attempts, as shown in Figure 11.
Threat actors have implemented DLL side-loading for another well-known malware, the Dridex banking Trojan. The initial infection vector for Dridex has most often been malicious emails or web traffic.
When executed, the Dridex loader has used AtomBombing to inject code into the process space used by explorer.exe. Next, the injected explorer.exe process writes Dridex DLLs as .tmp files and shell scripts with random names to the user’s TEMP directory. An example of these files being written to disk is shown in Figure 12.
Up to three of the shell scripts can appear, and they create the persistent Dridex infection in three different locations under random directory paths on the victim's host. The persistent infection uses DLL side-loading.
The shell scripts create these randomly-named directories under random directory paths, copy legitimate Microsoft executables and rename the Dridex DLL .tmp files for the DLL side-loading. An example of two shell scripts are shown below in Figure 13.
Afterward, the injected explorer.exe process creates persistence for the copied binaries using up to three methods:
Figure 15 shows Cortex XDR alerting on the legitimate file DeviceEnroller.exe side-loading a malicious Dridex DLL.
Pinpointing instances where an executable unexpectedly loads a malicious DLL with an identical name, but that is otherwise different in its content, is a rather challenging task. This challenge significantly increases when attempting to detect these behavioral anomalies at scale.
In this section we provide several principles for effective detection of DLL hijacking, including its variations. The principles will focus on the malicious DLL, the vulnerable application and the loading event, where a vulnerable application loads the malicious DLL.
Since the malicious DLL has the same name as a legitimate DLL, we look for abnormalities. For example:
The vulnerable application is usually a legitimate one to allow better disguise for the malicious DLL execution. Given that, we proceed to seek out distinct traits:
We can find different abnormalities also within the loading event. For example:
To secure applications from possible DLL hijacking attacks, developers need to be cognizant of this attack technique and integrate diverse protective measures.
Microsoft has published a DLL security article covering several best practices to support developers in this effort, including the following:
This article covers DLL hijacking, providing the technical background needed to understand how threat actors weaponize it, along with an explanation of popular variations in its implementation.
In addition, we provide examples that demonstrate how various threat actors – both APT nation-state and cybercrime groups – rely on this technique to achieve stealth, persistence and privilege escalation in their operations.
Lastly, we discuss possible approaches for detecting and mitigating DLL hijacking in enterprise environments.
For Palo Alto Networks customers, our products and services provide the following coverage associated with the threats described above:
If you think you might have been impacted or have an urgent matter, get in touch with the Unit 42 Incident Response team or call:
Palo Alto Networks has shared these findings with our fellow Cyber Threat Alliance (CTA) members. CTA members use this intelligence to rapidly deploy protections to their customers and to systematically disrupt malicious cyber actors. Learn more about the Cyber Threat Alliance.
The following are SHA256 hashes of files from the examples used in this article.
Sign up to receive the latest news, cyber threat intelligence and research from us