Skip to content

Latest commit

 

History

History
184 lines (155 loc) · 5.96 KB

Lab-003.md

File metadata and controls

184 lines (155 loc) · 5.96 KB

CrackME!

Now that we have bypass the emulator check, we can start digging into how the application generates the key. This is what we need to successfully submit.

-- Enumerate classes, and find keyword 'versprite' --

We can use Androguard to enumerate all the classes within are target package.

In [13]: classes = list()
In [14]: for c in d.get_classes(): classes.append(c.name)
In [15]: for c in classes:
    if "versprite" in c:
        print(c)
   ....:
Lcom/versprite/crackme/BuildConfig;
Lcom/versprite/crackme/KeyActivity$1;
Lcom/versprite/crackme/KeyActivity;
Lcom/versprite/crackme/R$anim;
Lcom/versprite/crackme/R$attr;
Lcom/versprite/crackme/R$bool;
Lcom/versprite/crackme/R$color;
Lcom/versprite/crackme/R$dimen;
Lcom/versprite/crackme/R$drawable;
Lcom/versprite/crackme/R$id;
Lcom/versprite/crackme/R$integer;
Lcom/versprite/crackme/R$layout;
Lcom/versprite/crackme/R$menu;
Lcom/versprite/crackme/R$mipmap;
Lcom/versprite/crackme/R$string;
Lcom/versprite/crackme/R$style;
Lcom/versprite/crackme/R$styleable;
Lcom/versprite/crackme/R;
Lcom/versprite/crackme/emulator/Detect;
Lcom/versprite/crackme/generate/Generate;
Lcom/versprite/crackme/generate/GenerateReceiver;

We see something suspect!

Lcom/versprite/crackme/generate/Generate; Lcom/versprite/crackme/generate/GenerateReceiver;

GenerateReceiver appears to be a Broadcast Receiver, lets verify that!

In [17]: a.get_receivers()
Out[17]: ['com.versprite.crackme.generate.GenerateReceiver']

-- GenerateReceiver --

In [18]: d.CLASS_Lcom_versprite_crackme_generate_GenerateReceiver.source()
package com.versprite.crackme.generate;
public class GenerateReceiver extends android.content.BroadcastReceiver {

    public GenerateReceiver()
    {
        return;
    }

    public void onReceive(android.content.Context p8, android.content.Intent p9)
    {
        android.os.Bundle v0 = p9.getExtras();
        if (v0 != null) {
            String v2 = v0.getString("key");
            android.util.Log.d("GenerateReceiver", new StringBuilder().append("Key Received: ").append(v2).toString());
            if (!new com.versprite.crackme.generate.Generate().c(v2).equals(Boolean.valueOf(1))) {
                android.widget.Toast.makeText(p8.getApplicationContext(), "Try Again!", 0).show();
            } else {
                android.widget.Toast.makeText(p8.getApplicationContext(), "Success!", 0).show();
            }
        }
        return;
    }
}

Can anyone tell me what is going here?

When the onReceive() method is called, it is called with an Intent object. The GenerateReceiver then retrieves the 'key' from the Intent extras, calls Generate() and evaluates it to be TRUE or FALSE.

Who can tell me what this is doing?

n [22]: for m in d.CLASS_Lcom_versprite_crackme_generate_Generate.get_methods(): print(m.pretty_show())
########## Method Information
Lcom/versprite/crackme/generate/Generate;-><init>()V [access_flags=public constructor]
########## Params
local registers: v0...v0
- return: void
####################
***************************************************************************
<init>-BB@0x0 :
	0  (00000000) invoke-direct       v0, Landroid/app/Application;-><init>()V
	1  (00000006) return-void

***************************************************************************
########## XREF
F: Lcom/versprite/crackme/generate/GenerateReceiver; onReceive (Landroid/content/Context; Landroid/content/Intent;)V 4e
####################
None
########## Method Information
Lcom/versprite/crackme/generate/Generate;->c(Ljava/lang/String;)Ljava/lang/Boolean; [access_flags=public]
########## Params
- local registers: v0...v3
- v4: java.lang.String
- return: java.lang.Boolean
####################
***************************************************************************
c-BB@0x0 :
	0  (00000000) const/16            v2, 10
	1  (00000004) new-array           v0, v2, [B
	2  (00000008) fill-array-data     v0, 20
	3  (0000000e) invoke-virtual      v4, Ljava/lang/String;->getBytes()[B
	4  (00000014) move-result-object  v1
	5  (00000016) invoke-static       v0, v1, Ljava/util/Arrays;->equals([B [B)Z
	6  (0000001c) move-result         v2
	7  (0000001e) if-eqz              v2, 5 [ c-BB@0x22 c-BB@0x28 ]

c-BB@0x22 :
	8  (00000022) sget-object         v2, Ljava/lang/Boolean;->TRUE Ljava/lang/Boolean; [ c-BB@0x26 ]

c-BB@0x26 :
	9  (00000026) return-object       v2

c-BB@0x28 :
	10 (00000028) sget-object         v2, Ljava/lang/Boolean;->FALSE Ljava/lang/Boolean;
	11 (0000002c) goto                -3 [ c-BB@0x26 ]

c-BB@0x2e :
	12 (0000002e) nop
	13 (00000030) fill-array-data-payload'Bs1d3s_SF0'

***************************************************************************
########## XREF
F: Lcom/versprite/crackme/generate/GenerateReceiver; onReceive (Landroid/content/Context; Landroid/content/Intent;)V 54
####################
None

1.) Create a new bytearray

	1  (00000004) new-array           v0, v2, [B
	2  (00000008) fill-array-data     v0, 20

2.) Call getBytes() on the parameter passed to the method, then compare it - equals() - against the bytearay it has created

	3  (0000000e) invoke-virtual      v4, Ljava/lang/String;->getBytes()[B
	4  (00000014) move-result-object  v1
	5  (00000016) invoke-static       v0, v1, Ljava/util/Arrays;->equals([B [B)Z
	6  (0000001c) move-result         v2
	7  (0000001e) if-eqz              v2, 5 [ c-BB@0x22 c-BB@0x28 ]

3.) If we look at idx 0x2e, we see are key being filled into the array

c-BB@0x2e :
	12 (0000002e) nop
	13 (00000030) fill-array-data-payload'Bs1d3s_SF0'

4.) Finally the source output

In [23]: d.CLASS_Lcom_versprite_crackme_generate_Generate.METHOD_c.source()

    public Boolean c(String p4)
    {
        Boolean v2_2;
        byte[] v0 = new byte[10];
        v0 = {66, 115, 49, 100, 51, 115, 95, 83, 70, 48};
        if (!java.util.Arrays.equals(v0, p4.getBytes())) {
            v2_2 = Boolean.FALSE;
        } else {
            v2_2 = Boolean.TRUE;
        }
        return v2_2;
    }