为什么.NET不验证BCL/CLR?

Rob*_*ean 6 .net

BCL和CLR中的所有.NET程序集(将仅使用CLR)都具有强名称和数字签名.提供数字证书是为了给予组件未被篡改或替换的信任度.然而,似乎.NET没有检查数字签名(它可以检查Hans 指出的强名称).

检查装配负载是否有缺陷是有道理的,因为修改后的CLR可以伪造答案.我的想法是,从.NET 1的角度来看,检查的唯一安全的地方是框架的启动,作为启动绑定框架的非托管代码的一部分.最大的缺点是性能影响.

我从开发人员的角度来看这个问题,换句话说,我怎么知道我的应用程序没有被已经拥有的CLR 2破坏,或者另外一种方式是让应用程序信任CLR?

所以我的问题是为什么.NET不验证CLR?是因为性能影响还是更多呢?



1.我专注于.NET,有可能弄乱Windows,从而打破了这个想法,但如果你已经拥有Windows,那么你真的不需要拥有.NET.
2.示例是用户输入密码到应用程序,它存储在SecureString中,但BCL受到攻击,因此攻击者现在正在获取该信息.它允许他们捕获其他信息.我意识到攻击者是否可以替换CLR也可以在机器上放置一个关键记录器,但是(希望)可以用一个不错的安全工具检测到.还有很多其他方法可以解决这个问题,核心是如何知道SecureString是否已被更改.

Han*_*ant 6

这在.NET 3.5 SP1中已经改变,旨在作为完全信任的应用程序的启动性改进,以使它们与不执行此类检查的本机程序进行奇偶校验.验证强名称是昂贵的,并且由于大量的DLL,托管程序的冷启动往往很慢.您可以使用.config文件重新打开它:

<configuration>
    <runtime>
        <bypassTrustedAppStrongNames enabled="false"/>
    </runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)

或者通过编辑注册表项使其对所有.NET程序生效:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
"AllowStrongNameBypass"=dword:00000000
Run Code Online (Sandbox Code Playgroud)

还要在64位计算机上设置HKLM\Software\Wow6432Node密钥.


Cod*_*aos 3

他们属于 GAC。谁能扰乱GAC,谁就已经是特权用户了。此外,大多数应用程序都在完全信任模式下运行,无论如何这都是无关紧要的。因为在完全信任的应用程序中,您可以使用指针、本机互操作……所有这些都可能破坏基于验证的安全性。

在执行信任度较低的代码的情况下(例如在 Silverlight 中),代码验证非常重要。在这样的沙箱中你只想执行:

  1. 经过验证的安全不受信任的代码
  2. 可信代码位于 GAC 中或使用您信任的密钥签名。

  1. 例如,用户在应用程序中输入密码,密码存储在 SecureString 中,但 BCL 已被泄露,因此攻击者现在可以获取该信息。它允许他们捕获信息以用于其他目的。我意识到,如果攻击者可以替换 CLR,他也可以在计算机上放置一个键盘记录器,但(希望)可以使用像样的安全工具检测到。

你这里的安全模型已经被破坏了。在这种威胁场景中,攻击您的应用程序的方法有很多种,您无需关心 BCL。例如,攻击者可以修补NGened 或 JIT 代码。要么直接挂钩到SecureString方法,要么输入处理代码。他可以使用各种关键日志记录或消息拦截功能,根据我的经验,这些功能很少被检测到。他可以对你的窗口进行子类化。您可以完全替换您的 GUI。他可以简单地替换磁盘上的所有程序集。用户不太可能注意到。

根据我的经验,大多数安全工具甚至不关心应用程序是否安装了低级键盘挂钩,这是最简单的键盘记录方法之一。

  • 但前提是您是该计算机的管理员。 (2认同)