Log in

View Full Version : .NET strong name signature.


naides
October 7th, 2007, 21:14
I have been dealing with a very big program coded in C#.
There are some files that mention Aladdin HASP HL, but I am not sure exactly how the protection is all put together.
Anyway solving this puzzle has been difficult because the files/code that contain the salt of the protection are not present in disk. they seem to be unpacked on the fly, and I have not been able to find where the original code is stored. If I analyze the application using Lutz Reflector, It asks me where module such and such is located and I cannot find it. I can see that the main application invokes classes from this "ghost" modules but the actual code is labeled as unavailable by Reflector.

I pretty much grepped the whole hard drive with strings (The name of classes and functions) that should be contained in the "ghost" protection modules, which are .NET dlls, and came out empty handed, suggesting that the ghost code is encrypted somewhere.

Eventually, using DBGClr.exe, I was able to see that the ghost modules were indeed loaded at specific memory addresses.

Let's call the key protection module "protectfile.dll".
Process dumpers like PE tools or LordPE do not see those ghost modules, but if I attach OllyDBG to the .NET executable and I look at the address given to me by DBGClr.exe I see the protectfile.dll .NET code right in memory on a nameless location, of type MAP, RW. It has a typical PE header and everything looks Kosher (Who said olly is useless with .NET? you can place breakpoints on regular API messaboxw and the like, to learn about the overall location of the protection)

Olly saved the contents of the MAP section to a file in disk which is a perfectly functioning .NET dll!!!!

I disassembled the .dll with IDA, analyzed it with Reflector: When Reflector asks for which file contains this and this code, I point to the dumped file, and now reflector analyzes its code seamlessly. What is better, If I load the original application with the dumped "protectfile.dll" in its working directory, instead of loading the unpacked ghost, the application loads my dumped "protectfile.dll", and works just fine

I did a small surgery to protectfile.dll so the application will always be licensed, and:

Fuck: Strong signature exception, .NET refuses to load the modified .dll.

I tried to remove the strong name form the file using SNremove.exe,
but now the application refuses to load protectfile.dll without strong name signature.

I know for a fact that my crack works, because if I modify the bytes in memory, using olly, after the original protectfile.dll is loaded, the main application works as licensed.

So I can think of a few ways to clear this hurdle:

Re-signing the modified protectfile.dll. It is my understanding that this is not an easy feat: The strong name signature works by making a hash from the file, and then the hash is encrypted using RSA 2048 bit key, with the vendor's private key. at load time, .NET generates a hash of the file, un-encrypts the hash out of the signature using the public key and if they don't match, blam!

Some people published a work around taking advantage of a bug in .NET framework 1.1 .
http://www.grimes.demon.co.uk/workshops/fusionWSCrackOne.htm
Apparently the bug was fixed in .NET 2.0 which is the framework of these executables, so I do not know how far this would take me.

Another approach would be to use a loader, that would patch protectfile.dll in memory, after it passed muster for integrity, but a loader for .NET executable has its own wrinkles: I don't know if the typical apis of a loader will clash with the .NET environment.

Another crazy idea I had was attacking the .NET framework itself, sabotaging the code that does the strong name validation and throws the invalid signature exception to make .NETsmile despite the signature being wrong.
(Doubt this will work, I think .NET is fraught with checks and self healing mechanisms)

Before I go on inventing the wheel, anyone here with knowledge in the issues could suggest something?

Note: I promise I will write a tutorial but I need to defeat this beast first. . .

rendari
October 8th, 2007, 00:31
That is quite.... strange. On CodeProject I've seen a tutorial on how to remove strong name signatures using ILasm, all he did was just cut out the strong name part of the .net program and reassemble it in ILasm. But from what I understand the application refuses to work without a valid strong name signature for the file? Well, I'm sure you thought of this, but what about patching the application to load irregardless?

Anyways, there is 2 places it can fuck you over:
a) the application checks for the strong name signature (solve: patch the app)
b) the .NET framework is checking for the signature(solve: remove signature via the method outline on the Code Project).

If you're looking to patch .NET itself so that it always returns good on the strong name... well I think I did that like a year ago. If I remember correctly the API you are interested in is "StrongNameSignatureVerification" in mscoree.dll.

Hope that helps.

disavowed
October 8th, 2007, 00:42
Quote:
[Originally Posted by naides;69263]I don't know if the typical apis of a loader will clash with the .NET environment.

They shouldn't clash... a loader should work just fine for this situation.

jstorme
October 8th, 2007, 04:30
The easiest way I know is by using sn.exe.
Code:

sn -Vr <assembly> [<userlist>] [<infile>]
Register <assembly> for verification skipping (with an optional, comma
separated list of usernames for which this will take effect and an
optional test public key in <infile>.

A second way that worked for me is to place the original assembly in the GAC (C:\windows\assembly). Drag and drop it there in Explorer. After that the file is located on disk in a directory similar to this:
C:\WINDOWS\assembly\GAC\<assembly>\<version>__<publickey>\<assemblyname>.dll
Now write a small program that patches the above file. Because the file is located in the GAC, the CLR skips the strong name verification test. It does this because it already checked the strong name when the assembly was dropped in the GAC.
Hope it helps

naides
October 8th, 2007, 16:04
As usual, big thanks to all the people that took the time to help me. You are always awesome. . .
As the lazy bastard I am, I tried first the simplest of the suggestions: the second one that jstorme gave me.

It worked like charm!!!!

I moved the original .dll to the GAC, and the app reads it from there as long as I erase the .dll from the working folder.
I used HIEW to modify the .dll in place and violá!!! Other HexEditors (HexWorkshop, Ultraedit) that use Windows API to browse for files in the GAC get lost and refuse to load GAC files at face value.

jstorme: I owe you one. Very many thanks

rendari
October 8th, 2007, 22:34
It also awakened an interesting idea in my head using StrongNameSignatureVerification" in mscoree.dll and mscowrks.dll for anti tampering, since I just found out it is possible to request the strong key of an image. So what you do is load the DLL into memory, and try to verify its strong key with the above listed API ( a variant of it actually). If no strong key is present or strong key is bad, you know that it has been tampered with and GG

dELTA
October 9th, 2007, 06:20
The following tool also comes to mind, which (depending on their verification method) could be useful here:

Re-Sign, for automatically removing and reapplying your own signature to .NET assemblies:
http://www.woodmann.com/forum/showthread.php?t=9926

naides
October 9th, 2007, 20:57
Thank you dELTA. I tried the re-signing with the .dll but it failed to work: The application checks some part of the strong signature when it loads .dll modules, so unless I want to make major surgery in the verification part of the code I stayed with the GAC solution. On the other hand, re-signing .exe modules became necessary and worked just fine. Ugghhhhh! This one was like peeling an onion.

I also tried the sn -Vr <assembly> trick but it failed at some point. I will work it around when I have more time. . .

[Ntoskrnl]
October 12th, 2007, 06:04
Load the assembly in the CFF Explorer, click on Rebuilder and check "Remove Strong Name Signature", then click on Rebuild.

Just like this:

http://ntoskrnl.pmode.net/remsns.jpg

To make an app work with a non-signed dll you have to set to 0 the PublicKeyOrToken in the AssemblyRef table.

Just like this:

http://ntoskrnl.pmode.net/snsinv.jpg

I hope this helps.

naides
October 12th, 2007, 06:54
Thank you for the suggestion NT. I'll give it a try . . .