Debugando con .NET reflector


El otro dia estuve recogiendo algunas cosas que aun tenía en casa de mi madre (me mudé hace relativamente poco) y en un cajón escondido por ahi encontre un documento impreso que empezaba así:

“La guía perfecta para comenzar a crackear: Volumen I” by ANTIKTON, MAY 98.

Me emocioné y todo. Empecé a hojear esos papeles y mientras veia cosas de ensamblador que hacía milenios que no veía me preguntaba por dentro: ¿qué habrá sido de Antikton? ¿igual está de gerente de alguna consultora o en plan jefe de proyecto cabrón? ¿dejó la informática para abrir una frutería? Dios, cuando lei en voz alta lo de “MAY 98” me retumbaba por dentro “Mayo del 68”, como si me hubiera retraido a tiempos lejanos.

Igual un dia me da por reproducir el doc en cuestión aqui … pero como no podía ser de otra manera, sufrí un ataque frikinosis nocturna y me dió por ver como está el tema en este siglo en cuanto a los cracks. Alguna vez he tenido que descompilar algun programita con cavaj, y bueno, aunque el programa se puede complicar hasta el infinito, no tiene nada que ver chuparse el código en ensamblador o en java (sin comentarios, eso si xD).

Cuando estaba con la frikinosis al máximo, estuve buscando páginas de “crackmes”, para ver como estaba el tema, que herramientas hay ¿seguira siendo SoftICE la herramienta universal?. Al final, di con la página www.crackmes.de, en la que la gente sube programas para que otros peten la protección.

Bien, ya tenía una misión ;P

Luego también estuve buscando acerca de las herramientas a usar, y no encontre muchisimas: SoftICE sigue ahí, w32dasm, IDA. Supongo que al no estar en la movida simplemente no he sabido buscar en los sitios correctos. Pero para aplicaciones .NET si que encontre una que me gustó por la simplicidad:

.NET Reflector

Estuve probando con un crackme de nivel superfácil (la edad no perdona), y bien, se pueden hacer cosas interesantes aunque lo mejor es que hay toneladas de plugins en la página del autor.

Yendo al lío: el tema consiste en bajarse el crackme escrito en .NET y abrirlo con Reflector, que nos enseña las tripas del programa como si nada.

El programa

Las Tripas

Un detalle que me ha gustado de Reflector: puedes elegir que te muestre el programa en C#, VB … no estoy acostumbrado a estos detalles al venir de Java.

En el namespace CrackMe2 (si lo vemos como VB que va a ser lo fácil) hay una función que se llama check_button_Click, veamos que hace:

Private Sub check_button_Click(ByVal sender As Object, ByVal e As EventArgs)
If Not Versioned.IsNumeric(Me.number_textbox.Text) Then
Interaction.MsgBox(“Please enter a valid number.”, MsgBoxStyle.Critical, “Error”)
Else
Dim str As String = “abcdefghijklmnopqrstuvwxyz”
Dim sString As String = Conversions.ToString(CDbl((Conversions.ToDouble(Me.number_textbox.Text) + 57842967)))
sString = String.Concat(New String() { Strings.Mid(str, 1, 1), Strings.UCase(Strings.Mid(str, &H1A, 1)), Strings.UCase(Strings.Mid(str, 11, 1)), sString, Conversions.ToString(2), Strings.UCase(Strings.Mid(str, 14, 1)), Strings.Mid(str, &H12, 1) })
If (Strings.UCase(Strings.Mid(Conversions.ToString(Me.sha1(sString)), 1, 20).Insert(4, “-“).Insert(9, “-“).Insert(14, “-“).Insert(&H13, “-“)) = Me.serial_combobox.Text) Then
Interaction.MsgBox(“Bravo, you’ve cracked me! :)”, MsgBoxStyle.Exclamation, “Message”)
Else
Interaction.MsgBox(“Serial and number do not match.”, MsgBoxStyle.Exclamation, “Message”)
End If
End If
End Sub
En la línea:

Dim sString As String = Conversions.ToString(CDbl((Conversions.ToDouble(Me.number_textbox.Text) + 57842967)))

Parece que coge el número que le entramos como “Number” y le suma un 578…..

A partir de ese nuevo número y jugando con la cadena “abcdef…”, genera un nuevo string “sString”. Si miramos a detalle la línea:

sString = String.Concat(New String() { Strings.Mid(str, 1, 1), Strings.UCase(Strings.Mid(str, &H1A, 1)), Strings.UCase(Strings.Mid(str, 11, 1)), sString, Conversions.ToString(2), Strings.UCase(Strings.Mid(str, 14, 1)), Strings.Mid(str, &H12, 1) })

