C# - Server-side Reflection/Dynamic Method Calling? - c#

This is probably coming off as a REALLY broad question.
But is there a way to have my applications code (or some of it) stored on a server, and download it and execute it securely?
I've been seeing ASP.net everywhere but I don't fully understand it. Is this basically exactly what im looking for, or is it some kind of C# Website Hosting, like xampp?
Either way, what im looking to do, is to be able to download some C# methods, not an entire namespace and be able to reference code like, System.*, Program, Form1 and such from those methods.
I managed to get CSHarpCodeProvider working and with System references using its CSharpParameter but it uses a direct namespace, essentially asking for an entire full valid .cs file, whereas I want to load in methods only and not have it secluded but to be interactable with all existing code.
This is probably a lot to ask and probably doesn't exist.
Here's my formula:
Make a request to website.com/api/login.php?e=email#domain.ext&p=Pass123, returns obfuscated C# code along with the first line of text being an MD5 hash of the C# code, Email, Password and random generated strings/numbers/symbols.
Generate the verification hash on the C# Client Side, send the returned hash back to the website on a different php script, That script will verify if it's correct and will return a session token even if it's an incorrect hash (meaning the request was tampered with).
The C# returned from the first request, This seems good to go, Everything matches up. Replace the placeholder garbtext like <!!TOKEN!!> with the token from request 2 without doing verification checks at all.
Execute the finalized C# code.
The finalized C# code will do stuff like create methods that would be used throughout the application including a private bool x() that returns if the application is licenced/purchased.
Use application as normal using the methods created.
Notes:
Having some unixtime checks in the hash and inside bool x() and such would be a good idea to further prevent un-licenced intrusion.
Pros:
The application is theoretically almost impossible to "Crack". To crack it, you would have to manually replace all the functions. Obfuscate the code on server-side before returning to the C# client and it will be extremely hard to do and would be very time consuming.
Can be auto-updated and you wouldn't need to update the .exe unless you did vast changes.
Cons:
Will require a lot more server power depending on the size of your userbase.
Costs you and makes profit a lot smaller if your selling an application licence.
Internet connection needed no-matter-what!
Startup time would be slower.
Downtime can seriously impact your application.

Related

Is there absolutely no protection for Windows applications on dotnet?

I am in the middle of developing an application in Winforms and there just doesn't seem to be any protection from decompilation of the executables and other generated assemblies... there are tools that decompile literally within seconds. There are obfuscators available; however, I am specifically looking for a free one.
I store some pretty sensitive strings within the application, and though I try my best to keep them encrypted or in the local sqlite database, there is always that one, single point of failure that leaves the entire application vulnerable. I checked out a couple of obfuscators, both open source and commercial offerings. The open source one seems to be broken, and the commercial ones are priced quite steeply, which is unaffordable for an indie developer like me.
I am aware that an executable has to run in memory, and this in itself makes it vulnerable. And a determined attacker can eventually decompile an application. However, I want to make this process as expensive as possible. At the very least I would want to protect the strings within my application.
My question is, is there just no way to protect an application assembly from getting reverse engineered if I decide not to use any of the expensive options available?
There's lots of protection in Windows. But it's all there to protect the your users from you, not the other way around.
The simple fact of decompliation is: "As long as a computer can still execute it, it can also still decompile it."
Execution is a process that translates binary into actions.
Decompliation is a process that translates binary into code.
If one is blocked, the other is blocked as well.
Obfuscation can make it harder to read the decompiled code. But that is about all it can do.
I store some pretty sensitive strings within the application, and though I try my best to keep them encrypted or in the local sqlite database, there is always that one, single point of failure that leaves the entire application vulnerable
Every string, is only as save as the place you keep it at. The same applies for encryption keys. There are 2 limited workarounds:
if it is around comparing the input to something in the backend - like you do with passwords - password security can work. Modern PW security means not even the Adminsitrator can figure out the passwored, yet you can still compare user input to it.
You could move the strings into a seperate application. Instead of giving applications the SQL Server Connection string, you give it access to a WebService that you control. Only the WebService actually knows how to contact the Database.
It depends on your practical scenario what you can do. But in the end, if a string or other peice of information is to be useable, it is vulnerable in memory.

Close wpf application using dll

I have a dll with an "authentication" method in it that checks if a password is valid, like this:
public static void AuthenticationExample(string password)
{
if (PasswordIsValid(password))
this.locked = false;
}
To prevent the password from being "cracked" by a loop, I want the method to crash the entire application if authentication fails, like this:
public static void AuthenticationExample(string password)
{
if (PasswordIsValid(password))
this.locked = false;
else
Crash();
}
Is there a way of doing this?
Alternatively, what is a better way of protecting a dll?
CLOSING WPF:
You can just call the main window and close it or throw a custom exception.
PASSWORD PROTECTION:
I had same issue. Finally, understood that whatever you do, it can be cracked. Nothing is fail proof. If your license verification is done on the cloud, like sending some info to a server and receiving back response, it can be managed to an extent.
Just because everything can be hacked, doesn't mean that you have to leave your product wide open for cracking. You can add some barriers so that it is little hard for the crackers. If the product is worth the effort, eventually someone will hack it.
For my applications, I have 2 or 3 licensing steps (which can slow down a hacker but not stop him/her)
A dll (say, DLL-A) with cryptography methods for verifying a license. DLL-A will be placed in working directory. Along with that, a copy of this dll (say, DLL-B) will also be placed as an embedded resource.
During runtime, when the DLL-A is about to be loaded, the DLL-B will be extracted and hash for both will be compared. This is to ensure that DLL-A is not tampered with. In case, DLL-A is tampered, the DLL-B will replaced DLL-A.
Along with that dll method, a XML-Signed file will also be used. This will be verified somewhere in the code.
A C++ native library, with different cryptography methods. This will also be used similar to DLL-A /DLL-B procedure (steps 1,2).
Thus, in my application, i generally use 3 to 4 different license verification scheme. All are independent. Even though everything can be hacked and broken, the hacker will have to be fed up trying to hack all the 4. And with every year, I change my licensing methods and update the new app. So, this means that for every year, hacker has to spend hard time to hack it. (Which should eventually make them feel frustrated).
Above all, I also have cloud based verification for my apps (the ones which store credentials in cloud DB). But, there are still some clients who expect their app to run without connection to internet (due to some security reasons).
Note: Eventually everything is hackable. Point is you just make it hard for hackers.

Communication between C# .NET and PHP/Laravel

In my laravel application, I want to provide the users with the opportunity to download a copy of their stored data in the form of a Word document. I found that certain parts of this can only be accomplished using C#/.NET.
For this, I wrote a C# application alongside a method called GetWordProfile(User user) which returns FileInfo set to the actual path of the output file (this is always within the storage folder of laravel, so laravel has access to it). I only need the path and everything's done and dusted since from this point on, I can manage my laravel application to download this for the user.
However, the question is how do I get there? I must not forget about potential errors which may occur and thus display them (the errors are (inside my C# application) handled by log4net in a file as well as on the console; same goes for all output).
I tried to run my application using shell_exec respectively exec, however, both only returned zero results (null) (despite having set $output for exec) and thus seem not to be suitable. Also, I usually don't want loops (inside PHP/laravel) too much since you're then using a lot of computing power which is unnecessary for this sort of task, also you don't want to let your users wait more than, say, 5 secs, seeing nothing in your browser but the script being executed within a blank page (during the execution there's no content, obviously).
EDIT: I also approached the use of COM which ultimately did not work properly out either.
What is an appropriate approach towards this?
I did something similar with Python + C# a while back using IPC (Inter-process Communication) using named pipes.
EDIT: URL is broken. Here's the question someone asked previously on this topic.
Interprocess Communication using Named Pipes in C# + PHP

How to test whether a given functional code unit (C#) does NOT create/write any files to disk?

Imagine there's a mission-critical process that'll be used in a business which handles sensitive information (think of Credit Card, social security, patient records...etc). I would think this unit ideally should do whatever it has to do on-the-fly, meaning it won't intentionally write files to disk containing sensitive information. The idea here is that if the computer that runs this process is compromised, no sensitive information can be leaked, at least not by means of files.
What approaches could be taken to, say, come up with a unit test that will fail if the unit under test tries to write any file to disk?
There is the FileSystemWatcher (http://www.c-sharpcorner.com/uploadfile/puranindia/filesystemwatcher-in-C-Sharp/) however this requires you to know a specific directory. In your case this probably isn't very helpful since the program could write anything to disk any where. This introduces a unique problem. However, I have also found something called Detours from Microsoft. This appears to intercept all native win32 api calls. http://research.microsoft.com/en-us/projects/detours/ The issue with this is that its kind of hard to test, and integrating it into unit testing will be a challenge.
When you have to treat your software as "untrusted" in the sense that you need to prove it doesn't do something, testing becomes a complex task that requires you to run them on very controlled environments. When hooking in to the Win32 API, you will be deluged with API calls that need to be processed quickly. This can result in unintentional side effects because the application is not running in a truly native environment.
My suggestion to you (having worked several years doing software testing for Pharma automation to the exacting standards of the FDA) is to create a controlled environment, eg a virtual machine, that has a known starting state. This can be accomplished by never actually saving vmdk changes to disk. You have to take a snapshot of the file system. You can do this by writing a C# app to enumerate all files on the virtual drive, getting their size, some timestamps and maybe even a hash of the file. This can be time consuming so you may want (or be able) to skip the hashing. Create some sort of report, easiest would be by dropping them in a CSV or XML export. You then run your software under normal circumstances for a set period of time. Once this is complete, you run a file system analysis again and compare the results. There are some good apps out there for comparing file contents (like WinMerge). When taking these snap shots, the best way to do it would be to mount the vmdk as a drive in the host OS. This will bypass any file locks the guest OS might have.
This method is time intensive but quite thorough. If you don't need something of this depth, you can use something like Process Monitor and write the output to a file and run a report against that. However in my work I would have to prove that Process Monitor shows all IO before I could use it which can be just as hard as the method I spoke of above.
Just my 2 cents.
UPDATE:
I've been thinking about it, and you might be able to achieve fairly reliable results if you remove all references to System.IO from your code. Write a library to wrap around System.IO that either does not implement a write method, or only implements one that also writes to a log file. In this case, you simply have to validate that every time a write occurs using your library, it gets logged. Then validate using reflection that you don't reference System.IO outside of this new wrapper library. Your tests can then simply look at this log file to make sure only approved writes are occurring. You could make use of a SQL Database instead of a flat log file to help avoid cases of tampering or contaminated results. This should be much easier to validate than trying to script a virtual machine setup like I described above. This, of course, all requires you to access to the source code of the "untrusted" application, although since you are unit testing it, I assume you do.
1st option:
Maybe you could use Code Access Security, but the "Deny" is obsolete in .NET 4 (but should works in previous version):
[FileIOPermission(SecurityAction.Deny)]
public class MyClass
{
...
}
You may reactivate this behavior in .NET 4 using NetFx40_LegacySecurityPolicy
2nd option:
reducing the level of privilege may also works, as I know that downloaded app can't write on the disk and must use a special storage area.
3rd option:
Remove any reference to System.IO and replace by an interface that your code must use to write data to disk.
Then write an implementation that use System.IO (in a separate project)
In the nunit test, mock this interface and throw an exception when a method id called.
Problem is to ensure any developers will not call System.IO anymore. You can try to do this by enforcing coding rules using FxCop (or other similar tools)

Faking GetCallingAssembly() to point to a different assembly

I'm a developer of a game in c#, and I have a security feature in which my server dynamically creates a DLL with some secret keys in it and uploads this DLL to amazon s3, and then pushes out challenges to people are random. When the clients receive this challenge they have 30 seconds to respond.
The clients download the DLL from amazon s3, and using reflection call a method, which takes in a key sent to them by the server.
The dll then takes the key passed into the function, the secret key randomly built into the dll, and a crc hash of the GetCallingAssembly() and hashes them together. This result is returned to the client and the client pushes the response back to the server.
Back to the question... We have a hacker who has somehow found a way to fake GetCallingAssembly and to better understand this, so that I may find a way to prevent it or use something a little harder to fake, I would like to replicate what he did.
From what I've gained its an application he is using, he did NOT use code to do this. But i have found NOTHING in regards to this. Any help with be greatly appreciated so that i can remove this guys security hole.
There are a variety of techniques that could be used for this. For example, the Moles framework allows one to replace the implementation of even static methods on BCL assemblies. It accomplishes this via use of a CLR profiler, which may or may not be what your hacker has done.
It seems like the only thing you'd have to do in order to trick GetCallingAssembly would be to create a new assembly with the same name. Now the chain is broken. I can't point to how he did it, but I can provide a suggestion to make it more difficult to crack...
Client downloads DLL from S3
Client invokes method in the DLL
DLL gets the calling assembly, and invokes a method on the client. This method takes in some salt (preferably one of the unique keys in the DLL or a datetime), appends it to a secret string (stored in the client), hashes the result, and returns this hash to the DLL.
Once the client provides the correct result, then the DLL answers the server correctly.
It's always possible to break in, but the more encryption-related steps in-between, the more difficult you make it for them. And this step wouldn't take much effort to add.

Categories