简体   繁体   English

如何在.NET中验证DLL的数字签名

[英]How to Verify a Digital Signature of a DLL in .NET

I've written a C# .NET application that uses a popular unmanaged DLL file for part of its functionality. 我编写了一个C#.NET应用程序,它使用流行的非托管DLL文件来实现其部分功能。 The DLL is imported using the standard DllImport from System.Runtime.InteropServices. 使用System.Runtime.InteropServices中的标准DllImport导入DLL。

However, unfortunately, my application (along with most .NET applications using DllImport) is vulnerable to DLL Hijacking. 但是,遗憾的是,我的应用程序(以及大多数使用DllImport的.NET应用程序)容易受到DLL劫持攻击。 Ie an attacker can place a malicous copy of the imported DLL in the same directory as any file opened by my application. 即攻击者可以将导入的DLL的恶意副本放在与我的应用程序打开的任何文件相同的目录中。 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. 为了缓解此漏洞,我想在导入之前验证DLL文件是否已正确签名(使用默认的Authenticode)。 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. 我知道可以使用像sigcheck.exe这样的工具验证签名,但这对我来说不是一个可行的解决方案,因为我需要在我的C#代码中进行。

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? 所以我的问题很简单: 在加载DLL之前,如何从我的托管C#代码中验证DLL是否具有有效的Authenticode签名?

Limitations: 限制:

  • The imported DLL isn't developed by me, it's from an external company. 导入的DLL不是由我开发的,而是来自外部公司。
  • The DLL is not distributed with my application, it is expected to already be installed prior to running my app. DLL不随我的应用程序一起分发,预计在运行我的应用程序之前已经安装了。
  • 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. 导入的DLL存在于许多不同的版本中(甚至会有更多版本),因此我无法在导入之前简单地验证DLL的MD5校验和

Failed approaches: 失败的方法:

  • Microsoft have a nice writeup on preventing "DLL preloading attacks" , however, this info isn't applicable for .NET's DllImport. 微软有一个关于防止“DLL预加载攻击”的好文章 ,但是,这个信息不适用于.NET的DllImport。
  • I've seen some people suggesting the use of the unmanaged function WinVerifyTrust from Wintrust.dll. 我见过一些人建议使用Wintrust.dll中的非托管函数WinVerifyTrust。 This is of course a stupid solution, since that would instead make my application vulnerable to DLL injection via Wintrust.dll. 这当然是一个愚蠢的解决方案,因为这会使我的应用程序容易受到Wintrust.dll的DLL注入。

You need to employ Authenticode verifier. 您需要使用Authenticode验证程序。 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. 这个问题的答案提供使用P / Invoke,如果您需要托管解决方案,您可能会对我们的SecureBlackbox库感兴趣,其中包括其他功能提供Authenticode签名和签名验证。

However, while you can defend yourself from loading fake DLL, you can't defend the application itself from being cracked. 但是,虽然您可以保护自己免于加载假DLL,但您无法防止应用程序本身被破解。 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. 让我指出,替换WinTrust.dll取决于需要访问计算机的不同攻击向量。 In this case the attacker can patch your application altogether. 在这种情况下,攻击者可以完全修补您的应用程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM