Archive

Posts Tagged ‘crackme’

CutedEvil Crackme #1 (Old Session – 2002)

April 5th, 2009 spark No comments

 

CuTedEvil CrackMe #1

Análisis y Parcheo.

 

Buenas, a todos los lectores de @rroba, soy SparK, del team DisidentS, y les ofrezco mis nobles y humildes conocimientos en este arte de la Ingeniería Inversa.

Espero que se diviertan tanto como yo lo he hecho con este crackme, en realidad no es nada difícil, pero a veces es lindo acorralar fácilmente a una víctima o no? :)

Quizás algunos de ustedes sean avezados Reverser’s y piensen al leerme, ¿pero que es esto? ¿El abecedario una y otra vez?, quizás otros novatos newbies, o simplemente lectores interesados en este arte digan: “mmmm, interesante”, quiero que sepan todos ustedes, intentaré darles siempre pensamientos frescos e ideas nuevas, por eso es bello este arte, es muy diverso.

Pero, vamos por partes, dijo Jack el Destripador, ¿Qué es un Crackme?

Ok, para los que no lo saben, un crackme es un programita que sirve para ejecitarse en el arte de la ingeniería inversa, en pocas palabras, es un “ejercicio de aplicación”.

¿ Que lograremos crackeando un crackme?

Pues, muchísimas cosas, primero, hay crackmes con las mas diversas protecciones y ocurrencias, en síntesis sirve para poder aprender, concentrarse en ese código difícil de aprender e interpretar a simple vista llamado Ensamblador, para poder memorizar técnicas, rutinas, y luego, en otro momento cuando miremos otro código digamos, “ah!, es mas o menos parecido a…” , en fin, ejercitas, la lógica, la memoria, y a la vez si no sabes o no entiendes ni medio de lo que pasa en ese maldito crackme, aprendes, que es lo más importante que te puede suceder aquí.

Les daré mas pistas, existen muchos tipos de ejercicios de aplicación, algunos de ellos son los Reverse me’s, los Tool me’s y demás, los primeros debes conocer ensamblador a fondo, y reprogramar la aplicación, o inclusive agregar código faltante, ¿ interesante no ? , ya veremos algunos, no desesperéis…. :)

Este Crackme, lo he bajado de www.crackmes.de , y hasta hoy no tenía solución.

El crackme, tiene un aspecto como una caja de registro típica de cualquier programa, deberemos ingresar Nombre de Usuario, Serial, y luego click en Check.

Si hacemos click en Read the Rulez!, nos dirá que debemos programar un keygen, ok, ¿que es eso? Un programa que genere seriales aceptables para el crackme, ingresandole cualquier nombre de usuario, para poder hacer esto debemos conocer y entender que sucede dentro del crackme y como se calcula el serial a partir de un nombre de usuario dado.

Ok, empecemos parcheándolo, ¿porque? , pues porque no tenemos que analizar mucho para parchearlo, aunque no este permitido en las reglas del juego, lo haré para explicarles a los más novatillos como se debe hacer.

Les comento algo a todos, parchear es nocivo para la mente del cracker, se dice que es un sucio crack, aquel que pudiendo aplicar técnicas mas “finas”, parchea, ¿ porque ?, porque aquí queremos aprender, y el facilismo nos lleva a la mediocridad, entonces, si parcheamos, es fácil crackearlo, como verán solo cambiando uno o dos bytes, pero si hacemos un serial fishing, y aún muchísimo mejor , programamos una keygen, estamos demostrandonos sobre todo, que sabemos bien lo que sucede en nuestra querida pc, y que podemos entender tarde o temprano, lo que sea. Aunque si no está a nuestros alcances hacer un keygen aún, paciencia, parchear es divertido :)

Carguemos el Olly, (¿que porque olly?, porque me anda muy bien en mi win xp), y ejecutemoslo, presionando F9, ¿que sucede?, aparece nuestro programilla, ponemos un nombre de usuario, SparK, ahora un serial, 0123456, y click en Check, que sucede?……… NADA!

Ok, se dice en el Zen Cracking, que todo cracker necesita una referencia para penetrar en el código de un programa, los seres humanos, tenemos referencias, los objetos los identificamos con los sentidos, son distintos, son reconocibles, en el cracking sucede lo mismo, el cracker necesita un punto de referencia, al principio los novatos necesitan puntos de referencia mas “humanos”, pero luego, te acostumbras al lenguaje interno de las máquinas y empiezas a encontrar referencias que antes no veías, esto , se llama práctica.

Nuestro punto de referencia, aquí sería un cartel, llamado messagebox que diga “Incorrect Serial” o algo por el estilo, entonces, nosotros desensamblaríamos el programa, y buscaríamos donde se llama a ese messagebox y un poco antes encontraríamos el salto que nos lleva al cartel exitoso o al fracaso, simplemente invertirlo y PUM!, “You are registered”.

Pero no, no soñemos mas, enfrentemos la realidad, no hay messagebox, no nos dice nada, pero tampoco nos registra y eso nos pone mal, muy mal. :)

Ok, busquemos en el Olly, por alguna referencia de strings, miremos un poquito más abajo y encontramos algo como esto:

figura11

