Introducción

Empezamos con lo que espero que sea una serie de crackmes RSA. En este caso en particular y como el propio autor nos adelanta, se trata de RSA-200.

En criptografía, RSA (Rivest, Shamir y Adleman) es un sistema criptográfico de clave pública desarrollado en 1977. Es el primer y más utilizado algoritmo de este tipo y es válido tanto para cifrar como para firmar digitalmente.

 Funcionamiento de RSA

  1. Inicialmente es necesario generar aleatoriamente dos números primos grandes, a los que llamaremos p y q.
  2. A continuación calcularemos n como producto de p y q:
    n = p * q
  3. Se calcula fi:
    fi(n)=(p-1)(q-1)
  4. Se calcula un número natural e de manera que MCD(e, fi(n))=1 , es decir e debe ser primo relativo de fi(n). Es lo mismo que buscar un numero impar por el que dividir fi(n) que de cero como resto.
  5. Mediante el algoritmo extendido de Euclides se calcula d que es el inverso modular de e.
    Puede calcularse d=((Y*fi(n))+1)/e para Y=1,2,3,... hasta encontrar un d entero.
  6. El par de números (e,n) son la clave pública.
  7. El par de números (d,n) son la clave privada.
  8. Cifrado: La función de cifrado es.
    c = m^e mod n
  9. Descifrado: La función de descifrado es.
    m = c^d mod n

OllyDbg

Con OllyDbg analizamos la parte del código que nos interesa.

00401065  |>push    19                          ; /Count = 19 (25.)
00401067  |>push    00404330                    ; |Buffer = dihux_ke.00404330
0040106C  |>push    2711                        ; |ControlID = 2711 (10001.)
00401071  |>push    dword ptr [ebp+8]           ; |hWnd
00401074  |>call    <GetDlgItemTextA>           ; \GetDlgItemTextA
00401079  |>cmp     eax, 5                      ;  Tamaño nombre >= 5
0040107C  |>jb      00401214
00401082  |>cmp     eax, 14                     ;  Tamaño nombre <= 0x14
00401085  |>ja      00401214
0040108B  |>mov     [404429], eax
00401090  |>push    96                          ; /Count = 96 (150.)
00401095  |>push    00404349                    ; |Buffer = dihux_ke.00404349
0040109A  |>push    2712                        ; |ControlID = 2712 (10002.)
0040109F  |>push    dword ptr [ebp+8]           ; |hWnd
004010A2  |>call    <GetDlgItemTextA>           ; \GetDlgItemTextA
004010A7  |>test    al, al
........
004010D8  |>xor     ecx, ecx                    ;  Case 0 of switch 004010B6
004010DA  |>/push    0
004010DC  |>|call    <__BigCreate@4>
004010E1  |>|mov     [ecx*4+404411], eax
004010E8  |>|inc     ecx
004010E9  |>|cmp     ecx, 6
004010EC  |>\jnz     short 004010DA
004010EE  |>push    dword ptr [404411]          ; /Arg3 = 00B60000
004010F4  |>push    10                          ; |16??
004010F6  |>push    0040401F                    ; |Arg1 = 0040401F ASCII "8ACFB4D27CBC8C2024A30C9417BBCA41AF3FC3BD9BDFF97F89"
004010FB  |>call    <__BigIn@12>                ; \dihux_ke.004013F3
00401100  |>push    dword ptr [404415]          ; /Arg3 = 00C70000
00401106  |>push    10                          ; |Arg2 = 00000010
00401108  |>push    00404019                    ; |Arg1 = 00404019 ASCII "10001"
0040110D  |>call    <__BigIn@12>                ; \dihux_ke.004013F3
00401112  |>push    dword ptr [404425]          ; /Arg3 = 00CB0000
00401118  |>push    10                          ; |Arg2 = 00000010
0040111A  |>push    00404349                    ; |Arg1 = 00404349 ASCII "123456789123456789"
0040111F  |>call    <__BigIn@12>                ; \dihux_ke.004013F3
00401124  |>push    00404330                    ; /String = "deurus"
00401129  |>call    <lstrlenA>                  ; \lstrlenA
0040112E  |>push    dword ptr [404419]
00401134  |>push    eax
00401135  |>push    00404330                    ;  ASCII "deurus"
0040113A  |>call    <__BigInB256@12>
0040113F  |>push    dword ptr [404421]          ;  c
00401145  |>push    dword ptr [404411]          ;  n = 8ACFB4D27CBC8C2024A30C9417BBCA41AF3FC3BD9BDFF97F89
0040114B  |>push    dword ptr [404415]          ;  e = 10001
00401151  |>push    dword ptr [404425]          ;  serial
00401157  |>call    <__BigPowMod@16>            ;  c = serial^e (mod n)
0040115C  |>mov     eax, 1337
00401161  |>push    0                           ; /Arg4 = 00000000
00401163  |>push    dword ptr [40441D]          ; |x
00401169  |>push    eax                         ; |0x1337
0040116A  |>push    dword ptr [404421]          ; |c
00401170  |>call    <__BigDiv32@16>             ; \x = c/0x1337
00401175  |>push    dword ptr [40441D]          ;  x
0040117B  |>push    dword ptr [404419]          ;  nombre
00401181  |>call    <__BigCompare@8>            ; ¿x = nombre?
00401186  |>jnz     short 0040119C
00401188  |>push    0                           ; /Style = MB_OK|MB_APPLMODAL
0040118A  |>push    00404014                    ; |Title = "iNFO"
0040118F  |>push    00404004                    ; |Text = "Serial is valid"
00401194  |>push    dword ptr [ebp+8]           ; |hOwner
00401197  |>call    <MessageBoxA>               ; \MessageBoxA
0040119C  |>xor     ecx, ecx
0040119E  |>/push    dword ptr [ecx*4+404411]
004011A5  |>|call    <__BigDestroy@4>
004011AA  |>|inc     ecx
004011AB  |>|cmp     ecx, 6
004011AE  |>\jnz     short 0040119E

 Lo primero que observamos es que el código nos proporciona el exponente público (e) y el módulo (n).

  • e = 10001
  • n = 8ACFB4D27CBC8C2024A30C9417BBCA41AF3FC3BD9BDFF97F89

A continuación halla c = serial^d mod n. Finalmente Divide c entre 0x1337 y lo compara con el nombre.

Como hemos visto en la teoría de RSA, necesitamos hallar el exponente privado (d) para poder desencriptar, según la fórmula vista anteriormente.

  • Fórmula original: m=c^d mod n
  • Nuestra fórmula: Serial = x^d mod n. Siendo x = c * 0x1337

Calculando un serial válido

Existen varios ataques a RSA, nosotros vamos a usar el de factorización. Para ello vamos a usar la herramienta RSA Tool. Copiamos el módulo (n), el exponente público (e) y factorizamos (Factor N).

rsatool1

Hallados los primos p y q, hallamos d (Calc. D).

rsatool4

Una vez obtenido d solo nos queda obtener x, que recordemos es nombre * 0x1337.

Cuando decimos nombre nos referimos a los bytes del nombre en hexadecimal, para deurus serían 646575727573.

Ejemplo operacional

Nombre: deurus

x = 646575727573 * 0x1337 = 7891983BA4EC4B5
Serial = x^d mod n
Serial = 7891983BA4EC4B5^32593252229255151794D86C1A09C7AFCC2CCE42D440F55A2D mod 8ACFB4D27CBC8C2024A30C9417BBCA41AF3FC3BD9BDFF97F89
Serial = FD505CADDCC836FE32E34F5F202E34D11F385DEAD43D87FCD

Como la calculadora de Windows se queda un poco corta para trabajar con números tan grandes, vamos a usar la herramienta Big Integer Calculator. A continuación os dejo unas imágenes del proceso.

bigint_1

bigint_2

crackme_dihux_solved

Keygen

En esta ocasión hemos elegido Java ya que permite trabajar con números grandes de forma sencilla, os dejo el código más importante.

dihux_keygenme1_keygen

JButton btnNewButton = new JButton("Generar");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
BigInteger serial = new BigInteger("0");
BigInteger n = new BigInteger("871332984042175151665553882265818310920539633758381377421193");//módulo
BigInteger d = new BigInteger("316042180198461106401603389463895139535543421270452849695277");//exponente privado
BigInteger x = new BigInteger("4919");//0x1337
String nombre = t1.getText();
BigInteger nombre2 = new BigInteger(nombre.getBytes());
nombre2 = nombre2.multiply(x);
serial = nombre2.modPow(d, n);
t2.setText(serial.toString(16).toUpperCase());
}
});

Links


AVISO: Debido a que este reto está en activo no publicaré a donde pertenece. En este pequeño CrackMe se nos
Si te interesa el mundo del hacking, ya sea como aficionado o como profesional, seguramente querrás estar al día de
Intro Hoy tenemos un crackme realizado en ensamblador y sin empacar. Consiste en el típico serial asociado a un nombre

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

En este pequeño CrackMe se nos pide investigar como se genera la clave que resuelve el reto. No tiene formulario donde introducir usuario y clave, cuando lo ejecutamos simplemente aparece una NAG dándonos a entender que no lo conseguimos.

Lo primero que vemos es esto:

004010B8 | 53                       | push ebx                                |
004010B9 | 56                       | push esi                                |
004010BA | 57                       | push edi                                |
004010BB | 83 C4 F4                 | add esp,FFFFFFF4                        |
004010BE | C6 05 84 20 40 00 00     | mov byte ptr ds:[402084],0              | Dirección 402084 = 0
004010C5 | C7 44 24 08 28 00 00 00  | mov dword ptr ds:[esp+8],28             | 
004010CD | 54                       | push esp                                |
004010CE | 6A 01                    | push 1                                  |
004010D0 | 6A 00                    | push 0                                  |
004010D2 | 68 0C 20 40 00           | push exepuzz1.40200C                    | ;0040200C:"Software\\Caesum\\rev1"
004010D7 | 68 02 00 00 80           | push 80000002                           |
004010DC | E8 F4 00 00 00           | call <exepuzz1.RegOpenKeyExA>           | Distracción
004010E1 | 85 C0                    | test eax,eax                            |
004010E3 | 0F 85 C6 00 00 00        | jne exepuzz1.4011AF                     | Parchear este salto
004010E9 | 8D 44 24 08              | lea eax,dword ptr ds:[esp+8]            |
004010ED | 50                       | push eax                                |
004010EE | 68 84 20 40 00           | push exepuzz1.402084                    | Coge lo que haya en la dirección 402084
........

Lo primero que nos llama la atención es que en 4010BE pone el DUMP 402084 a cero. Lo corroboramos:

00402000: 04 20 40 00 63 6D 62 69 70 6F 66 00 53 6F 66 74 ; . @.cmbipof.Soft
00402010: 77 61 72 65 5C 43 61 65 73 75 6D 5C 72 65 76 31 ; ware\Caesum\rev1
00402020: 00 6B 65 79 00 74 65 6C 6C 20 6D 65 20 74 68 65 ; .key.tell me the
00402030: 20 61 6E 73 77 65 72 00 59 6F 75 72 20 70 61 73 ;  answer.Your pas
00402040: 73 20 69 73 20 00 42 6C 61 68 00 54 68 69 73 20 ; s is .Blah.This 
00402050: 6C 69 74 74 6C 65 20 62 75 6E 6E 79 20 77 65 6E ; little bunny wen
00402060: 74 20 68 6F 70 00 42 6C 61 68 00 42 6C 61 68 2C ; t hop.Blah.Blah,
00402070: 20 73 65 65 20 69 66 20 49 20 63 61 72 65 00 42 ;  see if I care.B
00402080: 6C 61 68 00 00 00 00 00 00 00 00 00 00 00 00 00 ; lah.............
                       ^
                       |
                       ----402084 (Ahora no hay nada)

Además para poder continuar la ejecución debemos parchear el salto JNE de la dirección 4010E3. Seguimos:

........
004010F3 | 8D 54 24 0C              | lea edx,dword ptr ds:[esp+C]            |
004010F7 | 52                       | push edx                                |
004010F8 | 6A 00                    | push 0                                  |
004010FA | 68 21 20 40 00           | push exepuzz1.402021                    | ;00402021:"key"
004010FF | 8B 4C 24 14              | mov ecx,dword ptr ds:[esp+14]           |
00401103 | 51                       | push ecx                                |
00401104 | E8 C6 00 00 00           | call <exepuzz1.RegQueryValueExA>        | Distracción
00401109 | 8B 04 24                 | mov eax,dword ptr ds:[esp]              |
0040110C | 50                       | push eax                                |
0040110D | E8 B7 00 00 00           | call <exepuzz1.RegCloseKey>             |
00401112 | 68 25 20 40 00           | push exepuzz1.402025                    | ;00402025:"tell me the answer"
00401117 | 68 84 20 40 00           | push exepuzz1.402084                    | Coge lo que haya en la dirección 402084
0040111C | E8 17 FF FF FF           | call exepuzz1.401038                    |
00401121 | 83 C4 08                 | add esp,8                               |
00401124 | 85 C0                    | test eax,eax                            |
00401126 | 74 72                    | je exepuzz1.40119A                      |
00401128 | 68 84 20 40 00           | push exepuzz1.402084                    |
0040112D | E8 CE FE FF FF           | call exepuzz1.401000                    |
00401132 | 59                       | pop ecx                                 |
00401133 | 8B F0                    | mov esi,eax                             |
00401135 | 33 DB                    | xor ebx,ebx                             |
00401137 | B9 84 20 40 00           | mov ecx,exepuzz1.402084                 |
0040113C | 3B F3                    | cmp esi,ebx                             |
0040113E | 7E 21                    | jle exepuzz1.401161                     |
00401140 | 0F BE 01                 | movsx eax,byte ptr ds:[ecx]             |>----BUCLE------
00401143 | 8B D0                    | mov edx,eax                             | EAX y EDX contienen el valor HEX del dígito que toque
00401145 | BF 1A 00 00 00           | mov edi,1A                              | EDI = 1A
0040114A | 43                       | inc ebx                                 | incremento el contador
0040114B | 8D 04 C2                 | lea eax,dword ptr ds:[edx+eax*8]        | EAX = Dígito+Dígito*8
0040114E | 8D 04 C2                 | lea eax,dword ptr ds:[edx+eax*8]        | EAX = Dígito+EAX*8
00401151 | 83 C0 3B                 | add eax,3B                              | EAX = EAX+3B
00401154 | 99                       | cdq                                     |
00401155 | F7 FF                    | idiv edi                                | EAX / EDI
00401157 | 80 C2 61                 | add dl,61                               | DL + 61
0040115A | 88 11                    | mov byte ptr ds:[ecx],dl                |
0040115C | 41                       | inc ecx                                 |
0040115D | 3B F3                    | cmp esi,ebx                             | ¿He terminado de recorrer la string?
0040115F | 7F DF                    | jg exepuzz1.401140                      |^-----BUCLE------
........

En 401117 vemos que intenta leer del DUMP en la dirección 402084 y a partir de ahí según lo que haya en el DUMP realiza una serie de operaciones con los datos y nos devuelve el resultado en forma de NAG.

Probamos varias cosas y nuestra teoría funciona pero, ¿cúal es la cadena de texto que debemos introducir?. A partir de aquí ya es un poco la intuición de cada uno, aunque la más lógica es «tell me the answer» que aparece justo antes del bucle.

El BUCLE

En resumen:

