6

All .NET assemblies in the BCL & CLR (onwards just CLR will be used) are both strongly named and digitally signed. Digital certificates are provided to give a measure of trust that the assembly has not been tampered with or replaced. However it does not appear that .NET ever checks the digital signature (it can check the strong name as Hans pointed out).

It makes sense that checking on assembly load is flawed becaused an modified CLR could fake the answers. My thinking is that the only safe place from the perspective of .NET1 to check is on start of the framework as part of the unmanaged code that boot straps the framework. Big downside is the performance impact.

I am looking at this from the perspective of a developer, in otherwords how do I know that my application is not being compromised by an already owned CLR2, or put another way is there anyway for an application to trust the CLR?

So my question is why does .NET not verify the CLR? Is it because the performance impact or is there more to it?



1. I am focusing on .NET, it is possible to mess with Windows and thus break the idea but if you already own Windows you don't really need to own .NET.
2. Example of this is user inputs password into application, it is stored in a SecureString but the BCL is compromised so the attacker is now getting that info. It allows them to capture the information for something else. I realise the attacker if he could replace the CLR could put a key logger on the machine too, but that is (hopefully) detectable with a decent security tool. There is also lots of other ways to attack this, the core is how do I know if SecureString has been changed.
Community
  • 1
  • 1
Robert MacLean
  • 38,975
  • 25
  • 98
  • 152

2 Answers2

6

This was changed in .NET 3.5 SP1, intended as a startup perf improvement for apps that run in full trust to give them parity with native programs which do no such checking. Verifying the strong name is expensive and cold starts on managed programs tend to be slow due to the large number of DLLs. You can turn it back on with the .config file:

<configuration>
    <runtime>
        <bypassTrustedAppStrongNames enabled="false"/>
    </runtime>
</configuration>

Or by editing a registry key so it is in effect for all .NET programs:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
"AllowStrongNameBypass"=dword:00000000

Also set the HKLM\Software\Wow6432Node key on a 64-bit machine.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • The reason I am not marking this as the answer (I did +1 it) is because it focuses on strong names and not digital signing. Strong names are not trusted where digital signing should help in this regard. – Robert MacLean Sep 12 '11 at 10:21
  • The reason I didn't mention certificates is because they are not relevant to .NET and only ever checked during file transfers or operations where the identity of the certificate owner needs to be verified. The are *not* meant to protect against tampering. – Hans Passant Sep 12 '11 at 10:28
  • Digital certificates are relevant to .NET as the CLR is signed by them. Digital signing can be used to verify tampering (`signtool verify /a `), it may not be used that way in .NET but it can. Since it can be used that way, why isn't it? [More Info](http://msdn.microsoft.com/en-us/library/wd40t7ad.aspx) – Robert MacLean Sep 12 '11 at 12:42
  • We'll have to agree to disagree about this. Your link describes strong names, they *are* used to detect tampering. I showed you how to turn verification back on. Digital certificates are used to prove identity, a completely different goal. And expensive, surely a primary reason that they are not required or used this way in .NET. – Hans Passant Sep 12 '11 at 12:54
  • Disagree about what in particular? Digital signing not being relevant, digitial signing not being able to verify files (see [signtool](http://msdn.microsoft.com/en-us/library/8s9b9yaz.aspx)). I agree that digital certificates can be used to prove identity, but they can also be used to verify (see [this](http://en.wikipedia.org/wiki/Code_signing)). You state expensive as the issue, is that a cost factor or a performance factor (as I mentioned in the question)? – Robert MacLean Sep 12 '11 at 13:29
  • Cost, Verisign and the like charge about three hundred bucks for a certificate and a yearly fee. – Hans Passant Sep 12 '11 at 13:40
  • so the 'expensive' you use is cost? Considering I have been very clear that I am talking the ALREADY signed CLR/BCL, there is no cost to you. Does make your previous comment seem wrong. – Robert MacLean Sep 13 '11 at 07:59
3

They are in the GAC. Whoever can mess with the GAC is already a privileged user. Also most applications run in full-trust mode where this is irrelevant anyways. Because in a full-trust application you can use pointers, native-interop,... all of which can break verification based security.

Code verification is important in scenarios where you execute lower trust code, for example in Silverlight. In such a sandbox you only want to execute:

  1. Verified safe untrusted code
  2. Trusted code which is either in the GAC or signed with a key you trust.

  1. Example of this is user inputs password into application, it is stored in a SecureString but the BCL is compromised so the attacker is now getting that info. It allows them to capture the information for something else. I realise the attacker if he could replace the CLR could put a key logger on the machine too, but that is (hopefully) detectable with a decent security tool.

You already have a broken security model here. There are so many ways to attack your application in this threat scenario that you don't need to care about the BCL. For example the attacker could patch the NGened or JITed code. Either to directly hook into the SecureString methods, or your input handling code. He could use a variety of key logging or message interception features which in my experience are rarely detected. He could subclass your window. You could replace your GUI entirely. He could simply replace all your assemblies on disk. Unlikely that the user would notice.

In my experience most security tools don't even care if an application installs a low level keyboard hook, which is one of the easiest ways to key-log.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • The GAC assumption is wrong - the GAC does no extra checking and provides no additional trust. In fact it is easy to replace assemblies there, with no strong names and no digital signing. – Robert MacLean Sep 12 '11 at 08:33
  • 2
    But only if you're an admin on that machine. – CodesInChaos Sep 12 '11 at 08:33
  • I agree that if you can mess with the GAC you likely do not need to because you already have permissions high enough to own the machine. This doesn't help for attacks that place backdoors for later or hidden monitoring on the system - would it not be worth .NET to be check to mitigate those attacks? – Robert MacLean Sep 12 '11 at 08:34
  • No it's not .net's place to do that. How would it do that? Even an untrusted user can fool .net running on his account into believing that assemblies are signed by somebody else. Once you have raw memory access you own the process and .net isn't part of the security model anymore. The only use of this stuff is sandboxing code and prevent it from executing arbitrary code with the privileges of the hosting process. – CodesInChaos Sep 12 '11 at 08:37
  • "No it's not .net's place to do that." - My very question is why is it not .NET place? You talking about applications doing anything to the machine, but how do I know if MY application is being compromised by an owned BCL/CLR? – Robert MacLean Sep 12 '11 at 08:44
  • You should first specify the privileges of your attacker, and what privileges he wants to get. Else you just get what raymond calls "rather involved being on the other side of this airtight hatchway". Once the BCL is owned the attacker already owns your user or even machine and that includes your application. – CodesInChaos Sep 12 '11 at 09:00
  • thank you for the suggestion and I have updated my question to be more clear – Robert MacLean Sep 12 '11 at 10:21
  • I have cleared it up, again. Thank you for focusing on the attack vectors and I am learning a lot from this, but none of it is related to my question. See second last paragraph for details on what I am really concerned about. – Robert MacLean Sep 12 '11 at 12:33