by Adam
Smith
Index
Introduction
(From dictionary.com)
en·crypt (n-krpt)
v. tr. en·crypt·ed, en·crypt·ing,
en·crypts.
1. To put into code or cipher.
2. Computer Science. To scramble access codes to (computerized
information) so as to prevent unauthorized access.
This document will focus on a very small fraction of encryption.
That is, we will only discuss how to protect shareware applications
from being pirated using the encrypted keys. While there are many
other encryption source code sites, and such on the Internet (see
the Links section at the end of this document), we will focus
on how to create a system that will confuse any cracker and help
prevent him/her from cracking your encryption. There are a few
points that I need to make about this article outlining assumptions.
This article assumes:
- You are a shareware developer seeking a way to protect your
shareware program from being pirated
- You are at or near the advanced level
A note about the last assumption: when I say "advanced,"
I do not only mean in programming. In fact, even if you only know
a few functions and the basic syntax, you can create an above-average
encryption scheme using two often under-appreciated virtues: mathematical
talent and creativity. I consider them to be of either equal or
greater importance than knowing simple functions. Anybody can
throw together an encryption algorithm using a couple of neat
functions without any real mathematical thought. However, this
document is not a tutorial for developing a completely new encryption
algorithm. Chances are that you will end up using an already made
scheme. So why must one involve mathematical thought in order
to develop a *secure* encryption plan? While working to implement
a packaged set of code into your application, it would be to your
advantage to understand how it works and make any modifications
that would either make it faster, more secure, or less faulty.
Any modifications you make (provided that they do not impair functionality)
will make the cracker's job harder. If you go to a common site
and grab their encryption code to use, the cracker may have already
seen and/or used this code so they know how it works and therefore
can crack it with ease.
Now would be a good time to stop and enlighten those of you wondering
what a cracker is. For our purposes, cracker is any entity that
is trying to bypass your shareware protection. I have written
half-a-dozen applications that have been cracked. That means that
the protection was circumvented. Usually, after any given program
is cracked, source code that will allow anyone to bypass your
protection will be released. This program (which can be an executable,
text file, or just about anything else) is called a crack. So
crack along with a few suffixes can produce different nouns or
verbs.
When I first started considering options for this document, I
was overwhelmed. I could write a whole book on shareware protection
alone! I have been forced to specialize even more than just shareware
protection. As always, I choose to be as unique as possible. All
across the Internet, you can find source code for various encryption
techniques. Here we will focus away from the actual algorithms
and more toward methods of implementation and fooling crackers.
Be
Creative!
Introduction
I would estimate (please remember, this is only an estimate) that
95% of all shareware programs use a kind of string for the key.
Whether it is a number, hex value, serial number, or a plethora
of pseudo-random characters, crackers are used to these sort of
things. I would also assume that about 4.9% of shareware programs
use a file as the key. These are also often called certificates.
Basically, instead of having a string, a file is used as the key.
This method has been found less likely to be cracked because most
crackers only evolve their skills to meet the average requirements
(cracking a program protected by a string). The remaining 0.1%
comprises of other methods. If you only count current releases,
none of my shareware programs are cracked. This is not because
they are not popular enough; in fact, previous versions have been
cracked. As far as current releases go, however, both are in the
0.1%. The more creative you are in your techniques, the more the
crackers will be confused and go on to crack the next guy's program.
Now let's take a look at those two programs and their general
structure. We won't even touch on their function, but instead
look at the encryption schemes.
StuffV
The scheme here is VERY unique. Not only does it require the appropriate
programming skills; it also uses ASP on the server-side for a
client-server session. A Microsoft Access Database is kept on
the server with a list of all of the registered users. After the
user receives confirmation of their registration, they input their
name and email address into a form, then click a button. Upon
clicking the button, the user starts the client-server session,
requesting an URL like http://www.viratech.com/reg/key.asp?Name=Henry%20Ford&Email=user@host.com&HDSerial=00000000. Then the ASP file
(which can be written in VBScript of JavaScript) checks the database
to see if the user is registered. If the user is registered, it
will encrypt their key and send it back to the client. If the
user is not registered, it will deny the request. Also, as a preventive
measure, every time someone requests a look up (regardless of
whether or not they are found to be registered), the database
records the time, source IP, name, email, and HD serial number
of the client.
The encryption algorithm used here is very complex and hard to
break. This is necessary because the keys are stored in the registry
and can be retrieved by any would-be cracker who can find their
hidden location. In fact, the algorithm is so complex, it takes
the program about seven seconds to decrypt and verify it on a
Pentium 233MMX. The algorithm is a derivative of Skipjack, the
secret key encryption algorithm used by the US government in the
Clipper chip and Fortezza PC card. It was implemented in tamper-resistant
hardware and its structure had been classified since its introduction
in 1993. On June 24th, 1998, SkipJack was unclassified, and described
in the web site of the NIST.
This particular application was not Internet-related. If it was,
for example a FTP client, I could have made the application verify
registration every time it started. While encryption would still
be necessary, the fact that you would not have to store the keys
in the registry would be a big plus. Also with this you could
keep track of how often the program is started. You could also
use something like this to make a 30-day trial a REAL 30-day trial.
With most time-limited trials, the user can set his/her computer
clock back to regain functionality after the program has expired.
However, if the program refers to the server, time should be accurate.
Lines of code: 500+*
Advantages:
-Real-time verification
-Can monitor usage (and with considerable accuracy determine if
the user is using the product on multiple computers; see HD Serial
Number under the Precautions section)
-User does not have to keep track of key
Disadvantages:
-User must be connected to the Internet in order to query the
server for their key
-If the server is down, users cannot retrieve registration codes
* Not counting server-side code
Time
Manager
This one is fun! Not only that, but it was a real challenge to
implement. Here is what the user sees. After someone registers,
they receive an email with a HTML file attached. In the HTML file
is their name, their password, and their key. The user then encounters
a form that looks like the following:
As you can see, this is not the typical registration key entry
form. It is very unique. The typical cracker after seeing this
will say to themself "Ok, time to move on to our next victim."
In this particular program, I am using the Secure Hash Algorithm
(SHA-1) along with some simple conversion functions. The result
is two strings (name and password) and an image sequence. To enter
his or her registration, a user type in their name and password,
then click the Start button. After clicking the Start button,
the user has eighty seconds to click all of the images from their
key in the correct sequence. It can be fun or annoying, depending
on the mood of the user. However it is easier-to-use than one
would think. After the key is entered, the user never sees anything
about registration again.
The major problem with this system is that some user's email clients
do not support attachments. Either that or the user did not know
how to open HTML attachments. This is the case in about 10%-20%
of registered users. For them, I simply upload the HTML file to
my web server and they can browse to it just like any other page.
This contingency has never failed me, but there are a few security
precautions that should be taken to keep other people from accessing
this key. The HTML file can be put in a password protected directory
if your host supports it; also you can give it an unusual name
to the HTML file, and turn off directory listings. Another precaution
is to ask the user to tell you once they have accessed and printed
their key, then you can remove it from the server.
Lines of code: 400+
Advantages:
-Unique
-Can be fun
Disadvantages:
-User's email client must support HTML attachments
Tips
& Tricks
Introduction
Below are legions of various tips and tricks that will help you
make your program more secure. I have learned these through much
experience in trying to stop crackers in their tracks. Take them
to heart.
Serial
Numbers
Throughout shareware history, developers have been looking for
ways to enforce their policies. For example, I have seen keys
that only work on a hard drive with a certain serial number. This
is effective. Perhaps too effective, because if a user re-formats
their hard drive, they must obtain another key. This is an inconvenience
for the user *and* the developer. After paying for your product,
any customer will expect for the program to work without any nags.
Imagine their surprise when their key is rejected after a re-installation.
This system is often implemented in a challenge-response scheme.
When a user wants to register, they open up a registration screen
that contains instructions and a certain string. This string is
usually either the hard drive serial number itself or a derivative.
Then when you are building the key, you input this string and
the final product is specific to computers with that input string
that is based on that unique hard drive serial number.
There are distinct advantages and disadvantages to limiting a
key to a certain hard drive serial number. On one side it will
effectively restrict the user from using the program on any computer
other than that on which they gave you their challenge from. However,
if the user re-formats their hard drive or gets a new computer,
the challenge will change, and because of that the original key
will not work. At this point the user is obliged to obtain a new
key if they wish to continue to use the program that they have
already paid for.
This is one of the distinct advantages of the key system that
references an Internet server like StuffV. If the user formats
and reinstalls, they simply type in their name/email and get their
key. The key *can* be hard drive serial number specific to keep
users from simply copying the key from one computer to the next
via the registry. However, if the user wants to re-install StuffV,
they must go through the form. After they submit the form, the
hard drive serial number of that machine is recorded on the server.
Therefore I can keep track of how many different serial numbers
any StuffV user has registered with.
Check
for empty fields
It happens to all of us at some point: we release a product with
a major bug. It happens to the big guys too (*cough* Microsoft
*cough*)! I have seen people write elaborate and complex encryption
codes, but fall victim to an extremely simple error. In fact,
it happened to the person who got me started in programming. Josh
Straub forgot to add a routine to check the length of the name
field in an early version of his QuakeNameEditor, so any user
could leave the name empty, type in "0" for the key,
and become instantly registered!
Check,
check, and recheck
When a user inputs their key into your program, don't simply write
a boolean variable to the registry, but instead copy the key to
the registry. Then, on every execution, check the key from the
registry to confirm it. It might even be advisable to check the
key at random times in your program, and/or when a function for
registered users is called.
A
note on variables
When a cracker starts at a program, the typical method is to scan
through and monitor all of the variables to try to determine the
one that holds the keys and results in a decryption routine. Therefore,
if you have a boolean variable named IsRegistered, the cracker
will know that all that needs to be done is to write a modification
for your program to always switch the IsRegistered variable on
at every execution. Therefore, if you must use a boolean variable,
give it a misleading name. However, it would be to your advantage
if you could hide it even further. For example, in Time Manager,
there are a host of variables that hold numbers that work with
the time. When the function to validate the key from the registry
is called, I could tell it to write a random value between 30
and 60 to an integer variable if the key is valid, but a value
between 0 and 29 if the key is invalid. Then, when I wanted to
determine if the program is registered, inside a bunch of other
complex functions I could stick in stuff like:
C:
if(tsec
< 30) {
HideAdvanced();
}
VB:
If
tsec < 30 Then
Call HideAdvanced
End if
This is really going to make the cracker's job harder. The only
"weak" line in this code is the name of the function:
HideAdvanced. It would be better to name it something stealthier.
In the case of Time Manager, something like ResetTime might be
more appropriate.
(VB
Specific) P-Code: The Best
To be honest, I really do not know exactly why it is, but I do
know that P-Code is harder to disassemble than Native Code. While
it is really neat to be able to optimize your program for things
like size, speed, and Pentium Pro processors, this makes the cracker's
job easier. Also to take into consideration is that native code
can also cause other problems such as the compiler executing the
program incorrectly.
Discombobulate
now!
Your job as a shareware developer is to confuse the cracker in
your key system. Again, be creative (yes, that's an order)! Make
sure to integrate some of your routines into your main data functions,
so it is impossible to figure out. You can add in a simple layer
to the encryption scheme that could share a function with the
main data functions. For example, in Time Manager, when the user
enters their values for the time to start at, the program will
take the seconds field and if it is greater than 59, convert it
to a new hour/minute/second value. So if the seconds is 150, Time
Manager will convert this to two minutes and 30 seconds. This
could be used as a primitive mod function. Now imagine the cracker
trying to figure that out!
Layer,
layer, crack slayer
When the Russians were making their first Atomic bombs, they found
that a good way to induce pressure on the Uranium-235 was to stack
it in layers with some conventional explosives. For every layer
they added the bomb's power was increased exponentially. In the
same way, a highly secure program will use multiple layers of
encryption. Even if one is a simple Xor routine and another is
an easy Caesar algorithm, as long as there is a strong element
somewhere, all of the little things will pay off. Here is a sample
flow chart of three encryption techniques that we will lovingly
call A, B, and C. The terms Name and Key are simply generic; you
can use anything here!
Name >> EncryptA >> EncryptB >> EncryptC >>
Key
Key >> DecryptC >> DecryptB >> DecryptA >>
Name
It's that simple!
Armed
Combat
Introduction
Are you ready to take active measures against crackers? This is
for the people who really want to target the crackers in their
programs. This isn't easy, and should only be attempted by the
best of the best. If you are one of these few, suit up and prepare
to brandish your programming sword!
Let me open with an example for an introduction. At one time,
I noticed that a certain site was serving a crack to one of my
programs. That was the only site that I could find that had it.
The site was first brought to my attention when I was looking
at the sites that people were coming from on my website statistics.
A fair amount of traffic was coming from this page advertising
the crack. I decided to set up an ASP script that would separate
the traffic coming from this site and the traffic coming from
everywhere else. The traffic coming from that site downloaded
a version of the program that would do various things to the machine
it was ran on, such as deleting all of the DLL files it could.
All other traffic was directed to the real thing. A total of 12
copies of the malicious version were downloaded. I never heard
a word about it from anyone. After a while, though, the crack
was taken down. Victory.
Looking back now, I see how effective it was. I also can see more
clearly how risky it was. I probably could have been legally prosecuted
for it. While it serves as a good example of what Armed Combat
really is, we will not discuss or promote wreaking havoc on a
machine here.
This section will be presented in two sub-sections. In the first
we will discuss how to identify when the program is being attacked
by a cracker, then we will discuss what to do about it.
A big warning that EVERYONE should read: Don't cross the line.
Nothing you do should interfere with the end user's experience.
If your protection is so elaborate that you're warding off the
legitimate users, it doesn't matter how good your program or how
secure your protection is, you've lost. If a newbie does something
wrong or weird and they see a message box saying "GO AWAY
YOU CRACKER!" that's not good for business. You want to make
a direct distinction of what the end user sees and what the cracker
sees. The legitimate user should see a terse and modest key entry
form while the underlying code is very complex. Then, the cracker
will have to look at the code, trying to figure out what it is
doing.
Detection:
the first step to protection
Here is where we will test your creativity. I will only give you
one possible method of detection here. You can then either use
it or make up your own.
Declare a boolean variable IsRegistered. Set it to false, *never*
set it to true. Do checks when you're bringing up the main form.
If the variable is ever true, then your program has been tampered
with.
Attack
"Tell me where you at, I will be there in ten seconds flat.
You know I got your back, I'll be there just in time to counteract.
- Busta Rhymes, "Fire it up"
Now that we have identified that the program has been tampered
with, we can take action. Here we have a few interesting options:
a) Wreak havoc (this will not be discussed)
b) Ignore it
c) Fake the cracker out
There are more than these; you only need to be (again) creative.
If we ignore the variable, we will only have succeeded in wasting
some of their time. On the other side, we can also fake them out.
How? After detecting that the program has been tampered with,
change the program to act as if it were registered. However, encrypt
the current date (anything here will do, including Xor) and write
it to the registry or hide it in some other corner of their computer.
Every time the program starts, search for this date. If the date
can be found, you have a record of when the tampering was first
detected. If the current date is three or more days after when
the first tampering was detected, give the cracker a nice message
box saying something to the effect of it didn't work, then either
close out the program or let it continue unregistered.
Why the three day period? By the time that point is reached, the
user will have probably already distributed the crack to his friends.
Eventually it will probably reach the general public. After three
days, it will stop working, however. Then, the cracker will be
labeled as a lamer in the cracker community.
Sounds pretty easy, huh? Yeah, maybe so. Nevertheless, you must
be extremely stealthy about it. If you just put it out there in
plain code, maybe the newest of crackers will fall victim to the
trap, but the adept will catch on. Be creative and set it's roots
deep into the main functions of your program. This is why at the
beginning of this section I warned that only the best should try
this one.
Cracks
happen
Eventually, at some point one of your programs will be cracked.
That is provided that they are popular enough and that there are
enough of them. What do you do then? Fire up your tools and prepare
for battle.
Monitoring
Before you can start to fight against a crack, you have to know
that it exists. I am not going to turn this section in to a document
outlining how to find a crack for any program. However, some good
sites to look at are http://astalavista.box.sk and you can run
searches with keywords like "crack download YOUR-PROGRAM-NAME-HERE."
It is also a good idea to make friends with some crackers. A lot
of them will give you advice on what to do and what not to do.
They can also help keep a look out for cracks. Actually, tell
all of your friends to keep a look out for cracks.
Taking
Action
After a crack is released, you must then try to defeat it. It
is generally best to redesign your encryption scheme, as this
is the only long-term (hopefully) fix! Unfortunately, it involves
re-sending keys to all of your users; either that or simply issuing
new keys upon request (this is generally the best option). To
design a fully reliable encryption scheme can take hours, even
days. However, sooner or later will be necessary.
After you have completed your changes, you must decide whether
or not you want to release a new version. If you do decide to
do that, you can't hurt the cracker's reputation as described
below. In fact, I wouldn't recommend releasing a new version unless
you have a multitude of new features in it. My reasoning is that
these features should persuade users to leave the old cracked
version and to upgrade to the new version, which they will have
to pay for. If you do not release a new version but replace all
of the old cracked versions, then the problem should be remedied.
Replacing
Files
This topic is often overlooked. When you have a new fix, you want
to replace your old program with the new one as soon as possible.
The sooner you do it, the fewer people that will have the crack,
and the more registrations you will have. Consequently, it is
extremely important to maintain good control over your distribution
points. One of the best schemes to have here is as follows:
Primary: On the same server as your website, you should have direct
control.
Secondary: To be used if primary is too slow; these guys should
have MEGA bandwidth. You should have a contact here that has direct
control.
3rd-ary: This can be your friend's cable modem that is on 24/7,
which you can send ICQ updates to.
In the case that a crack is released, you need to be able to replace
the old version very quickly. This is the only thing I have against
big servers such as Simtel.Net. It may take days for them to update
their files. The same is true for ZDNet Downloads, who insists
on having their own copy of your software on their servers. One
can be caught having to wait for days or even weeks to get a program
updated. Yet I still have my software on their site, for the publicity.
Remember that it doesn't matter how good your program or encryption
is if you go so far as to hinder the real users.
Now, moving on, if you like you can possibly hurt the cracker's
reputation. In every crack there is almost always an address at
which the user of the crack can download the main program. Now,
let us assume that a working crack has been widely distributed
and many users are downloading your program only to be cracked.
After discovering this, here is what you do:
a) Fix the program so that the crack no longer works (described
above)
b) Adjust the file's dates and times in which they were created
c) Zip 'em up (or whatever you do for your distribution)
d) Set the zip date and time to the same as the original
e) Upload
I'll leave the changing of the file information up to you. Now
if the cracker claims that you changed the program so that the
crack no longer works, he will be put down. As far as the end
users see, the program is the exact same as it was before. But
the crack doesn't work!
Conclusion
In conclusion, I would like to drive home two main points:
a) Remember, there is no such thing as a program that cannot be
cracked!
b) Also remember that if you overdo yourself, you will lose potential
customers. Do not cross the line!
That's it! I hope that you learned something from this document.
Copyright © 2000 Sense of Security Incorporated All Rights
Reserved.