Sunday, June 26, 2016

Bypassing Protections: Exploiting Activation to Access Sensitive Data

Welcome to part 2 of the Bypassing Protections series. In this part, we will be looking at an application which uses online activation to verify a license key and activate the software. After activation, the server allows the user to upload their sensitive data to the server, using their registration information as authentication. In this tutorial, we will look into creating an activator which will allow us to bypass the online activation and access the sensitive data that other users have uploaded. Before we begin, I am obligated to say that this tutorial is provided for informational purposes only. By reading this tutorial, you agree not to use the information in this tutorial to hack the server or pirate the application of the software author. As last time, I will not mention the name of the software in this post, but will include pictures which will allow you to determine which software this tutorial was based upon.

To begin this tutorial, we will first try to find the license verification routine. Let's start the target up in ollydbg and attempt to register it with a random name and serial. In this example, I will be using the author's name and '123456' as a license key.

After clicking okay and the nag appears, let's pause ollydbg and follow the call stack back into the application code. After a few steps, we will arrive here:

It appears that this is the verification routine at first glance. Let's set a breakpoint on Function labeled "GenerujKluczProdukti..." and attempt to register again. After the breakpoint, we can step inside and look around. Inside this routine, we notice there is a loop that appears to be replacing the characters in our name which are greater than >=$80 with their numerical/ordinal value in a &#ordinal; format.

We can recreate this function in delphi like this:

After this routine, the application takes an MD5 hash of our name, extracts every other character from the hash, and inserts dashes every 5 characters.

We can generate a key in delphi like this:

I will publish the getMD5 code later which uses the CryptoAPI.

Now that we can generate a valid serial, we can look into the online activation. Following the jump past the nag routine, we begin preparing the url to verify our key with the server. At this point, I advise disconnecting the internet or blocking the application with the firewall. After scrolling down, we can see a string which says [RETURN:OK]. Below this, there is JLE. If we bypass this jump by setting EAX=0, our application will believe the server verified our serial as legitimate.
 Let's toggle a breakpoint on CMP EAX, -1 and allow the program to attempt to activate. Once we break here, immediately set EAX to 0. Now, we will begin storing our information in the registry. The activation data is stored in HKEY_CURRENT_USER\Software\Classes\.p k c d o c 2(remove spaces) in the following string values:
o1= encrypted name
k1= encrypted serial
v1= encrypted version
wk= server result (0)
Each value with the exception of wk(sever result) is encrypted with with the following algorithm.
This routine encrypts each individual character of the name, key, and version number. It then converts the encrypted character, which is a WORD(16 bits unsigned) to a number string(inttostr) and adds it to a numerical string separated by a space. We can recreate the routine in this fashion:

The result of this routine is then added to the registry. We can do this in delphi using the TRegistry unit.

Now, we can use this activator to activate the application with any name we please, without having to verify it online. Now that the application is registered to the author of the software, we can now access any tournament data he has stored on the server.

This is due to the fact that the server grants access to information stored on the server by using the username and license key for authentication.

Since there is only one possible license key for each licensed user, and the name of each user is published with their tournament results, we can simply activate the software with their name to gain access to their data. This is a serious flaw which I tried to bring to the attention of the author, but he ignored every email I attempted to send him.

A way that this authentication flaw could be fixed is to remove the md5 license scheme and make the serial number for each user generated at random. That way, there are trillions, if not an infinite number of possible serial numbers for each user. This way, if I activated the application in the manner above, using a serial I generated at random, it would be next to impossible for me to generate the exact key issued by the author, thus, causing the authentication to fail. The author could also add a second layer of authentication for accessing the online data which required the user to create an account on the server with their email and password.

I want to thank you for reading and following along with this tutorial. If you have any questions, feel free to ask them below. Until next time, happy reversing.

Friday, June 17, 2016

Incredimail Password Recovery Tool

Incredimail Password Recovery Tool can recover all of your Incredimail passwords from your email passwords, to your incredimail account. It is 100% free for non-commercial use.


For use in a commercial environment, use the donate button to donate $5 for each computer on which it is installed.

Monday, January 4, 2016

