简体   繁体   English

如何保护.NET应用程序免受DLL劫持?

[英]How can I proctect my .NET application against DLL Hijacking?

We have a .NET 3.5 application with registered extensions. 我们有一个带有注册扩展名的.NET 3.5应用程序。 How can we protect it against DLL Hijacking attacks? 我们如何保护它免受DLL劫持攻击?

Because of legacy & design problems strong naming/signing is not an option right now 由于遗留和设计问题,目前无法选择强大的命名/签名

Extra Information if you don't know what DLL Hijacking is: 如果您不知道什么是DLL劫持,请获取更多信息:

I had came across similar issue, I had ended up writing my own logic for verifying the dll. 我遇到了类似的问题,最终我写了自己的逻辑来验证dll。 For me I was just using that dll in LGPL fashion (I can't modify the dll), but wanted to make sure that my application uses the genuine dll (not the hi-jacked one). 对我来说,我只是以LGPL方式使用了该dll(我无法修改该dll),但想确保我的应用程序使用的是真正的dll(而不是被劫持的dll)。

Simple solution: 简单的解决方案:

  • While developing the application create MD5 Checksum of the dll and hardcode the hash in the application 在开发应用程序时,创建dll的MD5校验和并在应用程序中对哈希进行硬编码
  • Everytime you start the application use the same logic to generate the MD5 Checksum of the dll file and compare it with the hardcoded one. 每次启动应用程序时,都使用相同的逻辑来生成dll文件的MD5校验和并将其与硬编码的文件进行比较。
  • You might be already aware but here is how to efficiently generate the Checksum of a file (see answer: https://stackoverflow.com/a/1177744/392850 ) 您可能已经知道了,但这是如何有效地生成文件的校验和(请参阅答案: https : //stackoverflow.com/a/1177744/392850

Better solution: 更好的解决方案:

  • Generate hash of the dll, with strong Hashing algorithm and salt 使用强大的哈希算法和盐生成dll哈希
  • Generate RSA key value pair (private key and public key) 生成RSA密钥值对(私钥和公钥)
  • Encrypt the hash of the dll with your private key 用您的私钥加密dll的哈希
  • Embed the public key, "encrypted hash" and salt in your application 在您的应用程序中嵌入公钥,“加密的哈希”和盐
  • Upon application start, decrypt the "encrypted hash" with your public key 应用程序启动后,用您的公共密钥解密“加密的哈希”
  • Generate the Hash again at runtime with the same salt, and compare with the hash decrypted using the public key 在运行时使用相同的盐再次生成哈希,然后与使用公钥解密的哈希进行比较

If you have any certificate from trusted CA like verisign, you can use that certificate instead of using RSA key value pair. 如果您有来自受信任CA的任何证书(如verisign),则可以使用该证书而不是使用RSA密钥值对。

This way even if someone replaces your dll with cracked dll, the hash will not match and your application will know the Hijacking attempt. 这样,即使有人用破解的dll替换了您的dll,哈希也将不匹配,并且您的应用程序将知道劫持尝试。

This approach could is better than only giving dll a strong name because, may be strong name verification can be disabled by running 这种方法可能比只给dll一个强名称更好,因为强名称验证可能会因运行而被禁用

SN -Vr HijackedAssembly

Hope this helps you, or someone who wants to understand how digital signature things work internally. 希望这对您或想了解数字签名事物在内部如何工作的人有所帮助。

Robert, 罗伯特

In fairness to Jim's question about "what kind of design would that be". 公平地讲,吉姆关于“那是什么样的设计”的问题。 By answering, instead of just saying "it is what it is" you could give us insight into the constraints our suggestions/solutions must fall within. 通过回答,而不仅仅是说“这就是它”,您可以使我们洞悉我们的建议/解决方案必须包含的限制。

Put another way, without knowing why the legacy code prevents you from doing it the "right way" it's hard to provide ideal workarounds to your problem. 换句话说,在不知道遗留代码为何会阻止您以“正确的方式”进行操作的情况下,很难为问题提供理想的解决方法。

Unless your architecture prevents the MD5 checksum idea suggested by Vishalgiri, I'd suggest taking his advice. 除非您的体系结构阻止了Vishalgiri提出的MD5校验和想法,否则我建议您采纳他的建议。 Again though, without knowing what application(s) call these DLLs and why they can't be signed, it's hard to know if this will work for you. 同样,尽管不知道哪些应用程序调用了这些DLL以及为何无法对其进行签名,但很难知道这是否对您有用。

My idea might be a lot simpler, but can you not adjust your application to preload the DLL from a predefined location? 我的想法可能简单得多,但是您是否可以不调整应用程序以从预定义的位置预加载DLL? For example, only allow it to load from the BIN folder of your main applicaton, and failing that - never try again? 例如,仅允许它从您的主应用程序的BIN文件夹中加载,而失败了-永远不要重试?

See this link on how to load from a distinct path: http://www.chilkatsoft.com/p/p_502.asp 有关如何从不同路径加载的信息,请参见以下链接: http : //www.chilkatsoft.com/p/p_502.asp

This may be faster than writing all the MD5 checksum code. 这可能比编写所有MD5校验和代码更快。 Even though I like that idea as well. 即使我也喜欢这个主意。

看看这个线程 ....它可能会帮助您并为您提供见解....另一件事,您当然可以签出EasyHook ,并拦截API createRemoteThread并确定DLL是否是未经授权的DLL之一。 ...看一下这个线程 ,它解释了如何阻止dll注入

如果要混淆您的应用程序,则在混淆之前先使用ILMerge将DLL与EXE合并,将提供针对DLL劫持的绝对保护,还可以消除未使用的代码,并为您提供独立的EXE。

Couldn't you include the dll as a resource and write it out to where you want at run time then load the dll into the assembly? 您是否可以将dll作为资源包括在内,并在运行时将其写到所需位置,然后将dll加载到程序集中? I did this once because we wanted to distribute as one .exe but I think it would also solve this problem, wouldn't it? 我这样做是因为我们想作为一个.exe分发,但我认为它也可以解决此问题,不是吗?

If you have folder/data access priveledges, you could write code to proactively go and look in the same places Windows looks for your .DLL prior to calling your own .DLL (or search the whole drive), and you could compute a CRC check for your legit DLL, or other pattern match to compare your legit.DLL on located, matching DLL files, and thus make sure no one else has hijacked you (placed a file in a location that would be searched prior to your own location - or even any location). 如果您具有文件夹/数据访问特权,则可以编写代码以主动调用Windows并在调用自己的.DLL(或搜索整个驱动​​器)之前查找.DLL的相同位置,并且可以计算CRC检查为您的合法DLL或其他模式匹配文件,以比较位于相匹配的DLL文件上的legit.DLL,从而确保没有其他人劫持您(将文件放置在可以在您自己的位置之前进行搜索的位置-或甚至任何位置)。 This could take some research into the methodology under different versions of Windows for the various orders of searches. 对于不同的搜索顺序,这可能需要对Windows不同版本下的方法进行一些研究。 Then, if you find a hijacking attempt, you could take some action, depending on how sure you are that someone is trying to hijack your DLL... Rename the faker.DLL, delete it, notify the user, notify admin, don't call your DLL, etc. 然后,如果您发现了劫持尝试,则可以采取一些措施,具体取决于您是否确定有人试图劫持DLL ...重命名faker.DLL,将其删除,通知用户,通知管理员,不要调用您的DLL等

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

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