t 74  74*8+74 = 414*8+74 = 2114+3B = 214F MOD 1A = 19 + 61 = 72 (z)
e 65  65*8+65 = 38D*8+65 = 1CCD+3B = 1D08 MOD 1A = 16 + 61 = 77 (w)
l 6C  6C*8+6C = 3CC*8+6C = 1ECC+3B = 1F07 MOD 1A =  D + 61 = 6E (n)
l 6C  6C*8+6C = 3CC*8+6C = 1ECC+3B = 1F07 MOD 1A =  D + 61 = 6E (n)
  20  20*8+20 = 120*8+20 = 0920+3B = 095B MOD 1A =  3 + 61 = 64 (d)
m 6D  6D*8+6D = 3D5*8+6D = 1F15+3B = 1F50 MOD 1A =  8 + 61 = 69 (i)
e 65  65*8+65 = 38D*8+65 = 1CCD+3B = 1D08 MOD 1A = 16 + 61 = 77 (w)
  20  20*8+20 = 120*8+20 = 0920+3B = 095B MOD 1A =  3 + 61 = 64 (d)
t 74  74*8+74 = 414*8+74 = 2114+3B = 214F MOD 1A = 19 + 61 = 72 (z)
h 68  68*8+68 = 3A8*8+68 = 1DA8+3B = 1DE3 MOD 1A =  7 + 61 = 68 (h)
e 65  65*8+65 = 38D*8+65 = 1CCD+3B = 1D08 MOD 1A = 16 + 61 = 77 (w)
  20  20*8+20 = 120*8+20 = 0920+3B = 095B MOD 1A =  3 + 61 = 64 (d)
a 61  61*8+61 = 369*8+61 = 1BA9+3B = 1BE4 MOD 1A = 10 + 61 = 71 (q)
n 6E  6E*8+6E = 3DE*8+6E = 1F5E+3B = 1F9C MOD 1A =  6 + 61 = 67 (g)
s 73  73*8+73 = 40B*8+73 = 20CB+3B = 2106 MOD 1A =  4 + 61 = 65 (e)
w 77  77*8+77 = 42F*8+77 = 21EF+3B = 222A MOD 1A =  A + 61 = 6B (k)
e 65  65*8+65 = 38D*8+65 = 1CCD+3B = 1D08 MOD 1A = 16 + 61 = 77 (w) 
r 72  72*8+72 = 402*8+72 = 2082+3B = 20BD MOD 1A =  9 + 61 = 6A (j)

zwnndiwdzhwdqdekwj

La cadena de texto resultante ¿sera la correcta?

Si te interesa el mundo del hacking, ya sea como aficionado o como profesional, seguramente querrás estar al día de las últimas novedades, técnicas y herramientas que se utilizan en este campo. Para ello, una buena opción es suscribirte a alguna de las revistas sobre hacking que existen en el mercado. Estas publicaciones te ofrecen información de calidad, actualizada y veraz sobre todo lo relacionado con la seguridad informática, el pentesting, el hacking ético y otros temas de interés. En este artículo te presentamos cinco revistas sobre hacking que deberías leer si quieres ampliar tus conocimientos y habilidades en este ámbito.

Es una de las revistas más populares y reconocidas sobre hacking. Se publica desde el año 2005 y cuenta con una amplia comunidad de lectores y colaboradores. Su contenido abarca desde los aspectos más básicos hasta los más avanzados del hacking, con artículos, tutoriales, entrevistas, casos de estudio y reseñas de herramientas. Además, tiene ediciones especiales dedicadas a temas específicos como el hacking web, el hacking móvil, el malware o el IoT. Puedes acceder a su versión digital o impresa desde su página web.

hakin9.org

Es una revista electrónica sobre hacking que se publica desde el año 1985. Tiene una periodicidad irregular y se distribuye de forma gratuita a través de Internet. Sus contenidos son principalmente artículos técnicos sobre hacking, seguridad informática, programación, etc. También incluye algunos textos de ficción y humor relacionados con el hacking. Es una revista muy apreciada por la comunidad hacker por su calidad y originalidad.

phrack.org

2600: The Hacker Quarterly es una revista legendaria entre los hackers, ya que se publica desde 1984 y ha sido testigo de la evolución de este movimiento a lo largo de las décadas. Su nombre hace referencia a la frecuencia de 2600 Hz que se usaba para hackear las líneas telefónicas en los años 60 y 70. En sus páginas encontrarás artículos sobre hacking, seguridad informática, cultura hacker, activismo digital y mucho más.

2600.com

Revista especializada en pentesting o pruebas de penetración, una de las ramas más importantes del hacking ético. Su contenido está dirigido tanto a principiantes como a expertos en esta materia, con artículos prácticos, teóricos y metodológicos sobre cómo realizar pentests eficaces y profesionales. También incluye entrevistas a destacados pentesters, reseñas de herramientas y reportajes sobre proyectos y eventos relevantes. Puedes descargar su versión digital desde su página web o comprar su versión impresa.

pentestmag.com

Es una revista para los entusiastas del hacking creativo, es decir, aquellos que usan la tecnología para crear proyectos innovadores y divertidos. En sus páginas encontrarás ideas, tutoriales, consejos y reseñas sobre temas como la electrónica, la robótica, el hardware libre, el software libre, el internet de las cosas, la impresión 3D y mucho más..

hackspace.raspberrypi.com

Intro

Hoy tenemos un crackme realizado en ensamblador y sin empacar. Consiste en el típico serial asociado a un nombre sin mucha complicación excepto en lo que a la utilización de memoria se refiere. Como veremos más adelante si no tenemos cuidado se solapan en memoria el nombre y el serial y como siempre evitaremos eso.

El algoritmo

Abrimos el crackme con Olly y buscamos las string references, pinchamos sobre cualquiera y encima encontramos el código que no interesa.

stringref

Subimos hasta las funciones que recojen el nombre y serial (GetDlgItemTexA) y nos fijamos que guarda el nombre a partir de la dirección de memoria 403014 y el serial a partir de 40301A. Además el nombre debe tener por lo menos tres caracteres.

getdlgitemaymemoria

compserial

El algoritmo consiste en lo siguiente, recorre el nombre y comprueba si el dígito se corresponde con 5A(Z), 7A(z) y 39(9). Si coincide los deja como está y si no les suma 1 al valor ascii. A continuación concatena después de cada conversión de dígito el caracter 61(a) aumentándole en 1 para cada nuevo dígito del nombre.

Ejemplo:

Nombre: ZZZZZ
Serial: ZaZbZcZdZe

Nombre: zzzzz
Serial: zazbzczdze

Nombre: 99999
Serial: 9a9b9c9d9e

Como veréis a continuación, para el nombre «deuru» el serial correcto sería «eafbvcsdve«. Simplemente a los caracteres del nombre les suma 1, d es e, e es f, u es v, etc, y los concatena con digito+a+digito+b+digito+c…

Nombre: deuru
Serial: eafbvcsdve

Bucle se repite tantos veces como dígitos tenga el nombre

d  e  u  r  u
64 65 75 72 75

e  a  f  b  v  c  s  d  v  e
65 61 66 62 76 63 73 64 76 65

DUMP
----
00403010  00 00 00 00 64 65 75 72 75 00 65 61 66 62 76 63  ....deuru.eafbvc
00403020  73 64 76 65 00 05 00 00 00 00 00 00 00 00 00 00  sdve...........

 La asignación de memoria

El problema viene cuando elegimos un nombre >5 caracteres, ya que, éste se solapa con la memoria del serial (recordemos 40301A y siguientes) haciendo que sea una chapuza. En la siguiente imagen queda claro. No se si es un error o es intencionado, pero nos conviene no utilizar nombres mayores de 5 dígitos para que nuestro keygen sea lo más limpio posible.

ejemplodump2

El KeyGen

Está realizado en C++ y como véis el nombre debe tener entre 3 y 5 dígitos para que todo vaya bien.

char Nombre[10];
GetWindowText(hwndEdit1, Nombre, 10);
SetWindowText(hwndEdit2, "");
string serial = "";
int len = strlen(Nombre);
char consecutivo[5] = {'a','b','c','d','e'};
if (len <=5 && len >=3){
    for(int i = 0; i <= len; i++)
    {
         if (Nombre[i] == 0x5A || Nombre[i] == 0x7A || Nombre[i] == 0x39)
         {
             serial+=Nombre[i];
             serial+=consecutivo[i];
         }else{
             serial+=Nombre[i]+1;
             serial+=consecutivo[i];
         }
     }
     serial = serial.substr(0, len*2);
     LPCTSTR Sfinal = serial.c_str();
     SetWindowText(hwndEdit2, Sfinal);
}else{
MessageBox(NULL,"Nombre demasiado largo/corto","Info",MB_OK | MB_ICONINFORMATION);
}

 Links


Intro Hoy tenemos un crackme realizado en ensamblador y sin empacar. Consiste en el típico serial asociado a un nombre
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en
Hemos interceptado un mensaje secreto, pero ninguno de nuestros traductores lo sabe interpretar, ¿sabrías interpretarlo tú? Lo único que hemos
Introducción El otro día navegando por la red fuí a dar a un mirror de la gran web "Karpoff Spanish

Introducción

Este crackme pertenece a la página de Karpoff Spanish Tutor. Data del año 2000 y está realizado en «Borland Delphi 6.0 – 7.0», además, para resolverlo deberemos activar un botón y conseguir la clave de registro. La principal dificultad proviene a la hora de activar el botón ya que el serial es en realidad un serial hardcodeado muy sencillo.

Activar un botón en memoria

Existen numerosas herramientas para facilitarnos esta tarea, una de las más conocidas en el entorno del Cracking es «Veoveo» realizado por Crack el Destripador & Marmota hace ya unos añitos. Con el crackme ejecutado, ejecutamos VeoVeo y nos aparece el icono en la barra de tareas, hacemos click derecho y elegimos Activar Botones (manual) y ya tenemos el botón activado. Claro está que en cada ejecución del Crackme debemos de Re-activarlo.

17-02-2015 17-34-16

Activar el botón de forma permanente

Lo que siempre nos interesa es que el botón esté activado de forma permanente y eso nos exige un poco más de atención. En este caso nos enfrentamos a Delphi y no nos sirve ni Resource Hacker ni Dede. Cuando nos encontramos en un punto muerto el último recurso siempre es realizar un programa en Delphi con un botón activado y otro desactivado y compararlos con un editor hexadecimal para saber que cambia. Si hacemos esto llegaremos a la conclusión de que en Delphi el bit que equivale a desactivado es 8 y ha activado es 9. Con este simple cambio ya tenemos el crackme parcheado. Comentar que en este caso el crackme no tiene ningún timer ni ninguna rutina que desactive el botón de forma periódica, este es el caso más simple.

16-02-2015 05-22-40

16-02-2015 05-23-45

Serial Hardcodeado

Abrimos Ollydbg y en las «String references» encontramos los mensajes de versión registrada, pinchamos sobre ellos y vemos a simple vista la zona de comprobación del serial. Como podéis observar, el serial se vé a simple vista.

0045811A   |.  B8 10824500         MOV EAX,CrackMe3.00458210                 ;  ASCII "ESCRIBE ALGO JOER"
0045811F   |.  E8 D889FDFF         CALL CrackMe3.00430AFC
00458124   |.  EB 5C               JMP SHORT CrackMe3.00458182
00458126   |>  807D FF 4F          CMP BYTE PTR SS:[EBP-1],4F - O
0045812A   |.  75 56               JNZ SHORT CrackMe3.00458182
0045812C   |.  807D FE 41          CMP BYTE PTR SS:[EBP-2],41 - A
00458130   |.  75 50               JNZ SHORT CrackMe3.00458182
00458132   |.  807D FD 45          CMP BYTE PTR SS:[EBP-3],45 - E
00458136   |.  75 4A               JNZ SHORT CrackMe3.00458182
00458138   |.  807D FC 4B          CMP BYTE PTR SS:[EBP-4],4B - K
0045813C   |.  75 44               JNZ SHORT CrackMe3.00458182
0045813E   |.  807D FB 43          CMP BYTE PTR SS:[EBP-5],43 - C
00458142   |.  75 3E               JNZ SHORT CrackMe3.00458182
00458144   |.  807D FA 41          CMP BYTE PTR SS:[EBP-6],41 - A
00458148   |.  75 38               JNZ SHORT CrackMe3.00458182
0045814A   |.  807D F9 52          CMP BYTE PTR SS:[EBP-7],52 - R
0045814E   |.  75 32               JNZ SHORT CrackMe3.00458182
00458150   |.  807D F8 4B          CMP BYTE PTR SS:[EBP-8],4B - K
00458154   |.  75 2C               JNZ SHORT CrackMe3.00458182
00458156   |.  807D F7 20          CMP BYTE PTR SS:[EBP-9],20 - 
0045815A   |.  75 26               JNZ SHORT CrackMe3.00458182
0045815C   |.  807D F6 49          CMP BYTE PTR SS:[EBP-A],49 - I
00458160   |.  75 20               JNZ SHORT CrackMe3.00458182
00458162   |.  807D F5 4F          CMP BYTE PTR SS:[EBP-B],4F - O
00458166   |.  75 1A               JNZ SHORT CrackMe3.00458182
00458168   |.  807D F4 54          CMP BYTE PTR SS:[EBP-C],54 - T
0045816C   |.  75 14               JNZ SHORT CrackMe3.00458182
0045816E   |.  807D F3 20          CMP BYTE PTR SS:[EBP-D],20 - 
00458172   |.  75 0E               JNZ SHORT CrackMe3.00458182
00458174   |.  807D F2 41          CMP BYTE PTR SS:[EBP-E],41 - A
00458178   |.  75 08               JNZ SHORT CrackMe3.00458182
0045817A   |.  807D F1 59          CMP BYTE PTR SS:[EBP-F],59 - Y
0045817E   |.  75 02               JNZ SHORT CrackMe3.00458182
00458180   |.  B3 01               MOV BL,1
00458182   |>  80FB 01             CMP BL,1
00458185   |.  75 4C               JNZ SHORT CrackMe3.004581D3
00458187   |.  BA 2C824500         MOV EDX,CrackMe3.0045822C
0045818C   |.  8B86 F4020000       MOV EAX,DWORD PTR DS:[ESI+2F4]
00458192   |.  E8 B5EBFDFF         CALL CrackMe3.00436D4C
00458197   |.  BA 48824500         MOV EDX,CrackMe3.00458248                 ;  ASCII "VERSION REGISTRADA :)"

Serial = YA TOI KRACKEAO

16-02-2015 05-25-23

16-02-2015 05-25-38

Links


http://youtu.be/KR3PgtDMjmg Lista de reproducción
Introducción Cripto 1 Cripto 2 Cripto 3 Cripto 4 Cripto 5 Cripto 6 Cripto 7 Cripto 8 Cripto 9 Cripto 10
Introducción  Hoy vamos a ver como extraer el script de un ejecutable compilado por Autoit, modificarlo y recompilarlo como nuestro
Intro Es un crackme realizado en ensamblador y en el que el objetivo es remover la NAG de la forma

Introducción

Los retos de encriptación son muy variados como hemos comentado anteriormente. Aquí tenemos unos buenos ejemplos de ello.

Cripto 1

En este primer nivel nos encontramos con un método de encriptación muy antíguo.    Sólo diré como pista, que es de los más antiguos que se conocen.

