├── .gitignore ├── DLLHijackTest.sln ├── DLLHijackTest ├── DLLHijackTest.vcxproj ├── DLLHijackTest.vcxproj.filters ├── DLLHijackTest.vcxproj.user ├── dllmain.cpp ├── pch.cpp ├── pch.h ├── write.cpp └── write.h ├── Get-PotentialDLLHijack.ps1 ├── README.md └── example.png /.gitignore: -------------------------------------------------------------------------------- 1 | .vs 2 | .user 3 | [Dd]ebug 4 | [Rr]elease 5 | [Bb]in 6 | [Oo]bj 7 | [Oo]utput 8 | .DS_Store -------------------------------------------------------------------------------- /DLLHijackTest.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30011.22 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DLLHijackTest", "DLLHijackTest\DLLHijackTest.vcxproj", "{644758B1-C146-4D3B-B614-8EB6C933B0AA}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {644758B1-C146-4D3B-B614-8EB6C933B0AA}.Debug|x64.ActiveCfg = Debug|x64 17 | {644758B1-C146-4D3B-B614-8EB6C933B0AA}.Debug|x64.Build.0 = Debug|x64 18 | {644758B1-C146-4D3B-B614-8EB6C933B0AA}.Debug|x86.ActiveCfg = Debug|Win32 19 | {644758B1-C146-4D3B-B614-8EB6C933B0AA}.Debug|x86.Build.0 = Debug|Win32 20 | {644758B1-C146-4D3B-B614-8EB6C933B0AA}.Release|x64.ActiveCfg = Release|x64 21 | {644758B1-C146-4D3B-B614-8EB6C933B0AA}.Release|x64.Build.0 = Release|x64 22 | {644758B1-C146-4D3B-B614-8EB6C933B0AA}.Release|x86.ActiveCfg = Release|Win32 23 | {644758B1-C146-4D3B-B614-8EB6C933B0AA}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {0B05309F-8520-4C09-9371-2C72D2449A4E} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /DLLHijackTest/DLLHijackTest.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {644758B1-C146-4D3B-B614-8EB6C933B0AA} 24 | Win32Proj 25 | DLLHijackTest 26 | 10.0 27 | 28 | 29 | 30 | DynamicLibrary 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | DynamicLibrary 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | DynamicLibrary 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Use 88 | Level3 89 | true 90 | WIN32;_DEBUG;DLLHIJACKTEST_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 91 | true 92 | pch.h 93 | 94 | 95 | Windows 96 | true 97 | false 98 | 99 | 100 | 101 | 102 | Use 103 | Level3 104 | true 105 | _DEBUG;DLLHIJACKTEST_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 106 | true 107 | pch.h 108 | 109 | 110 | Windows 111 | true 112 | false 113 | 114 | 115 | 116 | 117 | Use 118 | Level3 119 | true 120 | true 121 | true 122 | WIN32;NDEBUG;DLLHIJACKTEST_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 123 | true 124 | pch.h 125 | 126 | 127 | Windows 128 | true 129 | true 130 | true 131 | false 132 | 133 | 134 | 135 | 136 | NotUsing 137 | Level3 138 | true 139 | true 140 | true 141 | NDEBUG;DLLHIJACKTEST_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 142 | true 143 | pch.h 144 | 145 | 146 | Windows 147 | true 148 | true 149 | true 150 | false 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | Create 161 | Create 162 | Create 163 | Create 164 | 165 | 166 | 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /DLLHijackTest/DLLHijackTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /DLLHijackTest/DLLHijackTest.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /DLLHijackTest/dllmain.cpp: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : Defines the entry point for the DLL application. 2 | #include "Windows.h" 3 | #include "write.h" 4 | 5 | HANDLE hThread; 6 | DWORD dwThread; 7 | 8 | DWORD WINAPI MyThread(LPVOID lpParam) 9 | { 10 | WriteToFile(); 11 | return 0; 12 | } 13 | 14 | BOOL APIENTRY DllMain(HMODULE hModule, 15 | DWORD ul_reason_for_call, 16 | LPVOID lpReserved 17 | ) 18 | { 19 | switch (ul_reason_for_call) 20 | { 21 | case DLL_PROCESS_ATTACH: 22 | hThread = CreateThread(NULL, 0, MyThread, NULL, 0, &dwThread); 23 | break; 24 | case DLL_THREAD_ATTACH: 25 | case DLL_THREAD_DETACH: 26 | case DLL_PROCESS_DETACH: 27 | break; 28 | } 29 | return TRUE; 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /DLLHijackTest/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: source file corresponding to the pre-compiled header 2 | 3 | #include "pch.h" 4 | 5 | // When you are using pre-compiled headers, this source file is necessary for compilation to succeed. 6 | -------------------------------------------------------------------------------- /DLLHijackTest/pch.h: -------------------------------------------------------------------------------- 1 | // pch.h: This is a precompiled header file. 2 | // Files listed below are compiled only once, improving build performance for future builds. 3 | // This also affects IntelliSense performance, including code completion and many code browsing features. 4 | // However, files listed here are ALL re-compiled if any one of them is updated between builds. 5 | // Do not add files here that you will be updating frequently as this negates the performance advantage. 6 | 7 | #ifndef PCH_H 8 | #define PCH_H 9 | 10 | #endif //PCH_H 11 | -------------------------------------------------------------------------------- /DLLHijackTest/write.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void WriteToFile() 4 | { 5 | LPCWSTR outputFile = L"C:\\Users\\John\\Desktop\\results.txt"; 6 | wchar_t path[MAX_PATH]; 7 | HMODULE hm = NULL; 8 | 9 | if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 10 | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, 11 | (LPCWSTR)&WriteToFile, &hm) == 0) 12 | { 13 | return; 14 | } 15 | if (GetModuleFileName(hm, path, sizeof(path) / sizeof(wchar_t)) == 0) 16 | { 17 | return; 18 | } 19 | 20 | HANDLE hCreateFile, hAppendFile; 21 | DWORD dwBytesWritten, dwBytesToWrite; 22 | 23 | hCreateFile = CreateFileW(outputFile, GENERIC_WRITE, NULL, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); 24 | CloseHandle(hCreateFile); 25 | 26 | hAppendFile = CreateFileW(outputFile, FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 27 | 28 | if (hAppendFile == INVALID_HANDLE_VALUE) 29 | { 30 | return; 31 | } 32 | 33 | dwBytesToWrite = sizeof(path) / sizeof(wchar_t); 34 | WriteFile(hAppendFile, (LPVOID)path, dwBytesToWrite, &dwBytesWritten, NULL); 35 | 36 | CloseHandle(hAppendFile); 37 | } -------------------------------------------------------------------------------- /DLLHijackTest/write.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | void WriteToFile(); -------------------------------------------------------------------------------- /Get-PotentialDLLHijack.ps1: -------------------------------------------------------------------------------- 1 | #Get-PotentialDLLHijack -CSVPath .\Logfile.CSV -MaliciousDLLPath .\DLLHijackTest.dll -ProcessPath "C:\Users\John\AppData\Local\Programs\Microsoft VS Code\Code.exe" 2 | function Get-PotentialDLLHijack { 3 | param ( 4 | [String] 5 | $CSVPath = "", 6 | [String] 7 | $MaliciousDLLPath = "", 8 | [String] 9 | $ProcessPath = "", 10 | [String] 11 | $ProcessArguments = "" 12 | ) 13 | 14 | 15 | if (-not (Test-Path $CSVPath)) 16 | { 17 | Write-Host "[-] $CSVPath does not exist" -ForegroundColor Red 18 | return 19 | 20 | } 21 | 22 | if (-not (Test-Path $MaliciousDLLPath)) 23 | { 24 | Write-Host "[-] $MaliciousDLLPath does not exist" -ForegroundColor Red 25 | return 26 | 27 | } 28 | 29 | 30 | $PotentialHijackPath = @() 31 | Import-CSV $CSVPath | Foreach-Object {$PotentialHijackPath += $_.Path} 32 | $PotentialHijackPath = $PotentialHijackPath | Select-Object -Unique 33 | 34 | $WriteablePath = @() 35 | foreach($x in $PotentialHijackPath) 36 | { 37 | $FileName = Split-Path $x -Leaf 38 | $System32Path = "C:\Windows\System32\" + $FileName 39 | if (Test-Path $System32Path -PathType Leaf) 40 | { 41 | try 42 | { 43 | [io.file]::OpenWrite($x).close() 44 | $WriteablePath += $x 45 | } 46 | catch { Write-Warning "Unable to write to output file $x" } 47 | Remove-Item $x 48 | } 49 | } 50 | Write-Host "[+] Parsed Procmon output for potential DLL hijack paths!" -ForegroundColor Green 51 | 52 | $ProcessName = [io.path]::GetFileNameWithoutExtension($ProcessPath) 53 | foreach($HijackPath in $WriteablePath) 54 | { 55 | try 56 | { 57 | Copy-Item $MaliciousDLLPath $HijackPath 58 | Write-Host "[+] Copied $MaliciousDLLPath to $HijackPath" -ForegroundColor Green 59 | } 60 | catch{ Write-Host "[-] Failed to copy $MaliciousDLLPath to $HijackPath" -ForegroundColor Red } 61 | 62 | if ($ProcessArguments -eq '') 63 | { 64 | try 65 | { 66 | Start-Process -FilePath $ProcessPath 67 | Write-Host "[+] Started $ProcessPath" -ForegroundColor Green 68 | } 69 | catch{ Write-Host "[-] Failed to start $ProcessPath" -ForegroundColor Red } 70 | } 71 | else 72 | { 73 | try 74 | { 75 | Start-Process -FilePath $ProcessPath -ArgumentList $ProcessArguments -WindowStyle Minimized 76 | Write-Host "[+] Started $ProcessPath $ProcessArguments" -ForegroundColor Green 77 | } 78 | catch{ Write-Host "[-] Failed to start $ProcessPath$ProcessArguments" -ForegroundColor Red } 79 | } 80 | 81 | Start-Sleep -s 7 82 | 83 | 84 | Get-Process $ProcessName -ErrorAction SilentlyContinue -ErrorVariable GetProcessError | Stop-Process -ErrorAction SilentlyContinue -ErrorVariable StopProcessError 85 | 86 | if ($GetProcessError) 87 | { 88 | Write-Host "[-] Failed to kill $ProcessName, it never started properly. Continuing..." -ForegroundColor Red 89 | } 90 | elseif($StopProcessError) 91 | { 92 | Write-Host "[-] Failed to kill $ProcessName" -ForegroundColor Red 93 | } 94 | else 95 | { 96 | Write-Host "[+] Killed $ProcessName process" -ForegroundColor Green 97 | } 98 | 99 | Start-Sleep -s 2 100 | 101 | 102 | Remove-Item $HijackPath -ErrorAction SilentlyContinue -ErrorVariable RemoveItemError 103 | if ($RemoveItemError) 104 | { 105 | Write-Host "[-] Failed to remove $HijackPath, trying again..." -ForegroundColor Red 106 | 107 | $count = 0 108 | while( $count -lt 2 ) 109 | { 110 | Remove-Item $HijackPath -ErrorAction SilentlyContinue -ErrorVariable RemoveItemError 111 | if ($RemoveItemError) 112 | { 113 | Write-Host "[-] Failed to remove $HijackPath" -ForegroundColor Red 114 | } 115 | else 116 | { 117 | Write-Host "[+] Removed $HijackPath" -ForegroundColor Green 118 | break 119 | } 120 | Write-Host "[-] Trying again..." -ForegroundColor Red 121 | Start-Sleep -s 5 122 | $count = $count + 1 123 | } 124 | } 125 | else 126 | { 127 | Write-Host "[+] Removed $HijackPath" -ForegroundColor Green 128 | } 129 | } 130 | 131 | Write-Host "[+] Script complete, check path specified in DLL for output!" -ForegroundColor Green 132 | 133 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DLLHijackTest 2 | 3 | ![Get-PotentialDLLHijack.ps1](https://raw.githubusercontent.com/slyd0g/DLLHijackTest/master/example.png) 4 | 5 | ## Blogpost 6 | - https://posts.specterops.io/automating-dll-hijack-discovery-81c4295904b0 7 | 8 | ## Usage 9 | - Use Procmon to obtain a CSV file of potential DLL hijacks 10 | - Modify ```outputFile``` variable within ```write.cpp``` 11 | - Build the project for the appropriate architecture 12 | - Open ```powershell.exe``` and load ```Get-PotentialDLLHijack.ps1``` into memory 13 | - ```. .\Get-PotentialDLLHijack.ps1``` 14 | - Run ```Get-PotentialDLLHijack``` with the appropriate flags 15 | - Example: 16 | - ```Get-PotentialDLLHijack -CSVPath .\Logfile.CSV -MaliciousDLLPath .\DLLHijackTest.dll -ProcessPath "C:\Users\John\AppData\Local\Programs\Microsoft VS Code\Code.exe"``` 17 | - ```-CSVPath``` takes in a path to a .csv file exported from Procmon 18 | - ```-MaliciousDLLPath``` takes in a path to your compiled hijack DLL 19 | - ```-ProcessPath``` takes in a path to the executable you want to run 20 | - ```-ProcessArguments``` takes in commandline arguments you want to pass to the executeable 21 | - View the contents of ```outputFile``` for found DLL hijacks 22 | - Run ```strings.exe``` on the ```outputFile``` to clean up the output paths 23 | - Party!!! 24 | 25 | -------------------------------------------------------------------------------- /example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slyd0g/DLLHijackTest/fad1d6139ad805a2ebefeb6d8c2e709704386199/example.png --------------------------------------------------------------------------------