While Crackmes.de returns, I leave a couple of files for practice.

Mientras vuelve Crackmes.de, os dejo un par de archivos para practicar.

In the folder crackmes.de_mirror you have two files:

En la carpeta crackmes.de_mirror tienes dos archivos:


 password of files = deurus.info


Intro Antes que nada, es importante saber que un archivo ELF en Linux es equivalente a un archivo EXE en
Intro Se suele decir que para cada problema hay una solución. Si esto lo llevamos al terreno stego podemos decir
Primeras impresiones Analizamos el programa con PEiD y nos muestra que está hecho en ensamblador. Unas pruebas introduciendo datos nos
Hoy analizamos Copycat, un thriller psicológico de 1995 que, como muchas películas de la época, no pudo resistirse a incorporar

Table of Contents

Intro

Antes que nada, es importante saber que un archivo ELF en Linux es equivalente a un archivo EXE en Windows. Dicho esto, es bastante común encontrarnos con ejecutables ELF en diversos CTFs (Capture The Flag), y a menudo representan un desafío para aquellos no familiarizados con el uso cotidiano de Linux. Sin embargo, tengo una buena noticia si no eres aficionado de Linux: existen herramientas que permiten realizar un análisis preliminar para determinar si es necesario abordar el problema desde Linux o si podemos resolverlo directamente desde Windows. Estas herramientas facilitan una transición más cómoda para los usuarios de Windows, permitiéndoles interactuar eficazmente con archivos ELF.

ELF

Un archivo ELF (Executable and Linkable Format) es un formato común de archivo para archivos ejecutables, código objeto, bibliotecas compartidas y volcados de memoria en sistemas basados en Unix, como Linux. Es el estándar de formato de archivo para programas compilados y enlazados en este tipo de sistemas operativos.

La cabecera de un archivo ELF es una estructura de datos al comienzo del archivo que proporciona información esencial sobre el contenido y la forma de procesar el archivo. Esta cabecera es fundamental para que el sistema operativo y otros programas puedan interpretar correctamente el archivo ELF. Aquí están los componentes clave de la cabecera de un archivo ELF:

  1. Identificación (e_ident): Esta sección incluye la magia del archivo ELF, representada por los primeros cuatro bytes 0x7F 'E' 'L' 'F'. También incluye información como la clase del archivo (32 o 64 bits), la codificación de datos (endianness), y la versión del formato ELF.
  2. Tipo (e_type): Indica el tipo de archivo ELF, como EXEC (ejecutable), DYN (biblioteca compartida), REL (relocalizable), entre otros.
  3. Máquina (e_machine): Especifica la arquitectura de hardware para la cual se diseñó el archivo, por ejemplo, x86, ARM.
  4. Versión (e_version): La versión del formato ELF, generalmente establecida en 1.
  5. Punto de Entrada (e_entry): La dirección de memoria virtual donde comienza la ejecución del proceso.
  6. Desplazamiento del Program Header (e_phoff): Indica dónde comienza el encabezado del programa en el archivo.
  7. Desplazamiento del Section Header (e_shoff): Indica dónde comienza el encabezado de la sección en el archivo.
  8. Flags (e_flags): Banderas específicas del procesador.
  9. Tamaño de esta cabecera (e_ehsize): El tamaño de la cabecera ELF.
  10. Tamaño del Program Header (e_phentsize): El tamaño de una entrada del encabezado del programa.
  11. Número de entradas del Program Header (e_phnum): El número total de entradas en el encabezado del programa.
  12. Tamaño del Section Header (e_shentsize): El tamaño de una entrada del encabezado de la sección.
  13. Número de entradas del Section Header (e_shnum): El número total de entradas en el encabezado de la sección.
  14. Índice del Section Header Table (e_shstrndx): El índice del encabezado de la sección que contiene los nombres de las secciones.

El reto

Se nos proporciona un fichero de 20KB que rápidamente catalogamos como ELF.

Para realizar un análisis preliminar siempre uso DogBolt, que no es más que un decompilador online con la ventaja de que usa varios motores y de esta forma casi siempre te da una decompilación aceptable. La versión actual tiene disponibles 11 motores y además es open source, ¿Qué más se puede pedir?

Echamos un vistazo y enseguida encontramos algo interesante.

La flag parece codificada de modo que vamos a indagar acerca de la función FUN_0010285d

Dentro de la función FUN_0010285d vemos que nuestra flag codificada la procesa la función FUN_00102752

Aquí os diría que depende de vuestra experiencia en programación veríais que se está procesando byte a byte la cadena de entrada (param_1) y haciendo a cada byte un XOR (^) con el param_3 (que es 1 según vemos en la llamada de la función FUN_00102752), pero en estos tiempos que corren vamos a preguntar a ChatGPT que opina.

ChatGPT

Le pido a ChapGPT que me analice el código y me responde:

Este código en C define una función llamada FUN_00102752 que realiza una operación de XOR (exclusivo OR) byte a byte sobre un bloque de memoria. La función toma tres parámetros:

  1. long param_1: Este parámetro es tratado como una dirección de memoria. Se utiliza como la base de un bloque de memoria sobre el que se realizará la operación.
  2. ulong param_2: Este parámetro especifica el tamaño del bloque de memoria que será afectado por la operación.
  3. byte param_3: Este es el valor de un solo byte que se utilizará en la operación XOR.

El cuerpo de la función consiste en un bucle for que itera sobre el bloque de memoria:

  • int local_c se declara como una variable local y se inicializa en 0. Esta variable actúa como un contador para el bucle.
  • La condición del bucle (ulong)(long)local_c < param_2 asegura que el bucle se ejecute sobre el rango completo del bloque de memoria especificado por param_2.
  • Dentro del bucle, *(byte *)(param_1 + local_c) = *(byte *)(param_1 + local_c) ^ param_3; realiza la operación XOR. Aquí, *(byte *)(param_1 + local_c) accede al byte actual en el bloque de memoria. Este byte se modifica aplicándole un XOR con param_3. La operación XOR se realiza entre el byte actual en la memoria y el valor de param_3, y el resultado se escribe de nuevo en la misma ubicación de memoria.

En resumen, la función FUN_00102752 modifica un bloque de memoria aplicando una operación XOR con un valor dado (param_3) a cada byte dentro del rango de memoria especificado desde param_1 hasta param_1 + param_2. Este tipo de operación es común en tareas como la manipulación de datos para cifrado/descifrado o para la generación de patrones específicos en un bloque de datos.

by ChatGPT

Ahora imaginad que no sois muy dados a programar o simplemente estáis vagos de modo que volvemos a recurrir a ChatGPT con el promt «Haz un XOR 1 con javascript a la cadena: gmfzuihr^vr^o^drx^nod^shfiu|» a lo que responde:

function xorString(str) {
return Array.from(str).map(char => String.fromCharCode(char.charCodeAt(0) ^ 1)).join(»);
}

console.log(xorString(‘gmfzuihr^vr^o^drx^nod^shfiu|’));

by ChatGPT

Copiamos el código y lo pegamos en un entorno online como por ejemplo playcode.io.

Este es un ejemplo simple, pero ¿percibís su potencial?


La imagen de portada de esta entrada ha sido generada con ChatGPT.

Intro

Se suele decir que para cada problema hay una solución. Si esto lo llevamos al terreno stego podemos decir que para cada reto hay una herramienta que nos da la solución. En la entrada anterior os comenté que mi fondo de armario son steganabara y stegsolve aunque cuando la imagen es PNG, una herramienta de uso obligatorio es TweakPNG.

La víctima

imagen original del reto

Nos enfrentamos a una imagen PNG de 112KB (115477 bytes) con una resolución de 300×225 píxeles. A priori llama la atención el elevado tamaño VS la baja resolución, lo que aviva nuestras sospechas de que esos KB extras se deban a que haya insertado otro archivo en su interior.

Chunk

Los archivos PNG tienen la peculiaridad de que están divididos en secciones (chunks) en la que algunas son críticas como IHDR (cabecera), IDAT (la imagen) e IEND (final) y otras muchas secundarias como por ejemplo tEXt (para insertar texto). Al explorar el archivo con TweakPNG vemos la cabecera, varios chunks de texto, muchos IDAT que he combinado en uno para mejorar el análisis y la sección final. Si os fijáis, al combinar los IDAT ha cambiado el tamaño del PNG de 115447 a 110893 bytes aunque en este caso sigue siendo un tamaño elevado.

aspecto original de los chunks
aspecto de los chunks tras combinar todos los IDAT en uno

Llama la atención el chunk cHRm de 12595 bytes del que TweakPNG ya nos avisa que no reconoce su contenido. Cargamos la imagen en un editor hexadecimal y buscamos la palabra «Great» que es el texto que hay justo antes del chunk cHRm que nos interesa.

detalle del chunk cHRm en editor hexadecimal

La búsqueda da sus frutos ya que el chunk parece que está formado por un archivo mp4. A partir de aquí tenemos varias opciones, para mí la más limpia es con un editor hexadecimal apuntar los offsets de inicio y fin del chunk y crear un archivo nuevo con el contenido. Otra opción es exportar el chunk desde TweakPNG con extensión mp4 y borrar los bytes del nombre del chunk con un editor hexadecimal, de lo contrario no podréis reproducir el mp4.

nombre del chunk a borrar para que funcione el mp4

Hecho esto, al escuchar el mp4 obtenemos la solución del reto.

Enlaces

Nota: si algo os pide clave es deurus.info

Primeras impresiones

Analizamos el programa con PEiD y nos muestra que está hecho en ensamblador.


Unas pruebas introduciendo datos nos muestran que el nombre debe tener entre 3 y 10 dígitos.


Determinando la rutina de creación del serial con Ollydbg

Llegados a este punto tenemos dos opciones que funcionan en el 90% de los casos. La primera es mediante las referenced strings o mediante los names.
 
Para el primer caso, con el keygenme cargado en olly, click derecho y Search > All referenced text strings. Haciendo doble click en “You got it” o en “Bad boy” vamos directamente a la rutina de comprobación del serial o muy cerca de ella en la mayoría de los casos.


Para el segundo caso, haremos click derecho y Search > Name (label) in current módule, o Ctrl+N. Vemos dos llamadas interesantes como son user32.GetDlgItemInt y user32.GetDlgItemTextA. Lo más seguro es que user32.GetDlgItemInt coja del textbox nuestro serial y user32.GetDlgItemTextA coja nuestro nombre. Para este caso colocaríamos breakpoints en las dos llamadas.


En mi caso elijo la primera opción. Nada más pulsar en “You got it” nos fijamos un poco más arriba y vemos las funciones donde coge el nombre y el serial y a simple vista se ven las operaciones que hace con ellos.

Generando un serial válido

Como se muestra en la imagen siguiente, la creación del serial es muy sencilla y al final la comparación es lineal ya que se compara nuestro serial con el serial válido. Veamos el serial válido para el usuario “abc” cuyos dígitos en hexadecimal son 0x61, 0x62 y 0x63.

Letra a
Letra b
Letra c
Suma + 0x61
Suma * 0x20
Suma xor 0xBEFF
Suma / 4
Suma = 0x2CB7
Suma + 0x62
Suma * 0x20
Suma xor 0xBEFF
Suma / 4
Suma = 0x14777
Suma + 0x63
Suma * 0x20
Suma xor 0xBEFF
Suma / 4
Suma = 0xA116F
Suma xor 0xBEA4 = 0xAAFCB
Serial válido = 700363

Generando un keygen con WinASM studio desde cero

Abrimos WinASM studio y pulsamos en File > New Project y en la pestaña dialog elegimos base.

  

Vemos que se nos generan tres archivos, uno con extensión asm, otro con extensión inc y otro con extensión rc. El archivo asm es el que contendrá nuestro código. El archivo inc no lo vamos a usar para simplificar las cosas y el archivo rc es nuestro formulario al que pondremos a nuestro gusto.
Empecemos con el aspecto del formulario. Por defecto viene como se muestra en la siguiente imagen. Que por cierto, es todo lo que necesitamos para un keygen básico.

Y el aspecto final:

Ahora veamos cómo viene nuestro archivo asm inicialmente y que haremos con él. En la siguiente imagen lo indico.

    Encima de la sección .code hemos creado dos secciones como son .data y .data? y hemos declarado las variables necesarias. 
  • szFormat está declarada en formato integer (%i). Más tarde la utilizaremos junto a la función wsprintf para dar formato a un número.
  • szSizeMin: habla por sí misma.
  • szSizeMax: habla por sí misma.
  •  szCap: habla por sí misma.
  • szName: contendrá el nombre introducido.
  • szCode: contendrá el serial válido.
Nuestro código queda de la siguiente manera:

A partir de aquí ya simplemente es escribir el código necesario para generar el serial válido. Una de las ventajas que tiene el ensamblador para hacer keygens sin muchas complicaciones, es que prácticamente es copiar el código que nos muestra Ollydbg. Si os fijáis a continuación, en el botón llamado “IDC_OK” (no le he cambiado el nombre) he puesto todo el código necesario para generar la simple rutina del serial.
Como veis el bucle del nombre es una copia de lo que nos mostró Ollydbg. Una vez que tenemos en EAX nuestro serial válido, mediante la función wsprintf guardamos en la variable szCode el serial válido con formato integer. Finalmente mediante la función SetDlgItemText, mostramos el serial válido en la caja de texto 1002, que es la del serial.