ozhlofxrlmvhxzorulimrz

Lo primero que suelo hacer en este tipo de retos cuando son solamente letras, es comprobar las dos opciones más típicas, que son el cifrado César y Vigenere. En este caso necesitamos ahondar un poco más, aunque enseguida llegamos a la conclusión de que el cifrado usado es el afín. Un ataque por fuerza bruta nos devuelve la solución y los coeficientes utilizados.

Solución: A=25,B=25  – LASOLUCIONESCALIFORNIA

Fuente: http://www.dcode.fr/chiffre-affine


Cripto 2

En este segundo nivel recordaremos a un general romano muy conocido. Lo complicaremos un poco, sólo lo justo para que cueste algo más de cinco minutos encontrar la clave 🙂

oehoeahhjoexhkzqhfsvzhffhwrhotqk

Lo primero que nos viene a la cabeza es el cifrado César pero no va. Probando varios cifrados por sustitución al final damos con el correcto. De nuevo un ataque por fuerza bruta nos da frutos.

Solución: (3,4,5)/1  – LACLAVEDELASEGUNDAPRUEBAESMEKONG

Fuente: https://www.dcode.fr/chiffre-decalages


Cripto 3

Este nivel también va a ser sencillo. Estos caracteres, pertenecientes a un sistema bastante conocido de encriptado, esconden una palabra que, al introducirla (en minúsculas), nos permitirá superar el nivel.

Investigando un poco llegamos a la conclusión de que se trata del cifrado Francmasón o Pig Pen.

Solución: primates

Fuente: https://www.dcode.fr/chiffre-pig-pen-francs-macons


Cripto 4

Esta prueba es tan simple que la he dividido en dos partes que, aunque de apariencia similar, se resuelven de distinta manera. La clave es la unión de las dos palabras resultantes de descifrar las dos líneas de números y que, juntas, forman una tercera palabra.

0111001101110101011100000110010101110010
0001001110011000111110100100110010010001

La primera parte se puede convertir en bloque:

0111001101110101011100000110010101110010 = super

Fuente: https://www.rapidtables.com/convert/number/binary-to-ascii.html

Para la segunda debemos separar en grupos de 5 dígitos y listo:

00010   01110   01100   01111   10100   10011   00100   10001

 C             O          M           P            U          T           E           R

Fuente: www.lindau-nobel.org


Cripto 5

Para descubrir la palabra clave sólo se necesita una mínima capacidad de observación.

31 04 40 23 20 34 33 13 23 22

Se trata del cuadrado de Polibio.


Cripto 6

Aquí hay que hacer un poco de trabajo de investigación: Hay que descubrir la clave que empleó un escritor francés (Una pista: «Lagardère») en una de sus novelas, que es la empleada aquí para formar la palabra clave (en minúsculas) que, por cierto, es alemana.

RI3I2MIL2I2A3

POR RESOLVER


Cripto 7

Seguimos con cosas fáciles. Se trata de descifrar este texto escrito en inglés.

kgw qkoev ol 617 qthpreoz iwjpz sdkg kgw pdeyeplk rwqdjzwe ipezwq spbbdq sgo sgwz goqkdbdkdwq iwjpz spq rwkwecdzwr ko cpmw gdq uweqozpb yozkedihkdoz ko kgw spe wlloek

Una vez descifrado, nos será fácil descubrir la clave:

pzpyozrp

Se trata de  un cifrado de sustitución mono alfabético.

ABCDEFGHIJKLMNOPQRSTUVWXYZ
ZLMIRVHUBGTFJKOASDWQPYEXCN

THE STORY OF 617 SQUADRON BEGAN WITH THE AIRCRAFT DESIGNER BARNES WALLIS WHO WHEN HOSTILITIES BEGAN WAS DETERMINED TO MAJE HIS PERSONAL CONTRIBUTION TO THE WAR EFFORT

Una vez descifrado el alfabeto la solución queda:

pzpyozrp = anaconda

Cripto 8

A veces, las cosas no son lo que parecen. Donde aparecen unos números, en realidad hay otros números distintos.

273664524572348321143738
853442616537643005319627

POR RESOLVER


Cripto 9

Para resolver algunos problemas, hay que tener una buena base. Este es un buen ejemplo de ello:

ZW50ZXJwcmlzZQ0K

¿Os suena base 64?

Solución: enterprise

Fuente: https://www.base64decode.org/


Cripto 10

Esto es más complicado. Para descifrar este texto que contiene la clave para superar el nivel, se necesita otra clave. Para que no sea demasiado difícil, he utilizado una palabra muy sencilla de sólo cuatro letras 🙂

myiemyuvbaeewcxweghkflxw

Mediante fuerza bruta matamos dos pájaros de un tiro.

lapalabraclaveesdiogenes

Fuente: https://www.guballa.de/vigenere-solver


Enlaces

Introducción

 Hoy vamos a ver como extraer el script de un ejecutable compilado por Autoit, modificarlo y recompilarlo como nuestro keygen. Como comprobareis si no se ofusca o se toman otro tipo de medidas recuperar información sensible es muy sencillo.

AutoIt es un lenguaje freeware multiproposito y de automatización para Microsoft Windows. Es un Visual Basic Killer, ya que mejora las características de los ejecutables (entre otras portabilidad, velocidad y peso, no fat-coding), y facilitan la programación con un buen repertorio de funciones «pre-diseñadas», y usando un Basic de fácil aprendizaje. Se ha expandido desde sus comienzos de automatización incluyendo muchas mejoras en el diseño del lenguaje de programación y sobre todo en nuevas funcionalidades.

El Script

Func CHECKKEY($USER, $PASS)
Local $OPKEY = "", $SIG = ""
Local $USER_LEN = StringLen($USER)
Local $PASS_LEN = StringLen($PASS)
If $USER_LEN < $PASS_LEN Then
MsgBox(0, "ERROR", "Invalid username or key.")
Exit
ElseIf $USER_LEN < 4 Then
MsgBox(0, "ERROR", "Invalid username or key.")
Exit
EndIf
$PASS_INT = Int($USER_LEN / $PASS_LEN)
$PASS_MOD = Mod($USER_LEN, $PASS_LEN)
$OPKEY = _STRINGREPEAT($PASS, $PASS_INT) & StringLeft($PASS, $PASS_MOD)
For $INDEX = 1 To $USER_LEN
$SIG &= Chr(BitXOR(Asc(StringMid($USER, $INDEX, 1)), Asc(StringMid($OPKEY, $USER_LEN - $INDEX + 1, 1))))
Next
If $SIG = _STRINGREPEAT(Chr(32), $USER_LEN) Then
MsgBox(0, "INFO", "Your key was registered.")
Exit
Else
MsgBox(0, "INFO", "Your key is invalid.")
EndIf
EndFunc

 El Algoritmo

El algoritmo es tremendamente sencillo ya que es nuestro nombre al revés y en mayúsculas.

 Modificando el script para generar nuestro propio keygen

El decompilador se llama myAut2exe y tiene este aspecto.

01-09-2014 11-56-37

Programar en AutoIt es muy sencillo e intuitivo. Nuestro keygen quedaría así.

$MAIN = GUICreate("Another keygen by deurus", 300, 80, -1, -1, 382205952, 385)
$NAME_LBL = GUICtrlCreateLabel("Username", 5, 5, 60, 20, BitOR(4096, 1))
$NAME_INP = GUICtrlCreateInput("", 70, 5, 225, 20, 1)
$PASS_LBL = GUICtrlCreateLabel("Key", 5, 30, 60, 20, BitOR(4096, 1))
$PASS_INP = GUICtrlCreateInput("", 70, 30, 225, 20, 1)
$REGISTER = GUICtrlCreateButton("Register", 5, 55, 60, 20)
$GIVE_UP = GUICtrlCreateButton("Generate", 70, 55, 60, 20)    <- Change name of button, Give Up by Generate
$TASK = GUICtrlCreateButton("?", 140, 55, 20, 20)
$AUTHOR = GUICtrlCreateLabel("keygen by deurus", 165, 55, 130, 20, BitOR(4096, 1))
GUISetState(@SW_SHOW, $MAIN)
While True
    $MSG = GUIGetMsg()
    Switch $MSG
        Case $REGISTER
            Call("CHECKKEY", GUICtrlRead($NAME_INP), GUICtrlRead($PASS_INP))
        Case $GIVE_UP
            Call("GETKEY", GUICtrlRead($NAME_INP), GUICtrlRead($PASS_INP))    <- Add the function to the button
        Case $TASK
            MsgBox(0, "Info", "keygen by deurus")
        Case - 3
            Exit
    EndSwitch
    Sleep(15)
WEnd

Func GETKEY($USER, $PASS)        <- this is our keygen function
    Local $OPKEY = "", $SIG = ""
    Local $USER_LEN = StringLen($USER)
    Local $PASS_LEN = StringLen($USER)
    If $USER_LEN < 4 Then
        GUICtrlSetData($PASS_INP  ,"min 4 chars");
    Else
    For $INDEX = 1 To $USER_LEN
        $SIG = Chr(BitXOR(Asc(StringMid($USER, $INDEX, 1)), 32)) & $SIG
    Next
        GUICtrlSetData($PASS_INP  ,$SIG);
    EndIf
EndFunc

Func CHECKKEY($USER, $PASS)        <- check function, the original
    Local $OPKEY = "", $SIG = ""
    Local $USER_LEN = StringLen($USER)
    Local $PASS_LEN = StringLen($PASS)
    If $USER_LEN < $PASS_LEN Then
        MsgBox(0, "ERROR", "Invalid username or key.")
    ElseIf $USER_LEN < 4 Then
        MsgBox(0, "ERROR", "Invalid username or key.")
        Exit
    EndIf
    $PASS_INT = Int($USER_LEN / $PASS_LEN)
    $PASS_MOD = Mod($USER_LEN, $PASS_LEN)
    $OPKEY = _STRINGREPEAT($PASS, $PASS_INT) & StringLeft($PASS, $PASS_MOD)
    For $INDEX = 1 To $USER_LEN
        $SIG &= Chr(BitXOR(Asc(StringMid($USER, $INDEX, 1)), Asc(StringMid($OPKEY, $USER_LEN - $INDEX + 1, 1))))
    Next
    If $SIG = _STRINGREPEAT(Chr(32), $USER_LEN) Then
        MsgBox(0, "INFO", "Your key was registered.")
    Else
        MsgBox(0, "INFO", "Your key is invalid.")
    EndIf
EndFunc

Este es el resultado.

01-09-2014 12-18-28

Links


st2 arcade
He de iniciar esta entrada diciendo que la segunda temporada de Stranger Things es sencillamente genial. Son 9 horas intensas
En esta ocasión vamos a hablar de una película de culto de los años 90, Hackers - Piratas Informáticos. La
El reto Se nos proporciona la imagen anterior y se nos invita a resolver la ecuación para el menor entero
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en

st2 arcade

He de iniciar esta entrada diciendo que la segunda temporada de Stranger Things es sencillamente genial. Son 9 horas intensas que no dejan indiferente a nadie y además en el capítulo 8 nos han dejado una de esas perlas informáticas que tanto nos gustan.

La escena la protagoniza Bob Newby, un buen hombre amante de la electrónica de aquella época que trabaja en RadioShack y transcurre en el laboratorio secreto de Hawkins. En un momento dado, Bob propone «saltarse» la seguridad del laboratorio y para ello se traslada al sótano donde se encuentran los «servidores».

El PC de la época

Para comprender esta escena hay que situarse temporalmente. Estamos hablando de los años 80, en concreto la escena transcurre en 1984 y los equipos de los que dispone el laboratorio son unos maravillosos IBM. No se llega a apreciar bien el modelo de IBM utilizado pero teniendo en cuenta que el monitor que aparece es un terminal IBM 3180, la búsqueda se reduce a los sistemas compatibles S/36, S/38, AS/400, 5294 ó 5394.

IBM 3180

