Executable Wrappers Part 1

Anonymous

Disclaimer
I’m a software developer, and as such think that crack distribution is not helpful to the industry. However, I also think that having a false sense of security is bad, and that broken systems should either be fixed or not used.

Introduction
Software wrappers are often mentioned as the “way to go” to protect your program. What are wrappers, why are they popular, and are they actually worth the investment? In the process of answering these questions, a common wrapper called eLicense will be dissected (i.e.: busted) and suggestions made as to what would make a better wrapper-like protection.

Wrappers are a method of controlling the execution of your program: who can run it where and for how long. The typical view of this from the user’s point of view is being able to use the program for 30 days before it stops working. The “next step” for the user is to be able to buy it and perform some action on their computer so that it will keep working forever (though only on one computer).

However, this is just a general description of a software protection mechanism. What makes wrappers different is the way they implement the protection. Wrappers require no modification to your unprotected program. They add their own code (either a DLL or by tacking another section on to the DLL, or sometimes like eLicense, both) which handles all the protection details, and lets you get on with writing the program. Most other types of protection (dongles, APIs, etc.) require building-in to the program. This is obviously a lot more effort (especially to do it securely) which is why the zero-work solution of wrappers is often suggested.

However, with this ease of use come two prices: one is the dollar price to buy the protection (which often involves paying per-licence for the use of the licensing-system-provider’s servers) and the other is a loss of security. What can be added to a file can be removed, and once the system is removed, the file is completely unprotected. So a lot of effort is put into making the wrapper hard to remove. In eLicense, there are two things done: the first is that the code segment is encrypted and the second is that the import table is obfuscated. These will be discussed later.

Developer & Client

Communication
Before worrying about how the software is unwrapped, a quick look is required at what needs to be done by the wrapper from a theoretical point of view. Since each licence should only function on a single machine, there needs to be some way of making sure that a replay attack cannot be made on the system. A replay attack involves storing a request and the response, and feeding the response back again (perhaps with some minor changes) when another request comes in. For example, if the “key” (which allows unlimited use of the program) contained no hardware-specific information and nothing from the client request was used to generate the key, then a replay attack is obvious. With one key, you could just give the key out to every request and have an unlimited number of licences. One way to “fix” this is to have the client generate a random number (hardware independently), send it with the request, and then use the combination of that number and the key (which is dependent on that random number) to unlock the program.

This can fail in two ways. The first is that if the random number is too small, or if the key changes too simply on the random number, only a few requests are needed to be able to generate a key for any random number. For example, if the key was just multiplied by the random number then returned modulo a prime number, then only a single request is needed to obtain enough information. Specifically, the function used to generate the number-specific key from the random number and the real key must be one-way. There are many functions like this, mostly from the realm of cryptography.

MD5 and SHA1 are by far the most commonly used in protection mechanisms due to their simplicity (no large-integer support needed), speed (they are very fast), and security (no reasonable known methods of “undoing” the function). These functions are called hashes, and take arbitrary length input and produce a fixed-length output. For example the SHA1 hash of the string “abc” is the hexadecimal string “a9993e364706816aba3e25717850c26c9cd0d89d”.

However, there is still a problem. The random number must be stored somewhere, so with a bit of patience it can be found and modified. Suddenly, many computers can be using the same random number and key. What needs to be done is to stop this transfer of random numbers between computers, or store them securely. Or even better, have the hardware itself store the number!
There are many ways to generate computer-specific numbers. MAC addresses on network cards, hard disk serial numbers (not the “c:” serial number, but the actual number hardwired into the drive, which all IDE and most SCSI disks have), and taking the hash of system information (such as CPU model, amount of RAM, plugged in hardware, etc.). The implementation details will be ignored here. Suffice it to say that the implementation should be protected to stop it from being patched to return the same key regardless of the hardware. Not that this protection is easy to do, but it would be getting too far off topic.

Moving Around
One further consideration is with regard to moving licences between computers. This is one of the things eLicense supports, but how safe is it? This comes back to the original problem of replay attacks. To move a licence, the computer currently holding the licence removes the key from the hard disk, and reports back to the server that it has done so. Then, another computer can request this same key and the server will not complain.

One simple way to fool the wrapper is to record the key that is supplied for that particular hardware ID. Then, once it has been unlicensed, get it to request a licence again and feed the previously given licence back to it without passing the request back to the licence server. The licence server does not know that the software has been re-licensed, and the wrapper thinks that it has. So another request (from a different computer) can be made to the licence server, and so on.

This can be partially fixed by having the client pass a random number to the server, but again the problem of keeping a stored random number secure arise, and cannot be blocked. There is also a much bigger problem in the form of file change detectors. If the locations of the licence data files are known, as these areas can be backed up prior to unlicensing and then restored once the program is “unlicensed”. No amount of trickery will beat this attack, and it is very easy to do because there are multitude of tools out there that monitor changes to the hard disk (and registry). All the attacker needs to do is:

1) Take a snapshot of the system (when licensed)
2) Unlicense the application and see what changed
3) Re-license the application
4) Back up the files that get changed
5) Unlicense again
6) Copy the modified files back again

