Contents

Ingeniería inversa Android Crackme03 de deurus

Introducción

  • crackme01 de deurus solucionado aquí
  • crackme02 de deurus solucionado aquí
  • Pueden descargar el crackme03 de deurus aquí

¡Ya estoy de vuelta con un nuevo crackme :D! La verdad que cuando vas entendiendo la metodología y como funcionan las cosas, empiezan a salir más rápido. Y este crackme me pareció sencillito, o a lo mejor voy mejorando (o eso quiero pensar) :p

Comportamiento de la app

Bueno, empecemos. Lo primero de todo, veamos como es el programa e introducimos datos:

Tenemos 2 constantes las cuales son HardwareID 01 y HardwareID 02. Y dos campos a introducir: uno el nombre y otro el serial. Y dos botones: uno check! y otro about. Al introducir un nombre ‘mgp25’ y un serial cualquiera ‘12345’, nos muestra un mensaje ‘Bad boy’.

Ah, y el motivo por el cual he desenfocado los valores HardwareID 01 y HardwareID 02, lo explico más adelante, porque se supone que en este paso aún no lo sabemos :p

Decompilado y análisis

Decompilado

Siempre me gusta pasarlo primero a smali y ver si puedo hacer algo, pero al hacerlo vemos que no se puede sacar mucha información. Así que obtenemos los archivos .class y buscamos “Bad boy”, y aquí encontramos el código donde se crea el serial.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
	public void onClick(View paramAnonymousView)
	{
		String str1 = ((EditText)HelloAndroid.this.findViewById(2131034116)).getText().toString();
		int i = str1.length();
		String str2 = "";
		String str3 = ((EditText)HelloAndroid.this.findViewById(2131034118)).getText().toString();
		if (i < 4) {}
		for (;;)
		{
			try
			{
				Toast.makeText(HelloAndroid.this.getApplicationContext(), "Min 4 chars", 1).show();
				return;
			}
			catch (Exception localException)
			{
				int k;
				String str4;
				TelephonyManager localTelephonyManager;
				String str5;
				String str6;
				String str7;
				String str8;
				long l;
				Toast.makeText(HelloAndroid.this.getApplicationContext(), "Another Error Ocurred :(", 1).show();
				return;
			}
			k = str1.length();
			if (j >= k)
			{
				str4 = String.valueOf(0x6B016 ^ Integer.parseInt(str2.substring(0, 5)));
				localTelephonyManager = (TelephonyManager)HelloAndroid.this.getSystemService("phone");
				str5 = localTelephonyManager.getDeviceId();
				str6 = localTelephonyManager.getSimSerialNumber();
				str7 = str5.substring(0, 6);
				str8 = str6.substring(0, 6);
				l = Integer.parseInt(str7) ^ Integer.parseInt(str8);
				if ((str4 + "-" + String.valueOf(l) + "-" + str7).equals(str3)) {
					Toast.makeText(HelloAndroid.this.getApplicationContext(), "God boy", 1).show();
				}
			}
			else
			{
				int m = str1.charAt(j);
				str2 = str2 + m;
				j++;
				continue;
			}
			Toast.makeText(HelloAndroid.this.getApplicationContext(), "Bad boy ", 1).show();
			return;
			int j = 0;
		}
	}

Análisis

1
2
3
4
		String str1 = localTelephonyManager.getDeviceId();
		((TextView)findViewById(2131034112)).setText("HardwareID 01: " + str1);
		String str2 = localTelephonyManager.getSimSerialNumber();
		((TextView)findViewById(2131034113)).setText("HardwareID 02: " + str2);

Solución

Podemos ver que tanto str1 como str2 son valores propios del teléfono, son el IMEI y el numero de serie de la SIM respectivamente. Por lo que no tiene sentido utilizar el crackme en un emulador, tendrá que ser directamente en el dispositivo. Es por eso que desenfoqué los datos :) Y leyendo el código, hice el siguiente keygen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/usr/bin/python

import sys
from datetime import date

print '''
######################################
#                                    #
#    Keygen for crackme03 deurus     #
#                                    #
######################################

Author: @_mgp25 - github.com/mgp25 - mgp25.com

'''

j=0
str2 = ""

if len(sys.argv) < 2:
	sys.exit("Usage: python serial.py <name> <phone> <imei> <sim serial>\n")
else:
	name = sys.argv[1]

def generateSerial(name, j, str2):
	if name == "":
		sys.exit("Enter a valid name")
	else:
		while True:
			if j>=len(name):
				str4 = str( 0x6B016 ^ int(str2[0:5]))
				phone = sys.argv[2]
				imei = sys.argv[3]
				simSerial = sys.argv[4]
				str7 = imei[0:6]
				str8 = simSerial[0:6]
				l = int(str7) ^ int(str8)
				break

			else:
				m = ord(name[j])
				str2 = str2 + str(m)
				j += 1

		print "Your serial is " +str4 + "-" + str(l) + "-" + str7

generateSerial(name, j, str2)

Bueno, ¡no fue tan complicado! Vamos a utilizarlo, y a ver si es verdad que funciona :p

Solución alternativa

¡Yay! Hemos conseguido el ‘God boy’, lo pasamos con éxito este crackme :D Pero como yo soy así, no me basta con el keygen, quiero que acepte cualquier serial que introduzcamos. Así que empecemos a ver el bytecode y a modificarlo.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    invoke-virtual/range {v22 .. v22}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v14

    .line 109
    .local v14, serial:Ljava/lang/String;
    invoke-virtual {v14, v15}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

    move-result v22

    if-eqz v22, :cond_2

    .line 111
    move-object/from16 v0, p0

    iget-object v0, v0, Lcom/example/helloandroid/HelloAndroid$2;->this$0:Lcom/example/helloandroid/HelloAndroid;

    move-object/from16 v22, v0

    invoke-virtual/range {v22 .. v22}, Lcom/example/helloandroid/HelloAndroid;->getApplicationContext()Landroid/content/Context;

    move-result-object v22

    .line 112
    const-string v23, "God boy"

    const/16 v24, 0x1

    .line 111
    invoke-static/range {v22 .. v24}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

    move-result-object v13

Es fácil identificar la construcción del serial y la comparación que hace que vaya a “God boy” o “Bad boy”. Así que, esta es la línea en cuestión:

1
	    invoke-virtual {v14, v15}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

El serial que hemos generado se guarda en v14 y se compara con v15. Yo simplemente cambié el v15 por el v14, de esa manera, v14 siempre será igual a v14 :P

1
	    invoke-virtual {v14, v14}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

Construímos y firmamos el .apk

E instalamos el .apk modificado en nuestro dispositivo:

Y finalmente, probamos cualquier serial:

¡Bien :D! Hemos pasado con éxito este crackme.

Un saludo y hasta la próxima :)