IBM 3180 (https://www.argecy.com/3180)

Cracking BASIC or BASIC Cracking?

La escena plantea un ataque de fuerza bruta a un código de 4 dígitos como se puede observar en la imagen a continuación. Esto puede parecer una chorrada hoy día pero podía suponer un pequeño reto para un micro de 8 bits.

Cracking Basic or Basic Cracking?

Cracking Basic or Basic Cracking?

A simple vista se aprecian una serie de bucles recursivos, una llamada a una función y una sentencia condicional. Desconozco si la sintaxis del lenguaje es la correcta pero mucho me temo que es más bien una mezcla de BASIC y pseudocódigo. Pero lo que más me ha llamado la atención sin duda es que la palabra THEN parece que se sale del monitor como si estuviera realizado en post-producción. Os invito a que ampliéis la imagen y comentéis lo que os parece a vosotr@s.

Os dejo aquí el código para los más curiosos.

10 DIM FourDigitPassword INTEGER
20 FOR i = 0 TO 9
30 		FOR j = 0 TO 9
40			FOR k = 0 TO 9
50				FOR l = 0 TO 9
60					FourDigitPassword = getFourDigits (i,j,k,l)
70					IF checkPasswordMatch(FourDigitPassword) = TRUE THEN
80						GOTO 140
90					END
100				NEXT l
110			NEXT k
120		NEXT j
130 NEXT i
140 PRINT FourDigitPassword

Aunque  la entrada está dentro del contexto de los Blooper Tech Movies, digamos que en esta ocasión no voy a ir más allá. La escena es creíble y queda bien integrada en la época en la que se desarrolla el capítulo. Por esto mismo, solamente espero que las temporadas venideras sean tan buenas y cuiden tanto los detalles como sus predecesoras.

Referencias

[1] Ficha IMDB – Stranger Thing

[2] Wikia de Stranger Things

[3] IBM 3180

[4] BASIC

En esta ocasión vamos a hablar de una película de culto de los años 90, Hackers – Piratas Informáticos. La verdad es que aunque puede ser entretenida, tecnológicamente es una pesadilla y es que esta película es un claro ejemplo de cuando Hollywood prefiere agradar visualmente a representar escenas realistas.

Tras cuatro minutos en los que se nos presenta a Dade (Jonny Lee Miller) y sus problemas con la ley a una temprana edad, saltamos unos años después hasta ver a Dade encerrado en su habitación volviendo a las andadas intentando acceder ilegítimamente a los servidores de una cadena de televisión. Para ello hace uso de algo muy conocido en el mundillo Hacker, la Ingeniería Social, y es que aunque ahora disponemos de «cierta» conciencia en seguridad informática, en los años 90 no había ninguna. Bien, el caso es que Dade llama a las oficinas de la citada cadena de televisión a una hora en la que no hay más que el vigilante de seguridad y éste le proporciona un número que debemos suponer que es la IP de un Módem y comienza la intrusión.

BTM

Para empezar, se le ve al protagonista escribir comandos cuando en la pantalla no hay más que una animación en algo parecido a una ventana de terminal al estilo «Commander», pero no vemos lo que escribe, algo irreal.

vlcsnap-2015-11-25-18h00m25s936

A continuación y como por arte de magia entra en el sistema y lo que se muestra es una animación parpadeante con el logo de la compañia y el nombre del sistema al que estamos accediendo, también irreal.

vlcsnap-2015-11-25-12h43m18s762

Finalmente nos muestra sus intenciones, y son nada más y nada menos que cambiar la programación actual simplemente cambiando de VHS, inmejorable. A continuación os muestro la secuencia.

Por lo menos nos queda el consuelo de que cambia la tertulia de un tipejo con ciertos prejuicios raciales por una programación más interesante como «The Outer limits«, aquí conocida como «Más allá del límite«.

El resto de escenas informáticas de la película carecen de veracidad, la única que se salva, puede ser cuando accede al servidor del Instituto para programar el sistema contra incendios y vengarse de Kate (Angelina Jolie), ya que las imágenes que aparecen son de los primeros entornos gráficos de Mac.

vlcsnap-2015-11-25-18h29m08s043

vlcsnap-2015-11-25-18h29m15s390

vlcsnap-2015-11-25-18h29m31s550

Es extraño que casi todas las intrusiones las realiza desde su propia casa, algo poco inteligente, ya que por muy bueno que seas, siempre dejas huellas. Solo cuando se enfrentan a un Super-Hacker se empiezan a tomar las cosas en serio y realizan los ataques desde cabinas telefónicas.

En la película También hacen mención al Phreaking y a algunos de los libros que eran famosos por aquella época pero poco más que destacar. Por todo esto y mucho más, y aunque me caen igual de bien tanto Angelina como Jonny, la película se merece un majestuoso sello de BTM.

hackers_sello

Enlaces


Aquí tenemos un crackme fuera de lo común, más que nada por que está programado en Brainfuck, un lenguaje de
Habitualmente suelo descargar shareware por diversión para evaluar de que manera protegen los programadores su software. Cada vez es más
Introducción Esta es la tercera y última entrega de los crackmes de Cruehead. En esta ocasión nos enfrentamos a un
Introducción Esta es la primera entrega de tres en las que vamos a  ver tres crackmes que todo reverser debería

Aquí tenemos un crackme fuera de lo común, más que nada por que está programado en Brainfuck, un lenguaje de programación esotérico bastante complejo.

[-]>[-]<>++++++++[<++++++++++>-]<.+++++++++++++++++.>+++[<++++++>-]<..++++.-
-------.+++.--------------.>++++++[<------>-]<-.>+++++[<------>-]<-.,>,>,>,>
>>>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++>>>>+++++++++++++++++++++++++++++++++++++++++
+++++++++++>>>>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++>>>>++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<<<
<<<<<<<<<<<<<<<<[>>>>>>>-<<<<<<<-]>>>>>>><<+>>[[-]++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++.<]<[>]<<<<<[>>>>>>>>>>-<<<<<<<<
<<-]>>>>>>>>>><<+>>[[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++.<]<[>]<<<<<<<<[>>>>>>>>>>>>>-<<<<<<<<<<<<<-]>>>>>>>>>>>>><<+>>[
[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.<]<[>]<<<<<<<<<<<[>>>>>>>>>>>>>>>>-<<<<<<<<<<<<<<<<-]>>>>>>>>>>>>>>>><<+>>[
[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++.<]<[>]>>>[-]>[-]<+++++++++++++.---.>+++++++[<++++++++++++>-]<.>+++++++[<
--------->-]<+.>+++++[<++++++++>-]<+.>++++[<+++++++>-]<+.>+++++++[<---------
->-]<.>++++++++[<+++++++++>-]<+.+++++++++++.>+++++++[<----------->-]<.>+++++
++[<+++++++++++>-]<-.>+++++++[<------------>-]<+.>++++++++[<+++++++++++>-]<-
.-----.---------.+++++++++++..---------------.+++++++++.>++++++[<-----------
-->-]<.+++++++.>+++++[<++++++>-]<+.-----.++++++++.+++.>++++++[<------>-]<-.-
------.>++++++++[<++++++++++>-]<-.+++.>+++++++++[<--------->-]<-.+++++++.>++
+++[<++++++>-]<+.-----.+++++++++++.>++++++[<------>-]<-.-------.>++++++++[<+
+++++++++>-]<-.+++.>+++++++++[<--------->-]<-.+++++++.>+++++[<+++++>-]<+.+++
+++++.+++.>++++++[<------>-]<-.+++++++...--------------.>++++++++[<+++++++++
++>-]<+.----------.++++++.>+++++++[<------------>-]<-.>++++++++[<+++++++++>-
]<.-------.>+++[<+++++++>-]<.-----------------.>+++++++[<---------->-]<+.>++
+++++[<++++++++++>-]<.-----.++++++++.+++.-------.-.>++++++[<--------->-]<.--
------------.>+++++[<++++++++>-]<+.>++++[<+++++++>-]<+.>+++++++[<---------->
-]<.>+++++++[<++++++++++++>-]<.------------.---.+++++++++++++.-------------.
>+++++++[<---------->-]<+.>++++++++[<+++++++++>-]<+.++++++++++.>+++++++[<---
--------->-]<+.>++++++[<+++++++++++++>-]<.+.+++++.------------.+.+++++.-----
--.>++++++[<---------->-]<+.------------.>++++++++[<+++++++++++>-]<+.-------
---.++++++.>+++++++[<------------>-]<-.>++++++++[<+++++++++>-]<.-------.>+++
[<+++++++>-]<.-----------------.>+++++++[<---------->-]<+.>++++++++[<+++++++
++++>-]<-.--------------.+++++.>++++++[<------------->-]<.+.

La solución que he encontrado yo, es convertir el código brainfuck a algo más amigable y depurarlo hasta encontrar la solución. La conversión la he realizado con VBBrainFNET y luego la depuración con Visual Studio. El crackme te pide una clave de cuatro cifras para darte la solución, pero si no quieres volverte loco puedes amañar los bucles para encontrar la solución.

¡SUERTE!

Enlaces

 

Introducción

Esta es la tercera y última entrega de los crackmes de Cruehead. En esta ocasión nos enfrentamos a un «keyfile«, un archivo llave para que nos entendamos. Tiene un poco más de dificultad que los anteriores pero es ideal para los que empiezan.

El algoritmo

Si iniciamos el crackme no pasa nada, lo único que vemos es la palabra «UNCRACKED» en el título. Abrimos el crackme con Olly y empezamos. En las «string references» vemos el nombre del archivo llave «crackme3.key«. Lo creamos y escribimos el serial 12345678 y empezamos a tracear.

El CMP EAX,-1 significa que está comprobando que el archivo no esté vacio, como no es nuestro caso continuamos.

07-09-2014 13-02-12

A continuación vemos que compara nuestra longitud de serial con 0x12 (18 en decimal). Nuestro serial tiene 8 dígitos así que nos tira fuera.

07-09-2014 13-07-59

Escribimos en el archivo llave el serial «deurus123456789012» y volvemos a tracear. Vemos que ahora si pasa los filtros iniciales y llegamos a la primera zona interesante. En la imágen está explicado pero os hago un resumen. En el bucle lo que hace es un XOR a los primeros 14 dígitos de nuestro serial con los valores del 41 al 4E (4F finaliza). El bucle solo se rompe si llegamos a 4F o si el resultado del XOR da 0. Además en EAX acumula la suma del resultado del XOR.

07-09-2014 17-13-57

Ejemplo:

d  e  u  r  u  s  1  2  3  4  5  6  7  8  9  0  1  2
64 65 75 72 75 73 31 32 33 34 35 36 37 38
                                          XOR
41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E
-----------------------------------------
25 27 36 36 30 35 76 7A 7A 7E 7E 7A 7A 76 = 4ED (Suma)

A continuación hace XOR entre 12345678 y 4ED, coge los 4 últimos dígitos de nuestro serial y los compara.

07-09-2014 17-23-45

Ejemplo:

12345678 XOR 4ED = 12345295
Compara 12345295 con 32313039
32313039 = 2109, nuestros 4 últimos dígitos al revés. Recordemos que nuestro serial era "deurus123456789012"

 El serial bueno para el nombre deurus12345678 serían los bytes correspondientes de «12345295», es decir, nuestro serial bueno sería:

Ejemplo:

Necesitamos 12345295 para la comparación.
12 34 52 95 hexadecimal
18 52 82 149 decimal
Tenemos que escribirlo al revés. Con Alt-Izq + 149 escribimos el primer caracter, el resto igual.
Nuestro serial quedaría: deurus12345678òR4↕

Metemos el serial y vemos que lo acepta pero que nos muestra un nombre extraño. Esto es por que nos está mostrando los bytes del nombre xoreados, tendremos que hacer un XOR antes al nombre que queramos para que lo muestre correctamente.

07-09-2014 18-15-19

Recapitulando

Con lo que sabemos ahora hay que empezar a coger el toro por los cuernos. Lo primero que queremos que muestre el nombre deurus y no deurus12345678. Para ello debemos cortar el bucle y eso solo lo podemos hacer forzando que el resultado del XOR sea 0. Ok pues para deurus el siguiente valor de BL, es decir el séptimo, en el bucle sería 47 lo que corresponde a la letra G. Pues si ponemos de serial deurusGxxxxxxxxxxx ya tendríamos la primera parte solucionada.

Pero recordemos que necesitamos XORear el nombre inicialmente, luego debemos escribir  el resultado del XOR.

Ejemplo:

d  e  u  r  u  s  
64 65 75 72 75 73
                  XOR
41 42 43 44 45 46
-----------------
25 27 36 36 30 35

25 27 36 36 30 35 ----- debemos meter esto en el archivo llave.
                  XOR
41 42 43 44 45 46
-----------------
64 65 75 72 75 73 ----- Al desencriptarlo el bucle se verá nuestro nombre correctamente.

En el archivo llave escribiriamos: %'6605

Ahora nos faltaría calcular el nuevo SUM. Como el resultado del XOR ahora es nuestro nombre, basta con sumar sus valores ascii (64+65+75+72+75+73 == 0x298)

0x12345678 XOR 0x298 == 0x123454E0

Luego nuestros 4 últimos dígitos deben ser lo correspondiente a los bytes E0, 54, 34, 12. Los pasamos a decimal y los escribimos en el archivo llave con el truco del ALT-Izq que hemos comentado antes.

El contenido final del archivo llave para el nombre deurus sería:

%’6605GxxxxxxxÓT4↕

07-09-2014 16-55-15

Aquí vemos el archivo llave normal.

keyfiletext

Y aquí lo vemos con un editor hexadecimal. Como veis se ven claramente los bytes E0, 54, 34, 12.

keyfilehex

Os dejo un keygen hecho en .Net para que probéis. Os genera el contenido del archivo y el archivo «crackme3.key».

keygen

Links


http://youtu.be/KR3PgtDMjmg Lista de reproducción
Aviso: Este crackme forma parte de una serie de pruebas de Yoire.com que todavía está en activo. Lo ético si
Introducción El otro día navegando por la red fuí a dar a un mirror de la gran web "Karpoff Spanish
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en

Aviso: Este crackme forma parte de una serie de pruebas de Yoire.com que todavía está en activo. Lo ético si continuas leyendo este manual es que no utilices la respuesta para completar la prueba sin esfuerzo. 😉

Analizando

Abrimos el crackme con Ollydbg y vamos a las referenced strings.

Pinchamos sobre cualquiera.

 

Vemos un «Call» donde seguramente se generará un SUM en función del serial metido ya que después del Call vemos una comprobación contra «B79E763E» lo que nos da una pista de que vamos a tener que utilizar fuerza bruta para llegar a ese valor. Vamos a explorar el Call.

Lo que resalto con la flecha son una par de Calls que podemos NOPear ya que lo único que hacen es ralentizar la generación del SUM.
A continuación vamos a analizar el algoritmo de generación del SUM.
MOV EDI,5EED                   - EDI = 5EED
JMP SHORT 01_crack.004010D7
/MOV EAX,EDI                   <----Bucle
|SHL EAX,5                     - 5EED * 32 = BDDA0
|MOVZX EDX,BYTE PTR DS:[EBX]   - Coge el dígito
|XOR EAX,EDX                   - BDDA0 XOR digito
|MOV EDI,EAX
|XOR EDI,1D0B1EED              - XOR 1D0B1EED
|INC EBX
|..
|MOV ESI,EAX
CMP BYTE PTR DS:[EBX],0
JNZ SHORT 01_crack.004010B4   - Bucle ---->

Para un serial de tres dígitos la secuencia sería esta (valores en hexadecimal):

1º Digit —> BDDA0 XOR 1D0B1EED XOR 1ºDigit XOR 1D0B1EED = Temp
2º Digit —> Temp = Temp * 20 Xor 1D0B1EED XOR 2ºDigit
3º Digit —> Temp = Temp * 20 Xor 1D0B1EED XOR 3ºDigit

CMP Temp, B79E763E

Aplicando Fuerza Bruta

La creación del «BruteForcer» os la dejo a vosotros. Aquí teneis un fragmento hecho en VB.Net.

Dim temp As Long
Dim temp2 As String
Dim letter As Integer
Dim brute As String
brute = TextBox4.Text
temp = 0
temp = Asc(Mid(brute, 1, 1)) Xor 487268077 Xor 777632
temp2 = Hex(temp)
temp2 = Microsoft.VisualBasic.Right(temp2, 8)
temp = Convert.ToUInt64(temp2, 16)
For i = 2 To Len(brute)
letter = Asc(Mid(brute, i, 1))
temp = temp * 32
temp2 = Hex(temp)
temp2 = Microsoft.VisualBasic.Right(temp2, 8)
temp = Convert.ToUInt64(temp2, 16)
temp = temp Xor 487268077
temp2 = Hex(temp)
temp2 = Microsoft.VisualBasic.Right(temp2, 8)
temp = Convert.ToUInt64(temp2, 16)
temp = temp Xor letter
'
temp2 = Hex(temp)
Next

Links


Intro Aquí tenemos un crackme clásico realizado en Visual C++. La única particularidad que tiene es que no muestra MessageBox
Introducción Desempacado Eliminar la NAG Password Nº serie asociado a un nombre Checkbox Trackbar Links Introducción Aquí tenemos un Crackme
Introducción Herramientas utilizadas Desempacado con Ollydbg 2 (Videotutorial) Desempacado con Ollydbg 1 (Videotutorial) Análisis de la rutina del número de
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en

Intro

Aquí tenemos un crackme clásico realizado en Visual C++. La única particularidad que tiene es que no muestra MessageBox al introducir bien o mal el serial, simplemente cambia una imagen de un emoticono. Si observamos el comportamiento del crackme notaremos que inicialmente el emoticono está neutral y al fallar se pone triste y por lo tanto es de suponer que al acertar se pondrá contento.

El BreakPoint

Intermodular Calls

Al mirar en las Intermodular Calls de OllyDbg vemos que LoadIconA es un buen candidato para ubicar la comprobación del serial. Si nos fijamos hay tres llamadas, ponemos un breakpoint en las tres y enseguida llegamos a la zona de comprobación del serial.

La comprobación

00401180   . 6A FF          PUSH -1
00401182   . 68 68194000    PUSH CrackMe_.00401968
00401187   . 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
0040118D   . 50             PUSH EAX
0040118E   . 64:8925 000000>MOV DWORD PTR FS:[0],ESP
00401195   . 83EC 0C        SUB ESP,0C
00401198   . 53             PUSH EBX
00401199   . 55             PUSH EBP
0040119A   . 8BE9           MOV EBP,ECX
0040119C   . 56             PUSH ESI
0040119D   . 57             PUSH EDI
0040119E   . 8D4C24 10      LEA ECX,DWORD PTR SS:[ESP+10]
004011A2   . E8 2F050000    CALL <JMP.&MFC42.#540>
004011A7   . 8D4C24 14      LEA ECX,DWORD PTR SS:[ESP+14]
004011AB   . C74424 24 0000>MOV DWORD PTR SS:[ESP+24],0
004011B3   . E8 1E050000    CALL <JMP.&MFC42.#540>
004011B8   . 8D4424 10      LEA EAX,DWORD PTR SS:[ESP+10]
004011BC   . 8BCD           MOV ECX,EBP
004011BE   . 50             PUSH EAX
004011BF   . 68 E9030000    PUSH 3E9
004011C4   . C64424 2C 01   MOV BYTE PTR SS:[ESP+2C],1
004011C9   . E8 02050000    CALL <JMP.&MFC42.#3097>                  ;  Lee el tamano del nombre
004011CE   . 8D4C24 14      LEA ECX,DWORD PTR SS:[ESP+14]
004011D2   . 51             PUSH ECX
004011D3   . 68 EA030000    PUSH 3EA
004011D8   . 8BCD           MOV ECX,EBP
004011DA   . E8 F1040000    CALL <JMP.&MFC42.#3097>                  ;  Lee el tamano del serial
004011DF   . 51             PUSH ECX
004011E0   . 8D5424 14      LEA EDX,DWORD PTR SS:[ESP+14]
004011E4   . 8BCC           MOV ECX,ESP
004011E6   . 896424 1C      MOV DWORD PTR SS:[ESP+1C],ESP
004011EA   . 52             PUSH EDX
004011EB   . E8 DA040000    CALL <JMP.&MFC42.#535>
004011F0   . 8D4424 1C      LEA EAX,DWORD PTR SS:[ESP+1C]   
004011F4   . 8BCD           MOV ECX,EBP       
004011F6   . 50             PUSH EAX                 
004011F7   . E8 D4010000    CALL CrackMe_.004013D0 
004011FC   . 50             PUSH EAX
004011FD   . 8D4C24 14      LEA ECX,DWORD PTR SS:[ESP+14]
00401201   . C64424 28 02   MOV BYTE PTR SS:[ESP+28],2
00401206   . E8 B9040000    CALL <JMP.&MFC42.#858>
0040120B   . 8D4C24 18      LEA ECX,DWORD PTR SS:[ESP+18]
0040120F   . C64424 24 01   MOV BYTE PTR SS:[ESP+24],1
00401214   . E8 A5040000    CALL <JMP.&MFC42.#800>
00401219   . 8B4C24 10      MOV ECX,DWORD PTR SS:[ESP+10]
0040121D   . 8B5424 14      MOV EDX,DWORD PTR SS:[ESP+14]
00401221   . 8B41 F8        MOV EAX,DWORD PTR DS:[ECX-8]
00401224   . 8B4A F8        MOV ECX,DWORD PTR DS:[EDX-8]
00401227   . 3BC1           CMP EAX,ECX                              ;  CMP len nombre y len serial
00401229   . 0F85 2C010000  JNZ CrackMe_.0040135B
0040122F   . 83F8 03        CMP EAX,3                                ;  len nombre >=3
00401232   . 0F8C 23010000  JL CrackMe_.0040135B
00401238   . 50             PUSH EAX
00401239   . E8 7A040000    CALL <JMP.&MFC42.#823>
0040123E   . 8BF0           MOV ESI,EAX
00401240   . 8B4424 14      MOV EAX,DWORD PTR SS:[ESP+14]
00401244   . 83C4 04        ADD ESP,4
00401247   . 33C9           XOR ECX,ECX
00401249   . 8B50 F8        MOV EDX,DWORD PTR DS:[EAX-8]
0040124C   . 4A             DEC EDX
0040124D   . 85D2           TEST EDX,EDX
0040124F   . 7E 37          JLE SHORT CrackMe_.00401288
.......
1ºBUCLE
.......
00401251   > 8A1401         MOV DL,BYTE PTR DS:[ECX+EAX]
00401254   . 8A5C01 01      MOV BL,BYTE PTR DS:[ECX+EAX+1]
00401258   . 8B4424 14      MOV EAX,DWORD PTR SS:[ESP+14]
0040125C   . 0FBED2         MOVSX EDX,DL
0040125F   . 0FBE0401       MOVSX EAX,BYTE PTR DS:[ECX+EAX]
00401263   . 8D4410 FE      LEA EAX,DWORD PTR DS:[EAX+EDX-2]
00401267   . 99             CDQ
00401268   . 2BC2           SUB EAX,EDX
0040126A   . 0FBED3         MOVSX EDX,BL
0040126D   . D1F8           SAR EAX,1
0040126F   . 40             INC EAX
00401270   . 83EA 02        SUB EDX,2
00401273   . 3BC2           CMP EAX,EDX
00401275   . 0F94C0         SETE AL
00401278   . 880431         MOV BYTE PTR DS:[ECX+ESI],AL
0040127B   . 8B4424 10      MOV EAX,DWORD PTR SS:[ESP+10]
0040127F   . 41             INC ECX
00401280   . 8B50 F8        MOV EDX,DWORD PTR DS:[EAX-8]
00401283   . 4A             DEC EDX
00401284   . 3BCA           CMP ECX,EDX
00401286   .^7C C9          JL SHORT CrackMe_.00401251
........
Última comprobación
........
00401288   > 0FBE1401       MOVSX EDX,BYTE PTR DS:[ECX+EAX]
0040128C   . 0FBE78 01      MOVSX EDI,BYTE PTR DS:[EAX+1]
00401290   . 8B4424 14      MOV EAX,DWORD PTR SS:[ESP+14]
00401294   . 83C7 FE        ADD EDI,-2
00401297   . 0FBE0401       MOVSX EAX,BYTE PTR DS:[ECX+EAX]
0040129B   . 8D4410 FE      LEA EAX,DWORD PTR DS:[EAX+EDX-2]
0040129F   . 99             CDQ
004012A0   . 2BC2           SUB EAX,EDX
004012A2   . D1F8           SAR EAX,1
004012A4   . 40             INC EAX
004012A5   . 3BC7           CMP EAX,EDI
004012A7   . 0F94C2         SETE DL
004012AA   . 881431         MOV BYTE PTR DS:[ECX+ESI],DL

La comprobación es muy sencilla, en resumen hace esto con todas las letras del nombre excepto la última:

1º Caracter
(1ºname + 1ºserial - 2 = X)
(X / 2)
(X + 1)
(2ºname - 2 = Y)
¿Y = X?
2º Caracter
(2ºname + 2ºserial - 2 = X)
(X / 2)
(X + 1)
(3ºname - 2 = Y)
¿Y = X?
...
Con el último caracter del nombre hace lo siguiente:
(6ºname + 6ºserial - 2 = X)
(X / 2)
(X + 1)
(2ºname - 2 = Y)
¿Y = X?
---------
Para revertir la primera parte de la comprobación para el nombre deurus quedaría:
X1 = (((2ºname-2-1)*2)+2)-1ºname
X2 = (((3ºname-2-1)*2)+2)-2ºname
X3 = (((4ºname-2-1)*2)+2)-3ºname
X4 = (((5ºname-2-1)*2)+2)-4ºname
X5 = (((6ºname-2-1)*2)+2)-5ºname
X6 = (((2ºname-2-1)*2)+2)-6ºname

Keygen

var nombre = "deurus";
nombre = nombre.toUpperCase();
var serial = "";
var tmp = "";

var i;
for (i = 0; i < nombre.length-1 ; i++) {
  tmp = ((nombre.charCodeAt(i+1)-2-1)*2+2)-nombre.charCodeAt(i);
  serial += String.fromCharCode(tmp);
}

tmp = ((nombre.charCodeAt(1)-2-1)*2+2)-nombre.charCodeAt(nombre.length-1);
serial += String.fromCharCode(tmp);

document.write(serial);

Enlaces

Y eso es todo, ¡a disfrutar!

Introducción

Aquí tenemos un Crackme clásico creado por Scarebyte hallá por el año 2000 y que cuenta con varias fases siendo un crackme muy interesante para iniciarse o simplemente para divertirse. Al estar realizado en Delphi, los apartados de las checkboxes y de las trackbars se simplifican y mucho, pero aún así hay que currarselo un poco para dejar todo bien atado. Si os fijáis en las soluciones que aparecen en crackmes.de, en aquellos años se usaba DEDE y aunque yo usaré otra herramienta, DEDE sigue siendo igual de útil.

Desempacado

PEiD nos dice que nos enfrentamos a ASPack 1.08.03 -> Alexey Solodovnikov, así que vamos al lío.

Eliminar la NAG

17-02-2016 12-46-19_nag

Tan sencillo como poner un Breakpoint a User32.MessageBoxA. La llamada a NOPear está en la dirección 441CF2.

Password

Desde las string references localizamos los mensajes de chico bueno y chico malo que nos llevan al código a analizar.

0044C3CD   |.  E8 5294FDFF     CALL CrackMe_.00425824
0044C3D2   |.  8B45 FC         MOV EAX,[LOCAL.1]
0044C3D5   |.  E8 9A76FBFF     CALL CrackMe_.00403A74
0044C3DA   |.  83F8 0C         CMP EAX,0C                             ; Lengh C = 12
0044C3DD   |.  0F85 53010000   JNZ CrackMe_.0044C536		      ; Salto a chico malo
0044C3E3   |.  8D55 FC         LEA EDX,[LOCAL.1]
0044C3E6   |.  8B83 E8020000   MOV EAX,DWORD PTR DS:[EBX+2E8]
0044C3EC   |.  E8 3394FDFF     CALL CrackMe_.00425824
0044C3F1   |.  8B45 FC         MOV EAX,[LOCAL.1]
0044C3F4   |.  8038 43         CMP BYTE PTR DS:[EAX],43               ; 1º dígito serial = C
0044C3F7   |.  0F85 27010000   JNZ CrackMe_.0044C524		      ; Salto a chico malo
0044C3FD   |.  8D55 F8         LEA EDX,[LOCAL.2]
0044C400   |.  8B83 E8020000   MOV EAX,DWORD PTR DS:[EBX+2E8]
0044C406   |.  E8 1994FDFF     CALL CrackMe_.00425824
0044C40B   |.  8B45 F8         MOV EAX,[LOCAL.2]
0044C40E   |.  8078 03 6F      CMP BYTE PTR DS:[EAX+3],6F             ; 4º dígito serial = o
0044C412   |.  0F85 0C010000   JNZ CrackMe_.0044C524			; Salto a chico malo
0044C418   |.  8D55 F4         LEA EDX,[LOCAL.3]
0044C41B   |.  8B83 E8020000   MOV EAX,DWORD PTR DS:[EBX+2E8]
0044C421   |.  E8 FE93FDFF     CALL CrackMe_.00425824
0044C426   |.  8B45 F4         MOV EAX,[LOCAL.3]
0044C429   |.  8078 08 6F      CMP BYTE PTR DS:[EAX+8],6F             ; 9º dígito serial = o
0044C42D   |.  0F85 F1000000   JNZ CrackMe_.0044C524			; Salto a chico malo
0044C433   |.  8D55 F0         LEA EDX,[LOCAL.4]
0044C436   |.  8B83 E8020000   MOV EAX,DWORD PTR DS:[EBX+2E8]
0044C43C   |.  E8 E393FDFF     CALL CrackMe_.00425824
0044C441   |.  8B45 F0         MOV EAX,[LOCAL.4]
0044C444   |.  8078 01 6C      CMP BYTE PTR DS:[EAX+1],6C             ; 2º dígito serial = l
0044C448   |.  0F85 D6000000   JNZ CrackMe_.0044C524			; Salto a chico malo
0044C44E   |.  8D55 EC         LEA EDX,[LOCAL.5]
0044C451   |.  8B83 E8020000   MOV EAX,DWORD PTR DS:[EBX+2E8]
0044C457   |.  E8 C893FDFF     CALL CrackMe_.00425824
0044C45C   |.  8B45 EC         MOV EAX,[LOCAL.5]
0044C45F   |.  8078 04 20      CMP BYTE PTR DS:[EAX+4],20             ; 5º dígito serial = espacio
0044C463   |.  0F85 BB000000   JNZ CrackMe_.0044C524			; Salto a chico malo
0044C469   |.  8D55 E8         LEA EDX,[LOCAL.6]
0044C46C   |.  8B83 E8020000   MOV EAX,DWORD PTR DS:[EBX+2E8]
0044C472   |.  E8 AD93FDFF     CALL CrackMe_.00425824
0044C477   |.  8B45 E8         MOV EAX,[LOCAL.6]
0044C47A   |.  8078 0A 52      CMP BYTE PTR DS:[EAX+A],52             ; 11º dígito serial = R
0044C47E   |.  0F85 A0000000   JNZ CrackMe_.0044C524									; Salto a chico malo
0044C484   |.  8D55 E4         LEA EDX,[LOCAL.7]
0044C487   |.  8B83 E8020000   MOV EAX,DWORD PTR DS:[EBX+2E8]
0044C48D   |.  E8 9293FDFF     CALL CrackMe_.00425824
0044C492   |.  8B45 E4         MOV EAX,[LOCAL.7]
0044C495   |.  8078 07 75      CMP BYTE PTR DS:[EAX+7],75             ; 8º dígito serial = u
0044C499   |.  0F85 85000000   JNZ CrackMe_.0044C524									; Salto a chico malo
0044C49F   |.  8D55 E0         LEA EDX,[LOCAL.8]
0044C4A2   |.  8B83 E8020000   MOV EAX,DWORD PTR DS:[EBX+2E8]
0044C4A8   |.  E8 7793FDFF     CALL CrackMe_.00425824
0044C4AD   |.  8B45 E0         MOV EAX,[LOCAL.8]
0044C4B0   |.  8078 09 6E      CMP BYTE PTR DS:[EAX+9],6E             ; 10º dígito serial = n
0044C4B4   |.  75 6E           JNZ SHORT CrackMe_.0044C524		; Salto a chico malo
0044C4B6   |.  8D55 DC         LEA EDX,[LOCAL.9]
0044C4B9   |.  8B83 E8020000   MOV EAX,DWORD PTR DS:[EBX+2E8]
0044C4BF   |.  E8 6093FDFF     CALL CrackMe_.00425824
0044C4C4   |.  8B45 DC         MOV EAX,[LOCAL.9]
0044C4C7   |.  8078 02 6E      CMP BYTE PTR DS:[EAX+2],6E             ; 3º dígito serial = n
0044C4CB   |.  75 57           JNZ SHORT CrackMe_.0044C524		; Salto a chico malo
0044C4CD   |.  8D55 D8         LEA EDX,[LOCAL.10]
0044C4D0   |.  8B83 E8020000   MOV EAX,DWORD PTR DS:[EBX+2E8]
0044C4D6   |.  E8 4993FDFF     CALL CrackMe_.00425824
0044C4DB   |.  8B45 D8         MOV EAX,[LOCAL.10]
0044C4DE   |.  8078 05 69      CMP BYTE PTR DS:[EAX+5],69             ; 6º dígito serial = i
0044C4E2   |.  75 40           JNZ SHORT CrackMe_.0044C524	      ; Salto a chico malo
0044C4E4   |.  8D55 D4         LEA EDX,[LOCAL.11]
0044C4E7   |.  8B83 E8020000   MOV EAX,DWORD PTR DS:[EBX+2E8]
0044C4ED   |.  E8 3293FDFF     CALL CrackMe_.00425824
0044C4F2   |.  8B45 D4         MOV EAX,[LOCAL.11]
0044C4F5   |.  8078 0B 6E      CMP BYTE PTR DS:[EAX+B],6E             ; 12º dígito serial = n
0044C4F9   |.  75 29           JNZ SHORT CrackMe_.0044C524	      ; Salto a chico malo
0044C4FB   |.  8D55 D0         LEA EDX,[LOCAL.12]
0044C4FE   |.  8B83 E8020000   MOV EAX,DWORD PTR DS:[EBX+2E8]
0044C504   |.  E8 1B93FDFF     CALL CrackMe_.00425824
0044C509   |.  8B45 D0         MOV EAX,[LOCAL.12]
0044C50C   |.  8078 06 67      CMP BYTE PTR DS:[EAX+6],67             ; 7º dígito serial = g
0044C510   |.  75 12           JNZ SHORT CrackMe_.0044C524	      ; Salto a chico malo
0044C512   |.  BA 78C54400     MOV EDX,CrackMe_.0044C578              ;  ASCII "Right Password"
0044C517   |.  8B83 E8020000   MOV EAX,DWORD PTR DS:[EBX+2E8]
0044C51D   |.  E8 3293FDFF     CALL CrackMe_.00425854
0044C522   |.  EB 22           JMP SHORT CrackMe_.0044C546
0044C524   |>  BA 90C54400     MOV EDX,CrackMe_.0044C590              ;  ASCII "Wrong Password"
0044C529   |.  8B83 E8020000   MOV EAX,DWORD PTR DS:[EBX+2E8]
0044C52F   |.  E8 2093FDFF     CALL CrackMe_.00425854
0044C534   |.  EB 10           JMP SHORT CrackMe_.0044C546
0044C536   |>  BA 90C54400     MOV EDX,CrackMe_.0044C590              ;  ASCII "Wrong Password"
	
Chequeo rápido
ABCD EFGHIJK
Clno iguonRn
	
; 1º  dígito serial = C
; 4º  dígito serial = o
; 9º  dígito serial = o
; 2º  dígito serial = l
; 5º  dígito serial = espacio
; 11º dígito serial = R
; 8º  dígito serial = u
; 10º dígito serial = n
; 3º  dígito serial = n
; 6º  dígito serial = i
; 12º dígito serial = n
; 7º  dígito serial = g

Básicamente chequea la frase «Cool Running» de forma desordenada como se ve justo encima, siendo el password correcto «Clno iguonRn«. Os dejo el código para que lo analicéis.

Nº serie asociado a un nombre

De nuevo con las string references localizamos el código.

0044C648  /.  55            PUSH EBP
0044C649  |.  8BEC          MOV EBP,ESP
0044C64B  |.  83C4 F8       ADD ESP,-8
0044C64E  |.  53            PUSH EBX
0044C64F  |.  56            PUSH ESI
0044C650  |.  33C9          XOR ECX,ECX
0044C652  |.  894D F8       MOV [LOCAL.2],ECX
0044C655  |.  8BF0          MOV ESI,EAX
0044C657  |.  33C0          XOR EAX,EAX
0044C659  |.  55            PUSH EBP
0044C65A  |.  68 83C74400   PUSH CrackMe_.0044C783
0044C65F  |.  64:FF30       PUSH DWORD PTR FS:[EAX]
0044C662  |.  64:8920       MOV DWORD PTR FS:[EAX],ESP
0044C665  |.  33C0          XOR EAX,EAX
0044C667  |.  8945 FC       MOV [LOCAL.1],EAX
0044C66A  |.  A1 80F84400   MOV EAX,DWORD PTR DS:[44F880]        ;  Eax = Nombre
0044C66F  |.  E8 0074FBFF   CALL CrackMe_.00403A74
0044C674  |.  83F8 06       CMP EAX,6                            ;  Cmp lengh nombre con 6
0044C677  |.  0F8E F0000000 JLE CrackMe_.0044C76D                ;  Salta si <= 6
0044C67D  |.  A1 80F84400   MOV EAX,DWORD PTR DS:[44F880]        ;  Eax = Nombre
0044C682  |.  E8 ED73FBFF   CALL CrackMe_.00403A74
0044C687  |.  83F8 14       CMP EAX,14                           ;  Cmp lengh nombre con 20 (14h)
0044C68A  |.  0F8D DD000000 JGE CrackMe_.0044C76D                ;  salta si >= 20
0044C690  |.  A1 80F84400   MOV EAX,DWORD PTR DS:[44F880]
0044C695  |.  E8 DA73FBFF   CALL CrackMe_.00403A74
0044C69A  |.  85C0          TEST EAX,EAX
0044C69C  |.  7E 17         JLE SHORT CrackMe_.0044C6B5
0044C69E  |.  BA 01000000   MOV EDX,1
0044C6A3  |>  8B0D 80F84400 /MOV ECX,DWORD PTR DS:[44F880]       ;  Bucle in
0044C6A9  |.  0FB64C11 FF   |MOVZX ECX,BYTE PTR DS:[ECX+EDX-1]
0044C6AE  |.  014D FC       |ADD [LOCAL.1],ECX                   ;  Suma dig nombre y guarda en 12FBC4
0044C6B1  |.  42            |INC EDX
0044C6B2  |.  48            |DEC EAX
0044C6B3  |.^ 75 EE         \JNZ SHORT CrackMe_.0044C6A3         ;  Bucle out
0044C6B5  |>  A1 84F84400   MOV EAX,DWORD PTR DS:[44F884]        ;  Eax = Compañia
0044C6BA  |.  E8 B573FBFF   CALL CrackMe_.00403A74
0044C6BF  |.  83F8 02       CMP EAX,2                            ;  Cmp lengh compañia con 2
0044C6C2  |.  7E 18         JLE SHORT CrackMe_.0044C6DC          ;  Salta si <= 2
0044C6C4  |.  A1 84F84400   MOV EAX,DWORD PTR DS:[44F884]        ;  Eax = Compañia
0044C6C9  |.  E8 A673FBFF   CALL CrackMe_.00403A74
0044C6CE  |.  83F8 08       CMP EAX,8                            ;  Cmp lengh compañia con 8
0044C6D1  |.  7D 09         JGE SHORT CrackMe_.0044C6DC          ;  Salta si >= 8
0044C6D3  |.  8B45 FC       MOV EAX,[LOCAL.1]                    ;  Eax = sum nombre
0044C6D6  |.  6BC0 02       IMUL EAX,EAX,2                       ;  Sum nombre * 2
0044C6D9  |.  8945 FC       MOV [LOCAL.1],EAX
0044C6DC  |>  68 98C74400   PUSH CrackMe_.0044C798               ;  ASCII "I Love Cracking and "
0044C6E1  |.  8D55 F8       LEA EDX,[LOCAL.2]
0044C6E4  |.  8B45 FC       MOV EAX,[LOCAL.1]
0044C6E7  |.  E8 68B0FBFF   CALL CrackMe_.00407754
0044C6EC  |.  FF75 F8       PUSH [LOCAL.2]                       ;  sum del nombre
0044C6EF  |.  68 B8C74400   PUSH CrackMe_.0044C7B8               ;  ASCII " Girls ;)"
0044C6F4  |.  B8 8CF84400   MOV EAX,CrackMe_.0044F88C
0044C6F9  |.  BA 03000000   MOV EDX,3
0044C6FE  |.  E8 3174FBFF   CALL CrackMe_.00403B34               ;  Concatena 1º frase + sum nombre + 2ºfrase
0044C703  |.  33C0          XOR EAX,EAX
0044C705  |.  8945 FC       MOV [LOCAL.1],EAX
0044C708  |.  A1 88F84400   MOV EAX,DWORD PTR DS:[44F888]        ;  Eax = Serial
0044C70D  |.  E8 6273FBFF   CALL CrackMe_.00403A74
0044C712  |.  8BD8          MOV EBX,EAX
0044C714  |.  A1 8CF84400   MOV EAX,DWORD PTR DS:[44F88C]
0044C719  |.  E8 5673FBFF   CALL CrackMe_.00403A74
0044C71E  |.  3BD8          CMP EBX,EAX                          ;  Compara tamaño frase con tamaño serial
0044C720  |.  75 4B         JNZ SHORT CrackMe_.0044C76D
0044C722  |.  A1 88F84400   MOV EAX,DWORD PTR DS:[44F888]
0044C727  |.  E8 4873FBFF   CALL CrackMe_.00403A74
0044C72C  |.  85C0          TEST EAX,EAX
0044C72E  |.  7E 27         JLE SHORT CrackMe_.0044C757
0044C730  |.  BA 01000000   MOV EDX,1
0044C735  |>  8B0D 88F84400 /MOV ECX,DWORD PTR DS:[44F888]	; Bucle in -->
0044C73B  |.  0FB64C11 FF   |MOVZX ECX,BYTE PTR DS:[ECX+EDX-1]
0044C740  |.  034D FC       |ADD ECX,[LOCAL.1]
0044C743  |.  8B1D 8CF84400 |MOV EBX,DWORD PTR DS:[44F88C]
0044C749  |.  0FB65C13 FF   |MOVZX EBX,BYTE PTR DS:[EBX+EDX-1]	; Compara dígito a dígito nuestro serial
0044C74E  |.  2BCB          |SUB ECX,EBX			; con la concatenación anterior
0044C750  |.  894D FC       |MOV [LOCAL.1],ECX
0044C753  |.  42            |INC EDX
0044C754  |.  48            |DEC EAX
0044C755  |.^ 75 DE         \JNZ SHORT CrackMe_.0044C735	; <-- Bucle out
0044C757  |>  837D FC 00    CMP [LOCAL.1],0
0044C75B  |.  75 10         JNZ SHORT CrackMe_.0044C76D		; Salta si algo ha ido mal
0044C75D  |.  8B86 14030000 MOV EAX,DWORD PTR DS:[ESI+314]
0044C763  |.  BA CCC74400   MOV EDX,CrackMe_.0044C7CC           ; "You have found the correct Serial :)"

En resumen

  • Tamaño del nombre entre 7 y 19.
  • Tamaño de la compañía entre 3 y 7 aunque no interviene en el serial.
  • Suma los valores ascii de los dígitos del nombre y lo multiplica por 2.
  • Concatena «I Love Cracking and » + «sum del nombre» + » Girls ;)».

Checkbox

Para afrontar esta parte del reto vamos a usar una herramienta llamada Interactive Delphi Reconstructor o IDR. En su día la mejor herramienta era DEDE, pero IDR a mi parecer es algo más potente.

Básicamente IDR nos permite sin quebraderos de cabeza localizar el código del botón que comprueba la secuencia de checkboxes correcta. Cargamos el crackme en IDR y dentro de la pestaña «Units (F2)«, abajo del todo hacemos doble click sobre «F Crack» y vemos que nos muestra todos los controles del formulario. El botón que nos interesa se llama «SpeedButton3«.

17-02-2016 13-21-14

Si hacemos doble click sobre el nos muestra el código que se muestra a continuación.

crack::TForm1.SpeedButton3Click
 0044C7F4    push       ebp
 0044C7F5    mov        ebp,esp
 0044C7F7    push       0
 0044C7F9    push       ebx
 0044C7FA    mov        ebx,eax
 0044C7FC    xor        eax,eax
 0044C7FE    push       ebp
 0044C7FF    push       44C920
 0044C804    push       dword ptr fs:[eax]
 0044C807    mov        dword ptr fs:[eax],esp
 0044C80A    mov        eax,dword ptr [ebx+324]; TForm1.cb3:TCheckBox
 0044C810    mov        edx,dword ptr [eax]
 0044C812    call       dword ptr [edx+0B8]; TCustomCheckBox.GetChecked
 0044C818    test       al,al
>0044C81A    je         0044C8ED
 0044C820    mov        eax,dword ptr [ebx+328]; TForm1.cb5:TCheckBox
 0044C826    mov        edx,dword ptr [eax]
 0044C828    call       dword ptr [edx+0B8]; TCustomCheckBox.GetChecked
 0044C82E    test       al,al
>0044C830    je         0044C8ED
 0044C836    mov        eax,dword ptr [ebx+32C]; TForm1.cb6:TCheckBox
 0044C83C    mov        edx,dword ptr [eax]
 0044C83E    call       dword ptr [edx+0B8]; TCustomCheckBox.GetChecked
 0044C844    test       al,al
>0044C846    je         0044C8ED
 0044C84C    mov        eax,dword ptr [ebx+358]; TForm1.cb12:TCheckBox
 0044C852    mov        edx,dword ptr [eax]
 0044C854    call       dword ptr [edx+0B8]; TCustomCheckBox.GetChecked
 0044C85A    test       al,al
>0044C85C    je         0044C8ED
 0044C862    mov        eax,dword ptr [ebx+364]; TForm1.cb15:TCheckBox
 0044C868    mov        edx,dword ptr [eax]
 0044C86A    call       dword ptr [edx+0B8]; TCustomCheckBox.GetChecked
 0044C870    test       al,al
>0044C872    je         0044C8ED
 0044C874    mov        eax,dword ptr [ebx+330]; TForm1.cb20:TCheckBox
 0044C87A    mov        edx,dword ptr [eax]
 0044C87C    call       dword ptr [edx+0B8]; TCustomCheckBox.GetChecked
 0044C882    test       al,al
>0044C884    je         0044C8ED
 0044C886    mov        eax,dword ptr [ebx+34C]; TForm1.cb9:TCheckBox
 0044C88C    mov        edx,dword ptr [eax]
 0044C88E    call       dword ptr [edx+0B8]; TCustomCheckBox.GetChecked
 0044C894    test       al,al
>0044C896    je         0044C8ED
 0044C898    mov        eax,dword ptr [ebx+354]; TForm1.cb11:TCheckBox
 0044C89E    mov        edx,dword ptr [eax]
 0044C8A0    call       dword ptr [edx+0B8]; TCustomCheckBox.GetChecked
 0044C8A6    test       al,al
>0044C8A8    je         0044C8ED
 0044C8AA    mov        eax,dword ptr [ebx+35C]; TForm1.cb13:TCheckBox
 0044C8B0    mov        edx,dword ptr [eax]
 0044C8B2    call       dword ptr [edx+0B8]; TCustomCheckBox.GetChecked
 0044C8B8    test       al,al
>0044C8BA    je         0044C8ED
 0044C8BC    mov        eax,dword ptr [ebx+33C]; TForm1.cb19:TCheckBox
 0044C8C2    mov        edx,dword ptr [eax]
 0044C8C4    call       dword ptr [edx+0B8]; TCustomCheckBox.GetChecked
 0044C8CA    test       al,al
>0044C8CC    je         0044C8ED
 0044C8CE    lea        eax,[ebp-4]
 0044C8D1    mov        edx,44C934; 'Ìõô¸ö÷ê¥ó¤ÉÚÀÆ²Äæââîàä¶¶'
 0044C8D6    call       @LStrLAsg
 0044C8DB    lea        eax,[ebp-4]
 0044C8DE    call       0044BF00
 0044C8E3    mov        eax,dword ptr [ebp-4]
 0044C8E6    call       ShowMessage
>0044C8EB    jmp        0044C90A
 0044C8ED    lea        eax,[ebp-4]
 0044C8F0    mov        edx,44C958; 'Åÿæò衦óàù¨ïêçð®øé¤íüàî诹'
 0044C8F5    call       @LStrLAsg
 0044C8FA    lea        eax,[ebp-4]
 0044C8FD    call       0044BF00
 0044C902    mov        eax,dword ptr [ebp-4]
 0044C905    call       ShowMessage
 0044C90A    xor        eax,eax
 0044C90C    pop        edx
 0044C90D    pop        ecx
 0044C90E    pop        ecx
 0044C90F    mov        dword ptr fs:[eax],edx
 0044C912    push       44C927
 0044C917    lea        eax,[ebp-4]
 0044C91A    call       @LStrClr
 0044C91F    ret
<0044C920    jmp        @HandleFinally
<0044C925    jmp        0044C917
 0044C927    pop        ebx
 0044C928    pop        ecx
 0044C929    pop        ebp
 0044C92A    ret

Como podéis apreciar, las checkboxes involucradas son la 3, 5, 6, 9, 11, 12, 13, 15, 19 y 20. Solo nos falta saber cuales se corresponden con esa numeración y aquí ya depende de cada uno, yo en su día saqué los números a mano mediante el orden de tabulación, pero ya que tenemos IDR, el nos va a dar la solución de una forma sencilla y rápida.

Vamos a la pestaña «Forms (F5)«, seleccionamos la opción Form y hacemos doble click sobre el formulario.

17-02-2016 13-29-34

Veréis que aparece el formulario con todos los recursos, incluso los puedes modificar. Localizar los checkboxes ahora es un juego de niños.

17-02-2016 13-30-15

Os dejo un vídeo.

Trackbar

De nuevo, con la ayuda de IDR, localizamos la parte del código y analizamos su funcionamiento. Esta parte es la más divertida ya que requiere de un keygen pero en vez de coger el número de serie de una caja de texto lo obtiene de 5 trackbars como muestra la siguiente imagen.

17-02-2016 12-47-06_trackbar

El código de comprobación es el siguiente.

CPU Disasm
Address   Hex dump          Command                                  Comments
0044C1FF  |.  E8 ECF6FCFF   CALL 0041B8F0                            ; b^3
0044C204  |.  D805 50C34400 FADD DWORD PTR DS:[44C350]               ; b^3+5
0044C20A  |.  D9FA          FSQRT                                    ; sqrt(b^3+5)
0044C20C  |.  E8 F365FBFF   CALL 00402804                            ; Cos(sqrt(b^3+5)) = U
0044C211  |.  DB7D B8       FSTP TBYTE PTR SS:[EBP-48]
0044C214  |.  9B            WAIT
0044C215  |.  D905 54C34400 FLD DWORD PTR DS:[44C354]                ; Coje a
0044C21B  |.  DC45 E8       FADD QWORD PTR SS:[EBP-18]               ; a+1
0044C21E  |.  D9FA          FSQRT                                    ; sqrt(a+1)
0044C220  |.  D9E0          FCHS                                     ; -sqrt(a+1) = V
0044C222  |.  DB6D B8       FLD TBYTE PTR SS:[EBP-48]
0044C225  |.  DEC1          FADDP ST(1),ST
0044C227  |.  DB7D AC       FSTP TBYTE PTR SS:[EBP-54]
0044C22A  |.  9B            WAIT
0044C22B  |.  D905 58C34400 FLD DWORD PTR DS:[44C358]                ; coje c
0044C231  |.  DC4D D8       FMUL QWORD PTR SS:[EBP-28]               ; c*3
0044C234  |.  D805 54C34400 FADD DWORD PTR DS:[44C354]               ; c*3+1
0044C23A  |.  D9ED          FLDLN2                                   ; Ln(c*3+1) = X
0044C23C  |.  D9C9          FXCH ST(1)
0044C23E  |.  D9F1          FYL2X
0044C240  |.  DB6D AC       FLD TBYTE PTR SS:[EBP-54]
0044C243  |.  DEC1          FADDP ST(1),ST                           ; U+V+X
0044C245  |.  DB7D A0       FSTP TBYTE PTR SS:[EBP-60]
0044C248  |.  9B            WAIT
0044C249  |.  D905 5CC34400 FLD DWORD PTR DS:[44C35C]                ; coje d
0044C24F  |.  DC45 D0       FADD QWORD PTR SS:[EBP-30]               ; d+2
0044C252  |.  D9FA          FSQRT                                    ; sqrt(d+2) = Y
0044C254  |.  DB6D A0       FLD TBYTE PTR SS:[EBP-60]
0044C257  |.  DEE1          FSUBRP ST(1),ST                          ; U+V+X+(-Y)
0044C259  |.  D905 58C34400 FLD DWORD PTR DS:[44C358]                ; coje e
0044C25F  |.  DC4D C8       FMUL QWORD PTR SS:[EBP-38]               ; e*3
0044C262  |.  D835 5CC34400 FDIV DWORD PTR DS:[44C35C]               ; (e*3)/2 = Z
0044C268  |.  DEC1          FADDP ST(1),ST                           ; U+V+X+Y+Z
0044C26A  |.  DB2D 60C34400 FLD TBYTE PTR DS:[44C360]
0044C270  |.  DEC1          FADDP ST(1),ST                           ; U+V+X+Y+Z+0.37
0044C272  |.  D80D 6CC34400 FMUL DWORD PTR DS:[44C36C]               ; (U+V+X+Y+Z+0.37)*1000
0044C278  |.  DD5D F0       FSTP QWORD PTR SS:[EBP-10]
0044C27B  |.  9B            WAIT
0044C27C  |.  DD45 F0       FLD QWORD PTR SS:[EBP-10]
0044C27F  |.  E8 9065FBFF   CALL 00402814                            ; Redondea((U+V+X+Y+Z+0,37)*1000)
0044C284  |.  8945 98       MOV DWORD PTR SS:[EBP-68],EAX
0044C287  |.  8955 9C       MOV DWORD PTR SS:[EBP-64],EDX
0044C28A  |.  DF6D 98       FILD QWORD PTR SS:[EBP-68]
0044C28D  |.  83C4 F4       ADD ESP,-0C
0044C290  |.  DB3C24        FSTP TBYTE PTR SS:[LOCAL.33]             
0044C293  |.  9B            WAIT                                     
0044C294  |.  8D45 FC       LEA EAX,[EBP-4]                          
0044C297  |.  E8 68BFFBFF   CALL 00408204                            
0044C29C  |.  8D45 FC       LEA EAX,[EBP-4]
0044C29F  |.  E8 5CFCFFFF   CALL 0044BF00                            ; Llamada de generación de hash
........
0044BF04  |.  8BF0          MOV ESI,EAX
0044BF06  |.  8B06          MOV EAX,DWORD PTR DS:[ESI]               ; EAX = 5415
0044BF08  |.  E8 677BFBFF   CALL 00403A74
0044BF0D  |.  8B15 98EE4400 MOV EDX,DWORD PTR DS:[44EE98]
0044BF13  |.  8902          MOV DWORD PTR DS:[EDX],EAX
0044BF15  |.  8B06          MOV EAX,DWORD PTR DS:[ESI]
0044BF17  |.  E8 587BFBFF   CALL 00403A74
0044BF1C  |.  84C0          TEST AL,AL
0044BF1E  |.  76 38         JBE SHORT 0044BF58
0044BF20  |.  880424        MOV BYTE PTR SS:[LOCAL.3],AL
0044BF23  |.  B3 01         MOV BL,1
0044BF25  |>  B8 1C000000   /MOV EAX,1C
0044BF2A  |.  E8 516AFBFF   |CALL 00402980
0044BF2F  |.  0D 80000000   |OR EAX,00000080
0044BF34  |.  8BFB          |MOV EDI,EBX
0044BF36  |.  81E7 FF000000 |AND EDI,000000FF
0044BF3C  |.  8B16          |MOV EDX,DWORD PTR DS:[ESI]
0044BF3E  |.  0FB6543A FF   |MOVZX EDX,BYTE PTR DS:[EDI+EDX-1]       ; Coje dig a dig el hash, en este caso 5415
0044BF43  |.  33C2          |XOR EAX,EDX                             ; 1 dig XOR 83; 2 dig XOR 89; 3 dig XOR 86; 4 dig XOR 8D
0044BF45  |.  50            |PUSH EAX
0044BF46  |.  8BC6          |MOV EAX,ESI
0044BF48  |.  E8 F77CFBFF   |CALL 00403C44                           
0044BF4D  |.  5A            |POP EDX
0044BF4E  |.  885438 FF     |MOV BYTE PTR DS:[EDI+EAX-1],DL
0044BF52  |.  43            |INC EBX
0044BF53  |.  FE0C24        |DEC BYTE PTR SS:[LOCAL.3]
0044BF56  |.^ 75 CD         \JNZ SHORT 0044BF25
........
0044C2AC  |.  E8 D378FBFF   CALL 00403B84                            ; Llamada a comparación
........
00403BAD  |> /8B0E          /MOV ECX,DWORD PTR DS:[ESI]              ; ECX = nuestro Serial XOReado
00403BAF  |. |8B1F          |MOV EBX,DWORD PTR DS:[EDI]              ; EBX = Serial bueno
00403BB1  |. |39D9          |CMP ECX,EBX                             ; Compara
00403BB3  |. |75 58         |JNE SHORT 00403C0D                      ; Chico malo
00403BB5  |. |4A            |DEC EDX
00403BB6  |. |74 15         |JZ SHORT 00403BCD
00403BB8  |. |8B4E 04       |MOV ECX,DWORD PTR DS:[ESI+4]
00403BBB  |. |8B5F 04       |MOV EBX,DWORD PTR DS:[EDI+4]
00403BBE  |. |39D9          |CMP ECX,EBX
00403BC0  |. |75 4B         |JNE SHORT 00403C0D
00403BC2  |. |83C6 08       |ADD ESI,8
00403BC5  |. |83C7 08       |ADD EDI,8
00403BC8  |. |4A            |DEC EDX
00403BC9  |.^\75 E2         \JNZ SHORT 00403BAD

En resumen

1) Siendo nuestro serial : 1 2 3 4 5
                           a b c d e
 
2) Realiza las operaciones matemáticas:
   Round(((Cos(sqrt(b^3+5)) + (-sqrt(a+1)) + Ln(c*3+1) + (-sqrt(d+2)) + ((e*3)/2))+0.37)*1000))
 