The bottom line is that any system that allows unlicensing of computers can easily be broken to allow sharing of the licenses. One way that this can be made inconvenient is to require renewal of licences after a certain period of time. This means that every time the licence needs to be renewed, the files would have to be backed up and the whole process gone through again. This puts a limit on how shared a licence can be. Sharing between 2 computers would not be much of a hassle, but sharing between 20 would be a huge hassle to deal with. In general, moving licences is quite insecure so will be ignored (as should any wrapper or system that supports this).

Keys and Exchanges
So now that our clients are (securely) generating a number and using it to verify the key they have received, what does the exchange look like? First of all the client generates the number. Then it sends it along with a “give me a licence” request to the server. The server performs some sort of one-way operation to generate a key for the client, and sends it back. Whenever the client runs, it re-generates the number, and verifies that the key it has is really for the computer it is running on. This is approximately what eLicense does.

There is also a further requirement on the key to do with how it changes with a changing computer ID. Given a certain change (e.g.: flipping a particular bit), the change in the key should not be easily derived. If, for example, flipping bit 1 in the computer ID always resulted in flipping bits 2 and 4 in the key, then given a particular ID/key combination it would be trivial to generate a key for a second (slightly different) computer ID. If the bits flipped in the key for each bit in the computer ID is known, then it would become trivial to construct a key for any given computer ID.

In cryptography, protection against this attack is known as avalanche and also strength against differential cryptanalysis. For any given change in the input (the computer ID), each bit in the output (key) should have a 50% chance of being changed. For example, the input 101010 might have the output 100110, and the input 101011 might have the output 110000. So flipping bit 0 flips bits 1, 2, and 4. However, the input 001010 might have the output 111011 and the input 001011 might generate the output 001111, which only flips bit 3 despite bit 0 being the only bit changed again.

What algorithm(s) can/should be used for generating the key? A good choice is DSA. It is a public-key signature algorithm, which gets around a problem with using hashes. The problem with hashes is that to check something, you have to run the correct text through the hash, then check to see if everything matches in the end. This is a problem, as the correct text can be intercepted, and suddenly the whole system breaks down again. For example, if you took the number, appended it to a secret code word, then hashed the whole thing, the same needs to be done for verification. So the secret code word can then be extracted into a key generator and it is back to square one again.

With an asymmetric algorithm (which DSA is), this problem is overcome. The secret is split into two parts: the public part and the private part. The private part is (obviously) kept secret, and is used to generate the signature. The public part can only be used to verify the signature. So the client sends the information to the server, who generates a key (which contains information such as the expiry date) and then uses the private key to sign the information. The returned “key” is the information and the signature. When the client wishes to check the key, it uses the public key to verify the signature on the information, and rejects the key if it doesn’t work. The maths behind how this works can be read in any decent cryptography book or from the FIPS PUB 180-1 standard.

The promotional materials for eLicense claim that is uses an asymmetric algorithm for key generation, which puts it into the “safe” class. However, they don’t appear to have any large-integer support in their libraries, which puts a shadow over the security of it, even more so as no particular algorithm is mentioned. If it is indeed a home-brew asymmetric algorithm, there is a large chance (judging from history)
that it is not, in fact, asymmetric.

Trials

Trials
A very common use for wrappers is to enable the user to run the program under restricted conditions (such as only for certain period of time or only for a limited number of times). Of course, to run at all the program needs to have a valid key, which gives two options. The first is to require the user to be online when the program is first run, and send a request to the online key server to get a limited-use trial key. The second option is to have the wrapper generate the key.

The second option is horribly insecure, though is the option taken by most wrapper programs. It requires any secret information (such as DSA private information) that is required to generate a key to be with the wrapper. However, this means that anyone with the ability to retrieve this information from the wrapper can also generate a key. Since eLicense takes this approach, this is probably the source of the information used by the DAMN eLicense Proxy to impersonate an eLicense server. The method used to communicate with the server has changed since the last update of this program, so it no longer works with newly wrapped eLicense-protected products. Before the changes, though, a large number of eLicense products could be “licensed” by the proxy, which was supplied with what appeared to be private information such as passwords.

The first option is not ideal either, as it places several requirements on the user. But it is much more secure. For example, the user cannot just erase licensing files placed on their computer to get another trial period. This is because the unique computer ID (which depends on their hardware) can be stored on the central server, which would reject any requests for further trials. Also, since no private information needs to be stored in the wrapper, keys cannot be generated by the end users (usually by crack programs called keygens).

Unwrapping, Improvements, and alternatives will be discussed in part two with code examples.

©2006 DIG Magazine || Terms

Introduction
by lowtec
The First Big Hack
Anonymous
Letters
Grab Real Video Files
by Avid
Executable Wrappers Part 1
Anonymous
Overview of Bit Torrent
by Vorpix
Telephone Recording Techniques
by Strom Carlson
Summer Fun
by lowtec
DMCA
Anonymous
The Fallen Manifesto
by the Skum
DIG #2