MEF: Component Authentication

I am creating a Windows application (Service), which, in short, consists of a “loader” and an “engine” (an object loaded by a loader that transfers control to it and then performs the actual expression tasks). Bootstrapper is a very simple startup procedure that has few features that can change. But the engine itself can be updated after installation, and I implement a mechanism so that it can update itself - by contacting the "main server" and checking its version number with the "latest" version. If a newer version of the engine is available, it will load it into the designated folder and call the method in bootstrapper to "restart".

So, whenever the bootloader starts, it uses MEF to "scan" the appropriate directories for IEngine implementations, compares their compatibility numbers with the boot, and selects the latest compatible version of the engine. Then it transfers control to the engine (which then, in turn, checks for updates, etc.). If there are no suitable IEngines — or MEF does not work during composition — it reverts to the default IEngine built-in implementation.

This application will work on a remote server (or several), and all this explains the need to maintain minimal maintenance of the manual application (for example, when there is no need to install / download a new version / reinstall, etc.).

So, the problem is: since the loader effectively transfers program execution to the IEngine object method, the implementation of a malicious IEngine (or simulator) that somehow finds its way to the scanned application folders can basically lead to complete chaos on the server if it was loaded and was recognized as the most suitable version of the engine.

I am looking for a mechanism to verify that the implementation of IEngine is "authentic" - as in the release of the corresponding authority. I play with some home-made “solutions” (having IEngine, it exposes a Validate function that is passed a “call” and should return the correct “answer” - differently, for example, if the boot file creates an arbitrary string that is encrypted and passed to the candidate for the engine, which then has to decrypt and modify the string, then hash, encrypt the hash and return it to the bootloader, which will perform a similar modification of the string in its random string, and then use the hash and compare this hash to the decrypted one the response (hash) from the candidate, etc.), but I'm sure that in .NET there are functions to perform this kind of check? I just looked at Strong Naming, but it seems that this is not the best way for a system that will dynamically load, but without thinking about the DLL.

Input would be greatly appreciated.

+4
source share
2 answers

Subscribers can be a digital signature with a private key. The result is called a strong named assembly .

When a strong named assembly is loaded, .NET automatically checks to see if its signature matches the built-in public key. Therefore, when a strong named assembly is loaded, you have a guarantee that the author has a private key that matches this public key.

You can get the public key by calling Assembly . GetName () . GetPublicKey () , and then compare it with the expected one, i.e. your.

You can scan through plugin assemblies, create an AssemblyCatalog for each of them with the correct public key (reject the rest), finally merge them into AggregateCatalog and build a CompositionContainer with it.

This is basically what Glenn Block also explained in this thread . (It’s best to ignore the Bnaya blog post; its interpretation of StrongNameIdentityPermission is incorrect.)

edit with answers to the comment wall:

To get this public key, I do a console application that displays the publication of a key byte array. I insert an array of bytes in my host application, and subsequently use this for comparison against the public keys of the candidates plugin. Would this be a way to do this?

Yes, but there is an easier way to extract the public key. Take a look at the -Tp sn.exe parameter.

Does this mechanism automatically prevent the build of the malicious plugin from opening the correct, but "fake" public key? As in the case, is there any mechanism to disqualify any assembly that is signed, but has a mismatch between the public key and the public private key, from loading / running in general?

As far as I know, verification happens automatically. A strong named assembly cannot be loaded (even dynamically) if its signature is incorrect. Otherwise, a strong name would be useless. To test this, you can open your strong named assembly in a hex editor, change something (for example, a character in the const string built into the assembly) and make sure that the assembly is no longer loading.

I guess I meant something similar to the hack / crack type described here: http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-security/407/Signed-assemblies-easily- cracked here too: http://blogs.msdn.com/b/shawnfa/archive/2008/05/14/strong-name-bypass.aspx

[... scan more comments ...]

However, this can apparently be bypassed by a simple fake (as shown in the first link, and explained more here): grimes.demon.co.uk/workshops/fusionWSCrackOne.htm

The “attacks” that you call fall into three categories:

  • removes a strong name at all. This does not violate authentication, the assembly will no longer have a public key, so you will reject it.
  • disable strong name verification, which requires full access to the machine. If this was done by an attacker, it means that the attacker already owns your machine. Any such security mechanism in this context does not make sense. In fact, we protect the attacker between the machine and the source of assemblies.
  • real exploit caused by a bug in .NET 1.1 that has since been fixed

Conclusion: strong names are suitable for use for authentication (at least with .NET 2.0)

+6
source

I wrote a blog post with source code for a directory that only downloads nodes with the keys you specify: How to control who can write extensions for your MEF application

+2
source

All Articles