3) Obtenemos un hash resultante de 5415

4) XORea los dígitos de la siguiente manera:
   (5)35 xor 86 = B6
   (4)34 xor 83 = BD
   (1)31 xor 86 = B7
   (5)35 xor 8D = B8
 
 De modo que tenemos B6BDB7B8
 
5) Compara B6BDB7B8 con B5BAB2BA

6) Revertimos el XOR para obtener el hash bueno
   B5 xor 86 = 36(6)
   BA xor 83 = 33(3)
   B2 xor 86 = 34(4)
   BA xor 8D = 37(7)
 
 Luego el hash bueno es 6347
 
7) Debemos hacer fuerza bruta buscando: 
   Round(((Cos(sqrt(b^3+5)) + (-sqrt(a+1)) + Ln(c*3+1) + (-sqrt(d+2)) + ((e*3)/2))+0.37)*1000)) = 6347

Para obtener los seriales válidos podemos hacer bucles recursivos hasta recorrer las 10^5 opciones posibles. Una forma de hacerlo en VBNet es la siguiente.

Dim tmp As Double
Dim an, bn, cn, dn, en As Integer
        For an = 0 To 9
            For bn = 0 To 9
                For cn = 0 To 9
                    For dn = 0 To 9
                        For en = 0 To 9
                            tmp = Round(((Cos(Sqrt((Pow(bn, 3)) + 5)) + (-Sqrt(an + 1)) + Log(cn * 3 + 1) + (-Sqrt(dn + 2)) + ((en * 3) / 2) + 0.37) * 1000))
                            txtdebug.Text = "a-b-c-d-e = Hash || " & an & "-" & bn & "-" & cn & "-" & dn & "-" & en & " = " & tmp
                            If tmp = 6347 Then
                                ListBox1.Items.Add("Serial: " & an & bn & cn & dn & en)
                            End If
                            Application.DoEvents()
                        Next
                    Next
                Next
            Next
        Next

