martes, 18 de septiembre de 2012

[Crackme] – Operadores lógicos (con Immunity Debugger)

Después de darle alguna que otra vez el coñazo para que se animara a escribir un artículo, por fin, Manu “The Sur” me ha hecho feliz y se ha dignado a realizar su primer solucionario de un crackme, y espero que no sea el último ;)

NOTA: Si es la primera vez que te enfrentas a un reto o crackme y no dispones de conocimientos básicos en ingeniería inversa, recomiendo la lectura de la serie “Introducción a la Ingeniería Inversa en x86” que podéis encontrar en el apartado de Artículos.

A continuación el artículo de Manu “The Sur”:

Una de las páginas más conocidas en donde se recopilan una gran cantidad de retos de reversing es crackmes.de. En este artículo veremos como resolver con 'Immunity Debugger' el crackme 'hackereh@' de dificultad fácil, escogido del portal crackmes.de.

Descarga del fichero: [Crackme_hackereh@]
Escaneo del fichero (exe) en VirusTotal:
MD5 (exe): 4d60550ba627682ee49aba65344ae627
SHA1 (exe): 4c7ad25a2f4c5495463a64f07ccb658980441076

IMPORTANTE: Siempre es bueno que probéis a resolver vosotros el crackme antes de leer la resolución.

Antes de empezar a analizar el binario con Immunity Debugger, vamos a ejecutarlo y ver que es lo que requiere.

image

Parece el típico crackme que nos pide un serial y tenemos que acertar la cadena correcta, vemos como nos muestra distintos mensajes de error a la hora de realizar la comprobación. Estos mensajes suelen ser un buen punto de partida para iniciar nuestro análisis.

Dos buenas formas de iniciar nuestro análisis sería la búsqueda de los “strings” referenciados en el binario, o si preferimos podríamos buscar mediante la opción “intermodular calls” de Immunity Debugger las llamadas a las APIs.

Si ejecutamos el crackme mediante Immunity Debugger, y nos centramos en la segunda opción “Search for -> All intermodular calls”, podemos observar las llamadas a las APIs utilizadas, entre ellas podemos localizar “GetDlgItemTextA”:

clip_image003

GetDlgItemTextA es una función que permite obtener título o el texto asociado a un control en concreto (posiblemente sea la función que utiliza para leer lo que le hemos introducido nosotros). Por lo que pondremos un breakpoint en la llamada a dicha función (en nuestro caso la dirección de memoria 0x00401180).

Si ahora ejecutamos la aplicación e introducimos como serial una ristra de caracteres “A”, llegaremos a la parte de código más interesante:

image

Como se puede observar en la dirección 0x0040118F, se está moviendo el la dirección de memoria donde está el valor que hemos introducido al registro EDI, y posteriormente realiza siete comprobaciones para verificar el serial.

Las seis primeras comprobaciones se realizan mediante la operación AND, y la séptima mediante la operación CMP. Cabe destacar que cada una de las comparaciones vienen precedidas de la instrucción MOVSX que se encarga de mover el byte N del registro EDI (dirección donde se encuentra el serial introducido por nosotros), al registro AL (donde N es un valor del 0 al 5), por lo que, vamos a ir cpiando al registro AL una a una las letras introducidas en el serial.

En la primera comprobación “AND AL, 0AD / JNZ Invalido” espera que el resultado de dicha operación lógica devuelva “0” como resultado. En caso de que no devuelva “0”, el flag Zero Flag “ZF” no se activará y la instrucción JNZ saltará hacia la dirección que nos muestra el cuadro de texto de serial inválido.

Es por ello que el primer carácter que introduzcamos en el serial debe dar “0” al realizar un AND con el valor “0x0AD”.

image
El carácter '@' (0x40) sería valido, igualmente que lo podría ser 'B' (0x42) ya que el resultado de la operación seguiría siendo “0” y el flag “ZF” seguiría activándose.

Las 5 comprobaciones siguientes es más de lo mismo, una operación AND con cada uno de los caracteres introducidos, y la sexta comprobación verifica que la longitud del texto son 6 caracteres mediante la operación “CMP ECX, 0x6”.

Una vez hemos llegado aquí, un ejemplo del serial correcto sería “Rdh@8)”, obteniendo así el deseado mensaje:

image

Para finalizar el solucionario, he desarrollado un “KeyGen” para este crackme, se puede ver un ejemplo en la siguiente captura donde cada uno de los serials seria válido:

image

Desde el siguiente enlace os podéis descargar el KeyGen compilado: [KeyGen_hackereh@]

Y a continuación dejo el código en C#:

using System;
using System.Collections.Generic;

namespace generadorSerial
{
class Program
{
static Int16[] values = new Int16[] { 0xAD, 0x9A, 0x97, 0xBF, 0x5FC5, 0xD6 };
static Int16 min = 0x21;
static Int16 max = 0x7E;

static Int16 Calc(Int16 value)
{
List possibilities = new List();

for (Int16 i = min; i <= max; i++)
{
Int16 X = (Int16)(value & (Int16)i);
if (X == 0)
possibilities.Add(i);
}

return possibilities[new Random().Next(0, possibilities.Count)];
}

static void Main(string[] args)
{
for (int i = 0 ; i < values.Length; i++)
Console.Write((char)Calc(values[i]));
}
}
}

Espero que os haya gustado y hasta pronto.


Saludos!!

1 comentario:

  1. El crackme es muy básico, pero el post está muy bien explicado. Yo he sacado este serial:

    Re@@:)

    Quizá era lo que esperaba el autor, ya que parece una cara sonriente pensando en Re (Reversing?). Jeje, no sé.

    ResponderEliminar