Quick reminder: DLL - Dynamic Link Library, a file that contains code and data that can be used by multiple programs simultaneously.
Programs need DLLs to perform various functions without having to include the code directly in their own executable files. And Windows need to store DLL somewhere to load them when needed.
-> So this finding DLL to load is the weak point that attackers exploit in DLL sideloading.
Windows DLL Search Order
When an executable call a DLL like:
LoadLibrary("abc.dll")Windows will find abc.dll in the following order:
- Current working directory
- The executable directory
- System32 directory
- System directory
- Windows directory
- Path
So if there is some malicious DLL file name abc.dll in any of these locations that appear before the legitimate DLL, Windows will load the malicious one instead. This is the core idea behind DLL sideloading.
DLL Sideloading
Sideloading means that an attacker places a malicious DLL in a location that appears earlier in the search order than the legitimate DLL. When the program loads the DLL, it inadvertently loads the malicious one instead, allowing the attacker to execute arbitrary code within the context of the vulnerable application.
So the danger here is:
- The EXE it self is a legitimate program with a legitimate signature (Microsoft / Adobe / Nvidia) -> Windows will trust it and allow it to run without suspicion.
- Attacker do not need to create a malicious process -> harder to detect and block.
- Malware run from legitimate process
Technique that DLL Sideloading usually associated with
Reflective DLL Loading
Normally windows will:
- Map DLL to memory
- Fix relocation
- Resolve imports
- Call
DllMain
Reflective DLL Loading: Attacker create a loader inside DLL that automatically load it self instead of using LoadLibraryA
In context of DLL sideloading: Legitimate EXE -> LoadLibrary(“something.dll”) -> something.dll is a Reflective DLL -> In DllMain, DLL will run Reflective loader to load payload.
Example: Load a becon PE. So the flow will be sideload → reflective load → beacon ran inside trusted process
Proxy DLL
Proxy DLL (also known as DLL Proxying or Forwarding) is a DLL Sideloading variant that keeps the application running without crashes.
The Concept
A legitimate application needs foo.dll with several exported functions: DoSomething, Init, Cleanup, etc.
The attacker places a malicious DLL with the same name foo.dll in the same directory as the EXE.
When the EXE loads foo.dll (the attacker’s version), the malicious code executes.
To prevent crashes, the malicious DLL:
- Executes the payload (beacon, loader, etc.)
- Loads the real DLL from another location (system path, renamed path, etc.)
- Forwards/wraps the exported functions so the app calls them normally
Result: The application runs normally, and users/admins are less likely to suspect anything.
Implementation Approaches
There are two main approaches:
Approach 1: Wrapper + GetProcAddress
In the malicious DLL code:
LoadLibraryA("C:\\Windows\\System32\\realfoo.dll");For each exported function the app needs, write a wrapper:
typedef int (__stdcall *pDoSomething)(int, int);pDoSomething realDoSomething = NULL;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if (fdwReason == DLL_PROCESS_ATTACH) { HMODULE hReal = LoadLibraryA("C:\\Windows\\System32\\realfoo.dll"); realDoSomething = (pDoSomething)GetProcAddress(hReal, "DoSomething");
// Execute payload here (beacon, shellcode, reflective loader...) RunMalware(); } return TRUE;}Approach 2: Export Forwarding (in PE)
In the PE format, the export table can forward exports to another DLL, for example:
DoSomething = realfoo.DoSomething
This makes the EXE call foo.dll!DoSomething → Windows redirects to realfoo.dll!DoSomething.
The attacker can:
- Use code in
DllMainto execute the payload - Configure export forwarding in PE so the app still runs properly
Why Proxy DLL is Hard to Detect
- Legitimate EXE runs normally
- Functions from the fake DLL forward/call back to the real DLL
- Users see no errors → few people check
- DLL path may be in Program Files → looks completely normal
Important (Detection Indicators)
Legitimate EXE loading DLL from:
- “Unusual” folder compared to standard installation
- Path doesn’t match the official version
DLL characteristics:
- Unsigned
- Timestamp much newer than the EXE
- Size anomaly (too large/small compared to original)
If you dump the DLL:
- Strange code in
DllMain(beacon, shellcode decode, reflective loader, etc.) - Contains
LoadLibrary+GetProcAddressto the real DLL - Compare with official version (hash, size, exports) → mismatch
COM Hijacking + DLL Sideloading
This is a powerful combination commonly used by APT groups.
What is COM (brief overview)?
COM (Component Object Model) is a Windows mechanism where:
Applications create objects using CLSID (GUID), for example:
CoCreateInstance(CLSID_SomeComponent, ...);Windows looks up the registry:
HKLM\Software\Classes\CLSID\{GUID}\InprocServer32→ points to a DLL- That DLL is loaded as the COM server
What is COM Hijacking?
The attacker modifies the registry to redirect a CLSID from a legitimate DLL to their malicious DLL, or registers a new COM with a CLSID that an application commonly calls.
Example:
Before:
HKLM\Software\Classes\CLSID\{ABC}\InprocServer32 = C:\Windows\System32\legit.dllAfter attack:
HKCU\Software\Classes\CLSID\{ABC}\InprocServer32 = C:\Users\...\malicious.dllSince HKCU overrides HKLM in many cases → the application will load malicious.dll instead of legit.dll.
How Does This Chain with DLL Sideloading?
Common scenario:
-
Legitimate (signed) app uses COM object A (CLSID X)
-
Attacker:
- Drops malicious DLL into the app’s folder (sideload)
- Registers CLSID pointing to that DLL (COM hijack)
-
When the app calls
CoCreateInstance(CLSID X), Windows:- Gets the DLL path from registry (
InprocServer32) - Loads malicious DLL (which is also sideloaded due to matching name and path)
- Gets the DLL path from registry (
-
The malicious DLL executes payload:
- Beacon, loader, etc.
- Or proxies to the real COM
Why Do APTs Love This Combo?
- COM is commonly used by system tools, Office, browsers, etc.
- Many enterprise applications use COM that admins don’t monitor closely
- COM registration in
HKCUdoesn’t require admin privileges - Excellent for persistence and stealth execution
APT groups like APT41 and APT29 have been observed using:
- COM hijack in
HKCU - Pointing to malicious DLL in user profile
- Combined with signed EXE for execution
Important (Detection Indicators)
COM CLSID with InprocServer32 pointing to:
- Path in user profile (
AppData,Temp,Downloads) - Unsigned DLL, suspicious timestamp
- New/unusual entry in
HKCU\Software\Classes\CLSID\... - Normal apps (Office, browser, system tools) suddenly loading DLL from user path
Tool: Autoruns (Sysinternals) will show COM objects → compare with baseline.
Detection Indicators
As a SOC analyst learning to hunt for DLL sideloading attacks, these are the key indicators I’ve learned to watch for:
1. Modules Loaded from Suspicious Locations
Warning (High-Risk Paths)
AppData\Local\TempDownloadsC:\ProgramDataDesktop- Any directory that doesn’t belong to the program’s installation path
Legitimate applications rarely load DLLs from user-writable directories. When you see a signed executable loading modules from these locations, investigate immediately.
2. Legitimate Programs Loading Unexpected DLLs
Example: OneDrive.exe loading abc.dll that doesn’t exist in the official version.
How to verify:
- Compare loaded modules against a known-good baseline
- Check vendor documentation for expected DLL dependencies
- Use tools like Process Explorer to enumerate loaded modules
- Cross-reference with VirusTotal or hash databases
3. Unsigned DLLs Loaded by Signed Executables
Pattern: Legitimate EXE (signed by Microsoft/Adobe/etc.) → loads unsigned DLL → RED FLAG
Most legitimate software vendors sign all their components. An unsigned DLL loaded by a signed executable is highly suspicious, especially if:
- The DLL has the same name as a system DLL
- The timestamp is recent but the executable is old
- The DLL is in the application directory, not system paths
4. DLL Path Mismatch / Name Collision
Common sideloaded DLL names:
version.dllws2help.dllwinmm.dllwlanapi.dlliphlpapi.dll
Detection logic:
IF DLL_name == known_system_dll AND DLL_path != System32 AND DLL_path != SysWOW64THEN flag as suspiciousThese DLLs should only be loaded from system directories. Finding them elsewhere is a strong indicator of sideloading.
5. File Replaced but EXE Signature Still Valid
This is a key characteristic of DLL sideloading:
- The attacker doesn’t modify the EXE → signature remains valid
- Only the DLL is replaced or added → no code signing violations on the main executable
- Windows trusts the signed EXE, which then loads the malicious DLL
Detection approach:
- Monitor DLL loads, not just process creation
- Use Sysmon Event ID 7 (Image Loaded) extensively
- Correlate signed executable with loaded module signatures
6. Creation Time Anomaly
Indicator: DLL creation time > EXE creation time
Example:
- EXE compiled/created: 2016
- DLL in the same folder: created 1 hour ago
Why this matters:
- Legitimate software ships with all components at once
- If a DLL is brand new but the EXE is years old, someone likely placed it there recently
Sysmon configuration to catch this:
<ImageLoad onmatch="include"> <Signed condition="is">false</Signed></ImageLoad>Real-World Examples: Cobalt Strike
Common patterns:
- Drops beacon DLL with names like
version.dllormsedge.dll - Sideloads into legitimate Windows utilities:
rundll32.exewmic.exemobsync.exe
Why it works: These executables are whitelisted by default and signed by Microsoft. When they load a malicious DLL, the process appears legitimate to most security tools.
Detection:
Process: rundll32.exe (Signed by Microsoft) → Loads: C:\Users\Public\version.dll (Unsigned) → Network: Beacon to attacker C2This is part of my “Building My Blue Team Skills from the Ground Up” series. The transition from understanding offensive techniques to building defensive detections continues. Each attack method I learn becomes a detection rule I can write.
If you’re also learning detection engineering or have experience hunting for DLL sideloading, I’d love to hear your insights. Connect with me on LinkedIn or drop a comment below.