I've written a C# .NET application that uses a popular unmanaged DLL file for part of its functionality. The DLL is imported using the standard DllImport from System.Runtime.InteropServices.
However, unfortunately, my application (along with most .NET applications using DllImport) is vulnerable to DLL Hijacking. I.e. an attacker can place a malicous copy of the imported DLL in the same directory as any file opened by my application. This could give the attacker full control of the user's machine.
To mitigate this vulnerability I'd like to verify that the DLL file is properly signed (with default Authenticode) before importing it. I know that signatures can be verified with tools like sigcheck.exe, but this isn't a viable solution for me since I need to do it from within my C# code.
So my question is simply: How can I verify that a DLL has a valid Authenticode signature, from within my managed C# code, before loading the DLL?
Limitations:
- The imported DLL isn't developed by me, it's from an external company.
- The DLL is not distributed with my application, it is expected to already be installed prior to running my app.
- The imported DLL exists in many different versions (and even more will come), so I can't simply verify an MD5 checksum of the DLL before importing it.
Failed approaches:
- Microsoft have a nice writeup on preventing "DLL preloading attacks", however, this info isn't applicable for .NET's DllImport.
- I've seen some people suggesting the use of the unmanaged function WinVerifyTrust from Wintrust.dll. This is of course a stupid solution, since that would instead make my application vulnerable to DLL injection via Wintrust.dll.