AfKayAs’s CrackMe#2 KeyGen

Intro

Hoy vamos a desmitificar un poco a Visual Basic. El Crackme reza que acabemos con la nag y hagamos un keygen.

La NAG

formnag

Lo primero que debemos establecer es a que tipo de Nag nos estamos enfrentando, si es una MessageBox, se localiza y se parchea, si es un formulario la cosa ya cambia un poco, ya que encontrar esa parte del código puede resultar tedioso.

Yo voy a utilizar el camino fácil. En VB contamos con una estupenda herramienta como es VBReformer, que nos muestra las entrañas del crackme y nos posibilita cambiar ciertos parametros.

Abrimos el crackme con VBReformer y vemos su contenido. Localizamos rápidamente el formulario que aparece inicialmente (CMSplash) y el temporizador que contiene (Timer1). Inicialmente el timer tiene un interval de 7000, es decir, la nag se muestra durante 7 segundos. Es tan sencillo como cambiarlo por 1 y guardar el ejecutable (File > Save binary as).

parcheform

Si no disponemos de esta estupenda herramienta, siempre podemos localizar el timer con un editor hexadecimal. Localizamos en Olly el nombre del timer (en las string references lo veréis), y lo buscamos en el editor hexadecimal. La duración de la nag la debemos estimar nosotros y a continuación buscar ese valor hexadecimal. Imaginemos que estimamos que son 7 segundos, lo pasamos a milisegundos y a hexadecimal. 7000 = 0x1B58. Buscamos en el editor hexadecimal «Timer1» y a continuación localizamos el valor 1B58 invertido, es decir, 581B. En las imágenes inferiores se ve claro.

hextimer1original

hextimer1parcheado

Cambiando el valor ya lo tendriámos.

El algoritmo

El algoritmo de este crackme es muy sencillo pero he elegido este en concreto para que veáis las vueltas que da VB para hacer 6 operaciones matemáticas. A continuación tenéis el código íntegro comentado y debajo el resumen.

004081F5      .  FF15 F8B04000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaLenBstr>]    ;  MSVBVM50.__vbaLenBstr
004081FB      .  8BF8                     MOV EDI,EAX
004081FD      .  8B4D E8                  MOV ECX,DWORD PTR SS:[EBP-18]
00408200      .  69FF 385B0100            IMUL EDI,EDI,15B38                              ;  TEMP = Len(nombre) *15B38
00408206      .  51                       PUSH ECX
00408207      .  0F80 B7050000            JO CrackmeV.004087C4
0040820D      .  FF15 0CB14000            CALL DWORD PTR DS:[<&MSVBVM50.#516>]            ;  MSVBVM50.rtcAnsiValueBstr
00408213      .  0FBFD0                   MOVSX EDX,AX                                    ;  digito a ax
00408216      .  03FA                     ADD EDI,EDX                                     ;  TEMP +=1digito
00408218      .  0F80 A6050000            JO CrackmeV.004087C4
0040821E      .  57                       PUSH EDI                                        ;  MSVBVM50.__vbaObjSet
0040821F      .  FF15 F4B04000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaStrI4>]      ;  MSVBVM50.__vbaStrI4
00408225      .  8BD0                     MOV EDX,EAX
00408227      .  8D4D E0                  LEA ECX,DWORD PTR SS:[EBP-20]
0040822A      .  FF15 94B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaStrMove>]    ;  MSVBVM50.__vbaStrMove
00408230      .  8BBD 50FFFFFF            MOV EDI,DWORD PTR SS:[EBP-B0]
00408236      .  50                       PUSH EAX
00408237      .  57                       PUSH EDI                                        ;  MSVBVM50.__vbaObjSet
00408238      .  FF93 A4000000            CALL DWORD PTR DS:[EBX+A4]                      ;  MSVBVM50.0F050D32
0040823E      .  85C0                     TEST EAX,EAX
00408240      .  7D 12                    JGE SHORT CrackmeV.00408254
00408242      .  68 A4000000              PUSH 0A4
00408247      .  68 AC6F4000              PUSH CrackmeV.00406FAC
0040824C      .  57                       PUSH EDI                                        ;  MSVBVM50.__vbaObjSet
0040824D      .  50                       PUSH EAX
0040824E      .  FF15 18B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaHresultCheck>;  MSVBVM50.__vbaHresultCheckObj
00408254      >  8D45 E0                  LEA EAX,DWORD PTR SS:[EBP-20]
00408257      .  8D4D E4                  LEA ECX,DWORD PTR SS:[EBP-1C]
0040825A      .  50                       PUSH EAX
0040825B      .  8D55 E8                  LEA EDX,DWORD PTR SS:[EBP-18]
0040825E      .  51                       PUSH ECX
0040825F      .  52                       PUSH EDX
00408260      .  6A 03                    PUSH 3
00408262      .  FF15 80B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaFreeStrList>>;  MSVBVM50.__vbaFreeStrList
00408268      .  83C4 10                  ADD ESP,10
0040826B      .  8D45 D4                  LEA EAX,DWORD PTR SS:[EBP-2C]
0040826E      .  8D4D D8                  LEA ECX,DWORD PTR SS:[EBP-28]
00408271      .  8D55 DC                  LEA EDX,DWORD PTR SS:[EBP-24]
00408274      .  50                       PUSH EAX
00408275      .  51                       PUSH ECX
00408276      .  52                       PUSH EDX
00408277      .  6A 03                    PUSH 3
00408279      .  FF15 08B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaFreeObjList>>;  MSVBVM50.__vbaFreeObjList
0040827F      .  8B9D 40FFFFFF            MOV EBX,DWORD PTR SS:[EBP-C0]                   ;  CrackmeV.00409A68
00408285      .  83C4 10                  ADD ESP,10
00408288      .  8B83 FC020000            MOV EAX,DWORD PTR DS:[EBX+2FC]
0040828E      .  56                       PUSH ESI
0040828F      .  8985 38FFFFFF            MOV DWORD PTR SS:[EBP-C8],EAX
00408295      .  FFD0                     CALL EAX
00408297      .  8B3D 20B14000            MOV EDI,DWORD PTR DS:[<&MSVBVM50.__vbaObjSet>]  ;  MSVBVM50.__vbaObjSet
0040829D      .  50                       PUSH EAX
0040829E      .  8D45 D8                  LEA EAX,DWORD PTR SS:[EBP-28]
004082A1      .  50                       PUSH EAX
004082A2      .  FFD7                     CALL EDI                                        ;  MSVBVM50.__vbaObjSet; <&MSVBVM50.__vbaObjSet>
004082A4      .  56                       PUSH ESI
004082A5      .  8985 58FFFFFF            MOV DWORD PTR SS:[EBP-A8],EAX
004082AB      .  FF93 08030000            CALL DWORD PTR DS:[EBX+308]
004082B1      .  8D4D DC                  LEA ECX,DWORD PTR SS:[EBP-24]
004082B4      .  50                       PUSH EAX
004082B5      .  51                       PUSH ECX
004082B6      .  FFD7                     CALL EDI                                        ;  MSVBVM50.__vbaObjSet
004082B8      .  8BD8                     MOV EBX,EAX
004082BA      .  8D45 E8                  LEA EAX,DWORD PTR SS:[EBP-18]
004082BD      .  50                       PUSH EAX
004082BE      .  53                       PUSH EBX
004082BF      .  8B13                     MOV EDX,DWORD PTR DS:[EBX]                      ;  MSVBVM50.0F025A95
004082C1      .  FF92 A0000000            CALL DWORD PTR DS:[EDX+A0]
004082C7      .  85C0                     TEST EAX,EAX
004082C9      .  7D 12                    JGE SHORT CrackmeV.004082DD
004082CB      .  68 A0000000              PUSH 0A0
004082D0      .  68 AC6F4000              PUSH CrackmeV.00406FAC
004082D5      .  53                       PUSH EBX
004082D6      .  50                       PUSH EAX
004082D7      .  FF15 18B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaHresultCheck>;  MSVBVM50.__vbaHresultCheckObj
004082DD      >  8B8D 58FFFFFF            MOV ECX,DWORD PTR SS:[EBP-A8]
004082E3      .  8B55 E8                  MOV EDX,DWORD PTR SS:[EBP-18]
004082E6      .  52                       PUSH EDX
004082E7      .  8B19                     MOV EBX,DWORD PTR DS:[ECX]
004082E9      .  FF15 74B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaR8Str>]      ;  MSVBVM50.__vbaR8Str
004082EF      .  D905 08104000            FLD DWORD PTR DS:[401008]
004082F5      .  833D 00904000 00         CMP DWORD PTR DS:[409000],0
004082FC      .  75 08                    JNZ SHORT CrackmeV.00408306
004082FE      .  D835 0C104000            FDIV DWORD PTR DS:[40100C]                      ;  10 / 5 = 2
00408304      .  EB 0B                    JMP SHORT CrackmeV.00408311
00408306      >  FF35 0C104000            PUSH DWORD PTR DS:[40100C]
0040830C      .  E8 578DFFFF              CALL <JMP.&MSVBVM50._adj_fdiv_m32>
00408311      >  83EC 08                  SUB ESP,8
00408314      .  DFE0                     FSTSW AX
00408316      .  A8 0D                    TEST AL,0D
00408318      .  0F85 A1040000            JNZ CrackmeV.004087BF
0040831E      .  DEC1                     FADDP ST(1),ST                                  ;  TEMP +=2
00408320      .  DFE0                     FSTSW AX
00408322      .  A8 0D                    TEST AL,0D
00408324      .  0F85 95040000            JNZ CrackmeV.004087BF
0040832A      .  DD1C24                   FSTP QWORD PTR SS:[ESP]
0040832D      .  FF15 48B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaStrR8>]      ;  MSVBVM50.__vbaStrR8
00408333      .  8BD0                     MOV EDX,EAX
00408335      .  8D4D E4                  LEA ECX,DWORD PTR SS:[EBP-1C]
00408338      .  FF15 94B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaStrMove>]    ;  MSVBVM50.__vbaStrMove
0040833E      .  899D 34FFFFFF            MOV DWORD PTR SS:[EBP-CC],EBX
00408344      .  8B9D 58FFFFFF            MOV EBX,DWORD PTR SS:[EBP-A8]
0040834A      .  50                       PUSH EAX
0040834B      .  8B85 34FFFFFF            MOV EAX,DWORD PTR SS:[EBP-CC]
00408351      .  53                       PUSH EBX
00408352      .  FF90 A4000000            CALL DWORD PTR DS:[EAX+A4]
00408358      .  85C0                     TEST EAX,EAX
0040835A      .  7D 12                    JGE SHORT CrackmeV.0040836E
0040835C      .  68 A4000000              PUSH 0A4
00408361      .  68 AC6F4000              PUSH CrackmeV.00406FAC
00408366      .  53                       PUSH EBX
00408367      .  50                       PUSH EAX
00408368      .  FF15 18B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaHresultCheck>;  MSVBVM50.__vbaHresultCheckObj
0040836E      >  8D4D E4                  LEA ECX,DWORD PTR SS:[EBP-1C]
00408371      .  8D55 E8                  LEA EDX,DWORD PTR SS:[EBP-18]
00408374      .  51                       PUSH ECX
00408375      .  52                       PUSH EDX
00408376      .  6A 02                    PUSH 2
00408378      .  FF15 80B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaFreeStrList>>;  MSVBVM50.__vbaFreeStrList
0040837E      .  83C4 0C                  ADD ESP,0C
00408381      .  8D45 D8                  LEA EAX,DWORD PTR SS:[EBP-28]
00408384      .  8D4D DC                  LEA ECX,DWORD PTR SS:[EBP-24]
00408387      .  50                       PUSH EAX
00408388      .  51                       PUSH ECX
00408389      .  6A 02                    PUSH 2
0040838B      .  FF15 08B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaFreeObjList>>;  MSVBVM50.__vbaFreeObjList
00408391      .  8B95 40FFFFFF            MOV EDX,DWORD PTR SS:[EBP-C0]                   ;  CrackmeV.00409A68
00408397      .  83C4 0C                  ADD ESP,0C
0040839A      .  8B82 00030000            MOV EAX,DWORD PTR DS:[EDX+300]
004083A0      .  56                       PUSH ESI
004083A1      .  8985 30FFFFFF            MOV DWORD PTR SS:[EBP-D0],EAX
004083A7      .  FFD0                     CALL EAX
004083A9      .  50                       PUSH EAX
004083AA      .  8D45 D8                  LEA EAX,DWORD PTR SS:[EBP-28]
004083AD      .  50                       PUSH EAX
004083AE      .  FFD7                     CALL EDI                                        ;  MSVBVM50.__vbaObjSet
004083B0      .  56                       PUSH ESI
004083B1      .  8985 58FFFFFF            MOV DWORD PTR SS:[EBP-A8],EAX
004083B7      .  FF95 38FFFFFF            CALL DWORD PTR SS:[EBP-C8]                      ;  MSVBVM50.0F10C340
004083BD      .  8D4D DC                  LEA ECX,DWORD PTR SS:[EBP-24]
004083C0      .  50                       PUSH EAX
004083C1      .  51                       PUSH ECX
004083C2      .  FFD7                     CALL EDI                                        ;  MSVBVM50.__vbaObjSet
004083C4      .  8BD8                     MOV EBX,EAX
004083C6      .  8D45 E8                  LEA EAX,DWORD PTR SS:[EBP-18]
004083C9      .  50                       PUSH EAX
004083CA      .  53                       PUSH EBX
004083CB      .  8B13                     MOV EDX,DWORD PTR DS:[EBX]                      ;  MSVBVM50.0F025A95
004083CD      .  FF92 A0000000            CALL DWORD PTR DS:[EDX+A0]
004083D3      .  85C0                     TEST EAX,EAX
004083D5      .  7D 12                    JGE SHORT CrackmeV.004083E9
004083D7      .  68 A0000000              PUSH 0A0
004083DC      .  68 AC6F4000              PUSH CrackmeV.00406FAC
004083E1      .  53                       PUSH EBX
004083E2      .  50                       PUSH EAX
004083E3      .  FF15 18B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaHresultCheck>;  MSVBVM50.__vbaHresultCheckObj
004083E9      >  8B8D 58FFFFFF            MOV ECX,DWORD PTR SS:[EBP-A8]
004083EF      .  8B55 E8                  MOV EDX,DWORD PTR SS:[EBP-18]
004083F2      .  52                       PUSH EDX
004083F3      .  8B19                     MOV EBX,DWORD PTR DS:[ECX]
004083F5      .  FF15 74B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaR8Str>]      ;  MSVBVM50.__vbaR8Str
004083FB      .  DC0D 10104000            FMUL QWORD PTR DS:[401010]                      ;  *3
00408401      .  83EC 08                  SUB ESP,8                                       ;  -2
00408404      .  DC25 18104000            FSUB QWORD PTR DS:[401018]
0040840A      .  DFE0                     FSTSW AX
0040840C      .  A8 0D                    TEST AL,0D
0040840E      .  0F85 AB030000            JNZ CrackmeV.004087BF
00408414      .  DD1C24                   FSTP QWORD PTR SS:[ESP]
00408417      .  FF15 48B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaStrR8>]      ;  MSVBVM50.__vbaStrR8
0040841D      .  8BD0                     MOV EDX,EAX
0040841F      .  8D4D E4                  LEA ECX,DWORD PTR SS:[EBP-1C]
00408422      .  FF15 94B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaStrMove>]    ;  MSVBVM50.__vbaStrMove
00408428      .  899D 2CFFFFFF            MOV DWORD PTR SS:[EBP-D4],EBX
0040842E      .  8B9D 58FFFFFF            MOV EBX,DWORD PTR SS:[EBP-A8]
00408434      .  50                       PUSH EAX
00408435      .  8B85 2CFFFFFF            MOV EAX,DWORD PTR SS:[EBP-D4]
0040843B      .  53                       PUSH EBX
0040843C      .  FF90 A4000000            CALL DWORD PTR DS:[EAX+A4]
00408442      .  85C0                     TEST EAX,EAX
00408444      .  7D 12                    JGE SHORT CrackmeV.00408458
00408446      .  68 A4000000              PUSH 0A4
0040844B      .  68 AC6F4000              PUSH CrackmeV.00406FAC
00408450      .  53                       PUSH EBX
00408451      .  50                       PUSH EAX
00408452      .  FF15 18B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaHresultCheck>;  MSVBVM50.__vbaHresultCheckObj
00408458      >  8D4D E4                  LEA ECX,DWORD PTR SS:[EBP-1C]
0040845B      .  8D55 E8                  LEA EDX,DWORD PTR SS:[EBP-18]
0040845E      .  51                       PUSH ECX
0040845F      .  52                       PUSH EDX
00408460      .  6A 02                    PUSH 2
00408462      .  FF15 80B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaFreeStrList>>;  MSVBVM50.__vbaFreeStrList
00408468      .  83C4 0C                  ADD ESP,0C
0040846B      .  8D45 D8                  LEA EAX,DWORD PTR SS:[EBP-28]
0040846E      .  8D4D DC                  LEA ECX,DWORD PTR SS:[EBP-24]
00408471      .  50                       PUSH EAX
00408472      .  51                       PUSH ECX
00408473      .  6A 02                    PUSH 2
00408475      .  FF15 08B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaFreeObjList>>;  MSVBVM50.__vbaFreeObjList
0040847B      .  8B95 40FFFFFF            MOV EDX,DWORD PTR SS:[EBP-C0]                   ;  CrackmeV.00409A68
00408481      .  83C4 0C                  ADD ESP,0C
00408484      .  8B82 04030000            MOV EAX,DWORD PTR DS:[EDX+304]
0040848A      .  56                       PUSH ESI
0040848B      .  8985 28FFFFFF            MOV DWORD PTR SS:[EBP-D8],EAX
00408491      .  FFD0                     CALL EAX
00408493      .  50                       PUSH EAX
00408494      .  8D45 D8                  LEA EAX,DWORD PTR SS:[EBP-28]
00408497      .  50                       PUSH EAX
00408498      .  FFD7                     CALL EDI                                        ;  MSVBVM50.__vbaObjSet
0040849A      .  56                       PUSH ESI
0040849B      .  8985 58FFFFFF            MOV DWORD PTR SS:[EBP-A8],EAX
004084A1      .  FF95 30FFFFFF            CALL DWORD PTR SS:[EBP-D0]                      ;  MSVBVM50.0F10C348
004084A7      .  8D4D DC                  LEA ECX,DWORD PTR SS:[EBP-24]
004084AA      .  50                       PUSH EAX
004084AB      .  51                       PUSH ECX
004084AC      .  FFD7                     CALL EDI                                        ;  MSVBVM50.__vbaObjSet
004084AE      .  8BD8                     MOV EBX,EAX
004084B0      .  8D45 E8                  LEA EAX,DWORD PTR SS:[EBP-18]
004084B3      .  50                       PUSH EAX
004084B4      .  53                       PUSH EBX
004084B5      .  8B13                     MOV EDX,DWORD PTR DS:[EBX]                      ;  MSVBVM50.0F025A95
004084B7      .  FF92 A0000000            CALL DWORD PTR DS:[EDX+A0]
004084BD      .  85C0                     TEST EAX,EAX
004084BF      .  7D 12                    JGE SHORT CrackmeV.004084D3
004084C1      .  68 A0000000              PUSH 0A0
004084C6      .  68 AC6F4000              PUSH CrackmeV.00406FAC
004084CB      .  53                       PUSH EBX
004084CC      .  50                       PUSH EAX
004084CD      .  FF15 18B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaHresultCheck>;  MSVBVM50.__vbaHresultCheckObj
004084D3      >  8B8D 58FFFFFF            MOV ECX,DWORD PTR SS:[EBP-A8]
004084D9      .  8B55 E8                  MOV EDX,DWORD PTR SS:[EBP-18]
004084DC      .  52                       PUSH EDX
004084DD      .  8B19                     MOV EBX,DWORD PTR DS:[ECX]
004084DF      .  FF15 74B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaR8Str>]      ;  MSVBVM50.__vbaR8Str
004084E5      .  DC25 20104000            FSUB QWORD PTR DS:[401020]                      ;  TEMP -= -15
004084EB      .  83EC 08                  SUB ESP,8
004084EE      .  DFE0                     FSTSW AX
004084F0      .  A8 0D                    TEST AL,0D
004084F2      .  0F85 C7020000            JNZ CrackmeV.004087BF
........
00408677      . /74 62                    JE SHORT CrackmeV.004086DB
00408679      . |8B35 14B14000            MOV ESI,DWORD PTR DS:[<&MSVBVM50.__vbaStrCat>]  ;  MSVBVM50.__vbaStrCat
0040867F      . |68 C06F4000              PUSH CrackmeV.00406FC0                          ;  UNICODE "You Get It"
00408684      . |68 DC6F4000              PUSH CrackmeV.00406FDC                          ;  UNICODE "\r\n"
00408689      . |FFD6                     CALL ESI                                        ;  <&MSVBVM50.__vbaStrCat>
0040868B      . |8BD0                     MOV EDX,EAX
0040868D      . |8D4D E8                  LEA ECX,DWORD PTR SS:[EBP-18]
00408690      . |FF15 94B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaStrMove>]    ;  MSVBVM50.__vbaStrMove
00408696      . |50                       PUSH EAX
00408697      . |68 E86F4000              PUSH CrackmeV.00406FE8                          ;  UNICODE "KeyGen It Now"

Que se puede resumir en esto.

004081F5      .  FF15 F8B04000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaLenBstr>]    ;  MSVBVM50.__vbaLenBstr
004081FB      .  8BF8                     MOV EDI,EAX
004081FD      .  8B4D E8                  MOV ECX,DWORD PTR SS:[EBP-18]
00408200      .  69FF 385B0100            IMUL EDI,EDI,15B38                              ;  TEMP = Len(nombre) *15B38
00408206      .  51                       PUSH ECX
00408207      .  0F80 B7050000            JO CrackmeV.004087C4
0040820D      .  FF15 0CB14000            CALL DWORD PTR DS:[<&MSVBVM50.#516>]            ;  MSVBVM50.rtcAnsiValueBstr
00408213      .  0FBFD0                   MOVSX EDX,AX                                    ;  digito a ax
00408216      .  03FA                     ADD EDI,EDX                                     ;  TEMP +=1digito
00408218      .  0F80 A6050000            JO CrackmeV.004087C4
........
004082E9      .  FF15 74B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaR8Str>]      ;  MSVBVM50.__vbaR8Str
004082EF      .  D905 08104000            FLD DWORD PTR DS:[401008]
004082F5      .  833D 00904000 00         CMP DWORD PTR DS:[409000],0
004082FC      .  75 08                    JNZ SHORT CrackmeV.00408306
004082FE      .  D835 0C104000            FDIV DWORD PTR DS:[40100C]                      ;  10 / 5 = 2
00408304      .  EB 0B                    JMP SHORT CrackmeV.00408311
00408306      >  FF35 0C104000            PUSH DWORD PTR DS:[40100C]
0040830C      .  E8 578DFFFF              CALL <JMP.&MSVBVM50._adj_fdiv_m32>
00408311      >  83EC 08                  SUB ESP,8
00408314      .  DFE0                     FSTSW AX
00408316      .  A8 0D                    TEST AL,0D
00408318      .  0F85 A1040000            JNZ CrackmeV.004087BF
0040831E      .  DEC1                     FADDP ST(1),ST                                  ;  TEMP +=2
00408320      .  DFE0                     FSTSW AX
00408322      .  A8 0D                    TEST AL,0D
........
004083F5      .  FF15 74B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaR8Str>]      ;  MSVBVM50.__vbaR8Str
004083FB      .  DC0D 10104000            FMUL QWORD PTR DS:[401010]                      ;  TEMP *=3
00408401      .  83EC 08                  SUB ESP,8                                       ;  TEMP -=2
00408404      .  DC25 18104000            FSUB QWORD PTR DS:[401018]
0040840A      .  DFE0                     FSTSW AX
0040840C      .  A8 0D                    TEST AL,0D
........
004084DF      .  FF15 74B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaR8Str>]      ;  MSVBVM50.__vbaR8Str
004084E5      .  DC25 20104000            FSUB QWORD PTR DS:[401020]                      ;  TEMP -= -15
004084EB      .  83EC 08                  SUB ESP,8
004084EE      .  DFE0                     FSTSW AX
004084F0      .  A8 0D                    TEST AL,0D
004084F2      .  0F85 C7020000            JNZ CrackmeV.004087BF
........
00408677      . /74 62                    JE SHORT CrackmeV.004086DB
00408679      . |8B35 14B14000            MOV ESI,DWORD PTR DS:[<&MSVBVM50.__vbaStrCat>]  ;  MSVBVM50.__vbaStrCat
0040867F      . |68 C06F4000              PUSH CrackmeV.00406FC0                          ;  UNICODE "You Get It"
00408684      . |68 DC6F4000              PUSH CrackmeV.00406FDC                          ;  UNICODE "\r\n"
00408689      . |FFD6                     CALL ESI                                        ;  <&MSVBVM50.__vbaStrCat>
0040868B      . |8BD0                     MOV EDX,EAX
0040868D      . |8D4D E8                  LEA ECX,DWORD PTR SS:[EBP-18]
00408690      . |FF15 94B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaStrMove>]    ;  MSVBVM50.__vbaStrMove
00408696      . |50                       PUSH EAX
00408697      . |68 E86F4000              PUSH CrackmeV.00406FE8                          ;  UNICODE "KeyGen It Now"

Y en esto:

TEMP = Len(nombre) *15B38
TEMP += 1ºdigitoascii
TEMP +=2
TEMP *=3
TEMP -=2
TEMP +=15

 Y el KeyGen nos ocupa una sola línea

txtserial.Text = (((((Len(txtnombre.Text) * 88888) + Asc(Mid(txtn.Text, 1, 1))) + 2) * 3) - 2) + 15

 Huevo de pascua (Easter egg)

Si nos fijamos en el VBReformer, en el formulario principal vemos muchas cajas de texto.

vbreformervistaproject

Las hacemos visibles, guardamos y ejecutamos haber que pasa.

textsvisibles

crackmebonus

Lo que pasa es que va guardando el resultado de las operaciones en ellas y en la de arriba concretamente está nuestro serial bueno, lo que nos hace poseedores de un KeyGen encubierto.

Links


Aquí tenemos un crackme fuera de lo común, más que nada por que está programado en Brainfuck, un lenguaje de
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
Aquí os dejo un video tutorial. El crackme lo podeis encontrar en crackmes.de.

Canyouhack.it – Crack Challenge 4 (Brain Fuck Me)

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

 

Wechall Training LSB Challenge (Esteganografía)

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

Resumidamente, esta técnica consiste en ocultar información en el bit menos significativo de cada uno de los píxeles de una imagen, consiguiendo así que el cambio realizado sea invisible al ojo humano. El problema de esta técnica, es que la información oculta puede obtenerse fácilmente si esta no se ha codificado previamente o si no se sigue un patrón concreto a la hora de ocultarla.

Desde la web del reto nos avisan de que esto es un simple truco pero espectacular. Nos animan a descargar una imágen y a encontrar la solución oculta.

Aprovecho este reto para presentaros una herramienta vital al enfrentaros a ciertos retos sobre esteganografía, steganabara.

Steganabara tiene dos apartados muy interesantes, uno es «color table» y otro «bit mask«, hoy veremos en acción a «bit mask».

No os preocupéis por la solución ya que cambia para cada usuario y sesión.

Buscando la solución oculta

Abrimos steganabara y empezamos a trastear con bit mask.

stegolsb02

Al poco tiempo ya vemos que vamos bien encaminados.

stegolsb03stegolsb04

Finalmente no nos cuesta dar con la solución.

stegolsb05stegolsb06

Links

Yoire PE Stage 3 Reversing Challenge (Benten) – Fuerza Bruta

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


Introducción Herramientas utilizadas Desempacado con Ollydbg 2 (Videotutorial) Desempacado con Ollydbg 1 (Videotutorial) Análisis de la rutina del número de
Introducción Activar un botón en memoria Activar el botón de forma permanente Serial Hardcodeado Links Introducción Este crackme pertenece a
Libros Hacker Épico La apacible existencia de Ángel Ríos da un vuelco cuando una antigua compañera de clase, de la
Intro Hoy tenemos un crackme realizado en ensamblador y sin empacar. Consiste en el típico serial asociado a un nombre

Wechall Stegano Attachment (Esteganografía)

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

Solución al Time Trial de Detten

Intro

Hoy tenemos aquí otro crackme sacado del baúl de los recuerdos. En este caso se trata de una protección por tiempo límite a través de un keyfile llamado «data.det«. Disponemos de tres días o nueve sesiones antes de que el crackme expire.

El algoritmo