Enlaces


MI_cartel
Intro La primera entrega de Misión Imposible es ya un clásico y poco o nada tiene que envidiar a sus
Estamos ante un ELF un poco más interesante que los vistos anteriormente. Básicamente porque es divertido y fácil encontrar la
Introducción  Este un crackme muy interesante para principiantes ya que la rutina no es muy compleja. Está hecho en ensamblador.

MI_cartel

Intro

La primera entrega de Misión Imposible es ya un clásico y poco o nada tiene que envidiar a sus secuelas. Es ágil, entretenida y como toda peli de espías que se precie, los protagonistas tienen gadgets por un tubo.

El argumento gira sobre la lista NOC. Dicha lista relaciona nombres en clave de agentes repartidos por el mundo con sus nombres reales y al parecer la quiere todo el mundo.

Lista NOC

¿Donde está la lista aquí o aquí?

Al inicio nos hacen creer que la lista NOC está en un sótano de una embajada (No jodas), sin seguridad y accesible por todo el mundo que sepa llegar allí. En esta ocasión no se puede ni llamar hackeo, ya que, el tipo en cuestión simplemente copia la lista (bueno la mitad 😉 en un disco de 3,5″

Tipo robando la lista NOC

¿Eso son Emails o Newsgroups?

Aquí empieza la locura. ¿Os acordáis del BTM de Dexter donde empieza a escribir en foros aleatorios con la esperanza de contactar con el carnicero de la bahía?, pues aquí lo mismo pero con grupos de noticias o newsgroups.

La cosa es que a Ethan Hank no se le ocurre mejor idea para encontrar a Max que buscar en todo tipo de grupos de noticias relacionados con temas bíblicos y en concreto con el libro de Job. Vamos a ver Ethan, hijo del metal, eso es una puta locura, ya de paso anúnciate en el periódico y ponte una diana en el pecho. Pero como es una película resulta que funciona. El caso es que parece que existen la ostia de grupos de discusión donde incluso se puede hablar sobre un capítulo y versículo en particular.

Newsgroup sobre el Libro de Job

El error

El problema es que en cada grupo que encuentra escribe un mensaje muy parecido a como se escribe un email y claro, queda un poco mal. Tanto si quieren hacer creer que escriben un email como si no, el caso es que la escena pierde credibilidad. Ni podría ser un email ni parece factible que alguien se ponga ese nombre de usuario, en definitiva, una chapuza.

¿Parece un email no?

Os dejo una serie de imágenes para que os deleitéis.

Estamos ante un ELF un poco más interesante que los vistos anteriormente. Básicamente porque es divertido y fácil encontrar la solución en el decompilado y quizá por evocar recuerdos de tiempos pretéritos.

ELF Decompilado

/* This file was generated by the Hex-Rays decompiler version 8.4.0.240320.
   Copyright (c) 2007-2021 Hex-Rays <info@hex-rays.com>

   Detected compiler: GNU C++
*/

#include <defs.h>


//-------------------------------------------------------------------------
// Function declarations

__int64 (**init_proc())(void);
__int64 sub_400650(); // weak
// int printf(const char *format, ...);
// int puts(const char *s);
// void __noreturn exit(int status);
// size_t strlen(const char *s);
// __int64 __fastcall MD5(_QWORD, _QWORD, _QWORD); weak
// int sprintf(char *s, const char *format, ...);
// __int64 ptrace(enum __ptrace_request request, ...);
// __int64 strtol(const char *nptr, char **endptr, int base);
// __int64 __isoc99_scanf(const char *, ...); weak
// int memcmp(const void *s1, const void *s2, size_t n);
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void));
void *sub_400730();
__int64 sub_400760();
void *sub_4007A0();
__int64 sub_4007D0();
void fini(void); // idb
void term_proc();
// int __fastcall _libc_start_main(int (__fastcall *main)(int, char **, char **), int argc, char **ubp_av, void (*init)(void), void (*fini)(void), void (*rtld_fini)(void), void *stack_end);
// __int64 _gmon_start__(void); weak

//-------------------------------------------------------------------------
// Data declarations

_UNKNOWN main;
_UNKNOWN init;
__int64 (__fastcall *funcs_400E29)() = &sub_4007D0; // weak
__int64 (__fastcall *off_601DF8)() = &sub_4007A0; // weak
__int64 (*qword_602010)(void) = NULL; // weak
char *off_602080 = "FLAG-%s\n"; // idb
char a7yq2hryrn5yJga[16] = "7Yq2hrYRn5Y`jga"; // weak
const char aO6uH[] = "(O6U,H\""; // idb
_UNKNOWN unk_6020B8; // weak
_UNKNOWN unk_6020C8; // weak
char byte_6020E0; // weak
char s1; // idb
char byte_602110[]; // weak
char byte_602120[33]; // weak
char byte_602141[7]; // idb
__int64 qword_602148; // weak
__int64 qword_602150; // weak
__int64 qword_602158; // weak
__int64 qword_602160; // weak
__int64 qword_602178; // weak


//----- (0000000000400630) ----------------------------------------------------
__int64 (**init_proc())(void)
{
  __int64 (**result)(void); // rax

  result = &_gmon_start__;
  if ( &_gmon_start__ )
    return (__int64 (**)(void))_gmon_start__();
  return result;
}
// 6021D8: using guessed type __int64 _gmon_start__(void);

//----- (0000000000400650) ----------------------------------------------------
__int64 sub_400650()
{
  return qword_602010();
}
// 400650: using guessed type __int64 sub_400650();
// 602010: using guessed type __int64 (*qword_602010)(void);

//----- (0000000000400700) ----------------------------------------------------
// positive sp value has been detected, the output may be wrong!
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void))
{
  __int64 v3; // rax
  int v4; // esi
  __int64 v5; // [rsp-8h] [rbp-8h] BYREF
  char *retaddr; // [rsp+0h] [rbp+0h] BYREF

  v4 = v5;
  v5 = v3;
  _libc_start_main((int (__fastcall *)(int, char **, char **))main, v4, &retaddr, (void (*)(void))init, fini, a3, &v5);
  __halt();
}
// 400706: positive sp value 8 has been found
// 40070D: variable 'v3' is possibly undefined

//----- (0000000000400730) ----------------------------------------------------
void *sub_400730()
{
  return &unk_6020C8;
}

//----- (0000000000400760) ----------------------------------------------------
__int64 sub_400760()
{
  return 0LL;
}

//----- (00000000004007A0) ----------------------------------------------------
void *sub_4007A0()
{
  void *result; // rax

  if ( !byte_6020E0 )
  {
    result = sub_400730();
    byte_6020E0 = 1;
  }
  return result;
}
// 6020E0: using guessed type char byte_6020E0;

//----- (00000000004007D0) ----------------------------------------------------
__int64 sub_4007D0()
{
  return sub_400760();
}

//----- (00000000004007D7) ----------------------------------------------------
__int64 __fastcall main(int a1, char **a2, char **a3)
{
  size_t v3; // rax
  size_t v4; // rax
  int i; // [rsp+1Ch] [rbp-24h]
  int n; // [rsp+20h] [rbp-20h]
  int m; // [rsp+24h] [rbp-1Ch]
  int k; // [rsp+28h] [rbp-18h]
  int j; // [rsp+2Ch] [rbp-14h]

  if ( ptrace(PTRACE_TRACEME, 0LL, 0LL, 0LL) == -1 )
    goto LABEL_2;
  if ( a1 > 4 )
  {
    qword_602148 = strtol(a2[1], 0LL, 10);
    if ( qword_602148 )
    {
      qword_602150 = strtol(a2[2], 0LL, 10);
      if ( qword_602150 )
      {
        qword_602158 = strtol(a2[3], 0LL, 10);
        if ( qword_602158 )
        {
          qword_602160 = strtol(a2[4], 0LL, 10);
          if ( qword_602160 )
          {
            if ( -24 * qword_602148 - 18 * qword_602150 - 15 * qword_602158 - 12 * qword_602160 == -18393
              && 9 * qword_602158 + 18 * (qword_602150 + qword_602148) - 9 * qword_602160 == 4419
              && 4 * qword_602158 + 16 * qword_602148 + 12 * qword_602150 + 2 * qword_602160 == 7300
              && -6 * (qword_602150 + qword_602148) - 3 * qword_602158 - 11 * qword_602160 == -8613 )
            {
              qword_602178 = qword_602158 + qword_602150 * qword_602148 - qword_602160;
              sprintf(byte_602141, "%06x", qword_602178);
              v4 = strlen(byte_602141);
              MD5(byte_602141, v4, byte_602110);
              for ( i = 0; i <= 15; ++i )
                sprintf(&byte_602120[2 * i], "%02x", (unsigned __int8)byte_602110[i]);
              printf(off_602080, byte_602120);
              exit(0);
            }
          }
        }
      }
    }
LABEL_2:
    printf("password : ");
    __isoc99_scanf("%s", &s1);
    if ( strlen(&s1) > 0x10 )
    {
      puts("the password must be less than 16 character");
      exit(1);
    }
    for ( j = 0; j < strlen(&s1); ++j )
      *(&s1 + j) ^= 6u;
    if ( !strcmp(&s1, a7yq2hryrn5yJga) )
    {
      v3 = strlen(&s1);
      MD5(&s1, v3, byte_602110);
      for ( k = 0; k <= 15; ++k )
        sprintf(&byte_602120[2 * k], "%02x", (unsigned __int8)byte_602110[k]);
      printf(off_602080, byte_602120);
      exit(0);
    }
    puts("bad password!");
    exit(0);
  }
  printf("password : ");
  __isoc99_scanf("%s", &s1);
  if ( strlen(&s1) > 0x10 )
  {
    puts("the password must be less than 16 character");
    exit(1);
  }
  for ( m = 0; m < strlen(&s1); ++m )
  {
    *(&s1 + m) ^= 2u;
    ++*(&s1 + m);
    *(&s1 + m) = ~*(&s1 + m);
  }
  if ( !memcmp(&s1, &unk_6020B8, 9uLL) )
  {
    for ( n = 0; n < strlen(aO6uH); n += 2 )
    {
      aO6uH[n] ^= 0x45u;
      aO6uH[n + 1] ^= 0x26u;
    }
    puts(aO6uH);
  }
  else
  {
    puts("bad password!");
  }
  return 0LL;
}
// 4006A0: using guessed type __int64 __fastcall MD5(_QWORD, _QWORD, _QWORD);
// 4006E0: using guessed type __int64 __isoc99_scanf(const char *, ...);
// 602148: using guessed type __int64 qword_602148;
// 602150: using guessed type __int64 qword_602150;
// 602158: using guessed type __int64 qword_602158;
// 602160: using guessed type __int64 qword_602160;
// 602178: using guessed type __int64 qword_602178;

//----- (0000000000400DE0) ----------------------------------------------------
void __fastcall init(unsigned int a1, __int64 a2, __int64 a3)
{
  signed __int64 v3; // rbp
  __int64 i; // rbx

  v3 = &off_601DF8 - &funcs_400E29;
  init_proc();
  if ( v3 )
  {
    for ( i = 0LL; i != v3; ++i )
      (*(&funcs_400E29 + i))();
  }
}
// 601DF0: using guessed type __int64 (__fastcall *funcs_400E29)();
// 601DF8: using guessed type __int64 (__fastcall *off_601DF8)();

//----- (0000000000400E54) ----------------------------------------------------
void term_proc()
{
  ;
}

// nfuncs=33 queued=10 decompiled=10 lumina nreq=0 worse=0 better=0
// ALL OK, 10 function(s) have been successfully decompiled

Análisis estático

Anti-debug

Si la función ptrace retorna -1, significa que el programa está siendo depurado y redirige a LABEL_2.

if (ptrace(PTRACE_TRACEME, 0LL, 0LL, 0LL) == -1) {
    goto LABEL_2;
}

Cálculos y validaciones

El programa espera al menos 5 argumentos (nombre del programa y cuatro números enteros). Si se proporcionan los cuatro números enteros, se realizan los siguientes cálculos:

if (-24 * qword_602148 - 18 * qword_602150 - 15 * qword_602158 - 12 * qword_602160 == -18393
    && 9 * qword_602158 + 18 * (qword_602150 + qword_602148) - 9 * qword_602160 == 4419
    && 4 * qword_602158 + 16 * qword_602148 + 12 * qword_602150 + 2 * qword_602160 == 7300
    && -6 * (qword_602150 + qword_602148) - 3 * qword_602158 - 11 * qword_602160 == -8613)

Esto es un sistema de ecuaciones lineales mondo y lirondo que debe ser resuelto para encontrar los valores correctos de qword_602148, qword_602150, qword_602158 y qword_602160. Una vez resuelto el sistema de ecuaciones se realiza la operación:

 qword_602178 = qword_602158 + qword_602150 * qword_602148 - qword_602160;

A continuación se pasa el resultado de la variable qword_602178 a hexadecimal y se genera su hash MD5.

Solución en Python

Lo más rápido en esta ocasión es usar Python, pero esto se puede resolver hasta con lápiz y papel 😉

