How to make my program not run on other computers? - c#

I have an assignment, and it has (amongst others) two demands:
make an installer
make it so that if it is installed on one computer, anyone trying to run the same files on another computer will fail.
I'm using VS9 (2008) express, I think I can do the installer part, but I'm not sure how to do the "security" part. I don't need any hard to crack safety, just a dumb condition that will stop most users from copying the files to another computer. (Like checking the MAC address).
Any ideas?
EDIT:
I would like to check the MAC address but I want the program finalized during installation. Meaning that after I install I can't move the program to another machine. It also does not have to be a very smart or difficult condition, just bare minimum. I just don't know how to do it in the installation.
EDIT:
It's sad I don't have the complete VS then I would be able to do it easily.

If you're looking for some way to mark the first computer as the "authorized" computer, then you need some external service you can ask for permission to launch.
The first person to ask permission would be allowed, the rest would be prevented.
You'll also need to come up with some way of identifying a particular instance of your application that's different for every install.
If your app needs to be authorized for the machine, then you will need to calculate some fingerprint for the machine it can use each time (eg across installs).
[Edit]
This approach is useful when you're worried about copies of the installer being distributed as well. You did specify that its ok to install on multiple machines, so in that case MasterMind's approach is superior. It will work, and does not requires a 3rd party server
[Edit 2]
If you're looking for info on how to build a custom installer, try here

First of all, come up with some function to generate a unique PC signature, like Windows does for activation.
Your installer will be creating this signature and writing it to a local file (better encrypted). You can create a simple console executable to generate this file and include that executable into your installer package, setting it up to run silently after the successful installation.
Your program when starting will be creating the signature again using the same algorithm and comparing it to the one created during installation. If the new signature is different from the original one or the signature file is missing, then exit without loading the UI.
ADDED: If you don't need it very complex, you can just choose a few unique values like the MAC address you suggested, maybe the hard drive serial number, mainboard serial number, concatenate them into a single string and generate the hash out of it.
This approach will allow for an unlimited number of copies to run (but each installation will only be workable on one single machine where it was installed). If you stick to the identification by hardware (or OS product key as well), then the application can run on various OS installations on the same machine.
This strategy, however, implies that you control all installations (or perform them yourself) or absolutely trust your client not to install additional copies elsewhere or distribute your installer. If you need that kind of protection as well, then you should consider product activation. It can be quite complicated if you do it yourself. There are however third party products to help you. Some offer product activation services: Google: activation service

Once you have a decent fingerprint, the rest is easy. Personally I'd take something like the MAC address and the windows product ID (at HKLM\Software\Microsoft\Windows\CurrentVersion\ProductId) and use a hashing algorithm to get something reasonably obscure.
edit:
Here's a question that shows you how to get your MAC address as a string:
Read MAC Address from network adapter in .NET
Then grab your windows product ID (in case they don't have a network adapter) from the above registry key. Concatenate both strings and do a GetHashCode() (or use your favorite hashing algorithm) on the result. This is a simple way to get a UID for a computer.
Write the hash to a file or to a registry entry when your installer is executing and check it when your program starts up.

Consider using two or more values that potentially identify the machine, e.g.
Windows product code
Volume serial number of the C: drive
MAC address of an ethernet interface
And if just one of these changes but the others match, update that one value in the registry and continue running normally. Hard drives get replaced (regularly), Windows gets upgraded (occasionally), Ethernet adapters get replaced (rarely but it does happen.) It can be very frustrating when old software stops working because of this.

Bare minimum answer, assuming the only requirement here is that the software should run if installed through the installer, and won't run if copied to another computer:
Write a simple key to the registry. Most likely your product's version number, incase they copy a newer version to the computer, it has a different number to check for.
In your software, just make sure this registry value exists.
For packaging installations, I enjoy using NSIS which has simple methods for writing to the registry.

I like the idea of checking the MAC address.
I have also seen product key/online activation combinations where you enter the product key and the software contacts a web service that logs the product key and # of installs.

This isn't the most secure option or anything but you did say it didn't have to be smart...
On install, you could set a program variable to be the machine name (or a hash of it if you like).
Like:
myProgram.Properties.Settings.Default.Machine = System.Environment.MachineName;
myProgram.Properties.Settings.Default.Save();
then check that on startup:
if (System.Environment.MachineName != myProgram.Properties.Settings.Default.Machine)
{
MessageBox.Show("Can't run on this computer");
this.Close();
}

To get the installer to only work for one machine, you'd pretty much have to build it for the target machine. I dont think it would be possible to make an installer that assumes the first machine it sees is it's mommy and is attached for life.

-1 for clinging to an antiquated license-restriction policy that is a poor practice in general. Hardware dongles and "device detection" are SO 1990.
People own more than one computer. They buy new computers. They upgrade their computers. Computers break, resulting in replacement of motherboards or network cards.
All of these, given your design, will result in honest, paying customers being locked out of what they've paid for and will have to call you for support to "reset" their activation.
And each time you do so, your overhead will increase by, very likely, more than the actual cost of a license.
I'm not suggesting you give up and just send your app off to the torrentverse, but you should think more creatively about how to allow customers the freedom to use what they paid for, keep your support costs low, and discourage pirates.
One creative solution would be to cache the user's settings on your server, keyed by their serial number, and synchronize them every time the application starts and is connected to the Net.
This will allow a user to install the app on, say, both a laptop and desktop, and will actually be a value-add for customers because their settings are synchronized between devices.
But it actively discourages users from sharing their license key, since doing so would mean they would be sharing their settings with every pirate user, or that they would have to remember to stay disconnected from the Interwebs when they open or close the app.

Related

Secure network traffic c#

I'm developing a program in C#.
It connects to the internet to see if this copy is valid.
Currently I'm just sending the licence key and getting a response (0 or 1) if the key is valid.
The problem is that some users just fake the data with some packet capturing tool and replay it.
So the application is very easy to crack. How can I prevent this?
Here is what I essentially want to prevent:
Network replay attacks
Authentication "emulators"
It should be impossible to find out what data is sent.
Maybe I should add the current time and then encrypt the packet ?
So it's always different ?
Attention: Please don't warn me that it's easy to crack the application itself by modifying it. I know that. This question is only about the network part.
If you use SSL or HTTPS then you don't have to worry about users cracking the data packets. This is easy because the libraries already exist and are easy to implement. With C# and IIs for example it is just a matter of installing the certs and changing a few configuration items. (Maybe a recompile with some slight code changes).
Assuming you actually want to prevent license abuse there are far better ways to do this. The "phone home" approach is easy to roll yourself, but as you've noticed it's full of holes.
Disclaimer: I work for a company that makes commercial tools to solve these license management and copy-protection issues. There are other similar products available from a variety of vendors.
This isn't that different from thinking about how to do setup for your application. Choices are roll your own or buy an existing 3rd party toolset. Rolling your own at first blush make seem cheaper, but that's perhaps only because you haven't really discovered all the true requirements to create something robust and reliable. The 3rd party tool vendor needs to charge for their products, but they've spent years discovering all the issues with particular problem set and have solved the problems. So that eliminates work for you and leaves you free to focus on where your application can add value.
The difference is if you get setup wrong your users will be irritated; if you get copy protection wrong your product will be pirated.
In any event, reducing license validation checking to a binary "either/or" condition is extremely easy to crack--doing that check over the net makes it 10 times easier (record playback attack). Modern approaches encrypt the executable and the license is contained in the key to decrypt it (this is an oversimplification since the actual methodology includes a lot more complexity to make it virtually impossible to get around). Only by having a valid license can the executable be decrypted on program load and run.
If you want to do it the way you've described, consider this:
Have the app use a predictable, changing value (such as a lookup from a table of random numbers coupled with some external value like time) to create some kind of hash. Have the server implement the same code. The server sends the hash to the app, which compares it to its own hash. If they match, the app is allowed to run. If they don't, it errors out. Since the hash is different on ever startup attempt, recording it over the network won't allow the user to get it to run the next time it tries to start.

How to generate new guid for each installed instance?

I use C#. Is it possible to make every installed instance has different guid?
To be more specific, let's say I have an application called "abc" and a setup for it. Each time it is installed on a different computer, I want it's assembly guid to be regenerated. If it's not possible, I always listen to new ideas.
Thanks in advance.
Why not just check for a file on startup ? You could then Generate a UID and insert it into the file. So the next time the Application loads you would be able to read the UID from the file ?
This could be either on a per user basis (where you would put the file in their user directory) or per installation (Where the file is right next to the executable or somewhere outside of the current user directory, just watch out for Windows File Permissions!).
It sounds like you want to uniquely identify the machine on which your application is installed. There are many ways to do this - but changing the assembly GUID is not a good option for this.
Instead, you should look at the machine configuration, and generate a unique Id from it rather than generating a random id. For example, you could take the machines MAC address as a starting point.
This would make the machines unique id deterministic, meaning you don't need to store it anywhere, you can generate it each time you need it :)
Early versions of the GUID specification (version 1) actually used the machines MAC address as part of the GUID - however this led to security problems and was the cause of the Melissa virus. The modern GUID specification does not use MAC address data.

C# Application License Components and Controls [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
If I have 5 target computers and I am going to install my application to one of those target computers. How I prevent users from copying my application to other target computers?
To make it clear, I don't want them to copy my application after installation (They should not copy my application from the installed application folder). The problem is now I setup and deploy my application using Visual Studio 2010 Setup and Deployment, but anyone can copy my application folder after the installation for example, my application folder (exe, DLLs, and resources) locates at "Program Files/MyApplication". They actually can copy my application from that folder and paste it to other computers then use it. Of course, they can copy it but I think they should not be able to use my copied application right? Is there a way to protect them copying my application? I have to write an additional code?
I am really new for software distribution. Please guide me what I have to do.
Thanks
You can use Rhino Licensing framework for license file generation. It has LicenseGenerator class which has a Generate method. Here is what it looks like:
public string Generate(string name, Guid id, DateTime expirationDate, IDictionary<string, string> attributes, LicenseType licenseType);
Generate method takes the name of the licensee. Unique id for the license which can be generate as Guid.NewGuid(), the expiration date and the attributes dictionary is a place where you can store a custom key value pair in the license file.
The way it can works is that, you can embed the information of the machine in the license and in the verification phase you can check whether the license belongs to the same machine. This means that you can not copy license file of one machine and put it on another machine because it won't work.
In the license file you can store the following information:
The expiry date of the license
Name of the person for whom the license is generated
Hash calculated based on the system information
The industry-standard way of preventing users from running an application on more than one machine is indeed to lock your product to some parameters of that system. However, you need to think about the following issues to avoid future work or upset customers down the road. Crude systems that don't deal with these issues have given node-locking a bad name, but when done properly node-locking is unobtrusive, flexible and secure:
How will you accurately obtain the system parameters you will lock to? Asking users to read/type them is a common source of error, for example by mis-reading an 'l' for a '1' or a '0' for an 'O'.
The MAC address is commonly used for node-locking, but this is a poor choice as the MAC address can be set by an admin under many operating systems.
Say you lock a license to several parameters of the system. What will happen if the user does a minor system upgrade, so causing one of them to change? They won't be happy if your app suddenly refuses to run.
Users will want to move their license to a different machine at some point. You'll need to think about how you support this without making it a security hole.
Users machines will crash - it happens. How can they get their license running again on their new/rebuilt system?
Just some issues we've encountered and dealt with in our solutions. Hope this helps.
I use Infralution License Tracker. It is payware but allows for licensing of some part or all of an application. It also allows for key verification on on-line verification. It is possible to use customer information to generate the key so it should be feasible to register using information from the target computer.
http://www.infralution.com/licensing.html
When you want it really easy you can use LimeLM.
Simple online-verification with a trial option.
You need to use machine-locked / activated licenses to prevent this. This ensures that the license can only be validated from a single machine - if license validation fails, you can decide what steps to take - whether to exit the app, show a message to the user, allow a grace period, etc.
Try CryptoLicensing which supports activated / machine-locked licenses.
DISCLAIMER: I work for LogicNP Software, the developer of CryptoLicensing.

How to reliably get the computer's on-board network adapter's MAC address?

I am trying to (more or less) uniquely identify a system for licensing purposes. I have chosen the computer's on-board network adapter's MAC address for this task, since I can be sure that every cmputer running this software actually has one, and this avoids re-activation when changing e.g. the harddrive.
I am having troubles reliably identifying the onboard network adapter, though.
Using the "Win32_NetworkAdapterConfiguration" ManagementClass, I can get a whole lot of MAC Addresses, including the address I like, but I have not found a way to distinguish the onboard one from virtual adapters installed by Windows or Virus Scanners.
This list seems to be ordered, though. The MAC Address I am interested in is (on my machine) listed before other (real) network adapters. (The list is ordered by interface index.)
Using NetworkInterface.GetAllNetworkInterfaces(), I think I can identify the real network adapters by filtering on .NetworkInterfaceType == NetworkInterfaceType.Ethernet, but this list seems to be unordered (an added network card appears before the onboards one).
Is first using the second method to get a list of real networks cards and then sorting them by the order of appearence in the first list a reliable way of identifying the MAC address I am looking for? Can the interface index in the first list change?
I'd be happy to hear your thoughts!
Thanks!
P.S.: I know that the MAC address can be rather easily changed, but I can live with that. I cannot live with the customer not being able to use the software after simply inserting a WLAN stick =)
A rather low-tech solution would be to invoke the netstat command and look for the MAC address of the adapter that has a valid IP address. I've never seen the netstat command fail on a machine whereas I've seen WMI give unexpected results numerous times.
In any case, I have done a similar activation system before and I used the MAC address as the identifying key. In the end, it wound up being more trouble than it was worth - both for me and the customer! What I found to be a far better balance and less hassle was to have the user "sign in" the first time the software was installed. With the user's consent, you could send some piece of identification to the server such as their MAC address.
Then you only need to periodically check your activation database for evidence of major license violations and deactivate the keys as necessary. As a customer that hates product activation, and an ISV that hates software piracy, I can see both sides of the argument and this way it avoids putting the customer in the uncomfortable position of having to convince you they are legit when something (inevitably) goes wrong.
Just to name a few reasons why MAC identification may not work... I use two NIC's (wired and wireless) in my laptop depending on whether I'm at work or home. One or the other may be disabled at any time. The other thing to note is that I use virtual machines quite a bit and not only do they get their own MAC but I could specify any MAC I want. Then of course one day you'll find out that you have like 100 people in your database with a MAC of all zeros. :) Nothing is guaranteed here.
you should consider some other properties from WMI in addition to MAC address.
The way that Windows Product Activation handles this, is to look at properties like the MAC address (as well as other identifying information about the card itself, such as PCI vendor info), as well as some common device properties (HDD controllers, display adapters), and base the need for reactivation on certain thresholds. If too many of these things change, then reactivation is required.
Here's a great article on the topic and should give you some food for thought on how to approach choosing good properties to look at for your own licensing/activation system:
http://aumha.org/win5/a/wpa.php
If your main requirement is to uniquely identify a PC, then I suggest you take a look at this question. The accepted answer talks about a solution as well as the pitfalls of using the MAC address identifier approach
Hope this helps
To access Network Interface details in .Net, refer to the NetworkInterface.GetPhysicalAddress method within the System.Net.NetworkInformation namespace.
Usage is detailed on MSDN.
I would definitely refer to the link Ryan has provided with regards to relying on a MAC address for identification.

A different Approach for anti-virus . Am I going in the right direction?

I'm currently conceiving a system that works like an anti-virus, but also uses the White Listing i.e
Preventing Viruses from Running by having a database of Known legitimate Programs
Yes , there is the Windows UAC, but still many viruses "work around" it. I'm planning on a more reliable system.
My system has also a database of known threats (cryptographic hash).
Is this approach viable,
What are the possible loop holes in this approach
I understand that there has been a lot of attempts at this. But still I want to try it out.
I'm planning to use C# and .Net for a prototype may be i'll move on to C++ for performance later
Update:
Thank you all for your time and thoughts.
I decided to do some more research in this area before actually designing something
Espcially as pointd out below the Zeroday threat problem
What about DLLs used by executables? Do you hash them too? A virus can replace a DLL.
This has been brought up before, and there are products out there which do that. (Faronics Anti-Executable works like this)
There are two main problems with this approach:
A virus can embed itself into any file; not just EXEs. Programs can load DLLs and other bits of code(macros, scripts, etc), and programs can contain bugs(such as buffer overflows) which can be exploited by malicious documents and other files.
Every time you patch a system or otherwise legitimately modify the software, you also need to update the white list.
There is products like Appsense Application Manager that do this already. It was temporarily pitched as a security product but they changed tact and focused it on licensing. I think it's because it didn't work too well as a security product.
If you are planning to work with a limited set of applications and you can work with application developers you can use a code signing model. You can find a similar approach in most mobile operating systems. You have to sign all the executable modules including libraries and need to verify they have a valid signature and not modified using a root certificate.
If you are only planning to white list applications based on their hash value you need to make sure your white listed applications verify any modules they use before they load. Even if the applications/installation files are digitally signed it does not guarantee that a library will be modified later in a malicious way.
In reality, it is not even enough to only verify executables and libraries. For example, Xbox Linux hack utilizes a malicious save file. It is a specially prepared save file that causes a legitimate and signed application behave in unexpected ways. And, of course it is not possible to white list a save file based on its hash value.
Another problem with keeping a database is zero day attacks. You need to be ahead of the curve for creating hash values for new attacks and propagating these updates to your users otherwise they will be vulnerable all new attacks. Unless you only allow only white listed applications to be executed and that would be really restrictive.
IMHO, it is really difficult build such a system on open platfom. Good luck with it.

Categories