La primera vez que ejecutamos el crackme, crea el fichero «data.det» y realiza lo siguiente:

  • Lee el fichero data.det que inicialmente tiene 10 bytes a cero y el último byte un 60(`).
  • Comprueba que tenga 11 bytes (B) y continúa.
  • Al detectar el fichero vacío le mete valores codificandolos con XOR 6969. Los almacena en memoria 4030AB y siguientes.
00401000 t>/$  6A 00               PUSH 0                                    ; /pModule = NULL
00401002   |.  E8 0B020000         CALL <JMP.&KERNEL32.GetModuleHandleA>     ; \GetModuleHandleA
00401007   |.  A3 F4304000         MOV DWORD PTR DS:[4030F4],EAX             ;  kernel32.BaseThreadInitThunk
0040100C   |.  6A 00               PUSH 0                                    ; /hTemplateFile = NULL
0040100E   |.  68 80000000         PUSH 80                                   ; |Attributes = NORMAL
00401013   |.  6A 03               PUSH 3                                    ; |Mode = OPEN_EXISTING
00401015   |.  6A 00               PUSH 0                                    ; |pSecurity = NULL
00401017   |.  6A 00               PUSH 0                                    ; |ShareMode = 0
00401019   |.  68 000000C0         PUSH C0000000                             ; |Access = GENERIC_READ|GENERIC_WRITE
0040101E   |.  68 A2304000         PUSH timetria.004030A2                    ; |FileName = "DATA.DET"
00401023   |.  E8 DE010000         CALL <JMP.&KERNEL32.CreateFileA>          ; \CreateFileA
00401028   |.  83F8 FF             CMP EAX,-1
0040102B   |.  74 07               JE SHORT timetria.00401034
0040102D   |.  A3 14314000         MOV DWORD PTR DS:[403114],EAX             ;  kernel32.BaseThreadInitThunk
00401032   |.  EB 18               JMP SHORT timetria.0040104C
00401034   |>  6A 30               PUSH 30                                   ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401036   |.  68 38304000         PUSH timetria.00403038                    ; |Title = "I don't like this !"
0040103B   |.  68 02304000         PUSH timetria.00403002                    ; |Text = "Where is my DATA.DET file?\r\nI can't run without it..."
00401040   |.  6A 00               PUSH 0                                    ; |hOwner = NULL
00401042   |.  E8 B3010000         CALL <JMP.&USER32.MessageBoxA>            ; \MessageBoxA
00401047   |.  E9 22010000         JMP timetria.0040116E
0040104C   |>  6A 00               PUSH 0                                    ; /pOverlapped = NULL
0040104E   |.  68 E0304000         PUSH timetria.004030E0                    ; |pBytesRead = timetria.004030E0
00401053   |.  6A 32               PUSH 32                                   ; |BytesToRead = 32 (50.)
00401055   |.  68 AB304000         PUSH timetria.004030AB                    ; |Buffer = timetria.004030AB
0040105A   |.  FF35 14314000       PUSH DWORD PTR DS:[403114]                ; |hFile = NULL
00401060   |.  E8 B9010000         CALL <JMP.&KERNEL32.ReadFile>             ; \ReadFile
00401065   |.  833D E0304000 0B    CMP DWORD PTR DS:[4030E0],0B
0040106C   |.  0F85 E9000000       JNZ timetria.0040115B
00401072   |.  BB AB304000         MOV EBX,timetria.004030AB
00401077   |.  68 E4304000         PUSH timetria.004030E4                    ; /pSystemTime = timetria.004030E4
0040107C   |.  E8 97010000         CALL <JMP.&KERNEL32.GetSystemTime>        ; \GetSystemTime
00401081   |.  803B 00             CMP BYTE PTR DS:[EBX],0
00401084   |.  75 22               JNZ SHORT timetria.004010A8               ;  Si existe el fichero salta a las comprobaciones
00401086   |.  51                  PUSH ECX
00401087   |.  33C9                XOR ECX,ECX
00401089   |.  EB 15               JMP SHORT timetria.004010A0
0040108B   |>  66:8B81 E4304000    /MOV AX,WORD PTR DS:[ECX+4030E4]          ;  |
00401092   |.  66:35 6969          |XOR AX,6969                              ;  |
00401096   |.  66:8981 AB304000    |MOV WORD PTR DS:[ECX+4030AB],AX          ;  |
0040109D   |.  83C1 02             |ADD ECX,2                                ;  | Bucle de codificacion de data.det por primera vez
004010A0   |>  83F9 08              CMP ECX,8                                ;  |
004010A3   |.^ 76 E6               \JBE SHORT timetria.0040108B              ;  |
004010A5   |.  59                  POP ECX                                   ;  kernel32.7580EE1C
004010A6   |.  EB 3A               JMP SHORT timetria.004010E2

 

Vigilando el proceso de creación del archivo podemos llegar a la conclusión de como se genera.

  • Los dos primeros bytes son el año = 2014 = 0x7DE. 7DE XOR 6969 = 6EB7.
  • Los dos siguientes son el mes = 10 = 0xA. A XOR 6969 = 6963.
  • Los dos siguientes usa un 4 (día de la semana???) = 0x4. 4 XOR 6969 = 696D.
  • Los dos siguientes son el día del mes = 2 = 0x2. 2 XOR 6969 = 696B
  • Los dos siguientes usa un 1 = 0x1. 1 XOR 6969 = 6968.
  • El número de sesiones lo deja como está, 60.

Estado de la memoria:

004030AB  B7 6E 63 69 6D 69 6B 69 68 69 60                 ·ncimikihi`
  •  Finalmente le resta 1 al número de sesiones y guarda el fichero.
004010E2   |> \A0 B5304000         MOV AL,BYTE PTR DS:[4030B5]
004010E7   |.  34 69               XOR AL,69
004010E9   |.  3C 00               CMP AL,0
004010EB   |. /74 59               JE SHORT timetria.00401146
004010ED   |. |FEC8                DEC AL
004010EF   |. |A2 01304000         MOV BYTE PTR DS:[403001],AL
004010F4   |. |34 69               XOR AL,69
004010F6   |. |A2 B5304000         MOV BYTE PTR DS:[4030B5],AL
004010FB   |. |6A 00               PUSH 0                                    ; /Origin = FILE_BEGIN
004010FD   |. |6A 00               PUSH 0                                    ; |pOffsetHi = NULL
004010FF   |. |6A 00               PUSH 0                                    ; |OffsetLo = 0
00401101   |. |FF35 14314000       PUSH DWORD PTR DS:[403114]                ; |hFile = 00000034 (window)
00401107   |. |E8 18010000         CALL <JMP.&KERNEL32.SetFilePointer>       ; \SetFilePointer
0040110C   |. |6A 00               PUSH 0                                    ; /pOverlapped = NULL
0040110E   |. |68 E0304000         PUSH timetria.004030E0                    ; |pBytesWritten = timetria.004030E0
00401113   |. |6A 0B               PUSH 0B                                   ; |nBytesToWrite = B (11.)
00401115   |. |68 AB304000         PUSH timetria.004030AB                    ; |Buffer = timetria.004030AB
0040111A   |. |FF35 14314000       PUSH DWORD PTR DS:[403114]                ; |hFile = 00000034 (window)
00401120   |. |E8 05010000         CALL <JMP.&KERNEL32.WriteFile>            ; \WriteFile

En cada ejecución realiza tres comprobaciones.
Recordemos el contenido del fichero:

B7 6E 63 69 6D 69 6B 69 68 69 60                 ·ncimikihi`

1) Mes y año (4 primeros bytes)

004010A8   |> \8B0D AB304000       MOV ECX,DWORD PTR DS:[4030AB] ; ECX=69636EB7
004010AE   |.  81F1 69696969       XOR ECX,69696969              ; 69636EB7 xor 69696969 = A07DE (A = mes y 7DE = año)
004010B4   |.  A1 E4304000         MOV EAX,DWORD PTR DS:[4030E4]
004010B9   |.  3BC1                CMP EAX,ECX                   ; Compara con mes y año actuales
004010BB   |.  0F85 85000000       JNZ timetria.00401146         ; Bad boy

2) Día (7º y 8º byte)

004010C1   |.  66:8B0D B1304000    MOV CX,WORD PTR DS:[4030B1]   ; CX = 696B
004010C8   |.  66:81F1 6969        XOR CX,6969                   ; 696B xor 6969 = 2
004010CD   |.  66:A1 EA304000      MOV AX,WORD PTR DS:[4030EA]   ; AX = día actual obtenido con GetSystemTime
004010D3   |.  66:2BC1             SUB AX,CX                     ; Los resta
004010D6   |.  66:83F8 03          CMP AX,3                      ; Compara con 3
004010DA   |.  77 6A               JA SHORT timetria.00401146    ; Si el resultado >=3 Bad Boy

3) Sesiones (11º byte)

004010DC   |.  2805 00304000       SUB BYTE PTR DS:[403000],AL   ;
004010E2   |>  A0 B5304000         MOV AL,BYTE PTR DS:[4030B5]   ; AL = numero de sesiones actual
004010E7   |.  34 69               XOR AL,69                     ; 61 Xor 69 = 8
004010E9   |.  3C 00               CMP AL,0                      ; Compara con 0
004010EB   |.  74 59               JE SHORT timetria.00401146    ; Salta si hemos superado las 9 sesiones. Bad boy
004010ED   |.  FEC8                DEC AL                        ; Si no le resta 1
004010EF   |.  A2 01304000         MOV BYTE PTR DS:[403001],AL
004010F4   |.  34 69               XOR AL,69                     ; y le hace xor 69 para codificar el nuevo valor de sesión
004010F6   |.  A2 B5304000         MOV BYTE PTR DS:[4030B5],AL

Con esto ya podemos alterar el archivo a nuestro antojo sin necesidad de parchear.

Keygen

Try
            ano = ano Xor 26985
            mes = mes Xor 26985
            dia = dia Xor 26985
            anos = Hex(ano).ToString
            mess = Hex(mes).ToString
            dias = Hex(dia).ToString
            If txtsesiones.Text <= 255 Then
                sesioness = Hex(sesiones)
            Else
                sesiones = 255
            End If
            sesioness = Hex(sesiones)
            'key = 00 00 00 00 00 00 00 00 00 00 00
            'key = año+año+mes+mes+X+X+dia+dia+X+sesiones
            key = Chr(Convert.ToInt32(anos.Substring(2, 2), 16)) & Chr(Convert.ToInt32(anos.Substring(0, 2), 16)) _
            & Chr(Convert.ToInt32(mess.Substring(2, 2), 16)) & Chr(Convert.ToInt32(mess.Substring(0, 2), 16)) _
            & Chr(106) & Chr(105) _
            & Chr(Convert.ToInt32(dias.Substring(2, 2), 16)) & Chr(Convert.ToInt32(dias.Substring(0, 2), 16)) _
            & Chr(103) & Chr(105) _
            & Chr(Convert.ToInt32(sesioness.Substring(0, 2), 16))
            'Creo el archivo llave
            Dim ruta As String = Application.StartupPath & "\DATA.DET"
            If File.Exists(ruta) Then
                File.Delete(ruta)
            End If
            Using sw As StreamWriter = New StreamWriter(ruta, True, System.Text.Encoding.Default)
                sw.Write(key)
                sw.Close()
            End Using
            MsgBox("DATA.DET generado correctamente", MsgBoxStyle.Information + MsgBoxStyle.OkOnly, "Info")
        Catch ex As Exception
            MsgBox("Ocurrió algún error" & vbCrLf & ex.Message)
        End Try

 Links


Computer Password Security Hacker En el primer vistazo con el editor hexadecimal ya vemos la solución al reto: Pho Al
Introducción Activar un botón en memoria Activar el botón de forma permanente Serial Hardcodeado Links Introducción Este crackme pertenece a
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en
Introducción Funcionamiento de RSA OllyDbg Calculando un serial válido Ejemplo operacional Keygen Links Introducción Empezamos con lo que espero que

5 Retos Stego sencillos

Computer Password Security Hacker

En el primer vistazo con el editor hexadecimal ya vemos la solución al reto:

Pho

Al igual que el caso anterior con el editor hexadecimal tenemos más que suficiente para resolver el reto.

Minions

En el análisis inicial no destaca prácticamente nada excepto la palabra myadmin que podemos ver con un editor hexadecimal.

La palabra myadmin es una buena candidata a ser contraseña ante una decodificación. Probamos con lo estándar y conseguimos resultados con steghide. La decodificación nos devuelve la cadena AEMAVABGAGwAZQBhAHIAbgB7AHQAaABpAHMAXwBpAHMAXwBmAHU***** que rápidamente catalogamos como base64 para resolver el reto.

Unopenable

Se nos entrega una imagen GIF aparentemente corrupta. Estudiando un poco la cabecera de los archivos GIF llegamos rápidamente a la conclusión de que faltan los cuatro primeros bytes del archivo.

Bytes originales
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  39 61 F4 01 F4 01 F4 00 00 00 00 00 3A 00 00 00  9aô.ô.ô.....:...
00000010  00 3A 3A 00 3A 66 00 00 66 00 3A 00 00 66 90 3A  .::.:f..f.:..f.:
00000020  00 90 3A 3A B6 66 00 B6 66 3A 90 90 3A DB 90 3A  ..::¶f.¶f:..:Û.:
00000030  FF B6 66 00 3A 90 66 3A 90 00 66 90 00 66 B6 3A  ÿ¶f.:.f:..f..f¶:

Después de insertar los bytes que faltan
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  47 49 46 38 39 61 F4 01 F4 01 F4 00 00 00 00 00  GIF89aô.ô.ô.....
00000010  3A 00 00 00 00 3A 3A 00 3A 66 00 00 66 00 3A 00  :....::.:f..f.:.
00000020  00 66 90 3A 00 90 3A 3A B6 66 00 B6 66 3A 90 90  .f.:..::¶f.¶f:..
00000030  3A DB 90 3A FF B6 66 00 3A 90 66 3A 90 00 66 90  :Û.:ÿ¶f.:.f:..f.

Una vez insertados los bytes podemos ver una animación que contiene una cadena de texto fácilmente reconocible como base64. La decodificamos y ya tenemos la solución.

Oreo

Mirando con un editor hexadecimal no encontramos nada excepto la frase This is not the flag you are looking for para intentar disuadirnos.

Cargamos la imagen en Aperi’Solve y enseguida nos llama la atención la sección Binwalk y un suculento Rar.

Descargamos el archivo Rar y al descomprimir nos encontramos con un archivo de texto con la misma frase desalentadora del inicio y una imagen JPG, esta vez con dos oreos. Inspeccionando la imagen damos con la solución.

Solución al Crackme 3 de Sotanez

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


Intro Hoy tenemos aquí otro crackme sacado del baúl de los recuerdos. En este caso se trata de una protección
Intro Os comparto un reto stego que me gustó cuando lo hice hace unos años. En realidad se tarda pocos
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

Blooper Tech Movie XIV – Parque Jurásico

En Parque Jurásico (1993), la informática no es solo un elemento narrativo, es una pieza clave del suspense y del conflicto. A diferencia de otras películas donde las pantallas muestran interfaces ficticias o visualmente espectaculares pero irreales, Parque Jurásico opta por una aproximación sorprendentemente sobria y auténtica.

Durante bastantes escenas, se nos muestran terminales, ventanas de código y comandos que, lejos de ser decorativos, pertenecen a sistemas reales utilizados por programadores profesionales de principios de los años 90. Este detalle, que puede pasar desapercibido para el público general, resulta especialmente interesante desde un punto de vista técnico. En otras palabras, el trabajo de producción es excelente y destaca como una de las películas más respetuosas con la informática real de su época.

No es “código de película”: es software real

Uno de los puntos más interesantes es que el código que aparece en pantalla no fue escrito para la película. No hay pseudocódigo, ni pantallas diseñadas solo para quedar bonitas en cámara. Lo que se ve es software real, ejecutándose en el entorno Macintosh Programmer’s Workshop (MPW), el kit oficial de Apple para desarrolladores en aquellos años. El sistema operativo que se reconoce es un Macintosh clásico (System 7) corriendo sobre máquinas de la serie Quadra, auténticos pepinos para la época. Vamos, que cuando John Hammond decía aquello de «no hemos reparado en gastos», también iba en serio en lo informático.

«No hemos reparado en gastos»

En este punto no se le puede reprochar demasiado a la película. En líneas generales es bastante fiel a la novela, aunque la resolución del problema de seguridad se aborda de forma distinta. En el libro es el ingeniero Ray Arnold quien detecta el fallo y consigue reconducir la situación. En la película, sin embargo, el personaje desaparece cuando va a los barracones a restablecer la corriente del parque, con el resultado que todos conocemos.

Lo curioso es que muchos personajes sí cambian de forma notable con respecto al libro, el niño es mayor y más friki de los ordenadores, Ray Arnold no muere y acaba salvando la situación, o Gennaro es más atlético y bastante más valiente. Sin embargo, el gran disparate técnico permanece intacto.

En la novela se menciona de pasada a un equipo de informáticos de Cambridge que supuestamente colaboró en el diseño del software. Aun así, la puesta en marcha y la explotación del sistema recaen prácticamente en una sola persona, Dennis Nedry. Evidentemente, tanto al libro como al guion les viene de perlas que todo dependa de una única persona para que el desastre sea posible, pero cuesta aceptar que en un parque donde todo está duplicado, el control informático central dependa de una sola persona.

Curiosamente, en uno de los monitores de Nedry se puede ver una foto de Oppenheimer con la frase «Beginning of baby boom», de la que podemos sacar la conclusión de que Nedry es perfectamente consciente de que su trabajo puede tener consecuencias catastróficas e irreversibles. También es un maravilloso guiño del equipo de producción que nos está indicando exactamente donde se va originar el desastre.

Al final, Parque Jurásico no va de dinosaurios, ni siquiera de genética. Va de personas. Y, más concretamente, de personas con demasiado poder y muy pocos compañeros de equipo y poca supervisión.

Desde el punto de vista informático, la película es casi entrañable. Todo es serio, profesional y real… hasta que descubrimos que el sistema más complejo jamás construido depende, en la práctica, de un solo programador cabreado, mal pagado y con demasiadas líneas de código en la cabeza. Ningún comité de arquitectura, ninguna auditoría externa, ningún segundo par de ojos. Solo Dennis Nedry y su teclado. ¿Qué podía salir mal?

Lo curioso es que ni la película ni el libro se molestan en disimularlo demasiado. Te hablan de sistemas redundantes, de seguridad, de control absoluto… pero el corazón digital del parque es un castillo de naipes. Eso sí, un castillo de naipes programado en máquinas de primera, con software real y pantallas que hoy siguen pareciendo más creíbles que muchas producciones actuales.

Quizá por eso Parque Jurásico envejece tan bien. Porque, incluso cuando se equivoca, lo hace con honestidad. No intenta venderte magia disfrazada de tecnología. Te muestra ordenadores de verdad, código de verdad y errores muy humanos. Y al final, tanto en la novela como en la película, el mensaje es el mismo, puedes clonar dinosaurios, diseñar parques imposibles y rodearte de la mejor tecnología del mundo, que si todo depende de una sola persona, tarde o temprano, el sistema se vendrá abajo.

Y no, el problema no eran los dinosaurios, nunca lo fueron.

Stego XVI – Bytes

Intro

Os comparto un reto stego que me gustó cuando lo hice hace unos años. En realidad se tarda pocos minutos en resolverlo pero depende de tus recursos es posible que se te atragante.

Procesando a la víctima

Cuando te has enfrentado a unos cuantos retos stego lo normal es que tengas un arsenal de herramientas por las que vas a pasar a la víctima. En mi caso cuando se trata de imágenes, mi fondo de armario está formado por steganabara y stegsolve. Si con esas dos herramientas no lo veo claro ya empiezo a mirar en sus entrañas y en este caso es justo lo que hace falta, mirar en su interior.

La víctima

imagen original del reto

Estamos ante una imagen GIF de 6,36KB (6513 bytes) cuya resolución es 236×42. Debido a la extensión tenderemos a analizar los frames por si se trata de una animación. Una vez desestimada la animación entran en juego steganabara, stegsolve y demás familia. Si todo lo anterior falla abro el archivo con un editor hexadecimal y lo reviso manualmente por si hay algo que me llama la atención.

Bytes

Explorando el interior del archivo enseguida encontramos algo que llama la atención, una sucesión de bytes con espacios intercalados.

Tras copiar los bytes lo primero es eliminar los espacios y empezar a jugar con ellos. Una de las cosas que podemos hacer es convertir los bytes a ascii y voilá, nos encontramos con lo que parece otro archivo GIF.

Copiamos los bytes con la ayuda de nuestro editor hexadecimal favorito, guardamos el archivo como GIF y reto superado.

Enlaces

Nota: si algo os pide clave es deurus.info

AfKayAs’s CrackMe#2 KeyGen

Intro

Hoy vamos a desmitificar un poco a Visual Basic. El Crackme reza que acabemos con la nag y hagamos un keygen.

La NAG

formnag

Lo primero que debemos establecer es a que tipo de Nag nos estamos enfrentando, si es una MessageBox, se localiza y se parchea, si es un formulario la cosa ya cambia un poco, ya que encontrar esa parte del código puede resultar tedioso.

Yo voy a utilizar el camino fácil. En VB contamos con una estupenda herramienta como es VBReformer, que nos muestra las entrañas del crackme y nos posibilita cambiar ciertos parametros.

Abrimos el crackme con VBReformer y vemos su contenido. Localizamos rápidamente el formulario que aparece inicialmente (CMSplash) y el temporizador que contiene (Timer1). Inicialmente el timer tiene un interval de 7000, es decir, la nag se muestra durante 7 segundos. Es tan sencillo como cambiarlo por 1 y guardar el ejecutable (File > Save binary as).

parcheform

Si no disponemos de esta estupenda herramienta, siempre podemos localizar el timer con un editor hexadecimal. Localizamos en Olly el nombre del timer (en las string references lo veréis), y lo buscamos en el editor hexadecimal. La duración de la nag la debemos estimar nosotros y a continuación buscar ese valor hexadecimal. Imaginemos que estimamos que son 7 segundos, lo pasamos a milisegundos y a hexadecimal. 7000 = 0x1B58. Buscamos en el editor hexadecimal «Timer1» y a continuación localizamos el valor 1B58 invertido, es decir, 581B. En las imágenes inferiores se ve claro.

hextimer1original

hextimer1parcheado

Cambiando el valor ya lo tendriámos.

El algoritmo

El algoritmo de este crackme es muy sencillo pero he elegido este en concreto para que veáis las vueltas que da VB para hacer 6 operaciones matemáticas. A continuación tenéis el código íntegro comentado y debajo el resumen.

004081F5      .  FF15 F8B04000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaLenBstr>]    ;  MSVBVM50.__vbaLenBstr
004081FB      .  8BF8                     MOV EDI,EAX
004081FD      .  8B4D E8                  MOV ECX,DWORD PTR SS:[EBP-18]
00408200      .  69FF 385B0100            IMUL EDI,EDI,15B38                              ;  TEMP = Len(nombre) *15B38
00408206      .  51                       PUSH ECX
00408207      .  0F80 B7050000            JO CrackmeV.004087C4
0040820D      .  FF15 0CB14000            CALL DWORD PTR DS:[<&MSVBVM50.#516>]            ;  MSVBVM50.rtcAnsiValueBstr
00408213      .  0FBFD0                   MOVSX EDX,AX                                    ;  digito a ax
00408216      .  03FA                     ADD EDI,EDX                                     ;  TEMP +=1digito
00408218      .  0F80 A6050000            JO CrackmeV.004087C4
0040821E      .  57                       PUSH EDI                                        ;  MSVBVM50.__vbaObjSet
0040821F      .  FF15 F4B04000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaStrI4>]      ;  MSVBVM50.__vbaStrI4
00408225      .  8BD0                     MOV EDX,EAX
00408227      .  8D4D E0                  LEA ECX,DWORD PTR SS:[EBP-20]
0040822A      .  FF15 94B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaStrMove>]    ;  MSVBVM50.__vbaStrMove
00408230      .  8BBD 50FFFFFF            MOV EDI,DWORD PTR SS:[EBP-B0]
00408236      .  50                       PUSH EAX
00408237      .  57                       PUSH EDI                                        ;  MSVBVM50.__vbaObjSet
00408238      .  FF93 A4000000            CALL DWORD PTR DS:[EBX+A4]                      ;  MSVBVM50.0F050D32
0040823E      .  85C0                     TEST EAX,EAX
00408240      .  7D 12                    JGE SHORT CrackmeV.00408254
00408242      .  68 A4000000              PUSH 0A4
00408247      .  68 AC6F4000              PUSH CrackmeV.00406FAC
0040824C      .  57                       PUSH EDI                                        ;  MSVBVM50.__vbaObjSet
0040824D      .  50                       PUSH EAX
0040824E      .  FF15 18B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaHresultCheck>;  MSVBVM50.__vbaHresultCheckObj
00408254      >  8D45 E0                  LEA EAX,DWORD PTR SS:[EBP-20]
00408257      .  8D4D E4                  LEA ECX,DWORD PTR SS:[EBP-1C]
0040825A      .  50                       PUSH EAX
0040825B      .  8D55 E8                  LEA EDX,DWORD PTR SS:[EBP-18]
0040825E      .  51                       PUSH ECX
0040825F      .  52                       PUSH EDX
00408260      .  6A 03                    PUSH 3
00408262      .  FF15 80B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaFreeStrList>>;  MSVBVM50.__vbaFreeStrList
00408268      .  83C4 10                  ADD ESP,10
0040826B      .  8D45 D4                  LEA EAX,DWORD PTR SS:[EBP-2C]
0040826E      .  8D4D D8                  LEA ECX,DWORD PTR SS:[EBP-28]
00408271      .  8D55 DC                  LEA EDX,DWORD PTR SS:[EBP-24]
00408274      .  50                       PUSH EAX
00408275      .  51                       PUSH ECX
00408276      .  52                       PUSH EDX
00408277      .  6A 03                    PUSH 3
00408279      .  FF15 08B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaFreeObjList>>;  MSVBVM50.__vbaFreeObjList
0040827F      .  8B9D 40FFFFFF            MOV EBX,DWORD PTR SS:[EBP-C0]                   ;  CrackmeV.00409A68
00408285      .  83C4 10                  ADD ESP,10
00408288      .  8B83 FC020000            MOV EAX,DWORD PTR DS:[EBX+2FC]
0040828E      .  56                       PUSH ESI
0040828F      .  8985 38FFFFFF            MOV DWORD PTR SS:[EBP-C8],EAX
00408295      .  FFD0                     CALL EAX
00408297      .  8B3D 20B14000            MOV EDI,DWORD PTR DS:[<&MSVBVM50.__vbaObjSet>]  ;  MSVBVM50.__vbaObjSet
0040829D      .  50                       PUSH EAX
0040829E      .  8D45 D8                  LEA EAX,DWORD PTR SS:[EBP-28]
004082A1      .  50                       PUSH EAX
004082A2      .  FFD7                     CALL EDI                                        ;  MSVBVM50.__vbaObjSet; <&MSVBVM50.__vbaObjSet>
004082A4      .  56                       PUSH ESI
004082A5      .  8985 58FFFFFF            MOV DWORD PTR SS:[EBP-A8],EAX
004082AB      .  FF93 08030000            CALL DWORD PTR DS:[EBX+308]
004082B1      .  8D4D DC                  LEA ECX,DWORD PTR SS:[EBP-24]
004082B4      .  50                       PUSH EAX
004082B5      .  51                       PUSH ECX
004082B6      .  FFD7                     CALL EDI                                        ;  MSVBVM50.__vbaObjSet
004082B8      .  8BD8                     MOV EBX,EAX
004082BA      .  8D45 E8                  LEA EAX,DWORD PTR SS:[EBP-18]
004082BD      .  50                       PUSH EAX
004082BE      .  53                       PUSH EBX
004082BF      .  8B13                     MOV EDX,DWORD PTR DS:[EBX]                      ;  MSVBVM50.0F025A95
004082C1      .  FF92 A0000000            CALL DWORD PTR DS:[EDX+A0]
004082C7      .  85C0                     TEST EAX,EAX
004082C9      .  7D 12                    JGE SHORT CrackmeV.004082DD
004082CB      .  68 A0000000              PUSH 0A0
004082D0      .  68 AC6F4000              PUSH CrackmeV.00406FAC
004082D5      .  53                       PUSH EBX
004082D6      .  50                       PUSH EAX
004082D7      .  FF15 18B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaHresultCheck>;  MSVBVM50.__vbaHresultCheckObj
004082DD      >  8B8D 58FFFFFF            MOV ECX,DWORD PTR SS:[EBP-A8]
004082E3      .  8B55 E8                  MOV EDX,DWORD PTR SS:[EBP-18]
004082E6      .  52                       PUSH EDX
004082E7      .  8B19                     MOV EBX,DWORD PTR DS:[ECX]
004082E9      .  FF15 74B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaR8Str>]      ;  MSVBVM50.__vbaR8Str
004082EF      .  D905 08104000            FLD DWORD PTR DS:[401008]
004082F5      .  833D 00904000 00         CMP DWORD PTR DS:[409000],0
004082FC      .  75 08                    JNZ SHORT CrackmeV.00408306
004082FE      .  D835 0C104000            FDIV DWORD PTR DS:[40100C]                      ;  10 / 5 = 2
00408304      .  EB 0B                    JMP SHORT CrackmeV.00408311
00408306      >  FF35 0C104000            PUSH DWORD PTR DS:[40100C]
0040830C      .  E8 578DFFFF              CALL <JMP.&MSVBVM50._adj_fdiv_m32>
00408311      >  83EC 08                  SUB ESP,8
00408314      .  DFE0                     FSTSW AX
00408316      .  A8 0D                    TEST AL,0D
00408318      .  0F85 A1040000            JNZ CrackmeV.004087BF
0040831E      .  DEC1                     FADDP ST(1),ST                                  ;  TEMP +=2
00408320      .  DFE0                     FSTSW AX
00408322      .  A8 0D                    TEST AL,0D
00408324      .  0F85 95040000            JNZ CrackmeV.004087BF
0040832A      .  DD1C24                   FSTP QWORD PTR SS:[ESP]
0040832D      .  FF15 48B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaStrR8>]      ;  MSVBVM50.__vbaStrR8
00408333      .  8BD0                     MOV EDX,EAX
00408335      .  8D4D E4                  LEA ECX,DWORD PTR SS:[EBP-1C]
00408338      .  FF15 94B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaStrMove>]    ;  MSVBVM50.__vbaStrMove
0040833E      .  899D 34FFFFFF            MOV DWORD PTR SS:[EBP-CC],EBX
00408344      .  8B9D 58FFFFFF            MOV EBX,DWORD PTR SS:[EBP-A8]
0040834A      .  50                       PUSH EAX
0040834B      .  8B85 34FFFFFF            MOV EAX,DWORD PTR SS:[EBP-CC]
00408351      .  53                       PUSH EBX
00408352      .  FF90 A4000000            CALL DWORD PTR DS:[EAX+A4]
00408358      .  85C0                     TEST EAX,EAX
0040835A      .  7D 12                    JGE SHORT CrackmeV.0040836E
0040835C      .  68 A4000000              PUSH 0A4
00408361      .  68 AC6F4000              PUSH CrackmeV.00406FAC
00408366      .  53                       PUSH EBX
00408367      .  50                       PUSH EAX
00408368      .  FF15 18B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaHresultCheck>;  MSVBVM50.__vbaHresultCheckObj
0040836E      >  8D4D E4                  LEA ECX,DWORD PTR SS:[EBP-1C]
00408371      .  8D55 E8                  LEA EDX,DWORD PTR SS:[EBP-18]
00408374      .  51                       PUSH ECX
00408375      .  52                       PUSH EDX
00408376      .  6A 02                    PUSH 2
00408378      .  FF15 80B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaFreeStrList>>;  MSVBVM50.__vbaFreeStrList
0040837E      .  83C4 0C                  ADD ESP,0C
00408381      .  8D45 D8                  LEA EAX,DWORD PTR SS:[EBP-28]
00408384      .  8D4D DC                  LEA ECX,DWORD PTR SS:[EBP-24]
00408387      .  50                       PUSH EAX
00408388      .  51                       PUSH ECX
00408389      .  6A 02                    PUSH 2
0040838B      .  FF15 08B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaFreeObjList>>;  MSVBVM50.__vbaFreeObjList
00408391      .  8B95 40FFFFFF            MOV EDX,DWORD PTR SS:[EBP-C0]                   ;  CrackmeV.00409A68
00408397      .  83C4 0C                  ADD ESP,0C
0040839A      .  8B82 00030000            MOV EAX,DWORD PTR DS:[EDX+300]
004083A0      .  56                       PUSH ESI
004083A1      .  8985 30FFFFFF            MOV DWORD PTR SS:[EBP-D0],EAX
004083A7      .  FFD0                     CALL EAX
004083A9      .  50                       PUSH EAX
004083AA      .  8D45 D8                  LEA EAX,DWORD PTR SS:[EBP-28]
004083AD      .  50                       PUSH EAX
004083AE      .  FFD7                     CALL EDI                                        ;  MSVBVM50.__vbaObjSet
004083B0      .  56                       PUSH ESI
004083B1      .  8985 58FFFFFF            MOV DWORD PTR SS:[EBP-A8],EAX
004083B7      .  FF95 38FFFFFF            CALL DWORD PTR SS:[EBP-C8]                      ;  MSVBVM50.0F10C340
004083BD      .  8D4D DC                  LEA ECX,DWORD PTR SS:[EBP-24]
004083C0      .  50                       PUSH EAX
004083C1      .  51                       PUSH ECX
004083C2      .  FFD7                     CALL EDI                                        ;  MSVBVM50.__vbaObjSet
004083C4      .  8BD8                     MOV EBX,EAX
004083C6      .  8D45 E8                  LEA EAX,DWORD PTR SS:[EBP-18]
004083C9      .  50                       PUSH EAX
004083CA      .  53                       PUSH EBX
004083CB      .  8B13                     MOV EDX,DWORD PTR DS:[EBX]                      ;  MSVBVM50.0F025A95
004083CD      .  FF92 A0000000            CALL DWORD PTR DS:[EDX+A0]
004083D3      .  85C0                     TEST EAX,EAX
004083D5      .  7D 12                    JGE SHORT CrackmeV.004083E9
004083D7      .  68 A0000000              PUSH 0A0
004083DC      .  68 AC6F4000              PUSH CrackmeV.00406FAC
004083E1      .  53                       PUSH EBX
004083E2      .  50                       PUSH EAX
004083E3      .  FF15 18B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaHresultCheck>;  MSVBVM50.__vbaHresultCheckObj
004083E9      >  8B8D 58FFFFFF            MOV ECX,DWORD PTR SS:[EBP-A8]
004083EF      .  8B55 E8                  MOV EDX,DWORD PTR SS:[EBP-18]
004083F2      .  52                       PUSH EDX
004083F3      .  8B19                     MOV EBX,DWORD PTR DS:[ECX]
004083F5      .  FF15 74B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaR8Str>]      ;  MSVBVM50.__vbaR8Str
004083FB      .  DC0D 10104000            FMUL QWORD PTR DS:[401010]                      ;  *3
00408401      .  83EC 08                  SUB ESP,8                                       ;  -2
00408404      .  DC25 18104000            FSUB QWORD PTR DS:[401018]
0040840A      .  DFE0                     FSTSW AX
0040840C      .  A8 0D                    TEST AL,0D
0040840E      .  0F85 AB030000            JNZ CrackmeV.004087BF
00408414      .  DD1C24                   FSTP QWORD PTR SS:[ESP]
00408417      .  FF15 48B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaStrR8>]      ;  MSVBVM50.__vbaStrR8
0040841D      .  8BD0                     MOV EDX,EAX
0040841F      .  8D4D E4                  LEA ECX,DWORD PTR SS:[EBP-1C]
00408422      .  FF15 94B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaStrMove>]    ;  MSVBVM50.__vbaStrMove
00408428      .  899D 2CFFFFFF            MOV DWORD PTR SS:[EBP-D4],EBX
0040842E      .  8B9D 58FFFFFF            MOV EBX,DWORD PTR SS:[EBP-A8]
00408434      .  50                       PUSH EAX
00408435      .  8B85 2CFFFFFF            MOV EAX,DWORD PTR SS:[EBP-D4]
0040843B      .  53                       PUSH EBX
0040843C      .  FF90 A4000000            CALL DWORD PTR DS:[EAX+A4]
00408442      .  85C0                     TEST EAX,EAX
00408444      .  7D 12                    JGE SHORT CrackmeV.00408458
00408446      .  68 A4000000              PUSH 0A4
0040844B      .  68 AC6F4000              PUSH CrackmeV.00406FAC
00408450      .  53                       PUSH EBX
00408451      .  50                       PUSH EAX
00408452      .  FF15 18B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaHresultCheck>;  MSVBVM50.__vbaHresultCheckObj
00408458      >  8D4D E4                  LEA ECX,DWORD PTR SS:[EBP-1C]
0040845B      .  8D55 E8                  LEA EDX,DWORD PTR SS:[EBP-18]
0040845E      .  51                       PUSH ECX
0040845F      .  52                       PUSH EDX
00408460      .  6A 02                    PUSH 2
00408462      .  FF15 80B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaFreeStrList>>;  MSVBVM50.__vbaFreeStrList
00408468      .  83C4 0C                  ADD ESP,0C
0040846B      .  8D45 D8                  LEA EAX,DWORD PTR SS:[EBP-28]
0040846E      .  8D4D DC                  LEA ECX,DWORD PTR SS:[EBP-24]
00408471      .  50                       PUSH EAX
00408472      .  51                       PUSH ECX
00408473      .  6A 02                    PUSH 2
00408475      .  FF15 08B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaFreeObjList>>;  MSVBVM50.__vbaFreeObjList
0040847B      .  8B95 40FFFFFF            MOV EDX,DWORD PTR SS:[EBP-C0]                   ;  CrackmeV.00409A68
00408481      .  83C4 0C                  ADD ESP,0C
00408484      .  8B82 04030000            MOV EAX,DWORD PTR DS:[EDX+304]
0040848A      .  56                       PUSH ESI
0040848B      .  8985 28FFFFFF            MOV DWORD PTR SS:[EBP-D8],EAX
00408491      .  FFD0                     CALL EAX
00408493      .  50                       PUSH EAX
00408494      .  8D45 D8                  LEA EAX,DWORD PTR SS:[EBP-28]
00408497      .  50                       PUSH EAX
00408498      .  FFD7                     CALL EDI                                        ;  MSVBVM50.__vbaObjSet
0040849A      .  56                       PUSH ESI
0040849B      .  8985 58FFFFFF            MOV DWORD PTR SS:[EBP-A8],EAX
004084A1      .  FF95 30FFFFFF            CALL DWORD PTR SS:[EBP-D0]                      ;  MSVBVM50.0F10C348
004084A7      .  8D4D DC                  LEA ECX,DWORD PTR SS:[EBP-24]
004084AA      .  50                       PUSH EAX
004084AB      .  51                       PUSH ECX
004084AC      .  FFD7                     CALL EDI                                        ;  MSVBVM50.__vbaObjSet
004084AE      .  8BD8                     MOV EBX,EAX
004084B0      .  8D45 E8                  LEA EAX,DWORD PTR SS:[EBP-18]
004084B3      .  50                       PUSH EAX
004084B4      .  53                       PUSH EBX
004084B5      .  8B13                     MOV EDX,DWORD PTR DS:[EBX]                      ;  MSVBVM50.0F025A95
004084B7      .  FF92 A0000000            CALL DWORD PTR DS:[EDX+A0]
004084BD      .  85C0                     TEST EAX,EAX
004084BF      .  7D 12                    JGE SHORT CrackmeV.004084D3
004084C1      .  68 A0000000              PUSH 0A0
004084C6      .  68 AC6F4000              PUSH CrackmeV.00406FAC
004084CB      .  53                       PUSH EBX
004084CC      .  50                       PUSH EAX
004084CD      .  FF15 18B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaHresultCheck>;  MSVBVM50.__vbaHresultCheckObj
004084D3      >  8B8D 58FFFFFF            MOV ECX,DWORD PTR SS:[EBP-A8]
004084D9      .  8B55 E8                  MOV EDX,DWORD PTR SS:[EBP-18]
004084DC      .  52                       PUSH EDX
004084DD      .  8B19                     MOV EBX,DWORD PTR DS:[ECX]
004084DF      .  FF15 74B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaR8Str>]      ;  MSVBVM50.__vbaR8Str
004084E5      .  DC25 20104000            FSUB QWORD PTR DS:[401020]                      ;  TEMP -= -15
004084EB      .  83EC 08                  SUB ESP,8
004084EE      .  DFE0                     FSTSW AX
004084F0      .  A8 0D                    TEST AL,0D
004084F2      .  0F85 C7020000            JNZ CrackmeV.004087BF
........
00408677      . /74 62                    JE SHORT CrackmeV.004086DB
00408679      . |8B35 14B14000            MOV ESI,DWORD PTR DS:[<&MSVBVM50.__vbaStrCat>]  ;  MSVBVM50.__vbaStrCat
0040867F      . |68 C06F4000              PUSH CrackmeV.00406FC0                          ;  UNICODE "You Get It"
00408684      . |68 DC6F4000              PUSH CrackmeV.00406FDC                          ;  UNICODE "\r\n"
00408689      . |FFD6                     CALL ESI                                        ;  <&MSVBVM50.__vbaStrCat>
0040868B      . |8BD0                     MOV EDX,EAX
0040868D      . |8D4D E8                  LEA ECX,DWORD PTR SS:[EBP-18]
00408690      . |FF15 94B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaStrMove>]    ;  MSVBVM50.__vbaStrMove
00408696      . |50                       PUSH EAX
00408697      . |68 E86F4000              PUSH CrackmeV.00406FE8                          ;  UNICODE "KeyGen It Now"

Que se puede resumir en esto.

004081F5      .  FF15 F8B04000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaLenBstr>]    ;  MSVBVM50.__vbaLenBstr
004081FB      .  8BF8                     MOV EDI,EAX
004081FD      .  8B4D E8                  MOV ECX,DWORD PTR SS:[EBP-18]
00408200      .  69FF 385B0100            IMUL EDI,EDI,15B38                              ;  TEMP = Len(nombre) *15B38
00408206      .  51                       PUSH ECX
00408207      .  0F80 B7050000            JO CrackmeV.004087C4
0040820D      .  FF15 0CB14000            CALL DWORD PTR DS:[<&MSVBVM50.#516>]            ;  MSVBVM50.rtcAnsiValueBstr
00408213      .  0FBFD0                   MOVSX EDX,AX                                    ;  digito a ax
00408216      .  03FA                     ADD EDI,EDX                                     ;  TEMP +=1digito
00408218      .  0F80 A6050000            JO CrackmeV.004087C4
........
004082E9      .  FF15 74B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaR8Str>]      ;  MSVBVM50.__vbaR8Str
004082EF      .  D905 08104000            FLD DWORD PTR DS:[401008]
004082F5      .  833D 00904000 00         CMP DWORD PTR DS:[409000],0
004082FC      .  75 08                    JNZ SHORT CrackmeV.00408306
004082FE      .  D835 0C104000            FDIV DWORD PTR DS:[40100C]                      ;  10 / 5 = 2
00408304      .  EB 0B                    JMP SHORT CrackmeV.00408311
00408306      >  FF35 0C104000            PUSH DWORD PTR DS:[40100C]
0040830C      .  E8 578DFFFF              CALL <JMP.&MSVBVM50._adj_fdiv_m32>
00408311      >  83EC 08                  SUB ESP,8
00408314      .  DFE0                     FSTSW AX
00408316      .  A8 0D                    TEST AL,0D
00408318      .  0F85 A1040000            JNZ CrackmeV.004087BF
0040831E      .  DEC1                     FADDP ST(1),ST                                  ;  TEMP +=2
00408320      .  DFE0                     FSTSW AX
00408322      .  A8 0D                    TEST AL,0D
........
004083F5      .  FF15 74B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaR8Str>]      ;  MSVBVM50.__vbaR8Str
004083FB      .  DC0D 10104000            FMUL QWORD PTR DS:[401010]                      ;  TEMP *=3
00408401      .  83EC 08                  SUB ESP,8                                       ;  TEMP -=2
00408404      .  DC25 18104000            FSUB QWORD PTR DS:[401018]
0040840A      .  DFE0                     FSTSW AX
0040840C      .  A8 0D                    TEST AL,0D
........
004084DF      .  FF15 74B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaR8Str>]      ;  MSVBVM50.__vbaR8Str
004084E5      .  DC25 20104000            FSUB QWORD PTR DS:[401020]                      ;  TEMP -= -15
004084EB      .  83EC 08                  SUB ESP,8
004084EE      .  DFE0                     FSTSW AX
004084F0      .  A8 0D                    TEST AL,0D
004084F2      .  0F85 C7020000            JNZ CrackmeV.004087BF
........
00408677      . /74 62                    JE SHORT CrackmeV.004086DB
00408679      . |8B35 14B14000            MOV ESI,DWORD PTR DS:[<&MSVBVM50.__vbaStrCat>]  ;  MSVBVM50.__vbaStrCat
0040867F      . |68 C06F4000              PUSH CrackmeV.00406FC0                          ;  UNICODE "You Get It"
00408684      . |68 DC6F4000              PUSH CrackmeV.00406FDC                          ;  UNICODE "\r\n"
00408689      . |FFD6                     CALL ESI                                        ;  <&MSVBVM50.__vbaStrCat>
0040868B      . |8BD0                     MOV EDX,EAX
0040868D      . |8D4D E8                  LEA ECX,DWORD PTR SS:[EBP-18]
00408690      . |FF15 94B14000            CALL DWORD PTR DS:[<&MSVBVM50.__vbaStrMove>]    ;  MSVBVM50.__vbaStrMove
00408696      . |50                       PUSH EAX
00408697      . |68 E86F4000              PUSH CrackmeV.00406FE8                          ;  UNICODE "KeyGen It Now"

Y en esto:

TEMP = Len(nombre) *15B38
TEMP += 1ºdigitoascii
TEMP +=2
TEMP *=3
TEMP -=2
TEMP +=15

 Y el KeyGen nos ocupa una sola línea

txtserial.Text = (((((Len(txtnombre.Text) * 88888) + Asc(Mid(txtn.Text, 1, 1))) + 2) * 3) - 2) + 15

 Huevo de pascua (Easter egg)

Si nos fijamos en el VBReformer, en el formulario principal vemos muchas cajas de texto.

vbreformervistaproject

Las hacemos visibles, guardamos y ejecutamos haber que pasa.

textsvisibles

crackmebonus

Lo que pasa es que va guardando el resultado de las operaciones en ellas y en la de arriba concretamente está nuestro serial bueno, lo que nos hace poseedores de un KeyGen encubierto.

Links


Intro Hoy tenemos aquí un crackme del 2009 originario de crackmes.de. El Crackme está hecho en VB6, sin empacar y
https://www.youtube.com/watch?v=iOYAn4l4wco Lista de reproducción
Introducción Hoy vamos a enfrentarnos a cuatro retos de esteganografía relativamente sencillos, y digo relativamente, debido a que hay tantas
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en

Solución a los CrackMes de CrkViZ 1-5

Introducción

Esta vez vamos a analizar los CrackMes de un antiguo colaborador de Karpoff Spanish Tutor, CrkViZ. En estas cinco soluciones vamos a pelearnos con Visual Basic 5/6 nativo y Pcode, con el registro de Windows y tendremos que parchear algúna rutina antidebug. Los CrackMes son del año 2000 y aunque algunos estaban ya solucionados, los analizaremos igualmente para ver la diferencia que existe con los análisis realizados en aquellos años, sí, estamos hablando del Softice.

Herramientas disponibles

Cuando hablamos de Visual Basic 5/6, podemos destacar 3 herramientas que nos facilitan mucho la vida, VB Decompiler, VB Reformer y ExDec. Las dos primeras se defienden bien tanto con código nativo como pcode y ExDec solamente nos sirve para pcode. Aún así, si todo lo demás falla, Ollydbg nos sacará de apuros.

CrkViz-1

03-03-2015 13-16-27

03-03-2015 13-16-17

Este primer crackme está compilado en Pcode y hoy día, con las herramientas de que disponemos no supone ninguna dificultad. Tan solo debemos abrirlo con VB Decompiler y ya nos encontramos con el serial válido.

03-03-2015 13-14-18

Los opcodes obtenidos con ExDec se ven de la siguiente manera.

......
402F14: 04 FLdRfVar                local_008C
402F17: 21 FLdPrThis              
402F18: 0f VCallAd                 7b3fc340
402F1B: 19 FStAdFunc               local_0088
402F1E: 08 FLdPr                   local_0088
402F21: 0d VCallHresult            7b3fbe88
402F26: 6c ILdRf                   local_008C
402F29: 1b LitStr:                 57230198        <--------------
402F2C: Lead0/30 EqStr            
402F2E: 2f FFree1Str               local_008C
402F31: 1a FFree1Ad                local_0088
402F34: 1c BranchF:                403012
402F37: 21 FLdPrThis              
402F38: 0d VCallHresult            7b3fc2b0
402F3D: 3a LitVarStr:              ( local_00AC )  Gracias por Registrar!!      
402F42: Lead2/00 FStVarCopy       
402F46: 27 LitVar_Missing         
402F49: 27 LitVar_Missing         
402F4C: 3a LitVarStr:              ( local_00AC ) CrkViz
402F51: 4e FStVarCopyObj           local_00BC
402F54: 04 FLdRfVar                local_00BC
402F57: f5 LitI4:                  0x40  64  (...@)
402F5C: 04 FLdRfVar                local_009C
402F5F: 0a ImpAdCallFPR4:          _rtcMsgBox
402F64: 36 FFreeVar
402F6D: 27 LitVar_Missing         
402F70: 25 PopAdLdVar             
402F71: 27 LitVar_Missing
......

CrkViz-2

03-03-2015 13-18-32

Este segundo crackme también está compilado en pcode. La rutina del serial es muy sencilla pero al introducir un número aleatorio nos obliga a parchear. Cargamos el crackme en VB Decompiler y nos muestra esto:

03-03-2015 13-19-48

Básicamente vemos que genera un número aleatorio entre 1 y 999999999 y luego le suma 1. La forma de afrontar esto es parcheando. Nos fijamos en el offset aproximado (4037F2) y abrimos el crackme en un editor hexadecimal. La forma de convertir el offset que nos muestra VB Decompiler a lo que nos muestra un editor hexadecimal es la siguiente.

VBdec_offset - Image Base - VirtualOffset + RawOffset = Offset_Editor.H

4037F2 - 400000 - 1000 + 400 = 2BF2

03-03-2015 14-00-27

Una vez localizados los bytes, los cambiamos por ceros y guardamos.

01-03-2015 04-50-05 01-03-2015 04-52-10

Una vez parcheado, el serial correcto es 1.

CrkViz-3

11-03-2015 21-20-07

En esta tercera entrega, CrkViz aumentó la dificultad. El crackme está compilado en código nativo y nos enfrentamos a un serial asociado a un nombre y a una rutina antidebug que en realidad es una Nag, ya que se muestra siempre.

Afrontar la nag es muy sencillo, basta con localizarla y parchear la llamada.

CPU Disasm
Address   Hex dump          Command                                            Comments
004058E2    8D4D DC         LEA ECX,[EBP-24]
004058E5    C785 BCFDFFFF B MOV DWORD PTR SS:[EBP-244],CrkMeViz-3.004033B8     ; UNICODE "  Debugger detectado!!!   "
004058EF    C785 B4FDFFFF 0 MOV DWORD PTR SS:[EBP-24C],8
004058F9    FFD7            CALL EDI
004058FB    B9 04000280     MOV ECX,80020004
00405900    B8 0A000000     MOV EAX,0A
00405905    898D FCFDFFFF   MOV DWORD PTR SS:[EBP-204],ECX
0040590B    898D 0CFEFFFF   MOV DWORD PTR SS:[EBP-1F4],ECX
00405911    8D95 B4FDFFFF   LEA EDX,[EBP-24C]
00405917    8D8D 14FEFFFF   LEA ECX,[EBP-1EC]
0040591D    8985 F4FDFFFF   MOV DWORD PTR SS:[EBP-20C],EAX
00405923    8985 04FEFFFF   MOV DWORD PTR SS:[EBP-1FC],EAX
00405929    C785 BCFDFFFF 8 MOV DWORD PTR SS:[EBP-244],CrkMeViz-3.00403188     ; UNICODE "Error"
00405933    C785 B4FDFFFF 0 MOV DWORD PTR SS:[EBP-24C],8
0040593D    FF15 C8914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarDup>]
00405943    8D85 F4FDFFFF   LEA EAX,[EBP-20C]
00405949    8D8D 04FEFFFF   LEA ECX,[EBP-1FC]
0040594F    50              PUSH EAX
00405950    8D95 14FEFFFF   LEA EDX,[EBP-1EC]
00405956    51              PUSH ECX
00405957    52              PUSH EDX
00405958    8D45 DC         LEA EAX,[EBP-24]
0040595B    6A 10           PUSH 10
0040595D    50              PUSH EAX
0040595E    FF15 50914000   CALL DWORD PTR DS:[<&MSVBVM50.#595>]               ; rtcMsgBox - NOPear para evitar la NAG
00405964    8D8D F4FDFFFF   LEA ECX,[EBP-20C]

Antes de llegar al keygen vemos que realiza unas llamadas al registro de Windows, ponemos un breakpoint «bp RegOpenKeyW» y ejecutamos.

CPU Disasm
Address   Hex dump            Command                                  Comments
00405677  |.  8B8D B8FDFFFF   MOV ECX,DWORD PTR SS:[EBP-248]
0040567D  |.  B8 54334000     MOV EAX,CrkMeViz-3.00403354              ; UNICODE "<Unregister>"
00405682  |.  68 B4304000     PUSH CrkMeViz-3.004030B4                 ; UNICODE "Serial number"
00405687  |.  894A 04         MOV DWORD PTR DS:[EDX+4],ECX
0040568A  |.  8985 BCFDFFFF   MOV DWORD PTR SS:[EBP-244],EAX
00405690  |.  68 84304000     PUSH CrkMeViz-3.00403084                 ; UNICODE "Register"
00405695  |.  68 58304000     PUSH CrkMeViz-3.00403058                 ; UNICODE "CrkMeViz3"
0040569A  |.  8942 08         MOV DWORD PTR DS:[EDX+8],EAX
0040569D  |.  8B85 C0FDFFFF   MOV EAX,DWORD PTR SS:[EBP-240]
004056A3  |.  8942 0C         MOV DWORD PTR DS:[EDX+0C],EAX
004056A6  |.  FF15 C0914000   CALL DWORD PTR DS:[<&MSVBVM50.#689>] 	; rtcGetSetting - Lee el numero de serie del registro
........
0040574F  |.  68 9C304000     PUSH CrkMeViz-3.0040309C                  ; UNICODE "User Name"
00405754  |.  68 84304000     PUSH CrkMeViz-3.00403084                  ; UNICODE "Register"
00405759  |.  68 58304000     PUSH CrkMeViz-3.00403058                  ; UNICODE "CrkMeViz3"
0040575E  |.  8948 08         MOV DWORD PTR DS:[EAX+8],ECX
00405761  |.  8B8D C0FDFFFF   MOV ECX,DWORD PTR SS:[EBP-240]
00405767  |.  8948 0C         MOV DWORD PTR DS:[EAX+0C],ECX
0040576A  |.  FF15 C0914000   CALL DWORD PTR DS:[<&MSVBVM50.#689>]	; rtcGetSetting - Lee el Usuario del registro

 Reconstruyendo la llamada al registro vemos que lee de esta ruta: HKEY_CURRENT_USER\Software\VB and VBA Program Settings\CrkMeViz3\Register el contenido de User Name y del Serial number.

Quizá uno de los fallos de éste crackme, es que no comprueba la autenticidad de estos parámetros y si los modificas parece que estás registrado. Un ejemplo:

11-03-2015 22-23-28

La rutina de comprobación del serial no es para nada complicada pero recordemos que estamos tratando con VB y éste delega el trabajo duro en otras librerias de modo que tenemos que «meternos» a tracear las llamadas para ver los valores que multiplica y divide.

CPU Disasm
Address     Hex dump          Command                                            Comments
00405A86      FF15 3C914000   CALL DWORD PTR DS:[<&MSVBVM50.#518>]    ;MSVBVM50.rtcLowerCaseVar
00405A8C      8D95 14FEFFFF   LEA EDX,[EBP-1EC]
00405A92      8D8D ACFEFFFF   LEA ECX,[EBP-154]
00405A98      FFD6            CALL ESI
00405A9A      8D95 ACFEFFFF   LEA EDX,[EBP-154]
00405AA0      8D8D 4CFEFFFF   LEA ECX,[EBP-1B4]
00405AA6      FFD7            CALL EDI
00405AA8      8D95 4CFEFFFF   LEA EDX,[EBP-1B4]
00405AAE      8D8D 7CFFFFFF   LEA ECX,[EBP-84]
00405AB4      FFD7            CALL EDI
00405AB6      8D85 14FEFFFF   LEA EAX,[EBP-1EC]
00405ABC      8D8D 7CFFFFFF   LEA ECX,[EBP-84]
00405AC2      50              PUSH EAX
00405AC3      6A 01           PUSH 1
00405AC5      8D95 04FEFFFF   LEA EDX,[EBP-1FC]
00405ACB      51              PUSH ECX
00405ACC      52              PUSH EDX
00405ACD      C785 1CFEFFFF 0 MOV DWORD PTR SS:[EBP-1E4],1
00405AD7      C785 14FEFFFF 0 MOV DWORD PTR SS:[EBP-1EC],2
00405AE1      FF15 68914000   CALL DWORD PTR DS:[<&MSVBVM50.#632>]   ;MSVBVM50.rtcMidCharVar (Esto lo hace 6 veces, lo omito para abreviar.)
........
00405CE1      FF15 34914000   CALL DWORD PTR DS:[<&MSVBVM50.#516>]   ;MSVBVM50.rtcAnsiValueBstr (Lo mismo, otras 6)
........
00405E7C    C785 BCFDFFFF 2 MOV DWORD PTR SS:[EBP-244],52E
00405E86    C785 B4FDFFFF 0 MOV DWORD PTR SS:[EBP-24C],2
00405E90    50              PUSH EAX
00405E91    FF15 84914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
		|
		->MSVBVM50.__vbaVarMul
			........
			741C19D3      0FB745 FE       MOVZX EAX,WORD PTR SS:[EBP-2]       ;Valor1
			741C19D7      0FB74D F2       MOVZX ECX,WORD PTR SS:[EBP-0E]      ;Valor2
			741C19DB      6BC0 12         IMUL EAX,EAX,12                     ;Valor1*Valor2
			........
00405E97    8D8D 04FEFFFF   LEA ECX,[EBP-1FC]
00405E9D    50              PUSH EAX
00405E9E    51              PUSH ECX
00405E9F    FF15 84914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
00405EA5    8D95 F4FDFFFF   LEA EDX,[EBP-20C]
00405EAB    50              PUSH EAX
00405EAC    52              PUSH EDX
00405EAD    FF15 84914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
00405EB3    50              PUSH EAX
00405EB4    8D85 E4FDFFFF   LEA EAX,[EBP-21C]
00405EBA    50              PUSH EAX
00405EBB    FF15 84914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
00405EC1    8D8D D4FDFFFF   LEA ECX,[EBP-22C]
00405EC7    50              PUSH EAX
00405EC8    51              PUSH ECX
00405EC9    FF15 84914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
00405ECF    50              PUSH EAX
00405ED0    8D95 B4FDFFFF   LEA EDX,[EBP-24C]
00405ED6    8D85 C4FDFFFF   LEA EAX,[EBP-23C]
00405EDC    52              PUSH EDX
00405EDD    50              PUSH EAX
00405EDE    FF15 94914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarDiv>]
		|
		->MSVBVM50.__vbaVarDiv
			........
			741C8094      DD43 08         FLD QWORD PTR DS:[EBX+8]      ;Recupera el resultado de las multiplicaciones anteriores
			741C8097      0FBF47 08       MOVSX EAX,WORD PTR DS:[EDI+8] ;EAX = 1326 (52E)
			741C809B      8945 F8         MOV DWORD PTR SS:[EBP-8],EAX
			741C809E      DA75 F8         FIDIV DWORD PTR SS:[EBP-8]    ;Divide los dos resultados
			741C80A1      DD5E 08         FSTP QWORD PTR DS:[ESI+8]
			........
00405F44      FF15 24914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaLenBstr>]          ;Len(nombre)
........
00405F85      FF15 94914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarDiv>]           ;Resultado anterior / Len(nombre)
........

En resumen:

  • Pasa nuestro nombre a minúsculas.
  • Obtiene el valor ascii de los 6 primeros dígitos del nombre.
  • Los multiplica entre sí y divide el resultado acumulado entre 1326 (52E).
  • Divide el resultado anterior entre el tamaño del nombre.

Ejemplo para deurus

64*65*75*72*75*73 = 1A605D70EB8
1A605D70EB8 / 52E = 5179FBF4
5179FBF4 / 6 = D9454A9

11-03-2015 21-20-17

Al estar correctamente registrados desaparece el botón de registrar.

CrkViz-4

12-03-2015 23-09-07

El cuarto crackme es prácticamente igual que el tercero salvo que en vez de nag ahora contamos con limitación de ejecuciones. Del mismo modo utiliza el registro de Windows para guardar los datos de registro y las ejecuciones que llevamos.

Ponemos un breakpoint «bp RegOpenKeyW» y llegamos a la conclusión de que la ruta es HKEY_CURRENT_USER\Software\VB and VBA Program Settings\ODBC\Register y los valores se guardan en Counter, User Name y Serial number respectivamente. Este crackme hereda el fallo del anterior y si alteramos los valores el crackme nos muestra como usuarios autorizados, aunque sabemos que no estamos registrados ya que seguimos limitados por ejecuciones. Ni que decir tiene que lo mismo que modificamos el nombre y número de serie, podemos modificar el contador a nuestro favor. Crear un archivo «Reiniciar_contador.reg» con el siguiente contenido sería suficiente.

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\VB and VBA Program Settings\ODBC]

[HKEY_CURRENT_USER\Software\VB and VBA Program Settings\ODBC\Register]
"Counter"="0"
"User Name"="deurus"
"Serial number"="12345"

El keygen es prácticamente igual que en el crackme anterior, solo cambia el divisor.

CPU Disasm
Address   Hex dump          Command                                                   Comments
........
00404BD2    C785 BCFDFFFF C MOV DWORD PTR SS:[EBP-244],6C1
00404BDC    C785 B4FDFFFF 0 MOV DWORD PTR SS:[EBP-24C],2
00404BE6    FF15 A0914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
   |
    ->MSVBVM50.__vbaVarMul
	741C19F9    0FBF4F 08       MOVSX ECX,WORD PTR DS:[EDI+8]      ;Valor1
	741C19FD    0FBF43 08       MOVSX EAX,WORD PTR DS:[EBX+8]      ;Valor2
	741C1A01    0FAFC8          IMUL ECX,EAX                       ;Valor1*Valor2
........
00404BEC    8D8D 04FEFFFF   LEA ECX,[EBP-1FC]
00404BF2    50              PUSH EAX
00404BF3    51              PUSH ECX
00404BF4    FF15 A0914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
00404BFA    8D95 F4FDFFFF   LEA EDX,[EBP-20C]
00404C00    50              PUSH EAX
00404C01    52              PUSH EDX
00404C02    FF15 A0914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
00404C08    50              PUSH EAX
00404C09    8D85 E4FDFFFF   LEA EAX,[EBP-21C]
00404C0F    50              PUSH EAX
00404C10    FF15 A0914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
00404C16    8D8D D4FDFFFF   LEA ECX,[EBP-22C]
00404C1C    50              PUSH EAX
00404C1D    51              PUSH ECX
00404C1E    FF15 A0914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
00404C24    50              PUSH EAX
00404C25    8D95 B4FDFFFF   LEA EDX,[EBP-24C]
00404C2B    8D85 C4FDFFFF   LEA EAX,[EBP-23C]
00404C31    52              PUSH EDX
00404C32    50              PUSH EAX
00404C33    FF15 B0914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarDiv>]
   |
    ->MSVBVM50.__vbaVarDiv
	741C8094    DD43 08         FLD QWORD PTR DS:[EBX+8]              ; Recupera el resultado de las multiplicaciones anteriores
	741C8097    0FBF47 08       MOVSX EAX,WORD PTR DS:[EDI+8]         ; EAX = 1729 (6C1)
	741C809B    8945 F8         MOV DWORD PTR SS:[EBP-8],EAX
	741C809E    DA75 F8         FIDIV DWORD PTR SS:[EBP-8]

00404C39    8BD0            MOV EDX,EAX
........
00404CA0    FF15 3C914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaLenBstr>]  ;Len(nombre)
........
00404CF1    FF15 B0914000   CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarDiv>]   ;Resultado anterior / Len(nombre)

En resumen:

  • Pasa nuestro nombre a minúsculas.
  • Obtiene el valor ascii de los 6 primeros dígitos del nombre.
  • Los multiplica entre sí y divide el resultado acumulado entre 1729 (6C1).
  • Divide el resultado anterior entre el tamaño del nombre.

Ejemplo para deurus

64*65*75*72*75*73 = 1A605D70EB8
1A605D70EB8 / 6C1 = 3E7C594A
3E7C594A / 6 = A6A0EE2

CrkViz-5

11-03-2015 23-23-16

Este último crackme está compilado en código nativo y simplemente se trata de una comparación lineal. La única diferencia reside en que no hay botón de registro, la comprobación la gestiona un evento «On Change«, de modo que está comprobando el tamaño del serial que introducimos y cuando éste tiene 8 dígitos llegamos aquí.

........
0040A64F         .  C745 9C CDD4DD02    MOV DWORD PTR SS:[EBP-64],2DDD4CD      ;2DDD4CD = 48092365
0040A656         .  C745 94 03800000    MOV DWORD PTR SS:[EBP-6C],8003
0040A65D         .  FF15 08C14000       CALL DWORD PTR DS:[<&MSVBVM50.__vbaVa> ;MSVBVM50.__vbaVarTstEq
0040A663         .  66:85C0             TEST AX,AX
0040A666         .  0F84 BA000000       JE CrkMeViZ.0040A726                   ;Si salta BAD  BOY
........

Luego el serial correcto es 48092365.

Notas finales

¿Ha sido indoloro no?, claro que sí, Visual Basic es un coñazo de tracear pero hay que reconocer que con el tiempo las herramientas han mejorado mucho y nuestra vida es mucho más sencilla. Bueno, pués esto ha sido todo, como siempre os dejo todo el material utilizado y un Keygen.

12-03-2015 23-06-33

Enlaces

Sotanez’s Crackme1 Keygen

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


El reto consiste en dos imágenes (v1.png y v2.png) que, a simple vista, parecen contener ruido aleatorio. Sin embargo, ambas
http://youtu.be/c4CNY902SAE Versión de texto Lista de reproducción
Los retos criptográficos son muy variados y muchas veces la dificultad está en saber a que te enfrentas. En este
Introducción Javascript 1 (Serial a la vista) Javascript 2 (La función charAt()) Javascript 3 (Input) Javascript 4 (Fuerza bruta manual) Javascript

Reto Stego – Dos por Uno

El reto consiste en dos imágenes (v1.png y v2.png) que, a simple vista, parecen contener ruido aleatorio. Sin embargo, ambas forman parte de un sistema de criptografía visual en la que cada imagen contiene información parcial que no es interpretable por separado, pero que al combinarse correctamente revelan información oculta.

La trampa está en que la combinación no se hace con operaciones normales como suma, resta o multiplicación. El autor del reto espera que el jugador use una herramienta como StegSolve y pruebe distintas operaciones tipo XOR, AND o MUL hasta encontrar una transformación en la que uno de los métodos muestre algo significativo. El truco está en llegar a la conclusión de que una de las imágenes hay que invertirla antes de combinar ambas imágenes. Todo esto se puede hacer con StegSolve sin necesidad de utilizar ninguna herramienta adicional, pero voy a aprovechar para hacerlo con python y así de paso entendemos como realiza las operaciones StegSolve. En resumen, para resolver el reto basta con:

  1. Invertir (Colour Inversion XOR) una de las imágenes.
  2. Combinar ambas imágenes mediante Analyse > Combine images.
  3. Operación MUL del combinador.

La operación MUL no es una multiplicación normalizada, sino una multiplicación de enteros de 24 bits (0xRRGGBB) con overflow, algo que la mayoría de herramientas no replican correctamente.

¿Por qué aparece la solución con esa combinación

Las imágenes están preparadas para que ciertos bits de color en una imagen sean el complemento de los de la otra. Por tanto:

  • Si se muestran tal cual → parecen ruido
  • Si se combinan mediante XOR → parte de la estructura aparece, pero no se ve el resultado correcto
  • Si se combinan mediante MUL «normal» → tampoco aparece
  • Si se aplica la multiplicación bitwise exacta usada por StegSolve → se alinean las partes ocultas

La operación MUL de StegSolve no es una multiplicación de píxeles, es decir, no hace:

R = (R1 * R2) / 255

sino:

c1 = 0xRRGGBB  (pixel 1)
c2 = 0xRRGGBB  (pixel 2)
resultado = (c1 * c2) & 0xFFFFFF

Con todo esto claro, he preparado un script para combinar las imágenes de forma automática.

import os
import numpy as np
from PIL import Image

# =========================================================
# UTILIDADES
# =========================================================

def ensure_output():
    if not os.path.exists("output"):
        os.makedirs("output")

def load_rgb(path):
    img = Image.open(path).convert("RGB")
    return np.array(img, dtype=np.uint32)

def save_rgb(arr, name):
    Image.fromarray(arr.astype(np.uint8), "RGB").save(os.path.join("output", name))

def invert_xor(arr):
    """Colour Inversion (Xor) de StegSolve."""
    out = arr.copy()
    out[..., :3] = 255 - out[..., :3]
    return out

# =========================================================
# FUNCIONES DE COMBINER EXACTAS DE STEGSOLVE
# =========================================================

def to24(arr):
    """Convierte RGB → entero 0xRRGGBB."""
    return ((arr[..., 0] << 16) |
            (arr[..., 1] << 8)  |
             arr[..., 2])

def from24(c):
    """Convierte entero 0xRRGGBB → RGB."""
    R = (c >> 16) & 0xFF
    G = (c >> 8)  & 0xFF
    B = c & 0xFF
    return np.stack([R, G, B], axis=-1).astype(np.uint8)

# ------------------------------
# Funciones auxiliares
# ------------------------------

def comb_xor(c1, c2):
    return from24((c1 ^ c2) & 0xFFFFFF)

def comb_or(c1, c2):
    return from24((c1 | c2) & 0xFFFFFF)

def comb_and(c1, c2):
    return from24((c1 & c2) & 0xFFFFFF)

def comb_add(c1, c2):
    return from24((c1 + c2) & 0xFFFFFF)

def comb_add_sep(c1, c2):
    R = (((c1 >> 16) & 0xFF) + ((c2 >> 16) & 0xFF)) & 0xFF
    G = (((c1 >> 8)  & 0xFF) + ((c2 >> 8)  & 0xFF)) & 0xFF
    B = ((c1 & 0xFF) + (c2 & 0xFF)) & 0xFF
    return from24((R << 16) | (G << 8) | B)

def comb_sub(c1, c2):
    return from24((c1 - c2) & 0xFFFFFF)

def comb_sub_sep(c1, c2):
    R = (((c1 >> 16) & 0xFF) - ((c2 >> 16) & 0xFF)) & 0xFF
    G = (((c1 >> 8)  & 0xFF) - ((c2 >> 8)  & 0xFF)) & 0xFF
    B = ((c1 & 0xFF) - (c2 & 0xFF)) & 0xFF
    return from24((R << 16) | (G << 8) | B)

def comb_mul(c1, c2):
    """MUL EXACTO StegSolve"""
    return from24((c1 * c2) & 0xFFFFFF)

def comb_mul_sep(c1, c2):
    R = (((c1 >> 16) & 0xFF) * ((c2 >> 16) & 0xFF)) & 0xFF
    G = (((c1 >> 8)  & 0xFF) * ((c2 >> 8)  & 0xFF)) & 0xFF
    B = ((c1 & 0xFF) * (c2 & 0xFF)) & 0xFF
    return from24((R << 16) | (G << 8) | B)

def comb_lightest(c1, c2):
    """Máximo por canal"""
    R = np.maximum((c1 >> 16) & 0xFF, (c2 >> 16) & 0xFF)
    G = np.maximum((c1 >> 8)  & 0xFF, (c2 >> 8)  & 0xFF)
    B = np.maximum(c1 & 0xFF, c2 & 0xFF)
    return from24((R << 16) | (G << 8) | B)

def comb_darkest(c1, c2):
    """Mínimo por canal"""
    R = np.minimum((c1 >> 16) & 0xFF, (c2 >> 16) & 0xFF)
    G = np.minimum((c1 >> 8)  & 0xFF, (c2 >> 8)  & 0xFF)
    B = np.minimum(c1 & 0xFF, c2 & 0xFF)
    return from24((R << 16) | (G << 8) | B)

# Lista de transformaciones
TRANSFORMS = {
    "xor": comb_xor,
    "or": comb_or,
    "and": comb_and,
    "add": comb_add,
    "add_sep": comb_add_sep,
    "sub": comb_sub,
    "sub_sep": comb_sub_sep,
    "mul": comb_mul,
    "mul_sep": comb_mul_sep,
    "lightest": comb_lightest,
    "darkest": comb_darkest,
}

# =========================================================
# GENERACIÓN DE TODAS LAS COMBINACIONES
# =========================================================

def generate_all(imA, imB, labelA, labelB):
    print(f"Generando combinaciones: {labelA} vs {labelB}")

    c1 = to24(imA)
    c2 = to24(imB)

    for name, fun in TRANSFORMS.items():
        out = fun(c1, c2)
        save_rgb(out, f"{labelA}__{labelB}__{name}.png")

    print(f"{labelA}-{labelB} completado.")

# =========================================================
# MAIN
# =========================================================

ensure_output()

print("Cargando imágenes v1.png y v2.png...")
im1 = load_rgb("v1.png")
im2 = load_rgb("v2.png")

print("Generando invertidas estilo StegSolve...")
im1_x = invert_xor(im1)
im2_x = invert_xor(im2)

save_rgb(im1_x, "v1_xored.png")
save_rgb(im2_x, "v2_xored.png")

# Generar las 52 combinaciones:
generate_all(im1,   im2,   "v1",   "v2")
generate_all(im1_x, im2,   "v1x",  "v2")
generate_all(im1,   im2_x, "v1",   "v2x")
generate_all(im1_x, im2_x, "v1x",  "v2x")

print("\nResultados en carpeta ./output/")

A continuación os muestro parte de las imágenes generadas por el script. El secreto oculto era un código QR que nos da la solución al reto.

Canyouhack.it – Cryptography Challenge 13

Los retos criptográficos son muy variados y muchas veces la dificultad está en saber a que te enfrentas. En este caso pasa eso, te dan un código y si no has visto algo parecido en la vida, no sabes por donde empezar. El título del autor da una pequeña pista pero para los desconocedores no es suficiente. La pista es el título y dice «WTF?!?» y el código a descifrar es el siguiente:

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

Si eres una persona con recursos, realizaras varias búsquedas por la red y al final llegarás a la conclusión de que te enfrentas a BRAINFUCK, un lenguaje de programación esotérico como ya vimos en el reto de Root-Me.

Enlaces

Solución a los retos javascript de rogerfm.net

Introducción

Los retos de Javascript son los retos más sencillos que podemos encontrar. Muchas veces solamente mirando el código fuente obtenemos la respuesta. Suponen una mala implementación de seguridad debido a que el código se ejecuta del lado del cliente, por lo que el código fuente es accesible y por lo tanto, javascript no garantiza seguridad alguna. En estos cinco casos haremos un recorrido por lo más básico, cinco retos fáciles de superar y que nos proporcionan los conocimientos base para Javascript. Dicho esto os puedo asegurar que en ocasiones he encontrado retos javascript realmente complicados que requieren de horas descifrarlos y en los que es fácil tirar la toalla.

Cuando el reto lo requiera, es buena idea utilizar un compilador online para obtener de forma rápida el valor de una variable o realizar una prueba concreta. Yo utilizo Jsfiddle para realizar pruebas pero existen muchos más.

Javascript 1

Este primer reto es lo básico, en el código fuente se pueden apreciar directamente el usuario y la clave.

<script language=JavaScript>
function Verify(name,pass)
{
if (name=="admin" & pass=="3***3")
	{
	location.href = name + pass + '.htm';
	}
else 
	{
	alert("Si ya fallamos el primero...");
	};
}
</script>

Javascript 2

Este segundo reto es bastante sencillo pero ya te obliga a conocer la función charAt() de Javascript. Dicha función lo que hace es coger el caracter indicado mediante un índice que comienza en cero. Por ejemplo si nombre = deurus y hacemos letra = nombre.charAt(3), estariámos extrayendo la cuarta letra, es decir, la letra r de la variable nombre.

function Verify(name,pass)
{
var name1 = "CrawlinG", pass1 = "capriccio"
	if (name==name1 & pass==pass1)
	{
	location.href = name + ".htm";
	}
else 
	{
	var x =  name1.charAt(7) + pass1.charAt(3)+ name1.charAt(2) + pass1.charAt(5) +  name1.charAt(5) + pass1.charAt(1);x = x.toLowerCase();
	var y =  name.charAt(3) + name.charAt(1) + pass.charAt(1)+ pass.charAt(6) +  pass.charAt(7) + name.charAt(2);var x1 = "des" + y;
	if (x==y){location.href = x1 + ".htm"}else{alert("Esto no va bien");location.href = "js2.htm"}
	}
}

Lo interesante está en la formación de las variables x e y. La variable x se forma de las variables name1 y pass1, formando la palabra gracia. Por otro lado, la variable y se forma con el nombre y clave que introduzcamos nosotros. Vemos que la variable x e y deben ser iguales, por lo tanto debemos construir un nombre (name) y una clave (pass) que cumpla con lo siguiente:

  • 4ª letra del nombre = 1ª letra de la palabra «gracia»
  • 2ª letra del nombre = 2ª letra de la palabra «gracia»
  • 2ª letra de la clave = 3ª letra de la palabra «gracia»
  • 7ª letra de la clave = 4ª letra de la palabra «gracia»
  • 8ª letra de la clave = 5ª letra de la palabra «graci
  • 3ª letra del nombre = 6ª letra de la palabra «gracia«

Como véis simplemente se trata de interpretar correctamente la función charAt() y de fijarse bien en los nombres de las variables.

Javascript 3

Este reto nos muestra diálogo donde nos pide la contraseña para validar el reto. Al fallar  o cancelar vuelve al índice para no dejarnos ver el código fuente. Aquí se pueden seguir varios caminos como bloquear el uso de javascript en el navegador o instalar un plugin en chrome o firefox para habilitar/deshabilitar de forma rápida el uso de javascript.

Una vez deshabilitado javascript vemos lo siguiente:

<script language="JavaScript" src="js3.gif" type=text/javascript>
<!--
function verify()
{
var pass="thebest";
var password=prompt("Introduce el password para superar el nivel","");
	if (password==pass)
		{
		location.href = pass + ".htm";
		}
	else
		{
		alert("No vamos bien...");
		location.href = "index.htm";
		}
}
//-->
</script>

Aquí el truco es darse cuenta que el código que se está ejecutando esta en «js3.gif» y no el código que nos muestra como válida la clave thebest. Si descargamos el archivo js3.gif y lo abrimos con un archivo de texto vemos nuestra querida clave.

function verify()
{
var pass="mo****ver";
var password=prompt("Introduce el password para superar el nivel","");
	if (password==pass)
		{
		location.href = pass + ".htm";
		}
	else
		{
		alert("No vamos bien...");
		location.href = "index.htm";
		}
}

Javascript 4

En este reto ya entramos con que la clave no es reversible y la debemos obtener por fuerza bruta. En este reto utiliza una nueva función como charCodeAt() que lo que hace es obtener el valor ascii del caracter indicado.

function Verify(pass1)
{
var cont1= 2, cont2= 6
var suma1 = 0, suma2 = 0
var pass2 = "FDRLF"
for(i = 0; i < pass1.length; i++) 
{
suma1 += (pass1.charCodeAt(i) * cont1);
cont1++
}
for(i = 0; i < pass2.length; i++) 
{
suma2 += (pass2.charCodeAt(i) * cont2);
cont2++
}
if (suma1==suma2)
{
window.location=suma1+".htm";
}
else
{
alert ("Algo no va bien...");
}
}

Vemos dos bucles en los que se calculan sendos valores suma que finalmente se comparan. la variable suma1 se calcula mediante nuestro password y la variable suma2 la obtiene de la palabra «FDRLF». Con el script que os muestro a continuación obtenemos que usando como clave deurus, suma1 = 3048 y suma2 = 2936. Nuestro punto de referencia es suma2 = 2936, de modo que vamos alterando con paciencia la variable pass1 obteniendo valores cercanos a 2936. Por ejemplo «deurua» nos da suma1 = 2922, un valor bastante cercano.

var pass1 = "deurus";
var cont1= 2, cont2= 6
var suma1 = 0, suma2 = 0
var pass2 = "FDRLF"
for(i = 0; i < pass1.length; i++) 
{
suma1 += (pass1.charCodeAt(i) * cont1);
cont1++
}
for(i = 0; i < pass2.length; i++) 
{
suma2 += (pass2.charCodeAt(i) * cont2);
cont2++
}
alert (suma1);
alert (suma2);

La solución a este reto es múltiple. Dos claves válidas son por ejemplo dfurqfzwfabz.

Javascript 5

Este último reto es similar al anterior pero ya nos obliga a crearnos una pequeña herramienta que nos busque el serial válido.

function Verify(pass)
{
var suma=0
var cadena = "abcdefghijklmnopqrstuvwxyz"
for (var i = 0; i < pass.length; i++) 
	{
	var letra = pass.charAt(i)
	var valor = (cadena.indexOf(letra))
	valor++
	suma *= 26
	suma += valor
	}
if (suma==6030912063)
	{
	window.location=pass+".htm";
	}
else
	{
	alert ("Algo no va bien...");
	}
}

Para esta ocasión utiliza una nueva función llamada indexOf() que lo que hace es devolver un número entero que representa la posición en la que se encuentra el parámetro pasado a la función. Por ejemplo, si tengo variable = deurus y realizo posición = variable.indexOf(«s»), obtengo como resultado 5 (se empieza a contar desde cero).

Las operaciones que realiza el bucle son las siguientes:

  • Coge las letras del nombre una a una.
  • valor = posición de nuestra letra dentro de la variable de texto llamada cadena.
  • valor = valor + 1.
  • Multiplica la variable suma por 26.
  • Suma = suma + valor.

Aunque el proceso de recuperación de esta clave es algo más largo, podemos acortarlo introduciendo una clave de inicio de fuerza bruta próxima al objetivo. Al ser una función bastante lineal podemos rápidamente mediante pruebas con nuestro código de fuerza bruta o con un compilador online, establecer que la clave tendrá 7 caracteres e incluso que para ahorrar tiempo podemos aproximar la clave para que su valor suma esté cercano al valor suma buscado 6030912063.

Realizando pruebas obtenemos:

  • Clave = aaaaaaa -> suma = 321272407
  • Clave = zzzzzzz -> suma = 8353082582
  • Clave = smaaaaa -> suma = 6024332887
  • Clave = smkkkkk -> suma = 6029085437

Como vemos, la clave smkkkkk ya está bastante próxima al objetivo y será un buen punto para lanzar la fuerza bruta.

Os dejo el código de fuerza bruta en .Net

Module Module1
    Sub Main()
inicio:
        Console.WriteLine("-------------------------")
        Console.WriteLine("Modo [1] Prueba password")
        Console.WriteLine("Modo [2] Fuerza bruta")
        Console.WriteLine("-------------------------")
        Dim modo = Console.ReadLine()
        '
        If modo = 2 Then
            Console.WriteLine("¿Password para comenzar?")
            Dim pass = Console.ReadLine()
inicio2:
            Dim cadena As String = "abcdefghijklmnopqrstuvwxyz"
            Dim valor As Integer = 0
            Dim suma As Long = 0
            Dim letra As String
            For i = 0 To pass.Length - 1
                letra = Mid(pass, i + 1, 1)
                valor = cadena.IndexOf(letra)
                valor += 1
                suma *= 26
                suma += valor
            Next
            Console.WriteLine("Password: " & pass & " - Sum: " & suma.ToString)
            pass = IncrementString(pass)
            If suma = 6030912063 Then
                MsgBox("Password is " & pass)
            Else
                If pass = "aaaaaaaa" Then
                    Console.WriteLine("pass not found")
                    Console.ReadKey()
                Else
                    GoTo inicio2
                End If
            End If
        End If
        '------------------------------------------------
        If modo = 1 Then
            Console.WriteLine("Password:")
            Dim pass = Console.ReadLine()
            Dim cadena As String = "abcdefghijklmnopqrstuvwxyz"
            Dim valor As Integer = 0
            Dim suma As Long = 0
            Dim letra As String
            For i = 0 To pass.Length - 1
                letra = Mid(pass, i + 1, 1)
                valor = cadena.IndexOf(letra)
                valor += 1
                suma *= 26
                suma += valor
            Next
            Console.WriteLine("Password: " & pass & " - Sum: " & suma.ToString)
            Console.WriteLine(".......")
            Console.WriteLine("Good = 6030912063")
            Console.WriteLine("Suma = " & suma.ToString)
            Console.ReadKey()
            Console.Clear()
            GoTo inicio
        End If
    End Sub
    Function IncrementString(ByVal strString As String) As String
        '
        ' Increments a string counter
        ' e.g.  "a" -> "b"
        '       "az" -> "ba"
        '       "zzz" -> "aaaa"
        '
        ' strString is the string to increment, assumed to be lower-case alphabetic
        ' Return value is the incremented string
        '
        Dim lngLenString As Long
        Dim strChar As String
        Dim lngI As Long

        lngLenString = Len(strString)
        ' Start at far right
        For lngI = lngLenString To 0 Step -1
            ' If we reach the far left then add an A and exit
            If lngI = 0 Then
                strString = "a" & strString
                Exit For
            End If
            ' Consider next character
            strChar = Mid(strString, lngI, 1)
            If strChar = "z" Then
                ' If we find Z then increment this to A
                ' and increment the character after this (in next loop iteration)
                strString = Left$(strString, lngI - 1) & "a" & Mid(strString, lngI + 1, lngLenString)
            Else
                ' Increment this non-Z and exit
                strString = Left$(strString, lngI - 1) & Chr(Asc(strChar) + 1) & Mid(strString, lngI + 1, lngLenString)
                Exit For
            End If
        Next lngI
        IncrementString = strString
        Exit Function

    End Function
End Module

Enlaces