17-02-2016 10-29-59_brute

Os dejo como siempre el crackme y el keygen en los enlaces.

Links


Intro Extensión PPM Clave cifrada Un nuevo lenguaje de programación Enlaces Intro Hoy tenemos aquí un reto de esteganografía bastante
Se nos entrega un html con un juego que consiste en hacer clic en un botón tantas veces como podamos
Aviso: Este crackme forma parte de una serie de pruebas de Yoire.com que todavía está en activo. Lo ético si
Introducción Aquí tenemos un crackme hecho en Java, lo que como comprobareis a continuación no es muy buena idea ya

Se nos entrega un html con un juego que consiste en hacer clic en un botón tantas veces como podamos para ganar al juego. Acompañando al html tenemos un código javascript ofuscado aparentemente con Obfuscator.io

El código javascript ofuscado tiene el siguiente aspecto.

(function(_0x144932, _0xfc69c5) { var _0x187428 = _0x588c,
        _0x3064c6 = _0x144932(); while (!![]) { try { var _0xb96d19 = -parseInt(_0x187428(0x1bd)) / 0x1 + parseInt(_0x187428(0x137)) / 0x2 + -parseInt(_0x187428(0x140)) / 0x3 * (-parseInt(_0x187428(0x13b)) / 0x4) + parseInt(_0x187428(0x15e)) / 0x5 * (parseInt(_0x187428(0x18c)) / 0x6) + -parseInt(_0x187428(0x159)) / 0x7 * (parseInt(_0x187428(0x1c3)) / 0x8) + parseInt(_0x187428(0x129)) / 0x9 * (-parseInt(_0x187428(0x149)) / 0xa) + parseInt(_0x187428(0x16d)) / 0xb; if (_0xb96d19 === _0xfc69c5) break;
            else _0x3064c6['push'](_0x3064c6['shift']()); } catch (_0x377a04) { _0x3064c6['push'](_0x3064c6['shift']()); } } }(_0x5be3, 0x6fe59));;

function _0x5be3() { var _0x5a2048 = ['Utf8', 'push', 'createDecryptor', 'Malformed\x20UTF-8\x20data', '_ENC_XFORM_MODE', 'string', '_prevBlock', 'extend', '_doReset', 'AnsiX923', 'error', 'fromCharCode', 'object', '130340XnpiqM', '#res', 'HmacSHA256', 'DES', '4FuuDzS', 'finalize', 'byteLength', 'salt', '_keyPriorReset', '372669TnxSTf', '_xformMode', 'HMAC', 'stringify', 'Latin1', 'cfg', 'start', 'padding', 'show', '47650FNyFfQ', 'parse', 'TripleDES', 'MD5', 'ZeroPadding', 'length', 'Rabbit', 'console', 'Base', 'HmacSHA3', 'kdf', '_doFinalize', 'drop', 'BufferedBlockAlgorithm', 'Cipher', 'HmacSHA1', '7PKTjbP', 'CTR', '_reverseMap', 'clone', 'Encryptor', '43750GcrrDy', 'SHA384', 'byteOffset', 'indexOf', 'Word', '#loader', 'algo', 'apply', 'bind', 'HmacMD5', 'Base64', '_key', 'createEncryptor', 'min', '_counter', '4232173VijiOj', '_lBlock', 'You\x20Lose', 'ECB', 'BlockCipherMode', 'ciphertext', 'floor', 'constructor', 'log', 'search', 'flush', 'Iso10126', 'update', 'NoPadding', 'max', 'HmacSHA384', 'SHA512', 'decrypt', '_des2', '(((.+)+)+)+$', 'high', 'U2FsdGVkX189ylLOlgNSxq/TLeSxBr7cYDcRBgMXXS9VmwusKZx1XFDNdpkwg24v98iYGnUATwQVyWwFnlyoCg==', 'charAt', 'return\x20(function()\x20', 'pow', 'prototype', 'compute', 'reset', 'warn', '_rBlock', 'HmacSHA512', '498WcTnbi', 'join', 'HmacSHA224', 'display', '#trim', 'StreamCipher', 'enc', 'click', '#statistic', 'random', 'keySize', 'SHA1', '_process', 'sigBytes', '$super', '#mybut', 'clamp', 'RC4', '_invSubKeys', 'loader', '_cipher', '#backstart', 'BlockCipher', 'formatter', 'WordArray', 'slice', 'decryptBlock', '_minBufferSize', 'execute', '_iv', '_hash', 'mixIn', '__proto__', 'text', 'concat', 'RabbitLegacy', 'ceil', 'splice', 'Utf16LE', 'array[0]', 'function', 'SHA3', 'charCodeAt', 'EvpKDF', 'toString', 'css', '_state', 'Decryptor', 'Hex', '82275HVLogQ', 'ivSize', 'encrypt', '_des1', '_mode', 'words', '5353976ERfqhe', 'init', '_hasher', '_createHmacHelper', '_oKey', 'lib', 'CipherParams', 'x64', '_keySchedule', 'RC4Drop', 'PBKDF2', '__creator', '_subKeys', '_nDataBytes', '_DEC_XFORM_MODE', 'format', 'substr', '_createHelper', '_data', '_parse', '#cssfilter', '_map', 'create', 'OpenSSL', 'hasher', 'table', 'key', 'hide', 'iterations', '#timecount', 'undefined', 'pad', '_iKey', 'CBC', 'OFB', '#apply', 'SHA224', '_keystream', 'mode', 'exception', 'call', 'hasOwnProperty', 'Utf16', 'encryptBlock', '_invKeySchedule', '#buttons', '_doCryptBlock', 'RIPEMD160', 'blockSize', 'low', '_des3', '{}.constructor(\x22return\x20this\x22)(\x20)', '_nRounds', 'Hasher', 'addClass', 'AES', 'CFB', 'sqrt', '171bibExj'];
    _0x5be3 = function() { return _0x5a2048; }; return _0x5be3(); }
