How to Verify a Digital Signature of a DLL in .NET

Erik picture Erik · Jul 20, 2013 · Viewed 7.8k times · Source

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.

Answer

Eugene Mayevski 'Callback picture Eugene Mayevski 'Callback · Jul 21, 2013

You need to employ Authenticode verifier. Answers to this question offer to use P/Invoke and if you need a managed solution, you might be interested in our SecureBlackbox library that among other functionality offers Authenticode signing and signature verification.

However, while you can defend yourself from loading fake DLL, you can't defend the application itself from being cracked. So signature verification protects you from only one attack vector, of course.

Let me point, that replacing WinTrust.dll depends to a different attack vector which requires access to the computer. In this case the attacker can patch your application altogether.