Bypassing Protections: Reversing and Recreating a Protected DLL

Hello and welcome to this new series called Bypassing Protections. Together, we will learn some new methods to bypass protections which have certain flaws in their implementation. In this example, we will look at an dll which is protected with asprotect and use a simple method to recreate it. Since this protected dll only performs license check procedures, it is very easy for us to recreate the dll in Delphi, bypassing the protection all together. In some applications, the authors like to place all of the license management code into a single dll which all modules of the application reference to determine if the it is registered. Since this handles all license management, this becomes the Achilles heel in the application. Together, we will reverse engineer this small dll and recreate all of the functions and procedures in delphi so that they always return that correct values. Due to legal purposes, I will not mention the name of this application in the article, but will include pictures that will clearly help you determine which application this tutorial is based upon.

Let's download the application. When you run it, you are met with this screen. Probing through the directory with protectionID, you will soon discover that the dll named ba8pro is protected with ASProtect. Let's view the export table of ba8pro in PETools and see what functions and procedures it contains.

As we can see, this only contains 4 procedures. If we check the main executable, we see that there are no import references to this dll and that on startup, this dll is not in memory. That means that it likely loads this dll using the LoadLibrary function and obtains the procedure VA using GetProcAddress. Since this is the case, we can find where these procedures are called by simply searching for string references of the function names. When we load the main executable in ollydbg, we can already see the ba8pro dll referenced in the main procedure. Below that we can see references to CheckVersion and CheckDays.
After we step to the point which I labeled Call To CheckVersion, we notice nothing is pushed onto the stack before we call this function. Therefore, we can conclude that the CheckVersion function does not take parameters. After this procedure, we return the value of $FFFFFFFF to EAX and store it at 5D9B04. Since we move the full EAX register to this value, we can conclude that CheckVersion Return an Integer. After playing around, I discovered that if we return a 0 from CheckVersion, it will run as registered. Therefore, we can recreate this dll function in Delphi like this:

Function CheckVersion(): Integer; stdcall;
Result:=0; //pro

The next function CheckDays works the same way. It does not take parameters and returns the number of days as an integer. We can declare it like this:

Function CheckDays():Integer;  stdcall;
 Result:=255; //Any value greater than 0 and <= $7FFFFFFF will work

Next, we will look at the function GetModeVersion. After a quick string search for GetModeVersion, we should arrive here:

Let's toggle a breakpoint here, run the application, go to help, and click the about button. This will cause ollydbg to break here. Once we step down to the call, we realize that a value is pushed onto the stack prior to entering this call. Take note of the value. Let's step into this routine to get a better idea of what is going on.

After stepping to the end of the procedure, we discover that the value pushed onto the stack is a pointer to a Unicode string value which gets populated with the registration information string which will appear on the about form. This routine does not return a value to EAX, so we can conclude that this is a procedure. After playing around with this procedure, I found that it will return the following string if registered: Registered Version /n Single User License /n Lifetime Free Upgrades We can recreate this Procedure to return this string like this:

Procedure GetModeVersion(s:pWideString); stdcall;
s^:='Registered Version'+#13+'Single User License'+#13+'Lifetime Free Upgrades'; //Write to the String.

Finally, we will look at the final function RegisterApplication. Since we are making this registered by default, this function we not be used, but we will add this anyway to complete the dll. Let's restart the application. After a quick string search, we can find the call to RegisterApplication.

Let's run the application and enter some random registration details.

As we can see, this is passing two strings to the function. When we return from this routine, we see that al is populated with a 0. Since the next function tests whether or not al is equal to 0, we can determine that al is a boolean where 0=false and 1=true. That means that the RegisterApplication function takes two constant(unchanging) strings as parameters and returns a boolean. We can recreate this function like this:

Function RegisterApplication(CONST s,s2:string):Boolean; stdcall;

Now that we have recreated these functions, our finished code will look like this:

The only thing left to do is to replace the dll in the directory with the one that we created, patch the integrity checks in the modules(not shown for legal purposes), and add a fake key in the registry(not shown for legal purposes).

Now that we have done this, we will discuss some ways for the author to improve this protection. Since this dll contains only licensing information, it makes it easy for us to duplicate. However, if the company were to add some core application functions along side of these license check routines, it would make recreating the dll much more difficult. They could also protect each individual module with asprotect to make it necessary for us to unpack each file in order to bypass/patch the integrity checks.

With that said, I hope you enjoyed the tutorial. Feel free to ask any questions you have below. Until next time, happy reversing.

Monday, October 26, 2015

Customizable aspr_ide.dll With Source Code

Sometimes, after unpacking an asprotect target, the application may still rely on the functions and procedures provided by asprotect in its aspr_ide.dll. While the sdk allows for custom functions to be added to it, the generic functions include  CheckKeyAndDecrypt, SetUserKey, GetHardwareID, GetTrialExecs, GetExpirationDate, GetRegistrationKeys, CheckKey, GetModeInformation, GetRegistrationInformation, GetTrialDays, GetKeyDate, and GetKeyExpirationDate. The aspr_ide.dll and its source code provided below simulate all of these functions and return the correct values to register the application. Using the delphi source code, you can modify it to fit the requirements of your target.

aspr_ide.dll Download:

Source Code Download:

Thursday, August 27, 2015

Delphi Tips: Hashing a String With Delphi Encryption Compendium(DEC)

Today, I wanted to use the Delphi Encryption Compendium(DEC) to hash a string. It is a little bit difficult to figure out how to use the components since they are poorly documented, but after a few minutes, I came up with this. At first, I tried to use the CalcBinary function, which allows you pass a string to it. It worked fine, but it is limited due to the fact that it would cast all input strings as an ansistring type. As a result, I switched to the CalcStream type to overcome this limitation. Here are two functions which you can use to calculate an MD5 hash for either a UnicodeString or AnsiString. These functions can be easily converted to a different hash type simply by changing the declaration and create type. The available hash types are: 
THash_MD2, THash_MD4, THash_MD5, THash_RipeMD128, THash_RipeMD160, THash_RipeMD256, THash_RipeMD320, THash_SHA, THash_SHA1, THash_SHA256, THash_SHA384, THash_SHA512, THash_Haval128, THash_Haval160, THash_Haval192, THash_Haval224, THash_Haval256, Thash_Tiger, THash_Panama, THash_Whirlpool, THash_Whirlpool1, THash_Square, THash_Snefru128, THash_Snefru256, and THash_Sapphire
You can specify haval rounds like this: hash.rounds:=3; //(3,4,and 5 are valid round types.)

Uses DECHash, DECFmt

Function GetMD5_Unicode(input: UnicodeString):String;
val: tStringStream;
hash: tHash_MD5;
len: int64;
val.Write(input[1], len);
val.Seek(0, soFromBeginning);
result:=string(hash.CalcStream(val, len, TFormat_HEX));


Function GetMD5_Ansi(input: AnsiString):String;
val: tStringStream;
hash: tHash_MD5;
len: int64;
val.Write(input[1] ,len);
val.Seek(0, soFromBeginning);
result:=string(hash.CalcStream(val, len, TFormat_HEX));


The Delphi Encryption Compendium(DEC) can be downloaded here:
Until next time, happy programming and reversing. :)

Friday, August 7, 2015

Gilisoft Password Recovery Tool

Gilisoft Password Recovery Tool is a simple utility that allows you to recover the master password for 4 Gilisoft applications.

This utility has been successfully tested on the following Gilisoft programs and versions:
  • Gilisoft Exe Lock 5.0.0
  • Gilisoft File Lock 10.0.0
  • Gilisoft USB Lock 5.5.0
  • Gilisoft Privacy Protector 7.0.0


Source Code:

Monday, June 1, 2015

String Xoring Utility 1.0

String Xoring Utility 1.0 is an application that will xor encrypt a text string, output it in an array format, and generate a decryption routine for both C++ and Delphi. This will help a programmer hide sensitive strings in their code. Since this will prevent the encrypted text from showing up in string references, this will make reverse engineering slightly more difficult.



Sample Programs + Source:

The program is 100% free and open source. However, if used for commercial purposes, a small donation would be greatly appreciated, though not required.