Perfecto!, algunas referencias hemos encontrado, miren esta, “Congratulations, you cracked this program :) ”, miremos mas arriba de esta referencia, y encontramos este salto:

004012E8 |. 74 0F |JE SHORT CuTedEvi.004012F9

Bien, si invertimos ese salto, tendríamos que estar registrados, probemos cambiar el 74 por un 75 (JNE), hagamos click sobre la instrucción de salto, presionemos la tecla espaciadora, y ahora, cambiemos el JE por un JNE, y listo, apretemos F9, ¿¿que pasa?? nada, sigue haciendo lo mismo, ¿pero que pasa aqui?

Seguramente existe lo que se llama, mirror check, es un chequeo primario o secundario, que se hace en otra parte del código, que seguramente chequea longitud del nombre de usuario, del serial ingresado, o algun cálculo con ellos posterior, miremos un poco más, ¿ven porque no es bueno parchear a lo bruto?, si no conoces el código y lo haces mecánicamente, puedes quedar mal parado ante una demostración ;oD

¿Pero, como encontrar el otro chequeo?, miremos, observermos, debugiemos el código, una y otra vez, pongamos breakpoints, haber, ¿ que sucede generalmente en estas rutinas a nivel interno para obtener los textos introducidos por el usuario?, una pista, referencia, aparentemente oculta, pero existe, generalmente se llama a la API GetDlgItemText, o GetDlgItemTextA, para obtener el texto, pues ¿que hace?, obtiene el texto del editbox del nombre de usuario por ejemplo, y pone en el registro EAX la longitud del texto introducido.

Busquemos la/las llamadas a esta hermosa API…..

Aquí hay algo interesante:

figura21

Ok, tenemos en 0040115B que carga el ID de uno de los editbox, seguramente el del nombre de usuario, y en

0040117E, el ID del serial, ahora 00401166 y en 00401191 es llamada la API mencionada.

Fijense algo curioso, luego de llamarlas a las APIs encontramos lo siguiente:

0040118E CMP EAX,0

00401191 JE CuTedEvi.0040132B

Recuerden que les conté en secreto que GetDlgItemTextA, devuelve en EAX la longitud del texto extraído de una editbox, entonces, aquí compara la longitud con 0 y si es 0, salta a otro lado, con lo que no iría por buen camino, ya que nosotros debemos ingresar un serial y un nombre de usuario, sino no chequeará nada y seguirá su rumbo…..

Existe otra API llamada lstrlenA, que justamente obtiene la longitud de una string. ¿ pero porque esta llamada aquí ?, si ya sabemos cuanto tiene cada string… quiere decir, que debe necesitarlo, miremos:

PUSH CuTedEvi.0040332B ; /String = “”

CALL <JMP.&KERNEL32.lstrlenA> ; \lstrlenA

CMP EAX,0

JE SHORT CuTedEvi.004012F7

De nuevo un chequeo por 0, y salta a donde el otro chequeo lo hace, 004012F7, como podemos ver, ese salto, es por donde NO debemos ir.

Bien, pensemos ahora, que sucede, ¿si no salta a 004012F7?, algo hace, algo debe hacer, y de hecho lo hace…

figura31

ROL es una instrucción de cálculo, rota los bits hacia la izquierda, hagamos de cuenta que multiplicamos por 5 (en decimal) un valor.

SUB resta 123 (en hexadecimal).

ADD suma 321 (en hexa también)

CMP compara con un valor, en este caso 2FE.

Luego si, no es EAX ese valor esperado, salta al famoso salto del fracaso. :)

Apliquemos Ingeniería Inversa:

 

el valor esperado en eax como resultado de los cálculos es 2FE (33 en decimal), en EAX, tenemos la longitud de la cadena serial luego de llamar a lstrlenA, entonces, hagamos el cálculo inverso para ver, que longitud necesitamos tener en el editbox serial.

Tomemos 2FE, restemosle 321, esto nos da un número negativo FFFFFFFFFFFFFFDD, ahora sumemos 123, y nos da 100 (siempre en hexadecimal, no se confundan), ahora ROL multiplica por 5, ahora DIVIDAMOS por 5, ¿¿ y que obtenemos ?? un lindo y hermoso 33.

Esa, esa cifra señores, es la longitud que el programa necesita que tenga el serial, para poder seguir chequeando.

Ahora , modifiquemos el valor del serial, y miremos, que pasa: 012345678901234567890123456789012 , ese serial introduje yo, 33 valores cualquiera ni más, ni menos…

Ahora miremos que estamos muy cerca de los cartelitos de antes, ¿se acuerdan?, ok, les muestro que pasa antes:

figura41

Ok, tenemos el salto que habíamos parcheado hoy, pero, con la diferencia que sabemos que pasa antes, ahora solamente lo que podemos hacer son dos cosas, o introducir un número cualquiera de 33 caracteres, y luego parchear ese salto, o sino, parchear los dos saltos:

Primero: CMP EAX,2FE

JNZ SHORT CuTedEvi.004012F7

 

Segundo: CMP BL,0

JE SHORT CuTedEvi.004012F9

y Listo!, felicidades lo has logrado. :)

convert this post to pdf.