Vemos que no es más que una forma rara de hacer:
aZK + String(numero+578...) + 2Nr

Hasta ahora, solamente se ha montado una cadena en base al número que le hemos introducido. La comprobación la hace en la línea:

If (Strings.UCase(Strings.Mid(Conversions.ToString(Me.sha1(sString)), 1, 20).Insert(4, “-“).Insert(9, “-“).Insert(14, “-“).Insert(&H13, “-“)) = Me.serial_combobox.Text) Then

Ok, o sea que calcula el sha1 del string, extrae los 1eros 20 caracteres, inserta guiones y compara? pues no, pero casi. Si seguimos el enlace de Me.sha1 (esta bien esto de tener enlaces dentro del código), vemos que la función Me.sha1 está implementada así:

Private Function sha1(ByVal sString As String) As Object
Dim provider As New MD5CryptoServiceProvider
Dim bytes As Byte() = Encoding.ASCII.GetBytes(sString)
bytes = provider.ComputeHash(bytes)
Dim str As String = “”
Dim num As Byte
For Each num In bytes
str = (str & num.ToString(“x2”))
Next
Return str
End Function

Vamos, que de sha1 solo tiene el nombre. Realmente está calculando el md5.

Entonces con todo esto, se supone que hay que generar numeros enteros, crear la cadena (aZK + ….) y calcular el md5 de eso. Si el resultado (con los guiones) coincide con el campo “Serial” bingo!.

Aun hay un cabo por atar: el botón “Need a clue?” esta desactivado. ¿Qué se supone que hace eso?

Pues vamos a averiguarlo con Reflector. Si vemos que hace la función que gestiona el botón:

Private Sub clue_textbox_Click(ByVal sender As Object, ByVal e As EventArgs)
Interaction.MsgBox(Me.clue_textbox.Text, MsgBoxStyle.Information, “Clue”)
End Sub

Una pista! y si comprobamos la función InitializeComponent(), hay una propiedad que se inicializa desde ahí:

Me.clue_textbox.Text = “The number is between 10000000 and 99999999.”

Pues ya lo tenemos todo:

Hay que generar números dentro de ese intervalo, sumarle la cte 578… y montar un string “aZK” + num + “2Nr”. Luego calcular el sha1 … esto … el md5 de la cadena y comprobar si coincide con alguna de los Serials.

Con todo esto, el programa para generar los números es este:

package org.azufre.crackme;

import java.security.*;
import java.util.*;

public class Generator {

private HashSet<String> serial = new HashSet<String>(
Arrays.asList(
new String [] {
“E9A1CFE4A2D6D19BE1E2”,
“F68A8002D1FD1BF6E6C4”,
“6F96AFB32A2DF6921A27”,
“5FE610E5FF3F01AE232E”,
“E04BD61890EF373B307D”,
“6C220B1F7C4A6ADE2796”,
“EC39552C9E438A3C5BA2”,
“6C8A82EC5EE91B1D4C26”
}
)
);

public static void main(String[] args) {
Generator g = new Generator();
g.force();
}

public void force () {
String buffer;
int i = 10000000;
int sString = 0;
while ( i<99999999 && !serial.isEmpty() ) {
sString = i + 57842967;
buffer = MD5(generateString(sString));
buffer = buffer.substring(0,20);
test(buffer,i);
i++;
}
}

private String generateString(int i) {
return new String(“aZK” + i + “2Nr”);
}

public String MD5(String p1) {
String retval = new String();
byte[] buffer;
MessageDigest md5;
try {
md5 = MessageDigest.getInstance(“MD5”);
md5.update(p1.getBytes());
buffer = md5.digest();
retval = this.convertToHex(buffer);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return retval;
}

private String convertToHex(byte[] data) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < data.length; i++) {
int halfbyte = (data[i] >>> 4) & 0x0F;
int two_halfs = 0;
do {
if ((0 <= halfbyte) && (halfbyte <= 9))
buf.append((char) (‘0’ + halfbyte));
else
buf.append((char) (‘a’ + (halfbyte – 10)));
halfbyte = data[i] & 0x0F;
} while(two_halfs++ < 1);
}
return buf.toString();
}

private int test(String p1, int j) {
int retval=0;
if ( serial.contains(p1) ) {
serial.remove(p1);
System.out.println(“key found: ” + j + “\tserial: ” + p1 );
retval = 1;
}
return retval;
}

}

Y funciona!

Las rutinas para calcular de una manera simple el MD5 de un string esta sacado de Java simple class to compute MD5 hash, porque aunque Java da mecanismos para calcular MD5 o SHA1, realmente son un rollo para usar en casos simples.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: