Logo
DLL Sideloading
Overview
DLL Sideloading

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:

  1. Current working directory
  2. The executable directory
  3. System32 directory
  4. System directory
  5. Windows directory
  6. 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 DllMain to 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 + GetProcAddress to 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.dll

After attack:

HKCU\Software\Classes\CLSID\{ABC}\InprocServer32 = C:\Users\...\malicious.dll

Since 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:

  1. Legitimate (signed) app uses COM object A (CLSID X)

  2. Attacker:

    • Drops malicious DLL into the app’s folder (sideload)
    • Registers CLSID pointing to that DLL (COM hijack)
  3. 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)
  4. 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 HKCU doesn’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\Temp
  • Downloads
  • C:\ProgramData
  • Desktop
  • 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.dll
  • ws2help.dll
  • winmm.dll
  • wlanapi.dll
  • iphlpapi.dll

Detection logic:

IF DLL_name == known_system_dll
AND DLL_path != System32
AND DLL_path != SysWOW64
THEN flag as suspicious

These 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.dll or msedge.dll
  • Sideloads into legitimate Windows utilities:
    • rundll32.exe
    • wmic.exe
    • mobsync.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 C2

This 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.