...

Deofuscado el código con la web Obfuscator.io llegamos a interpretar la estructura aunque sigue siendo un galimatías en gran parte. Aún así, si nos fijamos al final encontramos una parte interesante con una clave encriptada cuya desencriptación depende de una comparación (línea 13 resaltada). Invirtiendo esa comparación engañamos al código y obtenemos la flag.

    $("#mybut").click(function () {
      _0x4171cc++;
      $("#cssfilter").text(_0x4171cc);
    });
    $("#statistic").addClass("hide");
    _0x35a8b9 = setInterval(function () {
      _0x97292c--;
      $("#timecount").text(_0x97292c);
      if (_0x97292c == 0x0) {
        clearInterval(_0x35a8b9);
        $("#mybut").hide();
        $("#buttons").show(0x64);
        if (_0x4171cc > _0x43eef3) {
          $('#trim').text(CryptoJS.AES.decrypt("U2FsdGVkX189ylLOlgNSxq/TLeSxBr7cYDcRBgMXXS9VmwusKZx1XFDNdpkwg24v98iYGnUATwQVyWwFnlyoCg==", "array[0]").toString(CryptoJS.enc.Utf8));
        } else {
          $("#trim").text("You Lose");
        }
      }
    }, 0x3e8);
    intervalcomp = setInterval(function () {
      _0x43eef3++;
      $('#apply').text(_0x43eef3);
      if (_0x97292c == 0x0) {
        clearInterval(intervalcomp);
      }
    }, 0x32);
  }
});

Aviso: Este crackme forma parte de una serie de pruebas de Yoire.com que todavía está en activo. Lo ético si continuas leyendo este manual es que no utilices la respuesta para completar la prueba sin esfuerzo. 😉

Analizando…

Cargamos el crackme en Ollydbg y vamos a las «Referenced Strings«. Vemos una referencia muy interesante que se llama «checkkey«.

 Pinchamos sobre ella y aparecemos aquí:

Vemos una referencia a «GetDlgItemTextA» y depués un Call también interesante, vamos a explorarlo.

Entendiendo la rutina de comprobación del serial

 

Dentro del Call hay dos bucles, uno realiza una operación con nuestro serial (bucle nombre) y el otro comprueba nuestro serial con «3d34273130276a» dígito a dígito (bucle comprobación).

Bucle nombre se puede resumir así:

MOVSX EAX,BYTE PTR DS:[EBX]   --> Dígito a EAX
XOR EAX,55                    --> EAX xor 55
...
CMP BYTE PTR DS:[EBX],0       --> ¿hemos acabado?
JNZ SHORT 10001022            --> bucle
LEA ECX,DWORD PTR SS:[EBP-20] --> ECX = nuestro serial xoreado

Bucle comprobación se podría resumir así:

MOV EDX,10006000             --> EDX = "3d34273130276a"
...
MOV AL,BYTE PTR DS:[ECX]     --> AL = 1ºdígito serial xoreado
CMP AL,BYTE PTR DS:[ECX+EDX] --> AL = 1ºdígito de EDX?
JNZ SHORT 1000105A           --> Si no son iguales bad boy
INC ECX 

TEST AL,AL
JNZ SHORT 1000104A           --> bucle

Ejemplo para «deurus».

   Nombre: d  e  u  r  u  s
Ascii hex: 64 65 75 72 75 73 
   XOR 55: 31 30 20 27 20 26

Serial XOReado para deurus sería = 313020272026 que obviamente se aleja bastante de 3d34273130276a.
Por suerte XOR es una función reversible por lo que si revertimos 3d34273130276a nos dará el serial correcto.

Serial correcto XOReado: 3d 34 27 31 30 27 6a
XOR 55:                 
68 61 72 64 65 72 3F
Valor ascii:             h  a  r  d  e  r  ?

Links


Intro Hoy tenemos un crackme hecho en ensamblador y que cuenta con tres niveles. En el primero de todos nos
Warning: This challenge is still active and therefore should not be resolved using this information.  Aviso: Este reto sigue en
Intro Se suele decir que para cada problema hay una solución. Si esto lo llevamos al terreno stego podemos decir
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en

Introducción

Hoy vamos a enfrentarnos a cuatro retos de esteganografía relativamente sencillos, y digo relativamente, debido a que hay tantas formas de esconder información en un archivo, ya sea imagen, vídeo o sonido, que afrontarlos suele ser desesperante. Las cuatro imágenes son aparentemente las mismas que la que se ve en portada.

Una buena práctica cuando te enfrentas a retos stego de tipo imagen es realizar una búsqueda inversa. Una búsqueda inversa consiste en buscar la imagen original mediante buscadores especializados como TinEye o Google. Si conseguimos la imagen original podemos resolver el reto simplemente comparando o nos puede dar una idea del tipo de modificación por su diferencia de tamaño, colores, degradados, etc.

Stego 1

Descargamos la imagen del reto. Se trata de una imagen JPEG de 526×263 y 76.6 KB (78445 bytes). Su hash SHA1 es «89aed5bbc3542bf5c60c4c318fe99cb1489f267a«

Realizamos una búsqueda inversa de la imagen y encontramos sin dificultad la imagen original mediante TinEye.

18-06-2016 07-27-02

Características de la imagen original:

  • Resolución: 526×263
  • Tamaño: 78447 bytes (76.6 KB)
  • Hash SHA1: 8924676317077fc07c252ddeec04bd2a0ecfdda4

Por lo que vemos ha cambiado el tamaño de 78447 bytes a 78445 bytes y su hash SHA1 tampoco coincide obviamente, lo que nos confirma que ha sufrido alguna modificación. Echando un vistazo con un editor hexadecimal te puedes volver loco por lo que vamos a realizar una comparación mediante la herramienta online DiffNow.

18-06-2016 07-40-51

Al realizar la comparación sale a relucir lo que buscamos. La clave es una simple cadena de texto.

Stego 2

Lo primero es realizar de nuevo la comparación.

ImagenTamañoSHA1
Original78447 bytes8924676317077fc07c252ddeec04bd2a0ecfdda4
imagen2.jpeg116386 bytes7641e3906f795c137269cefef29f30fcb9cb1b07

Como vemos, la imagen ha aumentado significativamente, de 76,6 KB a 113 KB. Cuando el aumento de tamaño llama la atención normalmente tenemos otro archivo insertado. Lo primero que suelo hacer yo es fijarme si ha sido modificado el final del archivo con un editor hexadecimal. Los bytes de cola de un archivo jpg/jpeg son FFD9 y en este caso no vemos modificación alguna al final del archivo. Si el archivo no está al final requiere realizar una búsqueda más exhaustiva. Para estos casos tengo una herramienta de creación propia que se llama Ancillary y que sirve para buscar cierto tipo de archivos dentro de otros como imágenes, documentos de Office, Open Office, pdf, etc. Ancillary encuentra otro jpg que es el que le daba el peso extra y que vemos a continuación. La clave es el título de la película (ojo a las mayúsculas/minúsculas).

image2_thumb

Stego 3

El tercer reto parece que tiene algún error debido a que el archivo coincide completamente con el original. Pienso que se ha subido la imagen original por error. Se lo he comunicado al admin del dominio y si algún día obtengo respuesta actualizaré la entrada.

ImagenTamañoSHA1
Original78447 bytes8924676317077fc07c252ddeec04bd2a0ecfdda4
imagen3.jpeg78447 bytes8924676317077fc07c252ddeec04bd2a0ecfdda4

Actualización 21/08/2016

Al parecer, la solución de este reto es llegar a la conclusión de que la imagen no está modificada. La respuesta del Administrador de la web así lo confirma.

desingsecurity [at] gmail [dot] com – Sorry about the delay, is precisely what is intended with that challenge, they can determine if the image is changed or not , the challenge was solved you . We’ll be equal way improving this point.

Greetings and Thanks

Stego 4

Lo primero es realizar de nuevo la comparación.

ImagenTamañoSHA1
Original78447 bytes8924676317077fc07c252ddeec04bd2a0ecfdda4
imagen4.jpeg93174 bytesa6329ea4562ef997e5afd067f3b53bdab4665851

Al igual que en el caso dos el tamaño ha aumentado significativamente de modo que miramos al final del archivo y esta vez si vemos que hay insertado unos bytes tras el final del jpg (recordemos FFD9)

18-06-2016 07-10-40

El archivo tiene pinta de ser una hoja de cálculo de Open Office o Libre Office según indica la palabra «spreadsheet«. Lo abrimos con Excel y tras analizar la maraña de datos enseguida vemos una clave que llama la atención.

  • Challengeland (El dominio ya no existe) [Archive]

Herramientas utilizadas

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....

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

En los retos de esteganografía ya uno se espera de todo, y cuantos más haces más enrevesados encuentras. Hoy no, hoy vamos a tratar un clásico dentro de este tipo de retos, ocultar un archivo dentro de otro.

Buscando la solución

Prácticamente lo primero que hago cuando me descargo una imágen en éste tipo de retos es abrirla con un editor hexadecimal, y en este caso hemos dado en el clavo. La abrimos con un editor cualquiera y al final del archivo encontramos que estamos tratando con un archivo ZIP (cabecera PK).

29-08-2014 03-00-03

La abrimos con 7zip y vemos el prometido archivo txt, dentro ¿qué abrá?

29-08-2014-03-02-19

Links

Intro

Hace poco me reencontré con esta entrañable serie que tanto me entretuvo cuando era pequeño y para mi sorpresa, me percaté de que nunca había visto el episodio piloto. La nostalgia me llevó a tragarme el episodio entero y a disfrutar a lo grande de la parafernalia técnica de la que hace gala para justificar la creación que da nombre a la serie.

La visión tecnológica de los años 80

Esto hay que analizarlo con perspectiva. Estamos en los años 80 y nos están presentando un coche capaz de mantener una conversación, es decir, nos están presentando una inteligencia artificial (IA) llamada KITT. Puede parecer que el término inteligencia artificial es nuevo pero realmente se acuño en 1956 por John McCarthy. A partir de ese momento surgieron líneas de estudio e hipótesis pero a partir de los 70 se puede considerar que la investigación sobre la IA perdió financiación y quedó en el congelador hasta los años 90. Dicho esto, cuando nos presentan a KITT lo hacen de la siguiente manera:

Devon Miles: Está totalmente controlado por microprocesadores que hacen físicamente imposible que se vea implicado en ningún tipo de colisión o percance a no ser que se lo ordene su piloto específicamente

Michael Knight: ¿Piloto?, no me diga que esta cosa vuela

Devon Miles: ¡No!, pero piensa

Michael Knight: ¿Piensa?, ¿mi coche piensa?

Intel daba a conocer el primer microprocesador allá por el 71 y la serie se estrenó en el 82 lo que le da credibilidad en ese aspecto, aunque dudo que el público de esa época supiera que era un microprocesador, un ordenador y menos una IA.

Los Chips

La serie arranca con un grupo de personas realizando espionaje industrial donde nos muestran las hojas de datos de dos chips Japoneses como son el PD8257-5 y el PD780. Un aplauso para los guionistas y sus asesores ya que el PD8257-5 es una interfaz de comunicaciones y el PD780 un microprocesador de 8 bits.

Detalle del esquema del chip PD8257-5 y del set de instrucciones del chip PD780

Lo más interesante es que lo que se muestra es real como podéis apreciar en la siguiente imagen

Detalle del esquema mostrado en la serie VS la hoja de datos

A continuación un detalle de las capturas realizadas:

Más adelante vuelven a aparecer imágenes en un PC que parecen puestas en post-producción y que son robadas en un maravilloso disco de 5 1/4.

Los diálogos

Llaman la atención mucho los diálogos centrados en el microprocesador como si de un ser superior se tratase, éste es la referencia continua y la parte central del guion de los dos primeros capítulos. Curiosamente aparecen en pantalla multitud de imágenes de circuitos integrados pero no se llega a ver ningún microprocesador. Por otro lado, es interesante el esfuerzo que hacen los guionistas por que llamemos a KITT él en vez de ello, convirtiendo al coche en un personaje más.

Otra cosa que llama mucho la atención son los tópicos de los que hace gala como la asociación de los microprocesadores a los videojuegos o que la empresa villana esté afincada en Silicon Valley. Incluso el nombre KITT es un tópico ya que las siglas vienen de Knight Industries Two Thousand que en cristiano quiere decir Industrias Knight 2000. Y es que en mi opinión el año 2000 se imaginaba como una barrera lejana en la que todo iba a ser tecnológicamente más avanzado.

Conclusiones

Tengo que reconocer que me ha sorprendido que dieran realismo a los chips mostrados teniendo en cuenta que aparecen muy pocos segundos en pantalla y podían haber puesto cualquier cosa.

Por otro lado, la realidad es que en el año 2022 aún nos queda recorrido para llegar a tener un coche fantástico y lo más parecido que tenemos hoy día sería un Tesla con Alexa.

Enlaces de interés