from sympy import symbols, Eq, solve
import hashlib

# Definir las variables
A, B, C, D = symbols('A B C D')

# Definir las ecuaciones
eq1 = Eq(-24*A - 18*B - 15*C - 12*D, -18393)
eq2 = Eq(9*C + 18*(A + B) - 9*D, 4419)
eq3 = Eq(4*C + 16*A + 12*B + 2*D, 7300)
eq4 = Eq(-6*(A + B) - 3*C - 11*D, -8613)

# Resolver el sistema de ecuaciones
solution = solve((eq1, eq2, eq3, eq4), (A, B, C, D))

# Verificar si se encontró una solución
if solution:
    print("Solución encontrada:")
    print(solution)

    # Obtener los valores de A, B, C y D
    A_val = solution[A]
    B_val = solution[B]
    C_val = solution[C]
    D_val = solution[D]

    # Mostrar los valores encontrados
    print(f"A = {A_val}")
    print(f"B = {B_val}")
    print(f"C = {C_val}")
    print(f"D = {D_val}")

    # Calcular qword_602178
    qword_602178 = C_val + B_val * A_val - D_val
    qword_602178 = int(qword_602178)  # Convertir a entero de Python
    print(f"qword_602178 = {qword_602178}")

    # Convertir qword_602178 a una cadena en formato hexadecimal
    byte_602141 = f"{qword_602178:06x}"
    print(f"byte_602141 (hex) = {byte_602141}")

    # Calcular el MD5 de la cadena
    md5_hash = hashlib.md5(byte_602141.encode()).hexdigest()
    print(f"MD5 hash = {md5_hash}")

    # Generar la flag
    flag = f"FLAG-{md5_hash}"
    print(f"Flag = {flag}")

else:
    print("No se encontró una solución.")

Al ejecutar el script veremos algo como esto:

Solución encontrada:
{A: 227, B: 115, C: 317, D: 510}
A = 227
B = 115
C = 317
D = 510
qword_602178 = 25912
byte_602141 (hex) = 006538
MD5 hash = 21a84f2c7c7fd432edf1686215db....
Flag = FLAG-21a84f2c7c7fd432edf1686215db....

Introducción

 Este un crackme muy interesante para principiantes ya que la rutina no es muy compleja. Está hecho en ensamblador.

Saltar el antidebug

Arrancamos el crackme en Olly damos al play y se cierra. Buscamos en las «Intermodular Calls» y vemos «IsDebuggerPresent«, clickamos sobre ella y vemos el típico call, lo NOPeamos.

names

Aquí vemos el call.

isdebuggerpresent

Call Nopeado.

antidebug

Encontrando un serial válido

Encontrar en serial válido en esta ocasión es muy sencillo, basta con buscar en las «String References» el mensaje de «Bad boy» y fijarse en la comparación.

comparacion

 El algoritmo

Si nos fijamos en el serial generado nos da muchas pistas pero vamos a destriparlo ya que tampoco tiene mucha complicación. De nuevo miramos en las «String references» y clickamos sobre el mensaje de «bad boy«. Encima de los mensajes vemos claramente la rutina de creación del serial.

004010EB        |.  83F8 04             CMP EAX,4                      ;Longitud del nombre >4
004010EE        |.  72 05               JB SHORT Ice9.004010F5
004010F0        |.  83F8 0A             CMP EAX,0A                     ;Longitud del nombre <=10
004010F3        |.  76 15               JBE SHORT Ice9.0040110A
004010F5        |>  6A 00               PUSH 0                                ; /Style = MB_OK|MB_APPLMODAL
004010F7        |.  68 04304000         PUSH Ice9.00403004                    ; |Title = "Error, Bad Boy"
004010FC        |.  68 1C304000         PUSH Ice9.0040301C                    ; |Text = "name must be at least 4 chars"
00401101        |.  6A 00               PUSH 0                                ; |hOwner = NULL
00401103        |.  E8 70010000         CALL <JMP.&user32.MessageBoxA>        ; \MessageBoxA
........
00401183         .  3BD3                CMP EDX,EBX
00401185         .  74 15               JE SHORT Ice9.0040119C
00401187         .  8A07                MOV AL,BYTE PTR DS:[EDI]
00401189         .  3C 5A               CMP AL,5A                     ;Compara que el dígito < 5A
0040118B         .  7E 05               JLE SHORT Ice9.00401192
0040118D         >  03C8                ADD ECX,EAX                   ;ECX + Ascii(dígito)
0040118F         .  47                  INC EDI 
00401190         .^ EB EE               JMP SHORT Ice9.00401180
00401192         >  3C 41               CMP AL,41                     ;Compara que el dígito > 41
00401194         .  7D 02               JGE SHORT Ice9.00401198
00401196         .  EB 02               JMP SHORT Ice9.0040119A
00401198         >  04 2C               ADD AL,2C                     ;Si cumple lo anterior dígito +2C
0040119A         >^ EB F1               JMP SHORT Ice9.0040118D
0040119C         >  81C1 9A020000       ADD ECX,29A                   ;ECX + 29A
004011A2         .  69C9 39300000       IMUL ECX,ECX,3039             ;ECX * 3039
004011A8         .  83E9 17             SUB ECX,17                    ;ECX - 17
004011AB         .  6BC9 09             IMUL ECX,ECX,9                ;ECX * 9
004011AE         .  33DB                XOR EBX,EBX
004011B0         .  8BC1                MOV EAX,ECX                   ;Mueve nuestro SUM en EAX
004011B2         .  B9 0A000000         MOV ECX,0A                    ;ECX = A
004011B7         >  33D2                XOR EDX,EDX
004011B9         .  F7F1                DIV ECX                       ;SUM / ECX (Resultado a EAX)
004011BB         .  80C2 30             ADD DL,30
004011BE         .  881433              MOV BYTE PTR DS:[EBX+ESI],DL
004011C1         .  83C3 01             ADD EBX,1
004011C4         .  83F8 00             CMP EAX,0
004011C7         .  74 02               JE SHORT Ice9.004011CB
004011C9         .^ EB EC               JMP SHORT Ice9.004011B7
004011CB         >  BF C8304000         MOV EDI,Ice9.004030C8
004011D0         >  8A4433 FF           MOV AL,BYTE PTR DS:[EBX+ESI-1]
004011D4         .  8807                MOV BYTE PTR DS:[EDI],AL
004011D6         .  47                  INC EDI 
004011D7         .  4B                  DEC EBX
004011D8         .  83FB 00             CMP EBX,0
004011DB         .^ 75 F3               JNZ SHORT Ice9.004011D0
004011DD         .  C607 00             MOV BYTE PTR DS:[EDI],0               ;Coje letras del nombre en función
004011E0         .  8D3D B4304000       LEA EDI,DWORD PTR DS:[4030B4]         ;del resultado anterior
004011E6         .  68 B7304000         PUSH Ice9.004030B7                    ;  ASCII "rus"
004011EB         .  68 C8304000         PUSH Ice9.004030C8                    ;  ASCII "134992368rus"
004011F0         .  E8 BB000000         CALL Ice9.004012B0                    ; Concatena
004011F5         .  68 C8304000         PUSH Ice9.004030C8                    ; /String2 = "136325628rus"
004011FA         .  68 98314000         PUSH Ice9.00403198                    ; |String1 = "12345"
004011FF         .  E8 98000000         CALL <JMP.&kernel32.lstrcmpA>         ; \lstrcmpA

Resumen (valores hexadecimales):

  • Len(Nombre ) >=4 y <=A
  • Comprueba si el dígito está es mayúsculas y si está le sume 2C al valor ascii.
  • Suma el valor ascii de todos los dígitos menos el último.
  • SUM + 29A
  • SUM * 3039
  • SUM – 17
  • SUM * 9

Finalmente concatena letras siguiendo este criterio:

  • Len(nombre) = 4 -> coje la última letra
  • Len(nombre) = 5 -> coje las dos últimas
  • Len(nombre) = 6 -> coje las tres últimas
  • Len(nombre) = 7 -> coje las cuatro últimas
  • Len(nombre) = 8 -> coje las cinco últimas
  • Len(nombre) = 9 -> coje las seis últimas
  • Len(nombre) = A -> coje las siete últimas

Ejemplo para deurus

d  e  u  r  u  (s)
64+65+75+72+75 = 225
225 + 29A   = 4BF
4BF * 3039  = E4DE87
E4DE87 - 17 = E4DE70
E4DE70 * 9  = 80BD1F0
;Pasamos a decimal y concatenamos
134992368rus

Ejemplo para Deurus

D       e  u  r  u  (s)
44(+2C)+65+75+72+75 = 25D
25D + 29A   = 4F7
4BF * 3039  = EF6AFF
EF6AFF - 17 = EF6AE8
EF6AE8 * 9  = 86AC228
;Pasamos a decimal y concatenamos
141214248rus

Como curiosidad decirtos que con el tiempo valores del estilo 29A y 3039 os pegarán rápido al ojo ya que equivalen a 666 y 12345 en decimal. Por cierto 29A fue un grupo de hackers creadores de virus muy conocido en la escena Nacional e Internacional.

Links


