miércoles, 21 de diciembre de 2011

Hacking Android, LVL Cracking


This is probably the last technical year post, consider it my Chrismast gift yo you. Happy holidays,

A little bit of history you can Check  Reto 14: Android crackme #2, it is an intersting publication where they challenge you to bypass LVL security on a developed APK; that was the perfect excuse for me to get to learn about decompile code in Android with practice, I mean I knew "How" but i theory never done it for myself, so thanks again to Hackerplayers for the challenge.

Clarifications

This post is not intended to be a profound explanation about how Android compile clases and package into an APK. I'm not going to explain deeply about Smali/Backsmali (Decompile code), there are already excelent places that you can check them out like Dissasembling Dex File or Android Cracking, personally I liked the last better because it's a whole blog intended to cracking, tells you a lot about tips and tricks in this subject, totally worth it to check it out.

This post is a pragmatic example on how you can bypass a security licencing solving ofcourse Reto 14: Android crackme #2. So lets start with the fun, here is the answer I gave and was approve by Hackerplayer author:

Download the APKTool

 Apktool is a wonderful tool, when it comes to cracking more like when it comes to decompiling, it becomes your bestfriend allows you to do several stuff like:
  • Decoding resources to nearly original form (including resources.arsc, XMLs and 9.png files) and rebuilding them
  • Smali debugging: SmaliDebugging
  • Helping with some repetitive tasks
After following the APKTool instalation you can proceed to execut the folowing command:

$apktool d cracme2hpys.apk out


*out  is the target folder where the apk it's decompressed.

Checking the extracted folder out

First I though I could bypass the application by changing the start up ACtivity on the Manifest, but that was unsucessful.

So No way, I had to check out the decompile code. The AndroidManifest.xml it's always a good place to start, gives you many hint where to look like the Start up Activity, probably there is where the  ALVL process start.



So you now we know we have to check LicenseCheck.smali. When you open this file, you'll se a lot of code similar to Assembly language if you are not confortable with this, get used to it's the only way.

Search for the #onCreate method on LicenseCheck, this is where the licesence que check and invoke the method doCheck on the same class.

    invoke-direct {v1, p0, v2, v3}, Lcom/android/vending/licensing/LicenseChecker;->(Landroid/content/Context;Lcom/android/vending/licensing/Policy;Ljava/lang/String;)V

    .line 120

    iput-object v1, p0, Lcom/hpys/crackmes/LicenseCheck;->mChecker:Lcom/android/vending/licensing/LicenseChecker;

    .line 123

    invoke-direct {p0}, Lcom/hpys/crackmes/LicenseCheck;->doCheck()V

    .line 125

    return-void


If you look at the line 123. you'll se there is a doCheck method invocation of the current class so lets dig out to see what does this method actually do:

.method private doCheck()V

    .locals 2

    .prologue

    .line 106

    iget-object v0, p0, Lcom/hpys/crackmes/LicenseCheck;->mChecker:Lcom/android/vending/licensing/LicenseChecker;

    iget-object v1, p0, Lcom/hpys/crackmes/LicenseCheck;->mLicenseCheckerCallback:Lcom/android/vending/licensing/LicenseCheckerCallback;

    invoke-virtual {v0, v1}, Lcom/android/vending/licensing/LicenseChecker;->checkAccess(Lcom/android/vending/licensing/LicenseCheckerCallback;)V

    .line 107

    return-void

.end method


Now is clear the method doCheck does the License check through a class named LicenseCecker aparently there is also a callback instance passed to this object probably to inform that the checking was successfuly, so now we have to into:

com/android/vending/licensing/LicenseChecker


Exploring LicenseChecker



Before we start to read all the LicenseChecker and $ classes, we should go straight to the checkAccess method that was invoke previusly in LicenseCheck class remember? I'll help you out here:

    invoke-virtual {v0, v1}, Lcom/android/vending/licensing/LicenseChecker;->checkAccess(Lcom/android/vending/licensing/LicenseCheckerCallback;)V

Probably this method gives us better clues than any other, this method is quite extensive, so I'll narrow it do to the important stuff:

# virtual methods

.method public declared-synchronized checkAccess(Lcom/android/vending/licensing/LicenseCheckerCallback;)V

    .locals 9

    .parameter "callback"

    .prologue

    .line 133

    monitor-enter p0

    :try_start_0

    iget-object v1, p0, Lcom/android/vending/licensing/LicenseChecker;->mPolicy:Lcom/android/vending/licensing/Policy;

    invoke-interface {v1}, Lcom/android/vending/licensing/Policy;->allowAccess()Z

    move-result v1

    if-eqz v1, :cond_0

    .line 134

    const-string v1, "LicenseChecker"

Did you see if-eqz v1, :cond_0  operation? well this it's a very important one if this it's not true then It will send you lower to instantiate the License Validator, and we don;t want that do we?, so lets negate that condition with another operation if-nez vx,target  so now it should work right? welll


Are you kidding It ain't working.... ¬¬

Yes, yes I know we change the license execution and recompile and repacked (I'll explained the process later) but still does not work, well turns out the challenge gives you another problem. The MyAndroidAppActivity does not seem to be invoking the onCreate method and generate the following trace on logcat:



So?, What's going on?, The answer is plain simple the MyAndroidActivity does not invoke onCreate, we need to add that into the backsmali. Look:

.class public Lcom/hpys/crackmes/MyAndroidAppActivity;

.super Lcom/hpys/crackmes/LicenseCheck;

.source "MyAndroidAppActivity.java"

# direct methods

.method public constructor ()V

    .locals 0

    .prologue

    .line 6

    invoke-direct {p0}, Lcom/hpys/crackmes/LicenseCheck;->()V

    return-void

.end method

# virtual methods

.method public onCreate(Landroid/os/Bundle;)V

    .locals 0

    .parameter "savedInstanceState"

    .prologue

    .line 11

    invoke-super {p0, p1}, Lcom/hpys/crackmes/LicenseCheck;->onCreate(Landroid/os/Bundle;)V

    .line 15

    return-void

.end method

The code above show a lots of lacks in the MyAndroidAppActivity, being a simple and small code we can aknowledge the following problems:


  • The onCreate method does not call the super.onCreate(savedInstanceState)
  • The onCreate method does not have any assign layout
  • The MyAndroidAppActivity inherit the LicenseCheck instead of the Activity, and also does not make the proper code on the init invocation.
Here is the right code:


.class public Lcom/hpys/crackmes/MyAndroidAppActivity;
.super Landroid/app/Activity;
.source "MyAndroidAppActivity.java"


# direct methods
.method public constructor ()V
    .locals 0

    .prologue
    .line 6
    invoke-direct {p0}, Landroid/app/Activity;->()V

    return-void
.end method


# virtual methods
.method public onCreate(Landroid/os/Bundle;)V
    .locals 1
    .parameter "savedInstanceState"

    .prologue
    .line 15
    invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

    .line 17
    const/high16 v0, 0x7f03
    invoke-virtual {p0, v0}, Lcom/hpys/crackmes/MyAndroidAppActivity;->setContentView(I)V

    .line 20
    return-void
.end method


We  can take the following notes like the onCreate and setContentView invocation, and the variable v0 was added, when adding variable you have to be careful to declare how many are you using in the block scope in this case we add locals 1 on the method declaration.

Are we done? kind of, we now need to recompile and repackaged this into an APK, as I promised this is how you do it

Back to an APK

Rembember apktool? well the same tool that allows you to decompile, help you into recompile and recreate an APK, but you probably going to need a little bit more to get it back into the phone. "But you'll se I'll show you" (Joker quote)

First build and create the apk with the following command

$ apktool b out crackemecracked.apk

You will also need to sign this out,  and you are going to need a keystore, you can easly created with keytool

$ keytool -genkey -v -keystore keystore.keystore


Now that you have a keystore, use it to signed your app

jarsigner -verbose -keystore keystore.keystore crackemecracked.apk crackmecracked


If you wish to learn more about how to sign Android application don't forget to pass by the  oficial documenation.

Now that we have our nice apk signed, we can reinstall it into the phone with the adb:

$ adb uninstall com.hpys.crackmes 
$ adb install crackemecracked-za.apk


If everything it's correct you should be seeing this:




And READY!! 



¿Some aditional tips ?

Particulary I've never done this before, the information on how to modify backsmali is not that wide, but it is not that hard (at least not the basic to do this)

- I suggest you learn a bit about Assembler because it is really similar the operator and the register changes.

- Whenever I get lost with a specific operation I went to Dalvik OpCode it was like the Larouse for me

- I did some small and simple classes to check out what does the decompile code looks like.

- No need to check everything like LicenseChecker$ResultListener$1 this classes are either anonymous or declare internal classes on the file so you can skip them.

- For the recompilation and reepackaging procedure I did small shellscript feel free to use it.

- I suggest you two excelent I/O presentations.

Google I/O 2008 - Dalvik Virtual Machine Internals



 Google I/O 2010 - A JIT Compiler for Android's Dalvik VM