dimanche 12 août 2012

Beatbox for free - Abusing a cheap authorization on Android

Hi kids, do you like human beatboxing?


Well I do, and a few months ago, I downloaded an application for my Nexus S running Android 2.3.4. I will call it Blabla.
This application was awesome, and allowed me to record and mix live loops from the microphone, exactly what I was looking for...

But I downloaded the free version of the app, and some basic features were missing, such as saving and exporting the tracks. Furthermore, a messy time limit for recording was present.

The full version of the application does not cost a lot, but just for fun I decided to take a look on the free app. Because sometimes the free app already contains the full app logic, and checks if it should authorize the use of 'paid' features...and it was the case here.

Furthermore, on the market, there is no full app. There is only an app called "Blabla unlock key". This means that the free app probably handles all the features.

In the following I will describe the main steps I went through to unlock the application.

NOTE: I'm not inviting people to hack the app. It is a good application, and the developers deserve to earn money for it. This is why I won't mention the name of the app, I won't show screenshots or anything that would lead to the identification of the application

Soft-rooting the phone


To feel comfortable and to be able to do whatever I want, I first soft root the phone.

To do that:
- enable debugging, to activate adb
- push a compiled version of zergRush on the filesystem and run it
- enjoy the root shell

Exploring the application environment


It is a classical part of the application discovery.After locating the application on file system, I take a look at the manifest to check the permissions:

Extract from AndroidManifest.xml:

    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />


So the free app is obviously able to write data on the SD card, which is exactly what is needed to save the tracks... It means that there is a chance that the free app handles the full app features... Let's digg a bit more...


Then I took a look at the configuration file, which is a simple plain text XML file called BlablaActivity.xml. I was looking for a field that tells if I paid or not. But there was nothing useful in this file...

The app doesn't use any database, so there is nothing more to see in the application environment.

I had to read the code, just to see how the application checks if I bought the unlock key.


Reversing the app


Reversing Android applications can be very easy.

To do that:
- extract the application apk to your computer using adb
- use dex2jar to get a jar archive of the application
- use jd-gui to access to the java code of the jar



Sometimes, dex2jar fails to create the exact java code. If it occurs, one can access the dex code using dedexer, and read the logic. But in this case, I didn't need to fully understand the exact code. I was just looking for the technique used to check if the unlocking key app is installed.

If we look at the class names, we can see that some are obfuscated (classes a, b, c and d). This attracts attention...




Some methods are called nativeSomething, so we can assume that some parts of the logic are embedded in a native library. Indeed, the methods for saving and loading tracks are native. There is also a native method that sets preferences.

It is used in the a() method of the class d. And we can see that this method checks if the unlockingapp is installed by using the PackageManager.getApplicationInfo() method. If the application is present, a specific key-value pair is set in the "native" preferences.



Unlocking the free app


In fact, the class d is a thread that performs that test until the unlocking key is found. It is launched at application startup and stops running when the key is found or when the application closes.

PackageManager.getApplicationInfo() returns true if an application with a specific name is installed. So to pass that test, the simplest way is to create an empty Android application and give it the right name. Then, when it is installed, the Blabla application will be unlocked.

It seems too easy to be true...
In fact the native library is essentially meant to handle the sound processing tasks. The developers decided to involve it in the unlocking key check, but the main checking logic is not native.

By the way, handling the whole key check in the native library would only make it slightly longer for an attacker to reverse it...

The developer released a few other applications that use the same process, a free app and a unlocking key you must buy to unlock the full features.



How could it be better?



I think the easiest way to perform the key check without implementing heavy cryptography would be to use the application signature features provided by Android.

Without changing anything to the application logic, I would just change the permissions. The Blabla Unlocking Key application could ask for the WRITE_EXTERNAL_STORAGE permission, instead of the Blabla application.

If the applications are defined to share their userID, they also share their permissions.
That way, the Blabla application could check if it has the WRITE_EXTERNAL_STORAGE permission and if so, it means that the key application is installed AND signed with the same developer key (because they share their UID).

Of course, it wouldn't stop from fully cracking or patching the application, but on Android, it is a general statement. The problem which I discussed here is that the phone doesn't need to be rooted for circumventing the key check. Anyone can install his own fake empty key application, just by enabling debugging and installing third party apps.

There might be some better ways to do that, but as I'm writing this post, I think the one I give would solve the problem.

Feel free to discuss everything I wrote by leaving a comment!

Aucun commentaire:

Enregistrer un commentaire