Introducción

Hoy tenemos aquí un crackme de los que te hacen temblar las conexiones neuronales. Estamos acostumbrados al típico serial asociado a un nombre y a veces nos sorprenden.

El crackme data del año 2000, está realizado por aLoNg3x y lo tenéis colgado en crackmes.de. En crackmes.de también disponéis de una solución muy elegante realizada por cronos, pero que no acaba de saciar nuestro afán de descubrir todas las soluciones posibles.

El algoritmo

Abrimos el crackme con Olly y enseguida encontramos la rutina de comprobación junto con los mensajes de éxito y error. Os dejo la rutina comentada como siempre.

004012D7   |.  83C4 08             ADD ESP,8                                 ;  
004012DA   |.  09C0                OR EAX,EAX                                ;  
004012DC   |. /74 16               JE SHORT Zebrone.004012F4                 ;  Salta a Bad boy
004012DE   |. |6A 00               PUSH 0                                    ; /Style = MB_OK|MB_APPLMODAL
004012E0   |. |68 26324000         PUSH Zebrone.00403226                     ; |Title = "Great !!!"
004012E5   |. |68 30324000         PUSH Zebrone.00403230                     ; |Text = "Congratulations, you have cracked the Zebra Crackme ver 1.1"
004012EA   |. |FF75 08             PUSH [ARG.1]                              ; |hOwner = 0011067C ('Zebra - aLoNg3x - 1.1 Version',class='#32770')
004012ED   |. |E8 C6010000         CALL <JMP.&USER32.MessageBoxA>            ; \MessageBoxA
004012F2   |. |EB 14               JMP SHORT Zebrone.00401308
004012F4   |> \6A 00               PUSH 0                                    ; /Style = MB_OK|MB_APPLMODAL
004012F6   |.  68 F8314000         PUSH Zebrone.004031F8                     ; |Title = "Hmmmm :P"
004012FB   |.  68 01324000         PUSH Zebrone.00403201                     ; |Text = "Sorry... The Serial isn't correct :Þ"
00401300   |.  FF75 08             PUSH [ARG.1]                              ; |hOwner = 0011067C ('Zebra - aLoNg3x - 1.1 Version',class='#32770')
00401303   |.  E8 B0010000         CALL <JMP.&USER32.MessageBoxA>            ; \MessageBoxA
00401308   |>  31C0                XOR EAX,EAX
0040130A   |.  40                  INC EAX
0040130B   |.  EB 39               JMP SHORT Zebrone.00401346
0040130D   |>  6A 00               PUSH 0                                    ; /Result = 0
0040130F   |.  FF75 08             PUSH [ARG.1]                              ; |hWnd = 0011067C ('Zebra - aLoNg3x - 1.1 Version',class='#32770')
00401312   |.  E8 89010000         CALL <JMP.&USER32.EndDialog>              ; \EndDialog
00401317   |.  31C0                XOR EAX,EAX
00401319   |.  40                  INC EAX
0040131A   |.  EB 2A               JMP SHORT Zebrone.00401346
0040131C   |>  6A 00               PUSH 0                                    ; /Style = MB_OK|MB_APPLMODAL
0040131E   |.  68 40304000         PUSH Zebrone.00403040                     ; |Title = "Zebra ver. 1.1"
00401323   |.  68 4F304000         PUSH Zebrone.0040304F                     ; |Text = "This is the 1.1 Zebra Crackme, Thanks to Quequero and Koma, to have said me a bug of the previous version. (It was due to an orrible cpu appoximation). As usually you cannot patch this .EXE, you've to find one of the many correct solut"...
00401328   |.  FF75 08             PUSH [ARG.1]                              ; |hOwner = 0011067C ('Zebra - aLoNg3x - 1.1 Version',class='#32770')
0040132B   |.  E8 88010000         CALL <JMP.&USER32.MessageBoxA>            ; \MessageBoxA
00401330   |.  31C0                XOR EAX,EAX
00401332   |.  40                  INC EAX
00401333   |.  EB 11               JMP SHORT Zebrone.00401346
00401335   |>  6A 00               PUSH 0                                    ; /Result = 0
00401337   |.  FF75 08             PUSH [ARG.1]                              ; |hWnd = 0011067C ('Zebra - aLoNg3x - 1.1 Version',class='#32770')
0040133A   |.  E8 61010000         CALL <JMP.&USER32.EndDialog>              ; \EndDialog
0040133F   |.  31C0                XOR EAX,EAX
00401341   |.  40                  INC EAX
00401342   |.  EB 02               JMP SHORT Zebrone.00401346
00401344   |>  31C0                XOR EAX,EAX
00401346   |>  C9                  LEAVE
00401347   \.  C2 1000             RETN 10
================================================================
0040134A   /$  55                  PUSH EBP
0040134B   |.  89E5                MOV EBP,ESP
0040134D   |.  83EC 68             SUB ESP,68
00401350   |.  FF75 08             PUSH [ARG.1]                              ; /x1
00401353   |.  E8 78010000         CALL <JMP.&CRTDLL.atof>                   ; \atof
00401358   |.  DD55 E8             FST QWORD PTR SS:[EBP-18]
0040135B   |.  83EC 08             SUB ESP,8
0040135E   |.  DD1C24              FSTP QWORD PTR SS:[ESP]
00401361   |.  E8 82010000         CALL <JMP.&CRTDLL.floor>
00401366   |.  DD5D F8             FSTP QWORD PTR SS:[EBP-8]
00401369   |.  FF75 0C             PUSH [ARG.2]                              ; /x2
0040136C   |.  E8 5F010000         CALL <JMP.&CRTDLL.atof>                   ; \atof
00401371   |.  DD55 D8             FST QWORD PTR SS:[EBP-28]
00401374   |.  83EC 08             SUB ESP,8
00401377   |.  DD1C24              FSTP QWORD PTR SS:[ESP]
0040137A   |.  E8 69010000         CALL <JMP.&CRTDLL.floor>
0040137F   |.  83C4 18             ADD ESP,18
00401382   |.  DD55 F0             FST QWORD PTR SS:[EBP-10]
00401385   |.  DC4D F8             FMUL QWORD PTR SS:[EBP-8]
00401388   |.  D9EE                FLDZ
0040138A   |.  DED9                FCOMPP                                    ;  floor(x1)*floor(x2)=0 ???
0040138C   |.  DFE0                FSTSW AX                                  ;  <<Store status word
0040138E   |.  9E                  SAHF                                      ;  <<Store AH into FLAGS
0040138F   |.  75 07               JNZ SHORT Zebrone.00401398                ;  Si salta todo OK
00401391   |.  31C0                XOR EAX,EAX
00401393   |.  E9 96000000         JMP Zebrone.0040142E                      ;  Bad boy
00401398   |>  DD45 F8             FLD QWORD PTR SS:[EBP-8]                  ;  <<Floating point load
0040139B   |.  DC5D F0             FCOMP QWORD PTR SS:[EBP-10]               ;  x1 = x2 ???
0040139E   |.  DFE0                FSTSW AX                                  ;  <<Store status word
004013A0   |.  9E                  SAHF                                      ;  <<Store AH into FLAGS
004013A1   |.  75 07               JNZ SHORT Zebrone.004013AA                ;  Si salta todo OK
004013A3   |.  31C0                XOR EAX,EAX
004013A5   |.  E9 84000000         JMP Zebrone.0040142E                      ;  Bad boy
004013AA   |>  DD45 F8             FLD QWORD PTR SS:[EBP-8]                  ;  <<Floating point load
004013AD   |.  DD5D C8             FSTP QWORD PTR SS:[EBP-38]
004013B0   |.  D9E8                FLD1                                      ;  Carga 1 en el stack
004013B2   |.  DD55 C0             FST QWORD PTR SS:[EBP-40]                 ;  <<Floating point store
004013B5   |.  DC5D C8             FCOMP QWORD PTR SS:[EBP-38]               ;  x1 > 1 ???
004013B8   |.  DFE0                FSTSW AX                                  ;  <<Store status word
004013BA   |.  9E                  SAHF                                      ;  <<Store AH into FLAGS
004013BB   |.  77 2D               JA SHORT Zebrone.004013EA                 ;  Si salta bad boy
004013BD   |.  DF2D 38304000       FILD QWORD PTR DS:[403038]                ;  <<Load integer>> 2540BE400 = 10^10
004013C3   |.  DD55 B8             FST QWORD PTR SS:[EBP-48]                 ;  <<Floating point store
004013C6   |.  DC5D C8             FCOMP QWORD PTR SS:[EBP-38]               ;  x1 < 10^10 ???
004013C9   |.  DFE0                FSTSW AX                                  ;  <<Store status word
004013CB   |.  9E                  SAHF                                      ;  <<Store AH into FLAGS
004013CC   |.  72 1C               JB SHORT Zebrone.004013EA                 ;  Si salta bad boy
004013CE   |.  DD45 F0             FLD QWORD PTR SS:[EBP-10]                 ;  <<Floating point load
004013D1   |.  DD5D B0             FSTP QWORD PTR SS:[EBP-50]                ;  <<Store and pop
004013D4   |.  DD45 C0             FLD QWORD PTR SS:[EBP-40]                 ;  <<Floating point load
004013D7   |.  DC5D B0             FCOMP QWORD PTR SS:[EBP-50]               ;  x2 > 1 ???
004013DA   |.  DFE0                FSTSW AX                                  ;  <<Store status word
004013DC   |.  9E                  SAHF                                      ;  <<Store AH into FLAGS
004013DD   |.  77 0B               JA SHORT Zebrone.004013EA                 ;  Si salta bad boy
004013DF   |.  DD45 B8             FLD QWORD PTR SS:[EBP-48]                 ;  <<Floating point load>> carga 10^10
004013E2   |.  DC5D B0             FCOMP QWORD PTR SS:[EBP-50]               ;  x2 < 10^10 ???
004013E5   |.  DFE0                FSTSW AX                                  ;  <<Store status word
004013E7   |.  9E                  SAHF                                      ;  <<Store AH into FLAGS
004013E8   |.  73 04               JNB SHORT Zebrone.004013EE                ;  Salta si menor
004013EA   |>  31C0                XOR EAX,EAX
004013EC   |.  EB 40               JMP SHORT Zebrone.0040142E                ;  Bad boy
004013EE   |>  DD45 F8             FLD QWORD PTR SS:[EBP-8]                  ;  <<Floating point load>> carga x1
004013F1   |.  D9FE                FSIN                                      ;  Sin(x1)
004013F3   |.  DD5D A8             FSTP QWORD PTR SS:[EBP-58]                ;  <<Store and pop
004013F6   |.  DD45 F0             FLD QWORD PTR SS:[EBP-10]                 ;  <<Floating point load>> carga x2
004013F9   |.  D9FE                FSIN                                      ;  Sin(x2)
004013FB   |.  DD5D A0             FSTP QWORD PTR SS:[EBP-60]                ;  <<Store and pop
004013FE   |.  DD45 A8             FLD QWORD PTR SS:[EBP-58]                 ;  <<Floating point load
00401401   |.  DC4D A0             FMUL QWORD PTR SS:[EBP-60]                ;  Sin(x1) * Sin(x2)
00401404   |.  DF2D 30304000       FILD QWORD PTR DS:[403030]                ;  <<Load integer>> 2386F26FC10000 = 10^16
0040140A   |.  DEC9                FMULP ST(1),ST                            ;  10^16 * (Sin(x1) * Sin(x2))
0040140C   |.  83EC 08             SUB ESP,8
0040140F   |.  DD1C24              FSTP QWORD PTR SS:[ESP]                   ;  <<Store and pop
00401412   |.  E8 D1000000         CALL <JMP.&CRTDLL.floor>
00401417   |.  83C4 08             ADD ESP,8
0040141A   |.  DD5D 98             FSTP QWORD PTR SS:[EBP-68]
0040141D   |.  D9EE                FLDZ                                      ;  <<Load 0.0 onto stack
0040141F   |.  DC5D 98             FCOMP QWORD PTR SS:[EBP-68]               ;  10^16 * (Sin(x1) * Sin(x2)) = 0 ???
00401422   |.  DFE0                FSTSW AX
00401424   |.  9E                  SAHF                                      ;  <<Store AH into FLAGS
00401425   |.  75 05               JNZ SHORT Zebrone.0040142C                ;  Si NO salta todo OK
00401427   |.  31C0                XOR EAX,EAX
00401429   |.  40                  INC EAX
0040142A   |.  EB 02               JMP SHORT Zebrone.0040142E
0040142C   |>  31C0                XOR EAX,EAX
0040142E   |>  C9                  LEAVE
0040142F   \.  C3                  RETN