Introducción Esta es la tercera y última entrega de los crackmes de Cruehead. En esta ocasión nos enfrentamos a un
Introducción Herramientas disponibles CrkViz-1 (Serial a la vista) CrkViz-2 (Parcheando rutina aleatoria) CrkViz-3 (Nag+Keygen) CrkViz-4 (Límite de ejecuciones+Keygen) CrkViz-5 (Serial
https://www.youtube.com/watch?v=iOYAn4l4wco Lista de reproducción
Se nos entrega el siguiente ELF: Extracción de la Flag Si nos fijamos en las líneas 41 a la 45

Introducción

La película «Contact«, estrenada en 1997 y dirigida por Robert Zemeckis, es una adaptación de la novela homónima de Carl Sagan. Más allá de su profunda exploración sobre la existencia de vida extraterrestre y el debate entre ciencia y fe, la película ofrece un interesante vistazo a la tecnología de la época. En este análisis, nos enfocaremos en los aspectos tecnológicos presentes en la película, detallando los sistemas operativos, software y hardware utilizados por los protagonistas.

Sinopsis

La Dra. Eleanor «Ellie» Arroway, interpretada por Jodie Foster, es una científica dedicada al proyecto SETI (Búsqueda de Inteligencia Extraterrestre). Tras años de búsqueda, capta una señal proveniente del espacio profundo que contiene instrucciones para construir una máquina enigmática. A medida que se desarrolla la trama, Ellie enfrenta desafíos políticos, religiosos y personales mientras lucha por interpretar el mensaje y lo que podría significar para la humanidad.

Análisis Tecnológico

Sistemas Operativos y Software

Uno de los aspectos más destacados en Contact es la presencia del sistema operativo UNIX. A lo largo de la película, se observan pistas que indican su uso, como pegatinas en las pantallas con mensajes del estilo: «Join the UNIX PARTY (The open system platform)». UNIX, desarrollado en la década de 1970, es conocido por su estabilidad y eficiencia, características esenciales en entornos científicos y de investigación.

La utilización de Netscape Navigator es recurrente. El logo de Netscape aparece en varias ocasiones, especialmente durante las videoconferencias que se muestran sin retrasos apreciables. Netscape fue uno de los primeros navegadores web ampliamente utilizados y jugó un papel crucial en la expansión de Internet durante los años 90.

Es importante destacar que, aunque la película promueve la idea de sistemas abiertos a través del uso de UNIX, Netscape Navigator no era software libre en el momento en que se rodó la película. Durante esa época, antes de 1997, Netscape era un navegador propietario. Sin embargo, en sistemas UNIX, Netscape tenía poca competencia y era el navegador predominante, soportando estándares abiertos como HTTP y HTML. Curiosamente, en 1998, poco después del estreno de la película, Netscape liberó el código fuente de su navegador, iniciando el proyecto Mozilla y contribuyendo significativamente al movimiento del software libre.

El software o plataforma denominada MADDEN HADDEN es utilizado por los protagonistas en diversas localizaciones, sugiriendo que es un estándar en su campo. Aunque en la realidad no existe un software conocido con ese nombre en el ámbito científico, en la película parece ser una herramienta integral para el análisis de datos y comunicación.

Videoconferencias y Comunicaciones

Las videoconferencias sin «lags» (retrasos) que se muestran en la película son notables, especialmente considerando las limitaciones tecnológicas de la época. La presencia del logo de Netscape durante estas comunicaciones resalta el optimismo sobre las capacidades de Internet en 1997. En ese entonces, las conexiones de alta velocidad no eran comunes, y las videollamadas de calidad eran más una aspiración que una realidad.

Estándares y Sistemas Abiertos

La promoción de sistemas abiertos es evidente en la película. El uso de UNIX, basado en estándares abiertos, refleja una filosofía de colaboración y accesibilidad en el ámbito científico. Aunque Netscape Navigator no era software libre durante la producción de la película, su soporte para estándares abiertos de Internet lo convirtió en una herramienta esencial para la comunicación y el intercambio de información entre científicos y profesionales.

Hardware

En términos de hardware, la película presenta una variedad de equipos representativos de la tecnología de los años 90:

Monitor NEC MultiSync XE21: Un monitor CRT de 21 pulgadas conocido por su alta resolución y calidad de imagen, ideal para aplicaciones que requieren detalles precisos.

Monitores con marcas ocultas: Es interesante notar que en varios monitores se utilizan post-its o adhesivos para cubrir la marca y el modelo. Esto podría deberse a decisiones de producción para evitar publicidad no deseada o cuestiones legales relacionadas con derechos de marca.

Monitor CTX: Aunque no se especifica el modelo, los monitores CTX eran populares por su fiabilidad y rendimiento a un costo razonable.

Monitor Hansol Mazellan 17px: Los monitores Hansol eran reconocidos por su calidad en la reproducción de gráficos, siendo utilizados en diseño y aplicaciones multimedia.

Monitor IBM: IBM fue pionera en tecnología informática, y sus monitores eran sinónimo de calidad y durabilidad. Aunque no se especifica el modelo exacto, es probable que se trate de uno de sus populares monitores CRT utilizados en entornos profesionales.

Evolución de UNIX y Windows

Para entender el contexto tecnológico de la época, es útil comparar la evolución de UNIX y Windows, así como de los navegadores Netscape Navigator e Internet Explorer.

Detalles Adicionales

Cobertura de marcas: La práctica de cubrir las marcas y modelos en los monitores podría indicar un intento de la producción por crear un entorno más universal y atemporal, evitando asociar la tecnología presentada con productos específicos que podrían quedar obsoletos rápidamente. En bastantes fotogramas se nota que esto es completamente intencionado.

Representación de la tecnología: La película equilibra la precisión técnica con las necesidades narrativas. Si bien algunas representaciones, como las videoconferencias fluidas, eran tecnológicamente avanzadas para la época, sirven para enfatizar la conectividad y colaboración global entre los científicos.

SETI y la Búsqueda de Vida Extraterrestre: En Contact, la Dra. Ellie Arroway dedica su vida al proyecto SETI (Search for Extraterrestrial Intelligence), reflejando el esfuerzo real de la comunidad científica por encontrar señales de inteligencia extraterrestre. SETI es una iniciativa internacional que utiliza radiotelescopios para detectar posibles comunicaciones de civilizaciones fuera de la Tierra. La película captura la pasión y los desafíos asociados con este tipo de investigación, destacando la dedicación de los científicos que trabajan en el límite de lo conocido.

El Mensaje de Arecibo: El radiotelescopio de Arecibo en Puerto Rico juega un papel significativo tanto en la realidad como en la película. En 1974, desde este observatorio, se envió el famoso Mensaje de Arecibo, una transmisión de radio dirigida al cúmulo estelar M13, diseñada para demostrar los avances tecnológicos humanos y nuestra existencia a posibles civilizaciones extraterrestres. El mensaje contenía información codificada sobre la composición humana, nuestro sistema numérico, la estructura del ADN y nuestra posición en el sistema solar. En «Contact», aunque la señal recibida por Ellie proviene de Vega y no está directamente relacionada con el Mensaje de Arecibo, la película establece paralelismos con este acontecimiento histórico. La utilización de Arecibo como escenario subraya la conexión entre los esfuerzos reales y ficticios en la búsqueda de inteligencia extraterrestre. La película explora la posibilidad de que, así como enviamos mensajes al espacio, podríamos recibir respuestas o comunicaciones de otras civilizaciones.

Matthew McConaughey: Es interesante notar cómo este actor ha participado en dos de las películas más destacadas de la ciencia ficción: Contact e Interstellar. En Contact, McConaughey interpreta un papel secundario como Palmer Joss, un escritor y asesor espiritual que cuestiona las implicaciones éticas y filosóficas del descubrimiento científico. Diecisiete años después, en Interstellar, asume el rol protagonista de Cooper, un ex piloto de la NASA que emprende una misión interestelar para salvar a la humanidad.

Números primos: El inicio de la investigación seria de la señal extraterrestre en la película se desencadena cuando, al analizar la señal recibida, los científicos descubren que esta codifica una secuencia de números primos. Este hallazgo resulta crucial, ya que los números primos, al ser divisibles únicamente por 1 y por sí mismos, no surgen de forma aleatoria en procesos naturales conocidos. Su presencia en la señal sugiere intencionalidad e inteligencia detrás de su emisión, lo que confirma que no se trata de ruido cósmico sino de una posible comunicación deliberada desde una civilización avanzada. Este descubrimiento impulsa a los científicos a profundizar en la decodificación, marcando el verdadero inicio de la búsqueda de vida extraterrestre.

Conclusión

Contact no solo es una obra que invita a reflexionar sobre nuestro lugar en el universo y la posibilidad de vida más allá de la Tierra, sino que también es un retrato de la tecnología de su tiempo. La inclusión de sistemas operativos como UNIX, navegadores como Netscape y hardware específico refleja una atención al detalle que enriquece la narrativa. A pesar de que Netscape Navigator no era software libre durante la producción de la película, su presencia destaca la importancia de los estándares abiertos y la colaboración en el avance científico.

También destaca por su compromiso con la precisión científica, en gran parte debido a la influencia de Carl Sagan, autor de la novela original y asesor en la producción. La representación de los procedimientos del SETI, el análisis de señales y las discusiones éticas y filosóficas reflejan debates reales en la comunidad científica. La inclusión de elementos como el Mensaje de Arecibo y las operaciones del radiotelescopio añaden autenticidad a la narrativa y acercan al público a la realidad de la exploración espacial.

Bibliografía y Enlaces

Galería

Introducción

Tal y como nos adelanta el creador está programado en .NET. Lo abrimos para ver su comportamiento y a simple vista ya vemos algo que no nos gusta y es que se abre una ventana de DOS y posteriormente aparece el crackme. Esto indica que el ejecutable está escondido dentro de otro, empaquetado, encriptado o vete a saber.

Desempaquetado

Nuestras sospechas eran ciertas, abrimos el executable con ILSpy y no encontramos lo que buscamos, pero si vemos que al assembly se le hace algo parecido a un XOR. Probemos con algo sencillo, abrimos el crackme y la herramienta .Net Generic Unpacker y probamos a desempaquetar.
27-08-2014-2B12-33-33
Esto nos genera un par de «exes» que ahora si abre correctamente nuestro decompilador.

Decompilado

Vamos a fijarnos en la rutina de comprobación del serial. Lo interesante se encuentra en btnCheckClick y TLicense.
Código fuente.
Como vemos en el código, License.a.a, License.a.b y License.a.c cogen 8 dígitos y License.a.d coge 10. A continuación comprueba que Licenseb.a = License.a.a XOR License.a.b y que Licenseb.b = License.a.c XOR License.a.d.
Una imagen vale más que mil palabras.
En su día hice un keygen, aquí teneis una captura.
Podeis encontrar el crackme, mi solución y otras soluciones en crackmes.de.

Links


Intro Hoy tenemos aquí un crackme del 2009 originario de crackmes.de. El Crackme está hecho en VB6, sin empacar y
Estamos ante un ELF un poco más interesante que los vistos anteriormente. Básicamente porque es divertido y fácil encontrar la
En Parque Jurásico (1993), la informática no es solo un elemento narrativo, es una pieza clave del suspense y del
Introducción Desempacado Eliminar la NAG Password Nº serie asociado a un nombre Checkbox Trackbar Links Introducción Aquí tenemos un Crackme

Warning: This challenge is still active and therefore should not be resolved using this information.
Aviso: Este reto sigue en activo y por lo tanto no se debería resolver utilizando esta información.

Introducción

El cifrado XOR es uno de los algoritmos más utilizados en el mundillo de la encriptación. Aunque por sí solo no es seguro, suele formar parte de cifrados más complejos e incluso si sois aficionados a los crackmes os habréis dado cuenta de que raro es el crackme que no lo utiliza.

Hoy vamos a hacer un recorrido sobre los retos de encriptación que nos propone yoire.com, que aunque son muy sencillos, nos proporcionan una estupenda base para iniciarnos en este tipo de retos.

/challenges/crypt/xor/0_chall_very_easy

En este primer reto, el autor te da directamente la solución, ya que, nos da un texto cifrado y nos dice que está cifrado con la clave 10. Lo que el autor no indica es que la clave es hexadecimal, mas adelante ya aprendereis a fijaros en esos detalles.

Texto cifrado: uqci0t~7d0ie0dxy~{

Clave: 10

challenges_crypt_xor_0_chall_very_easy

/challenges/crypt/xor/1_chall_easy

Esta vez disponemos de un texto cifrado pero sin pistas. Si nos fijamos en el código fuente veremos que la clave utilizada esta vez es 20 y decimal.

<?php
include("../../../core.php");
print Website::header(array("title"=>"The XOR Chall - Easy"));
print Challenges::header();
?>
Convierte la solución que está cifrada con una clave XOR para obtener la respuesta a este reto:
<br><br>
<?php

$solution_xored="m{a4s{`4}`5";
$key           = sprintf("%2x",20);
$solution      = Crypt::XorData($solution_xored,$key);

print "La solución es: ".$solution_xored;

print "<br><br>";
print Challenges::solutionBox();
print Challenges::checkSolution(Crypt::XorData($solution_xored,$key));
?>

challenges_crypt_xor_1_chall_easy

/challenges/crypt/xor/2_chall_mid

En esta ocasión debemos ojear el código fuente para averiguar como solucionar el reto. En esta ocasión y como de lo que se trata es de aprender, este lo dejaré sin solucionar.

<?php 
include("../../../core.php");
print Website::header(array("title"=>"The XOR Chall - Mid"));
print Challenges::header();
?>
Convierte la solución que está codificada y cifrada con una clave XOR para obtener la respuesta a este reto:
<br><br>
<?php

foreach (
        preg_split("/\./","2.4.10.71.3698") 
        as $something
        ) 

$value=pow($something,2);

$key            = dechex($value);
$solution_xored = base64_decode("ucSnos+lo8Oqtw==");
$solution       = Crypt::XorData($solution_xored,$key);

print Challenges::solutionBox();
print Challenges::checkSolution(Crypt::XorData($solution_xored,$key));
?>
<a href="<?=$_SERVER["PHP_SELF"]?>?showSource">Ver código fuente</a>

<?php
if(Common::getString("showSource")!==false) {
    print "<hr>";
    highlight_file(__FILE__);
}
print Website::footer();
?>
  • Lo primero es mediante un compilador online de PHP, obtener la variable $key.
  • Decodificar la clave xoreada «ucSnos+lo8Oqtw==«.
  • Solución = base64_decode(«ucSnos+lo8Oqtw==») XOR $key

Venga que casi lo tienes.

/challenges/crypt/xor/3_chall_average

En este reto nos indican que el código fuente está encriptado. Cuando nos enfrentamos a XOR en texto grandes y teniendo un indicio de lo que puede contener el código desencriptado es sencillo encontrar lo que buscamos. En este caso en concreto podemos intuir que seguramente el texto contenga la palabra «php«, una vez llegamos a esa conclusión la solución llega sola. Este método no deja de ser un ataque por fuerza bruta.

Código encriptado

lo 8 p]Z9>3<%45xr~~~~~~3?"5~ 8 ryk]Z "9>$p52#9$5jj85145"x1""1)xr$9

lt;5rmnr85pp81<$p81<<5>75#jj85145"xyk]Zon]Z1"535p!%5p5$5p81p#94?p396"14?~~~p%===~~~p$5>4"±#p!%5p1&5"97%1"p3£=?p 1"1p?2$5>5"p<1p"5# %5#$1p1p5#$5p"5$?j]Zl2"nl2"n]Zlo 8 ]Z]Zt;5)ppppppppppppmpre`rk]Zt=5pppppppppppppmp69<575$3?>$5>$#xyk]Zt=5(?"54pppppppmp") $jj?"1$1xt=5|t;5)yk]Z]Z "9>$p81<<5>75#jj#?<%$9?>?(xyk]Z "9>$p81<<5>75#jj3853;?<%$9?>xr3````aryk]Zon]Zl1p8"56mrlomtrr onolom%"<5>3?45x") $jj?"1$1xr#8?'?%"35r|t;5)yyonrn5"p3£497?p6%5>$5l1n]Z]Zlo 8 ]Z96x?==?>jj75$$"9>7x") $jj?"1$1xr#8?'?%"35r|t;5)yyqmm61<#5yp+]ZY "9>$prl8"nrk]ZY "9>$pt=5(?"54k]Z-]Z "9>$p52#9$5jj6??$5"xyk]Zon]Z

Código desencriptado

challenges_crypt_xor_3_chall_average

/challenges/crypt/xor/4_chall_hard

En este último reto nos aparece un mensaje que nos dice «La solución es: 7b1a4147100a155a0f45574e0f58«. Nos fijamos en el código fuente y vemos que en la encriptación interviene una cookie llamada «PHPSESSID«.

Código fuente

<?php 
include("../../../core.php");
print Website::header(array("title"=>"The XOR Chall - Hard"));
print Challenges::header();
?>
Convierte la solución que está codificada y cifrada con una clave XOR para obtener la respuesta a este reto:
<br><br>
<?php

$sessid             = isset($_COOKIE["PHPSESSID"])?$_COOKIE["PHPSESSID"]:">hi!|m¬_ö_Ó_;m'`ñ·$\"<";
$key                = Encoder::asc2hex($sessid);
$hiddenSolution     = file_get_contents(Config::$challsHiddenData."crypt_xor_average.solution");
$hex_xored_solution = Encoder::data2hex(Crypt::XorData($hiddenSolution,$key));

print "La solucion es: ".$hex_xored_solution;

print "<br><br>";

print Challenges::solutionBox();
print Challenges::checkSolution($hiddenSolution);
?>
<a href="<?=$_SERVER["PHP_SELF"]?>?showSource">Ver código fuente</a>

<?php
if(Common::getString("showSource")!==false) {
    print "<hr>";
    highlight_file(__FILE__);
}
print Website::footer();
?>

Desde Firefox vamos a usar una extensión muy interesante llamada Advanced Cookie Manager que nos permitirá visualizar y modificar dicha cookie.

challenges_crypt_xor_4_chall_hard_02

Una particularidad de la encriptación XOR es que si realizamos «algo XOR 0 == algo«, por lo que un ataque típico sería anular la cookie. La modificamos poniendo como valor 0 y guardamos. Recargamos la web con F5 y ahora nos fijamos que el valor de la solución ha cambiado a «7e5f4410435f1058514254100a19«. Finalmente y teniendo en cuenta que el texto que tenemos es hexadecimal, hacemos fuerza bruta marcando la opción Output First y clickamos en Search.

crypt_xor_4_chall_hard_2

En el mismo directorio donde tenemos el programa se genera un archivo llamado «XOR_enumeration.txt«, que contiene todos los resultados, echamos un vistazo y hemos tenido suerte.

crypt_xor_4_chall_hard_3

Enlaces

MI_cartel

Intro

La primera entrega de Misión Imposible es ya un clásico y poco o nada tiene que envidiar a sus secuelas. Es ágil, entretenida y como toda peli de espías que se precie, los protagonistas tienen gadgets por un tubo.

El argumento gira sobre la lista NOC. Dicha lista relaciona nombres en clave de agentes repartidos por el mundo con sus nombres reales y al parecer la quiere todo el mundo.

Lista NOC

¿Donde está la lista aquí o aquí?

Al inicio nos hacen creer que la lista NOC está en un sótano de una embajada (No jodas), sin seguridad y accesible por todo el mundo que sepa llegar allí. En esta ocasión no se puede ni llamar hackeo, ya que, el tipo en cuestión simplemente copia la lista (bueno la mitad 😉 en un disco de 3,5″

Tipo robando la lista NOC

¿Eso son Emails o Newsgroups?

Aquí empieza la locura. ¿Os acordáis del BTM de Dexter donde empieza a escribir en foros aleatorios con la esperanza de contactar con el carnicero de la bahía?, pues aquí lo mismo pero con grupos de noticias o newsgroups.

La cosa es que a Ethan Hank no se le ocurre mejor idea para encontrar a Max que buscar en todo tipo de grupos de noticias relacionados con temas bíblicos y en concreto con el libro de Job. Vamos a ver Ethan, hijo del metal, eso es una puta locura, ya de paso anúnciate en el periódico y ponte una diana en el pecho. Pero como es una película resulta que funciona. El caso es que parece que existen la ostia de grupos de discusión donde incluso se puede hablar sobre un capítulo y versículo en particular.

Newsgroup sobre el Libro de Job

El error

El problema es que en cada grupo que encuentra escribe un mensaje muy parecido a como se escribe un email y claro, queda un poco mal. Tanto si quieren hacer creer que escriben un email como si no, el caso es que la escena pierde credibilidad. Ni podría ser un email ni parece factible que alguien se ponga ese nombre de usuario, en definitiva, una chapuza.

¿Parece un email no?

Os dejo una serie de imágenes para que os deleitéis.

Intro

Hoy tenemos aquí un crackme del 2009 originario de crackmes.de. El Crackme está hecho en VB6, sin empacar y consta de 4 tareas a superar. Un anti-debugger, un parcheo, una sorpresa y finalmente un algoritmo sencillo.

Tarea#1 – Anti-Debugger

Nuestro primer incordio es el anti-debbuger. Este lo podemos afrontar de diferentes maneras, con un plugin desde Olly o de forma permanente parcheando. Si elegimos parchear debemos hacerlo en el offset 408328, cambiando el salto je por jmp.

00408328     /0F84 69030000         je T0RNAD0'.00408697

 Tarea#2 – Parche

Si iniciamos el crackme nos encontramos con la siguiente nag que nos impide el arranque.

01

Las referencias de texto parecen encriptadas así que, ponemos un breakpoint a MSVBVM60.rtcMsgBox y vemos que la llamada se hace desde el offset 406897. Un poco más arriba encontramos un salto condicional muy interesante, concretamente en el offset 40677B. Lo cambiamos por un jmp y arrancamos el programa.

Tarea#3 – Encontrando el camino

A continuación arranca el crackme y vemos lo siguiente.

04-10-2014 0-13-39

La sorpresa es que el formulario no se mueve y no hay rastro de las cajas de texto del keygenme. Por suerte para nosotros este crackme está hecho en vb6 y como tal podemos abrirlo con VB Reformer para ver que se nos ofrece.

Abrimos VB Reformer y cambiamos la propiedad «Moveable» del formulario a true.

04-10-2014 0-27-49

Ahora ya podemos mover el formulario y por suerte para nosotros, si lo movemos hacia la esquina superior izquierda aparecen las cajas de texto por arte de magia.

03-10-2014 12-41-51

Tarea#4 – El keygen

Como hemos dicho antes, las referencias de texto son inútiles, de modo que ponemos un breakpoint a MSVBVM60.__vbaStrCmp y enseguida obtenemos nuestro primer serial válido. También nos percatamos de que hasta que no metemos en el nombre 8 dígitos, no nos muestra un mensaje de error. De este mismo modo obtenemos que el nombre más grande puede tener 30 dígitos.

    Username: deurusab (lenght 8)
    0012F3F0   0040533A  RETURN to T0RNAD0'.0040533A from MSVBVM60.__vbaStrCmp
    0012F3F4   0015C954  UNICODE "L-8-deurus-0199F9CA"
    
    Username: abcdefghijklmnopqrstuvwxyz1234 (lenght 30)
    0012F3F0   0040533A  RETURN to T0RNAD0'.0040533A from MSVBVM60.__vbaStrCmp
    0012F3F4   0015F40C  UNICODE "L-30-lmnopq-DD19F9CA"

Finalmente llegamos a la rutina de comprobación del serial. Usaremos como nombre: abcdefghijklmnopqrstuvwxyz1234.

00404E82   .  52                    push edx
00404E83   .  56                    push esi
00404E84   .  C746 34 0DF0D1BA      mov dword ptr ds:[esi+34],BAD1F00D                                                    |Variables cachondas
00404E8B   .  C746 38 01ADDE10      mov dword ptr ds:[esi+38],10DEAD01                                                    |Variables cachondas
00404E92   .  C746 3C EFBE1010      mov dword ptr ds:[esi+3C],1010BEEF                                                    |Variables cachondas
00404E99   .  C746 40 D0BA0110      mov dword ptr ds:[esi+40],1001BAD0                                                    |Variables cachondas
00404EA0   .  FF91 2C070000         call ds:[ecx+72C]
00404EA6   .  3BC7                  cmp eax,edi
00404EA8   .  DBE2                  fclex
00404EAA   .  7D 12                 jge short T0RNAD0'.00404EBE
00404EAC   .  68 2C070000           push 72C
00404EB1   .  68 14404000           push T0RNAD0'.00404014
00404EB6   .  56                    push esi
00404EB7   .  50                    push eax
00404EB8   .  FF15 40104000         call ds:[<&MSVBVM60.__vbaHresultCheckObj>]     ;  MSVBVM60.__vbaHresultCheckObj
00404EBE   >  8B45 B4               mov eax,ss:[ebp-4C]
00404EC1   .  8D55 E0               lea edx,ss:[ebp-20]
00404EC4   .  52                    push edx
00404EC5   .  50                    push eax
00404EC6   .  8B08                  mov ecx,ds:[eax]
00404EC8   .  8985 48FFFFFF         mov ss:[ebp-B8],eax
00404ECE   .  FF91 A0000000         call ds:[ecx+A0]
00404ED4   .  3BC7                  cmp eax,edi
00404ED6   .  DBE2                  fclex
00404ED8   .  7D 18                 jge short T0RNAD0'.00404EF2
00404EDA   .  8B8D 48FFFFFF         mov ecx,ss:[ebp-B8]
00404EE0   .  68 A0000000           push 0A0
00404EE5   .  68 7C414000           push T0RNAD0'.0040417C
00404EEA   .  51                    push ecx
00404EEB   .  50                    push eax
00404EEC   .  FF15 40104000         call ds:[<&MSVBVM60.__vbaHresultCheckObj>]     ;  MSVBVM60.__vbaHresultCheckObj
00404EF2   >  8B45 E0               mov eax,ss:[ebp-20]                                                                       |Mueve el nombre a eax
00404EF5   .  8D55 A0               lea edx,ss:[ebp-60]
00404EF8   .  8945 A8               mov ss:[ebp-58],eax
00404EFB   .  6A 01                 push 1
00404EFD   .  8D45 90               lea eax,ss:[ebp-70]
00404F00   .  52                    push edx
00404F01   .  50                    push eax
00404F02   .  897D E0               mov ss:[ebp-20],edi
00404F05   .  C745 A0 08000000      mov dword ptr ss:[ebp-60],8
00404F0C   .  FF15 40114000         call ds:[<&MSVBVM60.#619>]                     ;  MSVBVM60.rtcRightCharVar
00404F12   .  8B3D D0104000         mov edi,ds:[<&MSVBVM60.__vbaStrVarVal>]        ;  MSVBVM60.__vbaStrVarVal
00404F18   .  8D4D 90               lea ecx,ss:[ebp-70]
00404F1B   .  8D55 DC               lea edx,ss:[ebp-24]
00404F1E   .  51                    push ecx
00404F1F   .  52                    push edx
00404F20   .  FFD7                  call edi                                       ;  <&MSVBVM60.__vbaStrVarVal>
00404F22   .  50                    push eax
00404F23   .  FF15 30104000         call ds:[<&MSVBVM60.#516>]                     ;  MSVBVM60.rtcAnsiValueBstr                |Toma el último dígito en ascii (4 asc = 34)
00404F29   .  66:6BC0 7B            imul ax,ax,7B                                                                              |34 * 7B = 18FC
00404F2D   .  8B4E 34               mov ecx,ds:[esi+34]                                                                        |Mueve BAD1F00D a ecx
00404F30   .  0F80 05070000         jo T0RNAD0'.0040563B
00404F36   .  0FBFC0                movsx eax,ax
00404F39   .  33C8                  xor ecx,eax                                                                                |18FC xor BAD1F00D = BAD1E8F1
00404F3B   .  894E 34               mov ds:[esi+34],ecx
00404F3E   .  8D4D DC               lea ecx,ss:[ebp-24]
00404F41   .  FF15 5C114000         call ds:[<&MSVBVM60.__vbaFreeStr>]             ;  MSVBVM60.__vbaFreeStr
00404F47   .  8D4D B4               lea ecx,ss:[ebp-4C]
00404F4A   .  FF15 60114000         call ds:[<&MSVBVM60.__vbaFreeObj>]             ;  MSVBVM60.__vbaFreeObj
00404F50   .  8D4D 90               lea ecx,ss:[ebp-70]
00404F53   .  8D55 A0               lea edx,ss:[ebp-60]
00404F56   .  51                    push ecx
00404F57   .  52                    push edx
00404F58   .  6A 02                 push 2
00404F5A   .  FF15 20104000         call ds:[<&MSVBVM60.__vbaFreeVarList>]         ;  MSVBVM60.__vbaFreeVarList
00404F60   .  8B06                  mov eax,ds:[esi]
00404F62   .  83C4 0C               add esp,0C
00404F65   .  8D4D B4               lea ecx,ss:[ebp-4C]
00404F68   .  51                    push ecx
00404F69   .  56                    push esi
00404F6A   .  FF90 2C070000         call ds:[eax+72C]
00404F70   .  85C0                  test eax,eax
00404F72   .  DBE2                  fclex
00404F74   .  7D 12                 jge short T0RNAD0'.00404F88
00404F76   .  68 2C070000           push 72C
00404F7B   .  68 14404000           push T0RNAD0'.00404014
00404F80   .  56                    push esi
00404F81   .  50                    push eax
00404F82   .  FF15 40104000         call ds:[<&MSVBVM60.__vbaHresultCheckObj>]     ;  MSVBVM60.__vbaHresultCheckObj
00404F88   >  8B45 B4               mov eax,ss:[ebp-4C]
00404F8B   .  8D4D E0               lea ecx,ss:[ebp-20]
00404F8E   .  51                    push ecx
00404F8F   .  50                    push eax
00404F90   .  8B10                  mov edx,ds:[eax]
00404F92   .  8985 48FFFFFF         mov ss:[ebp-B8],eax
00404F98   .  FF92 A0000000         call ds:[edx+A0]
00404F9E   .  85C0                  test eax,eax
00404FA0   .  DBE2                  fclex
00404FA2   .  7D 18                 jge short T0RNAD0'.00404FBC
00404FA4   .  8B95 48FFFFFF         mov edx,ss:[ebp-B8]
00404FAA   .  68 A0000000           push 0A0
00404FAF   .  68 7C414000           push T0RNAD0'.0040417C
00404FB4   .  52                    push edx
00404FB5   .  50                    push eax
00404FB6   .  FF15 40104000         call ds:[<&MSVBVM60.__vbaHresultCheckObj>]     ;  MSVBVM60.__vbaHresultCheckObj
00404FBC   >  8B45 E0               mov eax,ss:[ebp-20]
00404FBF   .  6A 01                 push 1
00404FC1   .  8945 A8               mov ss:[ebp-58],eax
00404FC4   .  8D45 A0               lea eax,ss:[ebp-60]
00404FC7   .  8D4D 90               lea ecx,ss:[ebp-70]
00404FCA   .  50                    push eax
00404FCB   .  51                    push ecx
00404FCC   .  C745 E0 00000000      mov dword ptr ss:[ebp-20],0
00404FD3   .  C745 A0 08000000      mov dword ptr ss:[ebp-60],8
00404FDA   .  FF15 2C114000         call ds:[<&MSVBVM60.#617>]                     ;  MSVBVM60.rtcLeftCharVar                    
00404FE0   .  8D55 90               lea edx,ss:[ebp-70]
00404FE3   .  8D45 DC               lea eax,ss:[ebp-24]
00404FE6   .  52                    push edx
00404FE7   .  50                    push eax
00404FE8   .  FFD7                  call edi
00404FEA   .  50                    push eax
00404FEB   .  FF15 30104000         call ds:[<&MSVBVM60.#516>]                     ;  MSVBVM60.rtcAnsiValueBstr                |Toma el primer dígito en ascii (a asc = 61)
00404FF1   .  66:6BC0 7B            imul ax,ax,7B                                                                              |61 * 7B = 2E9B
00404FF5   .  8B56 3C               mov edx,ds:[esi+3C]                                                                        |Mueve 1010BEEF a edx
00404FF8   .  0F80 3D060000         jo T0RNAD0'.0040563B
00404FFE   .  0FBFC8                movsx ecx,ax
00405001   .  33D1                  xor edx,ecx                                                                                | 2E9B xor 1010BEEF = 10109074
00405003   .  8D4D DC               lea ecx,ss:[ebp-24]
00405006   .  8956 3C               mov ds:[esi+3C],edx
00405009   .  FF15 5C114000         call ds:[<&MSVBVM60.__vbaFreeStr>]             ;  MSVBVM60.__vbaFreeStr
0040500F   .  8D4D B4               lea ecx,ss:[ebp-4C]
00405012   .  FF15 60114000         call ds:[<&MSVBVM60.__vbaFreeObj>]             ;  MSVBVM60.__vbaFreeObj
00405018   .  8D55 90               lea edx,ss:[ebp-70]
0040501B   .  8D45 A0               lea eax,ss:[ebp-60]
0040501E   .  52                    push edx
0040501F   .  50                    push eax
00405020   .  6A 02                 push 2
00405022   .  FF15 20104000         call ds:[<&MSVBVM60.__vbaFreeVarList>]         ;  MSVBVM60.__vbaFreeVarList
00405028   .  66:8BCB               mov cx,bx                                                                                 |Mueve a CX el tamaño del nombre
0040502B   .  83C4 0C               add esp,0C
0040502E   .  66:69C9 4101          imul cx,cx,141                                                                            |Tamaño nombre(1E) * 141 = 259E
00405033   .  8B46 3C               mov eax,ds:[esi+3C]
00405036   .  0F80 FF050000         jo T0RNAD0'.0040563B
0040503C   .  0FBFD1                movsx edx,cx
0040503F   .  8B4E 38               mov ecx,ds:[esi+38]                                                                       |Mueve a ECX 10DEAD01
00405042   .  33D0                  xor edx,eax                                                                               |10109074 xor 259E = 1010B5BA
00405044   .  33CA                  xor ecx,edx                                                                               |1010B5BA xor 10DEAD01 = 00CE18EB
00405046   .  66:8BD3               mov dx,bx
00405049   .  66:69D2 4101          imul dx,dx,141                                                                            |Tamaño nombre(1E) * 141 = 259E
0040504E   .  0F80 E7050000         jo T0RNAD0'.0040563B
00405054   .  894E 38               mov ds:[esi+38],ecx
00405057   .  81F1 01010101         xor ecx,1010101                                                                           |00CE18EB xor 1010101 = 01CF19EA (Temp1)
0040505D   .  0FBFD2                movsx edx,dx
00405060   .  3356 34               xor edx,ds:[esi+34]                                                                       |BAD1E8F1 xor 259E = BAD1CD6F
00405063   .  894E 38               mov ds:[esi+38],ecx
00405066   .  35 10101010           xor eax,10101010                                                                          |10109074 xor 10101010 = 8064
0040506B   .  8D4D B4               lea ecx,ss:[ebp-4C]
0040506E   .  3156 40               xor ds:[esi+40],edx                                                                       |BAD1CD6F xor 1001BAD0 = AAD077BF (Temp2)
00405071   .  8946 3C               mov ds:[esi+3C],eax
00405074   .  8B06                  mov eax,ds:[esi]
00405076   .  51                    push ecx
00405077   .  56                    push esi
00405078   .  FF90 2C070000         call ds:[eax+72C]
0040507E   .  85C0                  test eax,eax
00405080   .  DBE2                  fclex
00405082   .  7D 12                 jge short T0RNAD0'.00405096
00405084   .  68 2C070000           push 72C
00405089   .  68 14404000           push T0RNAD0'.00404014
0040508E   .  56                    push esi
0040508F   .  50                    push eax
00405090   .  FF15 40104000         call ds:[<&MSVBVM60.__vbaHresultCheckObj>]     ;  MSVBVM60.__vbaHresultCheckObj
00405096   >  8B45 B4               mov eax,ss:[ebp-4C]
00405099   .  8D4D DC               lea ecx,ss:[ebp-24]
0040509C   .  51                    push ecx
0040509D   .  50                    push eax
0040509E   .  8B10                  mov edx,ds:[eax]
004050A0   .  8985 48FFFFFF         mov ss:[ebp-B8],eax
004050A6   .  FF92 A0000000         call ds:[edx+A0]
004050AC   .  85C0                  test eax,eax
004050AE   .  DBE2                  fclex
004050B0   .  7D 18                 jge short T0RNAD0'.004050CA
004050B2   .  8B95 48FFFFFF         mov edx,ss:[ebp-B8]
004050B8   .  68 A0000000           push 0A0
004050BD   .  68 7C414000           push T0RNAD0'.0040417C
004050C2   .  52                    push edx
004050C3   .  50                    push eax
004050C4   .  FF15 40104000         call ds:[<&MSVBVM60.__vbaHresultCheckObj>]     ;  MSVBVM60.__vbaHresultCheckObj
004050CA   >  8B06                  mov eax,ds:[esi]
004050CC   .  8D4D B0               lea ecx,ss:[ebp-50]
004050CF   .  51                    push ecx
004050D0   .  56                    push esi
004050D1   .  FF90 2C070000         call ds:[eax+72C]
004050D7   .  85C0                  test eax,eax
004050D9   .  DBE2                  fclex
004050DB   .  7D 12                 jge short T0RNAD0'.004050EF
004050DD   .  68 2C070000           push 72C
004050E2   .  68 14404000           push T0RNAD0'.00404014
004050E7   .  56                    push esi
004050E8   .  50                    push eax
004050E9   .  FF15 40104000         call ds:[<&MSVBVM60.__vbaHresultCheckObj>]     ;  MSVBVM60.__vbaHresultCheckObj
004050EF   >  8B45 B0               mov eax,ss:[ebp-50]
004050F2   .  8D4D D0               lea ecx,ss:[ebp-30]
004050F5   .  51                    push ecx
004050F6   .  50                    push eax
004050F7   .  8B10                  mov edx,ds:[eax]
004050F9   .  8985 3CFFFFFF         mov ss:[ebp-C4],eax
004050FF   .  FF92 A0000000         call ds:[edx+A0]
00405105   .  85C0                  test eax,eax
00405107   .  DBE2                  fclex
00405109   .  7D 18                 jge short T0RNAD0'.00405123
0040510B   .  8B95 3CFFFFFF         mov edx,ss:[ebp-C4]
00405111   .  68 A0000000           push 0A0
00405116   .  68 7C414000           push T0RNAD0'.0040417C
0040511B   .  52                    push edx
0040511C   .  50                    push eax
0040511D   .  FF15 40104000         call ds:[<&MSVBVM60.__vbaHresultCheckObj>]     ;  MSVBVM60.__vbaHresultCheckObj
00405123   >  8B45 D0               mov eax,ss:[ebp-30]
00405126   .  6A 01                 push 1
00405128   .  8945 98               mov ss:[ebp-68],eax
0040512B   .  8D45 90               lea eax,ss:[ebp-70]
0040512E   .  8D4D 80               lea ecx,ss:[ebp-80]
00405131   .  50                    push eax
00405132   .  51                    push ecx
00405133   .  C745 A8 06000000      mov dword ptr ss:[ebp-58],6
0040513A   .  C745 A0 02000000      mov dword ptr ss:[ebp-60],2
00405141   .  C745 D0 00000000      mov dword ptr ss:[ebp-30],0
00405148   .  C745 90 08000000      mov dword ptr ss:[ebp-70],8
0040514F   .  FF15 40114000         call ds:[<&MSVBVM60.#619>]                     ;  MSVBVM60.rtcRightCharVar
00405155   .  8D55 80               lea edx,ss:[ebp-80]
00405158   .  8D45 CC               lea eax,ss:[ebp-34]
0040515B   .  52                    push edx
0040515C   .  50                    push eax
0040515D   .  FFD7                  call edi
0040515F   .  50                    push eax
00405160   .  FF15 30104000         call ds:[<&MSVBVM60.#516>]                     ;  MSVBVM60.rtcAnsiValueBstr
00405166   .  8B56 40               mov edx,ds:[esi+40]                                                                   |Mueve a EDX AAD077BF (Temp2)
00405169   .  68 90414000           push T0RNAD0'.00404190                         ;  UNICODE "L-"                        |Comienza el serial
0040516E   .  0FBFC8                movsx ecx,ax                                                                          |Mueve a ECX último dígito en ascii (34)
00405171   .  8B46 38               mov eax,ds:[esi+38]                                                                   |Mueve a EAX 01CF19EA (Temp1)
00405174   .  53                    push ebx                                                                                                                                                    
00405175   .  03D0                  add edx,eax                                                                           |AAD077BF + 01CF19EA = AC9F91A9
00405177   .  C785 70FFFFFF 0300000>mov dword ptr ss:[ebp-90],3
00405181   .  0F80 B4040000         jo T0RNAD0'.0040563B
00405187   .  03CA                  add ecx,edx                                                                           |AC9F91A9 + 34 = AC9F91DD (Nuestro serial)
00405189   .  0F80 AC040000         jo T0RNAD0'.0040563B
0040518F   .  898D 78FFFFFF         mov ss:[ebp-88],ecx
00405195   .  FF15 04104000         call ds:[<&MSVBVM60.__vbaStrI2>]               ;  MSVBVM60.__vbaStrI2
0040519B   .  8B3D 38114000         mov edi,ds:[<&MSVBVM60.__vbaStrMove>]          ;  MSVBVM60.__vbaStrMove
004051A1   .  8BD0                  mov edx,eax
004051A3   .  8D4D E0               lea ecx,ss:[ebp-20]
004051A6   .  FFD7                  call edi                                       ;  <&MSVBVM60.__vbaStrMove>
004051A8   .  50                    push eax                                                                              |EAX = tamaño del nombre
004051A9   .  FF15 38104000         call ds:[<&MSVBVM60.__vbaStrCat>]              ;  MSVBVM60.__vbaStrCat                |Concatena con "L-"
004051AF   .  8BD0                  mov edx,eax
004051B1   .  8D4D BC               lea ecx,ss:[ebp-44]
004051B4   .  FFD7                  call edi
004051B6   .  66:83EB 06            sub bx,6                                                                              |Tamaño nombre - 6 = 18
004051BA   .  50                    push eax
004051BB   .  0F80 7A040000         jo T0RNAD0'.0040563B
004051C1   .  0FBFCB                movsx ecx,bx
004051C4   .  898D 08FFFFFF         mov ss:[ebp-F8],ecx
004051CA   .  8D45 A0               lea eax,ss:[ebp-60]
004051CD   .  DB85 08FFFFFF         fild dword ptr ss:[ebp-F8]
004051D3   .  68 9C414000           push T0RNAD0'.0040419C
004051D8   .  50                    push eax
004051D9   .  DD9D 00FFFFFF         fstp qword ptr ss:[ebp-100]
004051DF   .  DD85 00FFFFFF         fld qword ptr ss:[ebp-100]
004051E5   .  833D 00A04000 00      cmp dword ptr ds:[40A000],0
004051EC   .  75 08                 jnz short T0RNAD0'.004051F6
004051EE   .  DC35 78114000         fdiv qword ptr ds:[401178]                                       |18 / 2 = C (C es la posición para cojer dígitos del nombre, coje 6)
004051F4   .  EB 11                 jmp short T0RNAD0'.00405207
004051F6   >  FF35 7C114000         push dword ptr ds:[40117C]
004051FC   .  FF35 78114000         push dword ptr ds:[401178]
00405202   .  E8 3DC0FFFF           call <jmp.&MSVBVM60._adj_fdiv_m64>
00405207   >  DFE0                  fstsw ax
00405209   .  A8 0D                 test al,0D
0040520B   .  0F85 25040000         jnz T0RNAD0'.00405636
00405211   .  FF15 44114000         call ds:[<&MSVBVM60.__vbaR8IntI4>]             ;  MSVBVM60.__vbaR8IntI4
00405217   .  8B55 DC               mov edx,ss:[ebp-24]                                                                   |EDX = nombre
0040521A   .  50                    push eax                                                                              |Eax = C
0040521B   .  52                    push edx
0040521C   .  FF15 6C104000         call ds:[<&MSVBVM60.#631>]                     ;  MSVBVM60.rtcMidCharBstr             |Mid(nombre,C,6) = "lmnopq"
00405222   .  8BD0                  mov edx,eax
00405224   .  8D4D D8               lea ecx,ss:[ebp-28]
00405227   .  FFD7                  call edi
00405229   .  8B1D 38104000         mov ebx,ds:[<&MSVBVM60.__vbaStrCat>]           ;  MSVBVM60.__vbaStrCat
0040522F   .  50                    push eax
00405230   .  FFD3                  call ebx                                       ;  <&MSVBVM60.__vbaStrCat>            |Concatena "-lmnopq"
00405232   .  8BD0                  mov edx,eax
00405234   .  8D4D D4               lea ecx,ss:[ebp-2C]
00405237   .  FFD7                  call edi
00405239   .  50                    push eax
0040523A   .  68 9C414000           push T0RNAD0'.0040419C
0040523F   .  FFD3                  call ebx                                                                             |Concatena "-lmnopq-"
00405241   .  8BD0                  mov edx,eax
00405243   .  8D4D C4               lea ecx,ss:[ebp-3C]
00405246   .  FFD7                  call edi
00405248   .  50                    push eax
00405249   .  8D85 70FFFFFF         lea eax,ss:[ebp-90]
0040524F   .  50                    push eax
00405250   .  FF15 F0104000         call ds:[<&MSVBVM60.#572>]                     ;  MSVBVM60.rtcHexBstrFromVar         |serial "AC9F91DD"
00405256   .  8BD0                  mov edx,eax
00405258   .  8D4D C8               lea ecx,ss:[ebp-38]
0040525B   .  FFD7                  call edi
0040525D   .  50                    push eax
0040525E   .  FF15 B4104000         call ds:[<&MSVBVM60.#713>]                     ;  MSVBVM60.rtcStrReverse             |Invierte el serial "DD19F9CA"
00405264   .  8BD0                  mov edx,eax
00405266   .  8D4D C0               lea ecx,ss:[ebp-40]
00405269   .  FFD7                  call edi
0040526B   .  50                    push eax
0040526C   .  FFD3                  call ebx                                                                             |Concatena "-lmnopq-DD19F9CA"
0040526E   .  8BD0                  mov edx,eax
00405270   .  8D4D B8               lea ecx,ss:[ebp-48]
00405273   .  FFD7                  call edi
00405275   .  50                    push eax
00405276   .  FFD3                  call ebx                                                                             |Concatena "L-30-lmnopq-DD19F9CA"
...
00405334   .  FF15 80104000         call ds:[<&MSVBVM60.__vbaStrCmp>]              ;  MSVBVM60.__vbaStrCmp               |Comparación final

Ejemplos:

Nombre: abcdefghijklmnopqrstuvwxyz1234

Serial: L-30-lmnopq-DD19F9CA

Nombre: deurus2014

Serial: L-10-eurus2-84D8F9CA

 Links


Hoy en día, la descarga de contenido multimedia de ciertas webs es imposible o muy difícil. En ciertos casos lo
En una entrada anterior sobre cómo Expediente X abordó la tecnología de vanguardia, comenté que dedicaría un espacio a esos
AVISO: Debido a que este reto está en activo no publicaré a donde pertenece. En este reto stego nos proporcionan
Introducción Esta vez se trata de un crackme realizado en VC++ 5.0/6.0 y en sus entrañas utiliza RSA-24. En este

Hoy en día, la descarga de contenido multimedia de ciertas webs es imposible o muy difícil. En ciertos casos lo entiendo, exponer el contenido supone una pérdida de ingresos y eso es inaceptable. Las cadenas de TV son tema aparte, emiten contenido por varios medios y les gusta que lo veas y que lo compartas, eso sí, que lo compartas desde su plataforma, ya que lo que estás compartiendo es un enlace, no el vídeo.

Este caso es un caso intermedio entre una plataforma de pago que codifica sus contenidos y una web que nos permita descargar su contenido directamente.

Imaginemos que vemos un vídeo y queremos mandarlo por Whatsapp a nuestros amigos. Lo primero es echar un vistazo al código fuente de la web y localizar el código del reproductor web (player). Para esta tarea podemos ayudarnos de una extensión muy conocida para navegadores como es Firebug. Una vez instalada, la activamos con F12 y mediante el botón Inspect localizamos el player.

...    
<p itemprop="keywords" itemscope="itemscope" itemtype="http://schema.org/Text" class="antetitulo" lang="es">EL INTERMEDIO LE PILLA EN "EL TRONO"</p>
    <h1 class="title-new" itemprop="headline">Joaquín Reyes se mete en la piel de Juan Carlos I: "Soy tan campechano que podéis llamarme Juan Carlos Palote"</h1>
    <sumary class="entradilla" itemprop="description">
<p><p class="MsoNormal">Los reyes eméritos han celebrado sus bodas de esmeralda y
con motivo de tan señalada fecha, Juan Carlos I ha hecho un hueco en su
apretada agenda para concederle unos minutos a <a title="<b>El Intermedio</b>" href="http://www.lasexta.com/temas/el_intermedio-1" target="_blank"><b>El Intermedio</b></a>. Eso sí, en su
versión de <a title="<b>Joaquín Reyes</b>" href="http://www.lasexta.com/temas/joaquin_reyes-1" target="_blank"><b>Joaquín Reyes</b></a>.  <o:p></o:p></p>	</sumary>

	<div class="great-element-multimedia">
	    <section class="modVideo a3mod_player" data-mod="a3mod_player" data-model="/json/video/7/2017/05/15/591a08c1986b2810b31577c1.json">
	        <a itemprop="url" href="#" class="icon link-content" title="" data-mod-elem="icon">
	            <div class="wrap-img" role="banner">
	                <div itemprop="video" itemscope itemtype="http://schema.org/VideoObject">
	                    <picture>
	                        <!--[if IE 9]><video style="display: none;"><![endif]-->
	                        <source media="(max-width:520px)" srcset="http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/64.jpg" />
	                        <source media="(max-width:1023px)" srcset="http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/60.jpg" />
	                        <source media="(min-width:1024px)" srcset="http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/58.jpg" />
	                        <!--[if IE 9]></video><![endif]-->
								<img src="http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/58.jpg" alt="Joaquín Reyes, como el rey Juan Carlos I" title="Joaquín Reyes, como el rey Juan Carlos I" />
	                    </picture>
	                    <meta itemprop="description" content=""/>
	                    <meta itemprop="name" content=""/>
	                    <meta itemprop="thumbnailUrl" content="" />
	                    <meta itemprop="uploadDate" content=""/>
	                    <meta itemprop="url" content=""/>
	                    <meta itemprop="width" content=""/>
	                    <meta itemprop="height" content=""/>
	                </div>
	            </div>
	        </a>
	    </section>
	</div>
...

Si os fijáis bien, el reproductor hace referencia a un archivo json (591a08c1986b2810b31577c1.json), reconstruimos la url y miramos su contenido

{"id":"591a08c1986b2810b31577c1","type":"video","tipo":"video","subtipo":"video","imgThumb":"http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/29.jpg","imgPoster":"http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/31.jpg","live":false,"autoplay":true,"sources":[{"src":"http://vclip.atresmedia.com/vclip/_definst_/smil:assets10/2017/05/15/01229E28-A57E-4AC9-AFE7-EF1C27B5AA2A/es.smil/manifest_mvlist.mpd","type":"application/dash+xml"},{"src":"http://vclip.atresmedia.com/vclip/_definst_/smil:assets10/2017/05/15/01229E28-A57E-4AC9-AFE7-EF1C27B5AA2A/es.smil/playlist.m3u8","type":"application/vnd.apple.mpegurl"}],"omniture":{"section":"Joaquín Reyes","category":"El Intermedio","channel":"lasexta","type":"short","name":"Joaquín Reyes se mete en la piel de Juan Carlos I: \"Soy tan campechano que podéis llamarme Juan Carlos Palote\"","embeddedMode":false},"comscore":{"comscoreTag":"LASEXTA.COM","channel":"lasexta","kantar":{"programID":"1019","firstBroadcastDate":"*null","firstBroadcastTime":"*null","typeTvStream":"0002","kantarGenre":"0","channelId":"240"},"content_form":"short_form"},"urlHits":"http://hits.lasexta.com/l6//591a08c1986b2810b31577c1/3/348128,351435,351827,351865/","duration":"211.797333","embeddedUrl":"<iframe src=\"http://www.lasexta.com/embed/el-intermedio-le-pilla-en-el-trono/video/7/2017/05/15/591a08c1986b2810b31577c1\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen></iframe>","playondraw":true,"nextRelated":{"service_url":"http://www.lasexta.com/json/video/7/2017/05/15/591a08c1986b2810b31577c1_related.json"},"subtitle":[],"titulo":"Joaquín Reyes se mete en la piel de Juan Carlos I: \"Soy tan campechano que podéis llamarme Juan Carlos Palote\"","descripcion":"","sociales":{"hasTwitter":true,"hasFacebook":true,"hasGooglePlus":true,"hasWhatsapp":true,"twitter":"EL INTERMEDIO LE PILLA EN “EL TRONO”","facebook":"EL INTERMEDIO LE PILLA EN “EL TRONO”","googlePlus":"EL INTERMEDIO LE PILLA EN “EL TRONO”","whatsapp":"","hashtag":"","via":"sextaNoticias","urlPage":"https://goo.gl/cu98f0"},"vp_data":{"vp_category":"Atresmedia/Lasexta/programas/el-intermedio*","vp_tags":"","vp_content_form":"short_form"}}

Se puede ver a simple vista una lista de reproducción playlist.m3u8, cuyo contenido contiene más listas de reproducción con diferentes calidades.

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=796400,CODECS="avc1.77.30,mp4a.40.5",RESOLUTION=640x360
chunklist_b724000.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1159400,CODECS="avc1.77.30,mp4a.40.5",RESOLUTION=640x360
chunklist_b1054000.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1643400,CODECS="avc1.77.30,mp4a.40.5",RESOLUTION=720x404
chunklist_b1494000.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2248400,CODECS="avc1.77.31,mp4a.40.5",RESOLUTION=1280x720
chunklist_b2044000.m3u8

Reconstruimos la URL para la lista de reproducción de mayor calidad e inspeccionamos su contenido.

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
media_b2044000_0.ts
#EXTINF:10.0,
media_b2044000_1.ts
#EXTINF:10.0,
media_b2044000_2.ts
#EXTINF:10.0,
media_b2044000_3.ts
#EXTINF:10.0,
media_b2044000_4.ts
#EXTINF:10.0,
media_b2044000_5.ts
#EXTINF:10.0,
media_b2044000_6.ts
#EXTINF:10.0,
media_b2044000_7.ts
#EXTINF:10.0,
media_b2044000_8.ts
#EXTINF:10.0,
media_b2044000_9.ts
#EXTINF:10.0,
media_b2044000_10.ts
#EXTINF:10.0,
media_b2044000_11.ts
#EXTINF:10.0,
media_b2044000_12.ts
#EXTINF:10.0,
media_b2044000_13.ts
#EXTINF:10.0,
media_b2044000_14.ts
#EXTINF:10.0,
media_b2044000_15.ts
#EXTINF:10.0,
media_b2044000_16.ts
#EXTINF:10.0,
media_b2044000_17.ts
#EXTINF:10.0,
media_b2044000_18.ts
#EXTINF:10.0,
media_b2044000_19.ts
#EXTINF:10.0,
media_b2044000_20.ts
#EXTINF:1.92,
media_b2044000_21.ts
#EXT-X-ENDLIST

Se pueden ver 21 archivos con extensión TS de 10 segundos cada uno a excepción del último que dura 1.92 segundos. Los archivos TS no son más que archivos MP4 por lo que una vez descargados, los podemos unir con MP4Tools por ejemplo.

La tarea es costosa, pero si os apetece enviar un vídeo en vez de un enlace, ya sabéis que en determinados casos se puede hacer.

En una entrada anterior sobre cómo Expediente X abordó la tecnología de vanguardia, comenté que dedicaría un espacio a esos tres personajes tan peculiares y entrañables que, desde el segundo plano, se ganaron un hueco en el corazón de los seguidores de la serie: los Pistoleros Solitarios. Pues bien, ha llegado el momento.

Estos tres tipos —John Fitzgerald Byers, Melvin Frohike y Richard “Ringo” Langly— no necesitaban armas ni placas del FBI. Su poder estaba en los teclados, los cables enredados y los monitores de tubo que parpadeaban en un sótano lleno de conspiraciones y café frío. Eran los outsiders de Expediente X, tres hackers con alma de periodistas que luchaban por algo tan simple y tan enorme como la verdad.

Su primera aparición fue en E.B.E. (temporada 1), casi como un alivio cómico: tres frikis que ayudaban a Mulder a rastrear información sobre ovnis. Pero pronto quedó claro que había algo especial en ellos. No solo eran fuente de datos, sino conciencia crítica en un mundo plagado de mentiras digitales y gobiernos con demasiados secretos. Con el tiempo se convirtieron en aliados imprescindibles de Mulder y Scully, y también en el reflejo más humano de lo que significa ser hacker: curiosos, testarudos, torpes a veces, pero con un sentido moral inquebrantable.

Byers era el idealista, el que aún creía en la decencia y en las instituciones (al menos en teoría). Frohike, el cínico veterano con corazón de oro, siempre dispuesto a arriesgarse por una buena causa… o por impresionar a Scully. Y Langly, el genio rebelde que parecía vivir en permanente conversación con su módem de 56 k. Juntos formaban un trío excéntrico, pero perfectamente equilibrado.

Mientras Mulder y Scully perseguían abducciones y virus extraterrestres, los pistoleros combatían en otra trinchera: la digital. Hackeaban redes gubernamentales, interceptaban comunicaciones cifradas y desmantelaban cortafuegos que, en los noventa, parecían pura ciencia ficción. Lo suyo no era la acción física, sino la resistencia informativa. Y aunque muchas veces eran el chiste del capítulo, también representaban algo muy real: la gente corriente que lucha contra el poder desde el conocimiento.

Su lema no declarado podría haber sido el clásico “la información quiere ser libre”, y en eso se mantuvieron firmes hasta el final. Si había que elegir entre la seguridad o la verdad, ellos siempre elegían la verdad, aunque les costara caro.

TemporadaEpisodioTítuloComentario
117E.B.E.Primera aparición de los pistoleros.
23BloodManipulación de dispositivos y mensajes ocultos. También control mental a través de la tecnología.
225AnasaziUn hacker roba archivos clasificados. Se tratan temas como el cifrado y filtración de datos del gobierno.
315ApocryphaAcceso a bases de datos secretas y descifrado de archivos comprometidos.
323WetwiredManipulación de señales televisivas.
414Memento MoriInfiltración digital en sistemas médicos y vigilancia biotecnológica.
51ReduxRobo y manipulación de pruebas digitales.
53Unusual SuspectsOrígenes de los pistoleros: intrusión, cifrado y espíritu hacker de los noventa.
511Kill SwitchIA autónoma y malware inteligente.
620Three of a KindHacking social, suplantación y síntesis de voz para infiltración corporativa.
713First Person ShooterHackeo de entornos virtuales y brechas de seguridad en sistemas de realidad aumentada.
915Jump the SharkSu sacrificio final: bloqueo de una amenaza biológica, ética hacker y altruismo extremo.
112ThisLangly como conciencia digital en un servidor. Debate sobre IA y trascendencia del código.

Morir por la verdad

El final de los pistoleros fue tan inesperado como heroico. En el episodio “Jump the Shark” de la novena temporada, descubren un complot bioterrorista que amenaza con liberar un virus mortal. No hay tiempo para avisar a nadie, ni margen para escapar. Así que, fieles a su estilo, deciden sacrificarse para salvar a otros. Sellan el laboratorio desde dentro, sabiendo que no volverán a salir.

Lo reconozco, este desenlace mi cogió completamente por sorpresa. No hay épica de Hollywood, ni música grandilocuente. Solo tres hombres anónimos haciendo lo correcto. Mueren juntos, sin reconocimiento, sin medallas, pero con la serenidad de quienes saben que su causa era justa. Y en ese silencio final, Expediente X nos recordó algo que las grandes historias suelen olvidar: que los verdaderos héroes a veces no llevan traje ni pistola, solo convicción.

Años después, Mulder vuelve a verlos —o cree verlos— en The Truth. Ya no están en este mundo, pero siguen a su lado, como fantasmas digitales de la conciencia hacker. Es un homenaje discreto a quienes siempre pelearon desde las sombras por liberar la verdad.

Para cerrar el círculo, Langly reaparece de forma inesperada en la temporada 11, dentro del episodio This. Su mente, o más bien su copia digital, sobrevive atrapada en un servidor, reclamando ser liberada. Es el epílogo perfecto: el hacker que muere físicamente, pero cuya conciencia sigue inmortal. Una vez más me volvió a sorprender Chris Carter con este homenaje.

Me gusta pensar que los pistoleros solitarios representaban algo más que tres hackers secundarios en una serie de los noventa. Fueron el reflejo de una época en la que creíamos que la tecnología podía liberar al ser humano, antes de que las redes sociales y la hiperconectividad lo diluyeran todo. Byers, Frohike y Langly no luchaban por fama ni por dinero: luchaban por entender el sistema para exponerlo, por esa curiosidad genuina que hoy apenas sobrevive entre líneas de código y algoritmos opacos. Quizá por eso seguimos recordándolos y mola tanto volver a ver los capítulos. Porque, de algún modo, todos los que amamos el conocimiento libre llevamos dentro un pequeño pistolero solitario, buscando la verdad entre los bits.

AVISO: Debido a que este reto está en activo no publicaré a donde pertenece.

En este reto stego nos proporcionan un archivo MP3 y nos dan una pequeña pista con el título.

Inicialmente lo pasé con GoldWave y me fijé en el la parte de control en el SPECtrogram y en el SPECtrum, pero no conseguí ver nada. A punto de rendirme di con un programa online llamado SPEK, que me dio la respuesta al instante.

SPECtrum mostrado por Spek

Se puede apreciar una palabra que escrita en Inglés nos da la solución al reto.

Introducción

Esta vez se trata de un crackme realizado en VC++ 5.0/6.0 y en sus entrañas utiliza RSA-24. En este caso la peculiaridad es que el nombre no interviene en la generación del serial siendo un resultado único.

Resumen RSA

Parámetros

p = Primer número primo
q = Segundo número primo
e = Exponente público que cumpla MCD(e,(p-1)*(q-1))==1
n = Módulo público siendo n=p*q
d = Exponente privado que cumpla d=e^(-1) mod ((p-1)*(q-1))

De este modo e y n son la parte pública de la clave y d y n la parte privada. Los número primos p y q se utilizan solo para generar los parámetros y de ahí en adelante se pueden desechar.

Funciones de Cifrado/Descifrado

cifrado = descifrado ^ e mod n
descifrado = cifrado ^ d mod n

OllyDbg

Nuestro primer vistazo con OllyDbg nos muestra cuatro números de los que podemos hacernos una idea de que 9901 es un buen candidato a ser el exponente público (e) y 12790891 el módulo n ya que casualmente es un número de 24 bits. Los otros dos números de momento no nos dicen nada.

Referencias de texto

A continuación de los números tenemos la rutina de comprobación en la que comprueba que nuestro serial tenga 14 dígitos y lo divide en dos partes de 7 dígitos. Interesante ya que los otros dos números que aparecían en las referencias de texto tienen 7 dígitos cada uno.

004029CD  |.  68 DC004200   PUSH    RSA24.004200DC                         ;  ASCII "9901"
004029D2  |.  8D8C24 E40000>LEA     ECX,[DWORD SS:ESP+E4]
004029D9  |.  E8 52E7FFFF   CALL    RSA24.00401130
004029DE  |.  68 D0004200   PUSH    RSA24.004200D0                         ;  ASCII "12790891"
004029E3  |.  8D4C24 1C     LEA     ECX,[DWORD SS:ESP+1C]
004029E7  |.  C78424 640600>MOV     [DWORD SS:ESP+664],0
004029F2  |.  E8 39E7FFFF   CALL    RSA24.00401130
004029F7  |.  68 C8004200   PUSH    RSA24.004200C8                         ;  ASCII "8483678"
004029FC  |.  8D8C24 740200>LEA     ECX,[DWORD SS:ESP+274]
00402A03  |.  C68424 640600>MOV     [BYTE SS:ESP+664],1
00402A0B  |.  E8 20E7FFFF   CALL    RSA24.00401130
00402A10  |.  68 C0004200   PUSH    RSA24.004200C0                         ;  ASCII "5666933"
00402A15  |.  8D8C24 AC0100>LEA     ECX,[DWORD SS:ESP+1AC]
00402A1C  |.  C68424 640600>MOV     [BYTE SS:ESP+664],2
00402A24  |.  E8 07E7FFFF   CALL    RSA24.00401130
00402A29  |.  8B9424 680600>MOV     EDX,[DWORD SS:ESP+668]
00402A30  |.  83CE FF       OR      ESI,FFFFFFFF
00402A33  |.  8BFA          MOV     EDI,EDX
00402A35  |.  8BCE          MOV     ECX,ESI
00402A37  |.  33C0          XOR     EAX,EAX
00402A39  |.  C68424 600600>MOV     [BYTE SS:ESP+660],3
00402A41  |.  F2:AE         REPNE   SCAS [BYTE ES:EDI]
00402A43  |.  F7D1          NOT     ECX
00402A45  |.  49            DEC     ECX
00402A46  |.  83F9 0E       CMP     ECX,0E                                 ;  serial 0xE chars -> 14 digitos
00402A49  |.  0F85 63010000 JNZ     RSA24.00402BB2
00402A4F  |.  33C9          XOR     ECX,ECX
00402A51  |>  8A0411        /MOV     AL,[BYTE DS:ECX+EDX]                  ;  {
00402A54  |.  3C 30         |CMP     AL,30
00402A56  |.  0F8C 56010000 |JL      RSA24.00402BB2
00402A5C  |.  3C 39         |CMP     AL,39                                 ;  comprueba que el serial sea numerico
00402A5E  |.  0F8F 4E010000 |JG      RSA24.00402BB2
00402A64  |.  41            |INC     ECX
00402A65  |.  83F9 0E       |CMP     ECX,0E
00402A68  |.^ 7C E7         \JL      SHORT RSA24.00402A51                  ;  }
00402A6A  |.  8BC2          MOV     EAX,EDX
00402A6C  |.  C64424 17 00  MOV     [BYTE SS:ESP+17],0                     ;  {
00402A71  |.  C64424 0F 00  MOV     [BYTE SS:ESP+F],0
00402A76  |.  8B08          MOV     ECX,[DWORD DS:EAX]
00402A78  |.  894C24 10     MOV     [DWORD SS:ESP+10],ECX
00402A7C  |.  66:8B48 04    MOV     CX,[WORD DS:EAX+4]
00402A80  |.  66:894C24 14  MOV     [WORD SS:ESP+14],CX
00402A85  |.  8B4A 07       MOV     ECX,[DWORD DS:EDX+7]
00402A88  |.  8A40 06       MOV     AL,[BYTE DS:EAX+6]                     ;  divide el serial en dos partes de 7 digitos
00402A8B  |.  894C24 08     MOV     [DWORD SS:ESP+8],ECX
00402A8F  |.  884424 16     MOV     [BYTE SS:ESP+16],AL
00402A93  |.  8D42 07       LEA     EAX,[DWORD DS:EDX+7]
00402A96  |.  8D4C24 10     LEA     ECX,[DWORD SS:ESP+10]
00402A9A  |.  66:8B50 04    MOV     DX,[WORD DS:EAX+4]
00402A9E  |.  8A40 06       MOV     AL,[BYTE DS:EAX+6]                     ;  }

A continuación hace una serie de operaciones matemáticas para finalmente comparar el resultado con 8483678 y con 5666933. Lo que está haciendo es cifrar con nuestro serial en dos partes para comprobar que tenemos el número descifrado. Veamos un ejemplo con el serial 12345678901234.

descifrado ^ e mod n = cifrado
x1 = 1234567 y x2 = 8901234
1º parte del serial
x1 ^ 9901 mod 12790891 != 8483678
2º parte del serial
x2 ^ 9901 mod 12790891 != 5666933

Obviamente el resultado de las operaciones anteriores no da ese resultado y el Crackme nos tira fuera de modo que no nos queda más que atacar a RSA para obtener los primos p y q y el módulo privado d. De este modo podremos obtener los números buenos.

Los primos p y q se obtienen factorizando (botón Factor N) y una vez que tenemos p y q hallamos d (botón Calc. D). Todo esto es coser y cantar con la ayuda de la herramienta RSA-Tool 2. El exponente público e se introduce en hexadecimal.

Obteniendo p, q y d

Una vez que tenemos d hallamos el serial de forma sencilla con la herramienta Big Integer Calculator.

cifrado ^ d mod n = descifrado
1º parte del serial
8483678 ^ 10961333 mod 12790891 = 7167622
2º parte del serial
5666933 ^ 10961333 mod 12790891 = 3196885

SERIAL = 71676223196885
1º parte del serial
2º parte del serial

Enlaces