La primera dificultad que podemos encontrar es que utiliza instrucciones FPU y coma flotante, ya que si no tenemos la vista entrenada nos puede resultar un engorro. Superado esto, la rutina de comprobación se puede resumir así:

  • x1 * x2 != 0
  • x1 != x2
  • x1 > 1 y < 10^10
  • x2 > 1 y < 10^10
  • Floor[10^16 * sin(x1) * sin(x2)] = 0

A priori no parece que tenga mucha dificultad, pero vamos a analizarlo más concienzudamente. Necesitamos que la parte entera del resultado de la multiplicación sea 0, algo que parece sencillo, pero fíjate que la constante 10^16 nos obliga a su vez, a que el resultado del seno sea muy pequeño, cosa que como comprobaréis limita mucho los resultados satisfactorios.

Repasando trigonometría

Cuando nos enseñó nuestro profesor la función del seno nos hizo el siguiente dibujo:

circunferencia_e

Partiendo de la circunferencia unitaria, podemos concluir que el seno de alpha es igual a la altura x. Como lo que nos interesa a nosotros es que el seno sea muy pequeño, en realidad estamos buscando que la x sea lo más pequeña posible. Llegamos entonces a la conclusión de que las soluciones para enteros entre 1 y 10^10 van a ser muy reducidas. Además nos percatamos que el ángulo alpha va a tener que estar muy proximo a 0º – 360 (0 – 2π) y a 180º (π). En el siguiente gráfico queda claro el estrecho margen en el que nos movemos.

circunferencia_angulos_e

Si habéis leído la solución de cronos ahora le encontraréis algo más de sentido a por que él utilizó fracciones continuas de π y cogió como resultado los numeradores más cercanos a 10^10, en su caso 245850922 y 411557987.

Análisis operacional

Vamos a analizar un ejemplo operacional.

sin( x rad)
sin(245850922) = 6,1180653830011163142712109862972e-9
sin(411557987) = 2,536716051963676479648989773448e-9

sin(245850922)*sin(411557987) = 1,5519794664022230015882605365808e-17

10^16 * 1,5519794664022230015882605365808e-17 = 0,15519794664022230015882605365808

Floor(0,15519794664022230015882605365808) = 0

Como veis, el exponente negativo (^-17) debe ser mayor que el positivo (^16) para tener éxito.

Fuerza bruta

Lo que vamos a hacer a continuación es buscar todos los senos con exponente negativo ^-8 ó ^-9 de enteros entre 1 y 10^10, y vamos a cruzar los resultados para determinar todos los resultados válidos.

Preparamos el programa y le dejamos trabajar. En principio vamos a filtrar todos los resultados que tengan exponente negativo y luego ya aislaremos los que nos interesan. Esto lo hago por curiosidad.

aprox

La fuerza bruta nos arroja 63663 resultados con exponente negativo entre ^-5 y ^-9, de los cuales solamente nos quedamos con 65, que son los comprendidos a exponentes de entre ^-8 y ^-9. Los números mágicos son los siguientes:

magicnumbers

Los rojos son exponentes ^-9, el resto ^-8.

La mayoría de estos números solo valen con ciertas combinaciones, de hecho, ninguno vale para todos. Esto se debe, a parte del propio exponente, a que hay senos positivos y negativos y para hacer válido a un seno negativo hay que combinarlo con otro negativo. Esto último se debe únicamente a la interpretación que hace el crackme.

 Finalmente cruzamos los resultados y obtenemos 44 combinaciones de seriales válidos que si obviamos repeticiones se reducen a la mitad.

 checker

Combinaciones válidas:

seriales

Conclusiones

Podemos concluir que para cada 10^10 enteros hay 22 soluciones posibles. Finalmente comentar que si aLoNg3x no hubiera puesto el límite en 10^10, habría soluciones infinitas.

Links


http://youtu.be/b9-GdmIQINQ Lista de reproducción
Introducción Hoy tenemos aquí un crackme hecho en Visual Basic 6 (pcode), pero lo vamos a abordar de una manera
Intro Análisis Keygen Links Intro El crackme que analizamos hoy está hecho en ensamblador y si bien su dificultad es
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en

Introducción

Hoy tenemos aquí un crackme hecho en Visual Basic 6 (pcode), pero lo vamos a abordar de una manera diferente, ya que, vamos a conseguir el código fuente mediante VB Decompiler, le vamos a hacer una serie de modificaciones para hacerlo funcional con la ayuda de ExDec, y a partir de eso vamos a generar nuestro propio keygen.

El funcionamiento del crackme es simple, tenemos una primera caja de texto «Code» que en función de lo que introduzcamos nos activa el botón «OK». Al pulsar el botón comprueba lo que tengamos en la caja de texto «Serial» para haber si está todo correcto.

Obteniendo el código fuente

Abrimos el crackme con VB Decompiler y vemos sus fauces.

29-08-2014 20-30-08

Pinchando en cada parte obtenemos su respectivo código fuente.

El botón OK

Private Sub Command1_Click() '402F70
  'Data Table: 402724
  Dim ourserial As Variant
   ourserial = CVar(Me.SERIAL.Text) 'String
   If (ourserial = cript(Left$(Me.CODE.Text, &HA))) Then
     MsgBox "Great", 0, ourserial
     End
   End If
   Dim x As String
   x = cript(Left$(Me.CODE.Text, &HA))
   MsgBox "Not Completed - " & x, 0, ourserial
   Me.CODE.Text = ""
   Me.SERIAL.Text = ""
   Exit Sub
End Sub

El evento KeyUp

Private Sub CODE_KeyUp(KeyCode As Integer, Shift As Integer)
  'Data Table: 402724
   If (Len(Me.CODE.Text) > 4) Then
     ourserialsum = checkcode(Me.CODE.Text)
     If CBool((ourserialsum > 70) And (ourserialsum < 90)) Then
       Me.Command1.Enabled = True
     End If
   End If
   Exit Sub
End Sub

La función cript

Public Function cript(a) 
  'Data Table: 402724
  Dim var_9C As Long
   var_98 = CStr(UCase(a))
   For var_10C = 1 To CVar(Len(var_98)): var_CC = var_10C 'Variant
     var_9C = CLng((CVar(var_9C) + (CVar((Asc(Mid$(var_98, CLng(var_CC), 1)) - 9) Xor &H58) + var_CC) ^ 2))
   Next var_10C 'Variant
  For var_160 = 1 To 100: var_140 = var_160 
     If (Mid$(CVar(Me.CODE.Text), CLng(var_140), 1) = vbNullString) Then
      GoTo loc_4030C0
     End If
   Next var_160 
loc_4030C0:
   var_9C = CLng(((CVar(var_9C) * Int((var_140 / 2))) * 16))
   var_94 = Hex(var_9C) 'Variant
   cript = var_94
End Function

La función checkcode

Public Function checkcode(a) 
   For var_F4 = 1 To CVar(Len(a)): var_A4 = var_F4
     var_128 = var_128 + (CVar(Asc(Mid$(a, CLng(var_A4), 1))))
   Next var_F4
   var_94 = Int(((var_128 / CVar(Len(a) / CVar(Len(a)))))
   checkcode = var_94
End Function

La rutina de comprobación del serial

Se compone de dos partes, el código y el serial.

El código

Si el resultado de la función checkcode está entre 70 y 90 nos activa el botón OK.

El serial

Lo genera la función cript en función del código anterior.

Arreglando el código fuente

Con lo obtenido anteriormente podemos entender perfectamente el comportamiento de la comprobación del serial pero si los cargamos en Visual Basic 6 y lo intentamos ejecutar tal cual nos dará una serie de errores. Es aquí cuando entra ExDec, ya que, nos proporciona el desensamblado del programa en forma de Opcode para poder comparar con el código obtenido.

29-08-2014 22-49-22

En este caso el único problema se encuentra en la función checkcode en concreto en ésta línea:

var_94 = Int(((var_128 / CVar(Len(a) / CVar(Len(a)))))

El problema está en que divide dos veces entre el número de dígitos de a, si lo analizamos vemos que es imposible ya que nunca nos daría un código entre 70 y 90. La corrección queda así:

var_94 = Int(((var_128 / CVar(Len(a)))))

El KeyGen

Finalmente el código fuente de nuestro keygen quedaría así:

Private Sub Command1_Click() 'Generate CODE
  Dim CODE As String
  Dim var As Integer
  Randomize
  var = CLng((0 - 9999) * Rnd + 9999)
  Me.CODE.Text = "deurus" & var
  codesum = checkcode(Me.CODE.Text)
  If CBool((codesum > 70) And (codesum < 90)) Then
       lbl.Caption = "Code valid, now generate a serial"
       Command2.Enabled = True
  Else
       Command2.Enabled = False
       Command1_Click
  End If
End Sub

Private Sub Command2_Click() 'Generate SERIAL
   If (Len(Me.CODE.Text) > 4) Then
     codesum = checkcode(Me.CODE.Text)
     If CBool((codesum > 70) And (codesum < 90)) Then
       SERIAL.Text = cript(Left$(Me.CODE.Text, 10))
       Else
       lbl.Caption = "Code not valid, first gen code"
     End If
   End If
End Sub

Private Sub CODE_KeyUp(KeyCode As Integer, Shift As Integer)
   If (Len(Me.CODE.Text) > 4) Then
     var_B0 = checkcode(Me.CODE.Text)
     lbl.Caption = "Value must be between 70 - 90. Yours: " & var_B0
     If CBool((var_B0 > 70) And (var_B0 < 90)) Then
       lbl.Caption = "Code valid, now generate a serial"
       Command2.Enabled = True
       Else
       Command2.Enabled = False
     End If
   End If
   Exit Sub
End Sub

Public Function cript(a)
  Dim var_9C As Long
   var_98 = CStr(UCase(a))
   For var_10C = 1 To CVar(Len(var_98)): var_CC = var_10C
     var_9C = CLng((CVar(var_9C) + (CVar((Asc(Mid$(var_98, CLng(var_CC), 1)) - 9) Xor &H58) + var_CC) ^ 2))
   Next var_10C
  For var_160 = 1 To 100: var_140 = var_160
     If (Mid$(CVar(Me.CODE.Text), CLng(var_140), 1) = vbNullString) Then
      GoTo loc_4030C0
     End If
   Next var_160
loc_4030C0:
   var_9C = CLng(((CVar(var_9C) * Int((var_140 / 2))) * 16))
   var_94 = Hex(var_9C)
   cript = var_94
End Function

Public Function checkcode(a)
   For var_F4 = 1 To CVar(Len(a)): var_A4 = var_F4
   'Suma el valor ascii de todos los caracteres / Add the ascii value of our code
     var_128 = var_128 + (CVar(Asc(Mid$(a, CLng(var_A4), 1))))
   Next var_F4
   'Lo divide entre la longitud del code / Divide our codesum by code lenght
   var_94 = Int(((var_128 / CVar(Len(a))))) 'corrección
   checkcode = var_94
End Function

29-08-2014 20-28-53

En crackmes.de podéis conseguir el crackme y el keygen.

Links


http://youtu.be/KR3PgtDMjmg Lista de reproducción
Introducción Esta es la tercera y última entrega de los crackmes de Cruehead. En esta ocasión nos enfrentamos a un
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en
En esta ocasión vamos a hablar de una película de culto de los años 90, Hackers - Piratas Informáticos. La

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


Introducción Activar un botón en memoria Activar el botón de forma permanente Serial Hardcodeado Links Introducción Este crackme pertenece a
Hoy analizamos Copycat, un thriller psicológico de 1995 que, como muchas películas de la época, no pudo resistirse a incorporar
Intro Análisis Keygen Links Intro El crackme que analizamos hoy está hecho en ensamblador y si bien su dificultad es
Introducción Esta vez se trata de un crackme realizado en VC++ 5.0/6.0 y en sus entrañas utiliza RSA-24. En este

Intro

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

Tarea#1 – Anti-Debugger

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

00408328     /0F84 69030000         je T0RNAD0'.00408697

 Tarea#2 – Parche

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

01

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

Tarea#3 – Encontrando el camino

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

04-10-2014 0-13-39

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

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

04-10-2014 0-27-49

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

03-10-2014 12-41-51

Tarea#4 – El keygen

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

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

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

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

Ejemplos:

Nombre: abcdefghijklmnopqrstuvwxyz1234

Serial: L-30-lmnopq-DD19F9CA

Nombre: deurus2014

Serial: L-10-eurus2-84D8F9CA

 Links


Con The Ring inauguro una nueva sección llamada Blooper Tech Movie (BTM), algo así como pifias o tomas falsas tecnológicas
AVISO: Debido a que este reto está en activo no publicaré a donde pertenece. En este pequeño CrackMe se nos
Hemos interceptado un mensaje secreto, pero ninguno de nuestros traductores lo sabe interpretar, ¿sabrías interpretarlo tú? Lo único que hemos
Intro Hoy vamos a hacer algo diferente, vamos a hacer un keygen con la propia víctima. El término anglosajón para

Introducción

Este es un crackme de la web de Karpoff programado por Sotanez y realizado en Delphi. Como máximo nos deja meter nombres de 10 dígitos.

El algoritmo

Es un algoritmo muy sencillo pero veremos que nos tendremos que fijar en el DUMP de Olly para saber que demonios hace. Como de costumbre abrimos Olly y en las «Referenced Strings» localizamos la palabra «Registrado«, pinchamos en ella y localizamos la porción de código que nos interesa. Vamos a analizarla.

bucles

Vemos 3 bucles, el primero pone la memoria (Dump) a cero, el segundo guarda nuestro nombre (errata en la imagen) en el Dump y el tercero realiza la suma de los valores ascii del nombre. Hasta aquí todo bien, pero vamos a hacer una prueba para el nombre deurus.

  • Nombre: deurus
  • Serial: 64+65+75+72+75+73 = 298 (664 en decimal)

Probamos el serial en el programa y nos da error, vale, vamos a analizar más a fondo los bucles.

El primer bucle hemos dicho que pone la memoria a 0, en concreto desde «45BC60» y de 4 en 4 (fíjate en el Add 4), es decir, pone a 0 los offsets 45BC60, 45BC64, 45BC68, 45BC6C, 45BC70, 45BC74, 45BC78, 45BC7C, 45BC80, 45BC84, ya que el bucle se repite 10 veces. En la imágen queda claro.

 pasado1bucle2

El segundo bucle se repite 11 veces y lo que hace es guardar en el dump el valor ascii de las letras de nuestro nombre. En la imagen lo vemos.

pasado2bucle

A primera vista ya vemos un valor extraño en la posición 45BC80, y es que cuando debiera haber un 0, hay un 12. Vamos a ver como afecta esto al serial final.

El tercer bucle se repite 10 veces y lo que hace es sumar los valores que haya en el DUMP en las posiciones anteriormente citadas.

pasado3bucle

En concreto suma 64+65+75+72+75+73+0+0+12+0 = 2AA (682 en decimal). Probamos 682 como serial y funciona. Realizando más pruebas vemos que para nombres con un tamaño inferior a 5 letras se ocupan las posiciones 45BC70 y 45BC80 con valores extraños, el resto de posiciones se mantienen a 0. En las imágenes inferiores se pueden apreciar más claramente los valores extraños.

Nombre de tamaño < 5.

dump1letra

Nombre de tamaño >5 y <9

05-09-2014 00-06-19

Nombre de tamaño = 10

 04-09-2014 16-37-31

En resumen:

Nombre de tamaño < 5 –> Ascii SUM + 14h
Nombre de tamaño >5 y <9 –> Ascii SUM + 12h
Nombre de tamaño =10 –> Ascii SUM

Con esto ya tenemos todo lo que necesitamos para nuestro keygen.

char Nombre[11];
GetWindowText(hwndEdit1, Nombre, 11);
char Serial[20];
int len = strlen(Nombre);
int suma = 0;
for(int i = 0; i <= len; i = i + 1)
{
   suma += Nombre[i];
}
if(len < 5){
   suma +=0x14;
}
if(len > 5 && len < 9){
   suma +=0x12;
}
wsprintf(Serial,"%d",suma);
SetWindowText(hwndEdit2, TEXT(Serial));

Links


Con The Ring inauguro una nueva sección llamada Blooper Tech Movie (BTM), algo así como pifias o tomas falsas tecnológicas
Libros Hacker Épico La apacible existencia de Ángel Ríos da un vuelco cuando una antigua compañera de clase, de la
Introducción  Hoy vamos a ver como extraer el script de un ejecutable compilado por Autoit, modificarlo y recompilarlo como nuestro
Primeras impresiones El crackme es el típico de usuario y número de serie. Si no introduces un nombre te salta

Con The Ring inauguro una nueva sección llamada Blooper Tech Movie (BTM), algo así como pifias o tomas falsas tecnológicas en películas. Aunque no os lo creáis, los creadores del séptimo arte y sus asesores son humanos, y como tal se rigen por la ley del mínimo esfuerzo. En este BTM vamos a ver como una simple escena nos puede arruinar la excelente atmósfera de intriga que hasta ese momento se respiraba.

BTM

Transcurridos 70 minutos de película vemos que la protagonista está en una redacción buscando información sobre la maldita cinta de vídeo en un PC.

vlcsnap-2015-11-22-01h10m04s660

Hasta aquí todo correcto, pero instantes después vemos que realiza una búsqueda sobre «Moesko Islands» y cuando se abre el plano y podemos ver la barra de direcciones, en realidad vemos un archivo local situado en «C:\WIN98\Desktop\search.com\2_moesko_island_pt2.html«. A continuación la secuencia, se pueden ver los enlaces «locales» en el segundo 13 y 17.

vlcsnap-2015-11-22-01h10m52s727

Imagen 1 – «C:\WIN98\Desktop\search.com\2_moesko_island_pt2.html»

vlcsnap-2015-11-22-01h11m25s822

Imagen 2 – «C:\WIN98\Desktop\search.com\restoration.html»

Teniendo en cuenta que la película data del año 2002, me parece increíble que los productores no se lo curraran un poco más y registraran un dominio como «jdoesearch.com» y simularan que se realizan las búsquedas ONline y no OFFline como se están haciendo en realidad.

Quizá no tenían pensado mostrar la parte superior del navegador o simplemente pensaron que nadie se fijaría pero el caso es que para cualquiera que haya navegado por Internet más de 2 veces, si se fija en la barra de direcciones su expresión facial cambia a WTF!.

ring_sello

Enlaces


Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en
Un error que habitualmente cometo cuando me enfrento a todo tipo de retos (especialmente en CTFs) es empezar a procesar
Introducción Continuamos con la segunda entrega de Cruehead. En este caso nos encontramos con un único campo de contraseña para
Toda esta aventura comienza con un archivo llamado pretty_raw, sin extensión. Porque sí. Porque las extensiones son una invención heredada

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

Un error que habitualmente cometo cuando me enfrento a todo tipo de retos (especialmente en CTFs) es empezar a procesar el fichero proporcionado con todo tipo de herramientas como pollo sin cabeza. En el caso que nos ocupa se proporcionaba un fichero de audio WAV que procesé hasta con 4 herramientas diferentes antes de tomar aire y decidir simplemente escuchar el audio. Al escucharlo me di cuenta de que se trataba de una marcación por tonos comúnmente conocido como DTMF (Dual-Tone Multi-Frequency).

Decodificar DTMF

Con una rápida búsqueda por la web encontré una sencilla herramienta realizada en python llamada dtmf-decoder con la que enseguida obtenemos resultados. La herramienta es bastante sencilla, simplemente parte la señal en trozos, calcula la FFT (Fast Fourier Transform) para obtener las amplitudes y las compara con las de los tonos DTMF. Hay que tener en cuenta que el audio entregado es muy limpio y eso facilita mucho las cosas.

El siguiente comando nos devuelve los números marcados.

Como era de esperar, los números obtenidos no son la solución final aunque en este caso enseguida damos con que el tipo de codificación es simple y llanamente ASCII.

DTMF = 837283123119104521169510048951214811795119521101166363125
HEX  = 53 48 53 7B 77 68 34 74 5F 64 30 5F 79 30 75 5F 77 34 6E 74 3F 3F 7D
Solución: SHS{wh4t_d0_y0u_w4nt??}

Introducción

Continuamos con la segunda entrega de Cruehead. En este caso nos encontramos con un único campo de contraseña para introducir.

El algoritmo

Abrimos con Olly y vemos dos saltos. El primer Call realiza una serie de operaciones con el serial introducido y el segundo comprueba si el serial es correcto.

01

A continuación llegamos aquí:

00401365     /$  C605 18214000 00         MOV BYTE PTR DS:[402118],0
0040136C     |.  8B7424 04                MOV ESI,DWORD PTR SS:[ESP+4]
00401370     |.  56                       PUSH ESI
00401371     |>  8A06                     /MOV AL,BYTE PTR DS:[ESI]      ; <---
00401373     |.  84C0                     |TEST AL,AL
00401375     |.  74 19                    |JE SHORT CRACKME2.00401390
00401377     |.  FE05 18214000            |INC BYTE PTR DS:[402118]
0040137D     |.  3C 41                    |CMP AL,41                     ; 41 = A
0040137F     |.  72 04                    |JB SHORT CRACKME2.00401385    ; ya es mayúscula
00401381     |.  3C 5A                    |CMP AL,5A                     ; 5A = Z
00401383     |.  73 03                    |JNB SHORT CRACKME2.00401388   ; Convertir a mayúscula
00401385     |>  46                       |INC ESI
00401386     |.^ EB E9                    |JMP SHORT CRACKME2.00401371   ; Bucle -->
00401388     |>  E8 25000000              |CALL CRACKME2.004013B2
0040138D     |.  46                       |INC ESI
0040138E     |.^ EB E1                    \JMP SHORT CRACKME2.00401371
00401390     |>  5E                       POP ESI
00401391     |.  E8 03000000              CALL CRACKME2.00401399         ;Convertido a mayúsculas continuamos
00401396     |.  EB 00                    JMP SHORT CRACKME2.00401398
00401398     \>  C3                       RETN

Si nuestro serial contiene solo letras, las convierte a mayúsculas y seguimos aquí. En resumen hace XOR byte a byte entre nuestro serial y la frase «Messing_in_bytes»

00401399     /$  33DB                     XOR EBX,EBX
0040139B     |.  33FF                     XOR EDI,EDI
0040139D     |>  8A8F A3214000            /MOV CL,BYTE PTR DS:[EDI+4021A3]  ; Carga el primer byte de 4021A3
004013A3     |.  8A1E                     |MOV BL,BYTE PTR DS:[ESI]         ;
004013A5     |.  84DB                     |TEST BL,BL
004013A7     |.  74 08                    |JE SHORT CRACKME2.004013B1
004013A9     |.  32D9                     |XOR BL,CL                        ; byteSerial XOR Byte"Messing_in..."
004013AB     |.  881E                     |MOV BYTE PTR DS:[ESI],BL
004013AD     |.  46                       |INC ESI                          ;Siguiente byte de "Messing_in_bytes"
004013AE     |.  47                       |INC EDI                          ;Siguiente byte del serial
004013AF     |.^ EB EC                    \JMP SHORT CRACKME2.0040139D
004013B1     \>  C3                       RETN                              ;XOR finalizado volvemos

Estado del DUMP (memoria) antes del XOR y con nuestro serial (12345678) cargado.

00402118  00 47 6F 6F 64 20 77 6F 72 6B 21 00 47 72 65 61  .Good work!.Grea
00402128  74 20 77 6F 72 6B 2C 20 6D 61 74 65 21 0D 4E 6F  t work, mate!.No
00402138  77 20 74 72 79 20 74 68 65 20 6E 65 78 74 20 43  w try the next C
00402148  72 61 63 6B 4D 65 21 00 1F 2C 37 36 3B 3D 28 19  rackMe!.,76;=(
00402158  3D 26 1A 31 2D 3B 37 3E 4E 6F 20 6C 75 63 6B 21  =&1-;7>No luck!
00402168  00 4E 6F 20 6C 75 63 6B 20 74 68 65 72 65 2C 20  .No luck there,
00402178  6D 61 74 65 21 00 31 32 33 34 35 36 37 38 39 00  mate!.123456789.
00402188  00 00 00 00 00 00 00 00 00 00 54 72 79 20 74 6F  ..........Try to
00402198  20 63 72 61 63 6B 20 6D 65 21 00 4D 65 73 73 69   crack me!.Messi
004021A8  6E 67 5F 69 6E 5F 62 79 74 65 73 00 00 00 00 00  ng_in_bytes.....

Estado del DUMP después del XOR.

00402118  0A 47 6F 6F 64 20 77 6F 72 6B 21 00 47 72 65 61  .Good work!.Grea
00402128  74 20 77 6F 72 6B 2C 20 6D 61 74 65 21 0D 4E 6F  t work, mate!.No
00402138  77 20 74 72 79 20 74 68 65 20 6E 65 78 74 20 43  w try the next C
00402148  72 61 63 6B 4D 65 21 00 1F 2C 37 36 3B 3D 28 19  rackMe!.,76;=(
00402158  3D 26 1A 31 2D 3B 37 3E 4E 6F 20 6C 75 63 6B 21  =&1-;7>No luck!
00402168  00 4E 6F 20 6C 75 63 6B 20 74 68 65 72 65 2C 20  .No luck there,
00402178  6D 61 74 65 21 00 7C 57 40 47 5C 58 50 67 50 5E  mate!.|W@G\XPgP^
00402188  00 00 00 00 00 00 00 00 00 00 54 72 79 20 74 6F  ..........Try to
00402198  20 63 72 61 63 6B 20 6D 65 21 00 4D 65 73 73 69   crack me!.Messi
004021A8  6E 67 5F 69 6E 5F 62 79 74 65 73                 ng_in_bytes

A continuación comprueba nuestro serial XOReado con los bytes en memoria.

004013B8     /$  33FF                     XOR EDI,EDI
004013BA     |.  33C9                     XOR ECX,ECX
004013BC     |.  8A0D 18214000            MOV CL,BYTE PTR DS:[402118]                                
004013C2     |.  8B7424 04                MOV ESI,DWORD PTR SS:[ESP+4]                    ; APUNTA AL DUMP 40217E
004013C6     |.  BF 50214000              MOV EDI,CRACKME2.00402150                       ; APUNTA AL DUMP 402150
004013CB     |.  F3:A6                    REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]   ; VER NOTA**
004013CD     \.  C3                       RETN

Nota**

Si buscamos el comando REPE encontramos que si el flag Z = 1 el bucle se corta y que trabaja con bytes. El problema es que en Olly la instrucción REPE nosotros la vemos con un solo paso y nos puede pasar desapercibida.
En resumen, está comprobando los bytes de las direcciones 402150 (1F 2C 37 36 3B 3D 28 19 3D 26 1A 31 2D 3B 37 3E) con nuestro serial XOReado, 40217E en adelante, por lo que si hacemos XOR entre los bytes de 402150 y la frase «Messing_in_bytes» obtendremos la clave correcta.

M  e  s  s  i  n  g  _  i  n  _  b  y  t  e  s
4D 65 73 73 69 6E 67 5F 69 6E 5F 62 79 74 65 73
                                                XOR
1F 2C 37 36 3B 3D 28 19 3D 26 1A 31 2D 3B 37 3E
-----------------------------------------------
52 49 44 45 52 53 4F 46 54 48 45 53 54 4F 52 4D
R  I  D  E  R  S  O  F  T  H  E  S  T  O  R  M

Serial: RIDERSOFTHESTORM

Links


Introducción Recién rescatados del inframundo que es mi disco duro, os traigo un paquete de seis crackmes facilones para vuestro
Intro President’s cat was kidnapped by separatists. A suspect carrying a USB key has been arrested. Berthier, once again, up
Si te interesa el mundo del hacking, ya sea como aficionado o como profesional, seguramente querrás estar al día de
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en

Introducción

Recién rescatados del inframundo que es mi disco duro, os traigo un paquete de seis crackmes facilones para vuestro uso y disfrute. Desgraciadamente ya no está en activo la web de retos de donde los saqué así que os los dejo en descargas.

Los cuatro primero están realizados en Dev-C++ 4.9.9.2 siendo de estilo consola de comandos. Los dos restantes compilados con MingWin32 GCC 3.x carecen de GUI y vamos, que no se han esmerado mucho en darles forma.

Level 1

No cuesta mucho dar con el código interesante mediante las referencias de texto. En Ollydbg clic derecho sobre el código y Search for > All referenced text strings.

004012E1   |.  8845 E8         MOV BYTE PTR SS:[EBP-18],AL                                    ; ||||
004012E4   |.  C70424 11304000 MOV DWORD PTR SS:[ESP],level1.00403011                         ; ||||ASCII "Input Serial: "
004012EB   |.  E8 C0050000     CALL <JMP.&msvcrt.printf>                                      ; |||\printf
004012F0   |.  8D45 C8         LEA EAX,[LOCAL.14]                                             ; |||
004012F3   |.  894424 04       MOV DWORD PTR SS:[ESP+4],EAX                                   ; |||
004012F7   |.  C70424 20304000 MOV DWORD PTR SS:[ESP],level1.00403020                         ; |||ASCII "%s"
004012FE   |.  E8 9D050000     CALL <JMP.&msvcrt.scanf>                                       ; ||\scanf
00401303   |.  8D45 D8         LEA EAX,[LOCAL.10]                                             ; ||
00401306   |.  8D55 C8         LEA EDX,[LOCAL.14]                                             ; ||
00401309   |.  894424 04       MOV DWORD PTR SS:[ESP+4],EAX                                   ; ||
0040130D   |.  891424          MOV DWORD PTR SS:[ESP],EDX                                     ; ||level1.00403022
00401310   |.  E8 7B050000     CALL <JMP.&msvcrt.strcmp>                                      ; |\strcmp
00401315   |.  8945 C4         MOV [LOCAL.15],EAX                                             ; |
00401318   |.  837D C4 00      CMP [LOCAL.15],0                                               ; |
0040131C   |.  75 0E           JNZ SHORT level1.0040132C                                      ; |
0040131E   |.  C70424 23304000 MOV DWORD PTR SS:[ESP],level1.00403023                         ; |ASCII "Well done. \n"
00401325   |.  E8 86050000     CALL <JMP.&msvcrt.printf>                                      ; \printf
0040132A   |.  EB 0C           JMP SHORT level1.00401338
0040132C   |>  C70424 30304000 MOV DWORD PTR SS:[ESP],level1.00403030                         ; |ASCII "Wrong. \n"
00401333   |.  E8 78050000     CALL <JMP.&msvcrt.printf>                                      ; \printf
00401338   |>  C70424 39304000 MOV DWORD PTR SS:[ESP],level1.00403039                         ; |ASCII "PAUSE"
0040133F   |.  E8 3C050000     CALL <JMP.&msvcrt.system>                                      ; \system
00401344   |.  B8 00000000     MOV EAX,0
00401349   |.  C9              LEAVE
0040134A   \.  C3              RETN

La madre del cordero está en la dirección 401310 que es donde se lleva a cabo la función de comparación strcmp.

756296A0 msvcrt.strcmp     8B5424 04         MOV EDX,DWORD PTR SS:[ESP+4]
756296A4                   8B4C24 08         MOV ECX,DWORD PTR SS:[ESP+8] 
756296A8                   F7C2 03000000     TEST EDX,3				; 0-3 = 4 bucles. Divide la comprobación en 4 bloques
756296AE                   75 3C             JNZ SHORT msvcrt.756296EC		; salta si hemos terminado los 4 bucles
756296B0                 > 8B02              MOV EAX,DWORD PTR DS:[EDX]		; coge 4 caracteres del serial (INICIO BUCLE)
756296B2                   3A01              CMP AL,BYTE PTR DS:[ECX]		; compara el 1º/5º/9º/13º dígito en función del bucle
756296B4                   75 2E             JNZ SHORT msvcrt.756296E4		; salto a zona mala
756296B6                   0AC0              OR AL,AL
756296B8                   74 26             JE SHORT msvcrt.756296E0
756296BA                   3A61 01           CMP AH,BYTE PTR DS:[ECX+1]		; compara el 2º/6º/10º/14º dígito en función del bucle
756296BD                   75 25             JNZ SHORT msvcrt.756296E4		; salto a zona mala
756296BF                   0AE4              OR AH,AH
756296C1                   74 1D             JE SHORT msvcrt.756296E0
756296C3                   C1E8 10           SHR EAX,10
756296C6                   3A41 02           CMP AL,BYTE PTR DS:[ECX+2]		; compara el 3º/7º/11º/15º dígito en función del bucle
756296C9                   75 19             JNZ SHORT msvcrt.756296E4		; salto a zona mala
756296CB                   0AC0              OR AL,AL
756296CD                   74 11             JE SHORT msvcrt.756296E0
756296CF                   3A61 03           CMP AH,BYTE PTR DS:[ECX+3]		; compara el 4º/8º/12º/16º dígito en función del bucle
756296D2                   75 10             JNZ SHORT msvcrt.756296E4		; salto a zona mala
756296D4                   83C1 04           ADD ECX,4
756296D7                   83C2 04           ADD EDX,4
756296DA                   0AE4              OR AH,AH
756296DC                 ^ 75 D2             JNZ SHORT msvcrt.756296B0		; Si no hemos terminado... 
756296DE                   8BFF              MOV EDI,EDI                         
756296E0                   33C0              XOR EAX,EAX			; EAX = 0 que es lo deseado
756296E2                   C3                RETN				; salimos de la función superando la comprobación
756296E3                   90                NOP							
756296E4                   1BC0              SBB EAX,EAX			; Zona mala
756296E6                   D1E0              SHL EAX,1
756296E8                   83C0 01           ADD EAX,1				; EAX = 1 implica bad boy
756296EB                   C3                RETN				; salimos de la función

Si atendemos al volcado vemos el serial bueno Kcgcv8LsmV3nizfJ.

0060FEF0  31 32 33 34 35 36 37 38 39 30 00 75 40 19 18 00  1234567890.u@.
0060FF00  4B 63 67 63 76 38 4C 73 6D 56 33 6E 69 7A 66 4A  Kcgcv8LsmV3nizfJ

Curiosamente, si introducimos el serial bueno el crackme no lo acepta. Fijándome en la comprobación veo que al introducir un serial de 16 caracteres inserta un carácter nulo (0x00) alterando el serial correcto y falseando la comprobación.

0060FEF0  4B 63 67 63 76 38 4C 73 6D 56 33 6E 69 7A 66 4A  Kcgcv8LsmV3nizfJ
0060FF00  00 63 67 63 76 38 4C 73 6D 56 33 6E 69 7A 66 4A  .cgcv8LsmV3nizfJ

Ahora ya no podemos comprobarlo pero recuerdo que la web consideraba válido el serial Kcgcv8LsmV3nizfJ, por lo que considero lo anteriormente citado un bug o un intento de despiste del autor.

Level 2

Es exactamente igual que el anterior cambiando el serial por 6LPw3vDYja9KrT2V.

Level 3

La comprobación del serial es igual a las dos anteriores pero añade una función intermedia que suma 0xD a cada carácter de nuestro serial

00401355                 |.  A1 03304000     MOV EAX,DWORD PTR DS:[403003]                  ; ||
0040135A                 |.  8945 E8         MOV [LOCAL.6],EAX                              ; ||
0040135D                 |.  A1 07304000     MOV EAX,DWORD PTR DS:[403007]                  ; ||
00401362                 |.  8945 EC         MOV [LOCAL.5],EAX                              ; ||
00401365                 |.  A1 0B304000     MOV EAX,DWORD PTR DS:[40300B]                  ; ||
0040136A                 |.  8945 F0         MOV [LOCAL.4],EAX                              ; ||
0040136D                 |.  A1 0F304000     MOV EAX,DWORD PTR DS:[40300F]                  ; ||
00401372                 |.  8945 F4         MOV [LOCAL.3],EAX                              ; ||
00401375                 |.  C70424 13304000 MOV DWORD PTR SS:[ESP],level3.00403013         ; ||ASCII "Input Serial: "
0040137C                 |.  E8 CF050000     CALL <JMP.&msvcrt.printf>                      ; |\printf
00401381                 |.  8D45 D8         LEA EAX,[LOCAL.10]                             ; |
00401384                 |.  894424 04       MOV DWORD PTR SS:[ESP+4],EAX                   ; |
00401388                 |.  C70424 00304000 MOV DWORD PTR SS:[ESP],level3.00403000         ; |ASCII "%s"
0040138F                 |.  E8 AC050000     CALL <JMP.&msvcrt.scanf>                       ; \scanf
00401394                 |.  8D5D E8         LEA EBX,[LOCAL.6]
00401397                 |.  8D45 D8         LEA EAX,[LOCAL.10]
0040139A                 |.  890424          MOV DWORD PTR SS:[ESP],EAX
0040139D                 |.  E8 EEFEFFFF     CALL level3.00401290			    ; NUEVA FUNCIÓN SUMA
004013A2                 |.  895C24 04       MOV DWORD PTR SS:[ESP+4],EBX                   ; ||
004013A6                 |.  890424          MOV DWORD PTR SS:[ESP],EAX                     ; ||
004013A9                 |.  E8 82050000     CALL <JMP.&msvcrt.strcmp>                      ; |\strcmp
004013AE                 |.  8945 D4         MOV [LOCAL.11],EAX                             ; |
004013B1                 |.  837D D4 00      CMP [LOCAL.11],0                               ; |
004013B5                 |.  75 0E           JNZ SHORT level3.004013C5                      ; |
004013B7                 |.  C70424 22304000 MOV DWORD PTR SS:[ESP],level3.00403022         ; |ASCII "Well done."
004013BE                 |.  E8 8D050000     CALL <JMP.&msvcrt.printf>                      ; \printf
004013C3                 |.  EB 0C           JMP SHORT level3.004013D1
004013C5                 |>  C70424 2D304000 MOV DWORD PTR SS:[ESP],level3.0040302D         ; |ASCII "Wrong. \n"
004013CC                 |.  E8 7F050000     CALL <JMP.&msvcrt.printf>                      ; \printf
004013D1                 |>  C70424 36304000 MOV DWORD PTR SS:[ESP],level3.00403036         ; |ASCII "PAUSE"
004013D8                 |.  E8 43050000     CALL <JMP.&msvcrt.system>                      ; \system
004013DD                 |.  B8 00000000     MOV EAX,0
004013E2                 |.  8B5D FC         MOV EBX,[LOCAL.1]                              
004013E5                 |.  C9              LEAVE
004013E6                 \.  C3              RETN
--------
004012A4                 |> /8B45 08         /MOV EAX,[ARG.1]                               ; |
004012A7                 |. |890424          |MOV DWORD PTR SS:[ESP],EAX                    ; |
004012AA                 |. |E8 B1060000     |CALL <JMP.&msvcrt.strlen>                     ; \strlen
004012AF                 |. |3945 FC         |CMP [LOCAL.1],EAX
004012B2                 |. |73 1C           |JNB SHORT level3.004012D0
004012B4                 |. |8B45 08         |MOV EAX,[ARG.1]
004012B7                 |. |8B55 FC         |MOV EDX,[LOCAL.1]
004012BA                 |. |01C2            |ADD EDX,EAX
004012BC                 |. |8B45 08         |MOV EAX,[ARG.1]
004012BF                 |. |0345 FC         |ADD EAX,[LOCAL.1]
004012C2                 |. |0FB600          |MOVZX EAX,BYTE PTR DS:[EAX]
004012C5                 |. |04 0D           |ADD AL,0D					    ; char + 0xD
004012C7                 |. |8802            |MOV BYTE PTR DS:[EDX],AL
004012C9                 |. |8D45 FC         |LEA EAX,[LOCAL.1]
004012CC                 |. |FF00            |INC DWORD PTR DS:[EAX]
004012CE                 |.^\EB D4           \JMP SHORT level3.004012A4
--------
756296A0 msvcrt.strcmp     8B5424 04         MOV EDX,DWORD PTR SS:[ESP+4]
756296A4                   8B4C24 08         MOV ECX,DWORD PTR SS:[ESP+8]
756296A8                   F7C2 03000000     TEST EDX,3
756296AE                   75 3C             JNZ SHORT msvcrt.756296EC
756296B0                   8B02              MOV EAX,DWORD PTR DS:[EDX]
756296B2                   3A01              CMP AL,BYTE PTR DS:[ECX]
756296B4                   75 2E             JNZ SHORT msvcrt.756296E4
756296B6                   0AC0              OR AL,AL
756296B8                   74 26             JE SHORT msvcrt.756296E0
756296BA                   3A61 01           CMP AH,BYTE PTR DS:[ECX+1]
756296BD                   75 25             JNZ SHORT msvcrt.756296E4
756296BF                   0AE4              OR AH,AH
756296C1                   74 1D             JE SHORT msvcrt.756296E0
756296C3                   C1E8 10           SHR EAX,10
756296C6                   3A41 02           CMP AL,BYTE PTR DS:[ECX+2]
756296C9                   75 19             JNZ SHORT msvcrt.756296E4
756296CB                   0AC0              OR AL,AL
756296CD                   74 11             JE SHORT msvcrt.756296E0
756296CF                   3A61 03           CMP AH,BYTE PTR DS:[ECX+3]
756296D2                   75 10             JNZ SHORT msvcrt.756296E4
756296D4                   83C1 04           ADD ECX,4
756296D7                   83C2 04           ADD EDX,4
756296DA                   0AE4              OR AH,AH
756296DC                 ^ 75 D2             JNZ SHORT msvcrt.756296B0
756296DE                   8BFF              MOV EDI,EDI
756296E0                   33C0              XOR EAX,EAX
756296E2                   C3                RETN
756296E3                   90                NOP
756296E4                   1BC0              SBB EAX,EAX
756296E6                   D1E0              SHL EAX,1
756296E8                   83C0 01           ADD EAX,1
756296EB                   C3                RETN

En la comparación vemos que el serial bueno es AvrQQsXjDk25Jrh por lo que si restamos 0xD (13 en decimal) a cada carácter obtendremos el serial bueno.

0060FF10  41 76 72 51 51 73 58 6A 44 6B 32 35 4A 72 68 00  AvrQQsXjDk25Jrh.

		  41 76 72 51 51 73 58 6A 44 6B 32 35 4A 72 68
	                                                      - D
		  34 69 65 44 44 66 4B 5D 37 5E 25 28 3D 65 5B
		  4  i  e  D  D  f  K  ]  7  ^  %  (  =  e  [
		  
		  Serial bueno: 4ieDDfK]7^%(=e[

Level 4

La comprobación del serial es igual que la anterior pero sustituyendo la función que sumaba un valor a cada dígito del serial por una que genera un hash con nuestro serial y después lo compara con otro hash almacenado en memoria. Si no nos viene a la mente el tipo de hash que puede ser PEiD ya nos avisaba de que efectivamente el crackme incorpora la función MD5.

La función MD5 hace tiempo que no se considera segura debido a la existencia de numerosos «diccionarios» de hashes que hacen que encontremos la solución en segundos. Yo he utilizado la web MD5 online pero existen muchas más.

0060FE5C   004013BF  RETURN to level4.004013BF from <JMP.&msvcrt.strcmp>
0060FE60   0060FEA0  ASCII "e807f1fcf82d132f9bb018ca6738a19f"
0060FE64   0060FEE0  ASCII "fe01d67a002dfa0f3ac084298142eccd"


e807f1fcf82d132f9bb018ca6738a19f == 1234567890
fe01d67a002dfa0f3ac084298142eccd == orange

Level 5

La carta de presentación de este crackme es la imagen que veis arriba. Al explorarlo unos minutos enseguida nos damos cuenta de que no realiza ninguna comprobación y que nos está haciendo perder el tiempo. Ahí es cuando empezamos a revisar el ejecutable más a fondo y enseguida encontramos la solución con nuestro amigo el editor hexadecimal.

the answer is AttachedString

Level 6

Misma carta de presentación que el anterior y misma ausencia de comprobación del serial. En esta ocasión echando un vistazo a los recursos encontramos la solución rápidamente.

Enlaces

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

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