Solución a los CrackMes de CrkViZ 1-5

- Introducción
- Herramientas disponibles
- CrkViz-1 (Serial a la vista)
- CrkViz-2 (Parcheando rutina aleatoria)
- CrkViz-3 (Nag+Keygen)
- CrkViz-4 (Límite de ejecuciones+Keygen)
- CrkViz-5 (Serial a la vista)
- Notas finales
- Enlaces
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
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.
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
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:
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
Una vez localizados los bytes, los cambiamos por ceros y guardamos.
Una vez parcheado, el serial correcto es 1.
CrkViz-3
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:
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
Al estar correctamente registrados desaparece el botón de registrar.
CrkViz-4
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
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.
Enlaces
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
CanYouHack.it Mobile2 Challenge – Follow The Web (English)

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


http://canyouhack.it/Content/Challenges/Mobile/2/submit.php?Token=68a571bcf7bc9f76d43bf931f413ab2c&&Attempts=0
http://canyouhack.it/Content/Challenges/Mobile/2/submit.php?Token=68a571bcf7bc9f76d43bf931f413ab2c&&Attempts=1
Links
Karpoff’s CrackME1 Keygen

Introducción
El otro día navegando por la red fuí a dar a un mirror de la gran web «Karpoff Spanish Tutor«. Para los que no la conozcais, debeis saber que fué una referencia para el Cracking en la escena nacional. Contenía manuales, cursos, utilidades y todo lo que te pudieras imaginar y/o necesitar para iniciarte en el mundillo del Cracking. Por aquel entonces yo era un cigoto en esto de la Ingeniería Inversa pero la web de Karpoff sentó mis bases y contribuyó a mi afán por saber y compartir. El lector debería saber que estamos hablando de finales de los 90, por lo que este crackme y sucesivos de la web de Karpoff ahora pueden parecer más fáciles pero hay que tener en cuenta que ahora tenemos mejores herramientas.
El objetivo es sacar un serial valido o hacer un generador de llaves, esta hecho para newbies y no tiene ninguna otra proteccion.
El crackme está hecho en Delphi y no tiene ningún tipo de protección antidebug ni nada por el estilo.
El algoritmo
Abrimos Delphi Decompiler y buscamos en los eventos el botón de registro, en este caso se llama «focusClick» y vemos que su RVA apunta a la dirección «442AEC«, lo apuntamos y abrimos el crackme con Ollydbg.
En Olly pulsamos Ctrl+G e introducimos el offset anterior. Un poco más abajo vemos un Call interesante, entramos en el.
Dentro del Call vemos a simple vista dos funciones muy interesantes como son «GetVolumeInformationA» y «GetUserNameA«.
Traceamos el código y vemos que obtiene el número de serie del disco C y el usuario de windows y finalmente los concatena. Se puede ver a simple vista en el Stack o Pila.
No necesitamos saber nada más, probamos el número de serie cazado y funciona. Os adjunto el keygen hecho en C++.
Links
AperiSolve (Zsteg)

AperiSolve es un conjunto de herramientas de análisis esteganográfico que nos ayuda a echar un primer vistazo cuando sospechamos que una imagen esconde algo.
Zsteg es una herramienta especializada en la detección y extracción de información oculta en imágenes, especialmente en formatos PNG y BMP. Está orientada a la esteganografía basada en bit-planes y es muy popular en entornos CTF y análisis forense, gracias a su capacidad para automatizar búsquedas exhaustivas de datos escondidos en los bits menos significativos (LSB) y en configuraciones de color poco habituales. Su principal fortaleza es que no se limita a examinar un único plano: prueba sistemáticamente combinaciones de canales (R, G, B, A), número de bits, orden de lectura y posicionamiento, detectando patrones que podrían pasar inadvertidos en una revisión manual.
Entre sus características más destacadas se encuentran la identificación automática de firmas de archivos (ZIP, PNG, texto ASCII, GZIP, etc.), la extracción directa de bitstreams reconstruidos y el soporte para diferentes rutas de exploración, como
b1,rgb,lsb,xy, que describen exactamente cómo se han recuperado los datos. Esta capacidad de correlacionar parámetros técnicos con resultados concretos convierte a zsteg en una herramienta muy eficiente tanto para localizar contenido oculto como para entender la técnica esteganográfica aplicada.
En AperiSolve se utiliza únicamente la parte de Zsteg encargada de ejecutar el análisis automático y devolver todas las detecciones posibles de esteganografía LSB en imágenes PNG y BMP. Concretamente, AperiSolve llama al comando zsteg <imagen> tal como está implementado en el módulo analyze_zsteg , y captura la salida completa línea por línea. Esta salida incluye todas las combinaciones probadas de bit-planes (b1, b2…), canales (r, g, b, a), orden de bits (lsb/msb) y métodos de recorrido (xy), junto con cualquier coincidencia que zsteg reconozca como firma de archivo o texto. Es decir, AperiSolve no aplica filtros ni interpretación adicional: muestra exactamente lo que zsteg detecta y lo organiza para que el usuario pueda identificar rápidamente si existe un archivo embebido, contenido ASCII, o algún patrón de interés.
En AperiSolve veremos algo como esto:
... b1,a,lsb,xy .. b1,a,msb,xy .. b1,rgb,lsb,xy .. file: Zip archive data, at least v1.0 to extract, compression method=store b1,rgb,msb,xy .. b1,bgr,lsb,xy .. b1,bgr,msb,xy .. b1,rgba,lsb,xy .. b1,rgba,msb,xy .. file: OpenPGP Public Key b1,abgr,lsb,xy .. b1,abgr,msb,xy .. file: OpenPGP Secret Key b2,r,lsb,xy .. b2,r,msb,xy .. text: "P@UPUUPAAUU@" b2,g,lsb,xy .. text: "(ahOFyIS!" ...
Para entender mejor a que se refiere todo esto vamos a repasar lo básico.
¿Qué es LSB y qué es MSB?
Cuando hablamos de esteganografía en imágenes PNG/BMP, nos referimos a manipular bits dentro de los canales de color (R, G, B, A). Cada canal tiene un valor de 0–255, es decir, 8 bits:
R = 11001010 G = 00110101 B = 11100001
LSB — Least Significant Bit (bit menos significativo). Es el bit más débil, el de la derecha:
1100101[0] ← LSB
Modificarlo cambia muy poco el color, por eso se usa en esteganografía.
Ejemplo: cambiar 11001010 ↦ 11001011 no cambia el color perceptible.
MSB — Most Significant Bit (bit más significativo). Es el bit más importante, el de la izquierda:
[1]1001010 ← MSB
Modificarlo sí altera mucho el color. A veces se usa pero suele ser detectable.
Cuando Zsteg muestra una línea del estilo b1,rgb,lsb,xy .. file: Zip archive data, está indicando que ha analizado la imagen extrayendo bits según la ruta especificada —en este caso, 1 bit por píxel (b1), combinando los canales rojo, verde y azul (rgb), utilizando el bit menos significativo (lsb) y recorriendo los píxeles en orden normal de lectura (xy)— y que, tras recomponer esos bits, el resultado coincide con la cabecera reconocible de un tipo de archivo real. Por eso aparece “file: Zip archive data”: significa que los bits ocultos forman un flujo válido cuya firma corresponde a un archivo ZIP. En otras ocasiones puede detectar texto ASCII, PNG, JPEG u otros formatos. En resumen, cuando Zsteg muestra esta línea no solo indica dónde se ocultan los datos, sino que confirma que lo recuperado es un archivo auténtico y probablemente extraíble, ya que la estructura binaria coincide con un formato conocido.
Si vemos que Zsteg nos ofrece algo interesante, podemos extraerlo mediante el comando:
zsteg -E b1,rgb,lsb,xy imagen.png > dump.bin
También es habitual usar herramientas como StegSolve. En este caso debemos dirigirnos a Analyse > Data extract para comprobar lo encontrado por zsteg y extraerlo mediante Save Bin.
| Zsteg | > Significado < | StegSolve |
|---|---|---|
| b1 | Extrae 1 bit por canal (bit plano 0, el menos significativo). | En Bit Planes, marca Red 0, Green 0, Blue 0. Solo esos. |
| rgb | Usa R + G + B en ese orden para reconstruir los bytes. | En Bit Plane Order, selecciona RGB. |
| lsb | Lee los bits empezando por el LSB (bit 0) antes que el MSB. | En Bit Order, selecciona LSB First. |
| xy | Recorre la imagen por filas (izquierda → derecha, arriba → abajo). | En Extract By, elige Row. |

Más allá de este caso concreto, conviene recordar que la esteganografía no se limita a los LSB: existen métodos basados en paletas, metadatos, manipulación de PNG chunks, secuencias alfa, audio incrustado o capas completas en formatos no comprimidos. Por ello, un análisis completo debería combinar la búsqueda clásica de LSB con herramientas complementarias como binwalk, foremost, exiftool, strings, o incluso análisis manual de cabeceras hexadecimales.
Cruehead’s Crackme 1.0 Keygen [1/3]

Introducción
Esta es la primera entrega de tres en las que vamos a ver tres crackmes que todo reverser debería hacer. Son la serie del autor Cruehead. Aunque los hice hace ya muchos años, he decidido documentarlos para que el lector que empieza pueda deleitarse. En este caso se trata del típico Nombre / Serial.
El algoritmo
El algoritmo de este crackme es lo más sencillo que nos podemos encontrar.
Abrimos el crackme con Olly y buscamos en las «string references» el mensaje de error. Pinchamos sobre el y en la parte superior enseguida vemos 2 calls muy interesantes.
Veamos que hace con el nombre.
Para «deurus» pondría todo en mayúsculas, sumaría su valor ascii y le haría XOR 0x5678.
Ejemplo:
deurus –> DEURUS –> 0x44+0x45+0x55+0x52+0x55+0x53 = 0x1D8 XOR 0x5678 = 0x57A0
Veamos que hace con el serial introducido.
Convierte nuestro serial a hexadecimal y le hace XOR 0x1234.
Ejemplo:
Serial = 12345 –> 0x3039 XOR 0x1234 = 0x220D
Una vez que tenemos el SUMNombre y el SUMSerial los compara. Lo vemos en CMP EAX, EBX.
En resumen, si a nuestro SUMNombre le hacemos XOR 0x5678 y XOR 0x1234 ya tenemos el serial bueno.
Ejemplo:
deurus –> DEURUS –> 0x44+0x45+0x55+0x52+0x55+0x53 = 0x1D8 XOR 0x5678 = 0x57A0 XOR 0x1234 = 0x4594
0x4594 = 17812
El Keygen
char Nombre[20];
GetWindowText(hwndEdit1, Nombre, 20);
char Serial[20];
int len = strlen(Nombre);
int suma = 0;
boolean error = false;
for(int i = 0; i <= len; i = i + 1)
{
suma += toupper(Nombre[i]);
}
suma = suma^0x444C; //444C == 5678 xor 1234
wsprintf(Serial,"%d",suma);
SetWindowText(hwndEdit2, TEXT(Serial));
Links
Afinador

Se nos entrega un ELF que decompilado presenta este aspecto:
/* This file was generated by the Hex-Rays decompiler version 8.4.0.240320.
Copyright (c) 2007-2021 Hex-Rays <info@hex-rays.com>
Detected compiler: GNU C++
*/
#include <defs.h>
//-------------------------------------------------------------------------
// Function declarations
__int64 (**init_proc())(void);
__int64 sub_401020();
__int64 sub_401030(); // weak
__int64 sub_401040(); // weak
__int64 sub_401050(); // weak
__int64 sub_401060(); // weak
__int64 sub_401070(); // weak
// int puts(const char *s);
// int printf(const char *format, ...);
// __int64 __isoc99_scanf(const char *, ...); weak
// void __noreturn exit(int status);
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void));
void dl_relocate_static_pie();
char *deregister_tm_clones();
__int64 register_tm_clones();
char *_do_global_dtors_aux();
__int64 frame_dummy();
int __fastcall main(int argc, const char **argv, const char **envp);
_BYTE *__fastcall encode(__int64 a1);
__int64 __fastcall validar(const char *a1);
int banner();
int comprar();
void _libc_csu_fini(void); // idb
void term_proc();
// int __fastcall _libc_start_main(int (__fastcall *main)(int, char **, char **), int argc, char **ubp_av, void (*init)(void), void (*fini)(void), void (*rtld_fini)(void), void *stack_end);
// __int64 _gmon_start__(void); weak
//-------------------------------------------------------------------------
// Data declarations
_UNKNOWN _libc_csu_init;
const char a31mparaSeguirU[43] = "\x1B[31mPara seguir usando este producto deber"; // idb
const char a32myaPuedesSeg[61] = "\x1B[32mYa puedes seguir afinando tus instrumentos (y tus flags "; // idb
const char aDirigaseANuest[21] = "\nDirigase a nuestra p"; // idb
__int64 (__fastcall *_frame_dummy_init_array_entry)() = &frame_dummy; // weak
__int64 (__fastcall *_do_global_dtors_aux_fini_array_entry)() = &_do_global_dtors_aux; // weak
__int64 (*qword_404010)(void) = NULL; // weak
char _bss_start; // weak
//----- (0000000000401000) ----------------------------------------------------
__int64 (**init_proc())(void)
{
__int64 (**result)(void); // rax
result = &_gmon_start__;
if ( &_gmon_start__ )
return (__int64 (**)(void))_gmon_start__();
return result;
}
// 404090: using guessed type __int64 _gmon_start__(void);
//----- (0000000000401020) ----------------------------------------------------
__int64 sub_401020()
{
return qword_404010();
}
// 404010: using guessed type __int64 (*qword_404010)(void);
//----- (0000000000401030) ----------------------------------------------------
__int64 sub_401030()
{
return sub_401020();
}
// 401030: using guessed type __int64 sub_401030();
//----- (0000000000401040) ----------------------------------------------------
__int64 sub_401040()
{
return sub_401020();
}
// 401040: using guessed type __int64 sub_401040();
//----- (0000000000401050) ----------------------------------------------------
__int64 sub_401050()
{
return sub_401020();
}
// 401050: using guessed type __int64 sub_401050();
//----- (0000000000401060) ----------------------------------------------------
__int64 sub_401060()
{
return sub_401020();
}
// 401060: using guessed type __int64 sub_401060();
//----- (0000000000401070) ----------------------------------------------------
__int64 sub_401070()
{
return sub_401020();
}
// 401070: using guessed type __int64 sub_401070();
//----- (00000000004010D0) ----------------------------------------------------
// positive sp value has been detected, the output may be wrong!
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void))
{
__int64 v3; // rax
int v4; // esi
__int64 v5; // [rsp-8h] [rbp-8h] BYREF
char *retaddr; // [rsp+0h] [rbp+0h] BYREF
v4 = v5;
v5 = v3;
_libc_start_main(
(int (__fastcall *)(int, char **, char **))main,
v4,
&retaddr,
(void (*)(void))_libc_csu_init,
_libc_csu_fini,
a3,
&v5);
__halt();
}
// 4010DA: positive sp value 8 has been found
// 4010E1: variable 'v3' is possibly undefined
//----- (0000000000401100) ----------------------------------------------------
void dl_relocate_static_pie()
{
;
}
//----- (0000000000401110) ----------------------------------------------------
char *deregister_tm_clones()
{
return &_bss_start;
}
// 404050: using guessed type char _bss_start;
//----- (0000000000401140) ----------------------------------------------------
__int64 register_tm_clones()
{
return 0LL;
}
//----- (0000000000401180) ----------------------------------------------------
char *_do_global_dtors_aux()
{
char *result; // rax
if ( !_bss_start )
{
result = deregister_tm_clones();
_bss_start = 1;
}
return result;
}
// 404050: using guessed type char _bss_start;
//----- (00000000004011B0) ----------------------------------------------------
__int64 frame_dummy()
{
return register_tm_clones();
}
//----- (00000000004011B6) ----------------------------------------------------
int __fastcall main(int argc, const char **argv, const char **envp)
{
int v4; // [rsp+10h] [rbp-10h] BYREF
int v5; // [rsp+14h] [rbp-Ch]
unsigned __int64 v6; // [rsp+18h] [rbp-8h]
v6 = __readfsqword(0x28u);
v5 = 0;
puts("\n\x1B[31m -----------Se le ha acabado el periodo de prueba gratuito-----------\n");
puts(a31mparaSeguirU);
do
{
banner();
__isoc99_scanf("%d", &v4);
if ( v4 == 3 )
exit(0);
if ( v4 > 3 )
goto LABEL_10;
if ( v4 == 1 )
{
comprar();
continue;
}
if ( v4 == 2 )
v5 = validar("%d");
else
LABEL_10:
puts("Opcion invalida, pruebe otra vez");
}
while ( !v5 );
puts(a32myaPuedesSeg);
return 0;
}
// 4010B0: using guessed type __int64 __isoc99_scanf(const char *, ...);
//----- (0000000000401291) ----------------------------------------------------
_BYTE *__fastcall encode(__int64 a1)
{
_BYTE *result; // rax
int i; // [rsp+14h] [rbp-4h]
for ( i = 0; i <= 33; ++i )
{
if ( *(char *)(i + a1) <= 96 || *(char *)(i + a1) > 122 )
{
if ( *(char *)(i + a1) <= 64 || *(char *)(i + a1) > 90 )
{
result = (_BYTE *)*(unsigned __int8 *)(i + a1);
*(_BYTE *)(i + a1) = (_BYTE)result;
}
else
{
result = (_BYTE *)(i + a1);
*result = (5 * ((char)*result - 65) + 8) % 26 + 65;
}
}
else
{
result = (_BYTE *)(i + a1);
*result = (5 * ((char)*result - 97) + 8) % 26 + 97;
}
}
return result;
}
//----- (00000000004013DB) ----------------------------------------------------
__int64 __fastcall validar(const char *a1)
{
int i; // [rsp+Ch] [rbp-64h]
char v3[48]; // [rsp+10h] [rbp-60h] BYREF
__int64 v4[6]; // [rsp+40h] [rbp-30h] BYREF
v4[5] = __readfsqword(0x28u);
qmemcpy(v4, "RisgAv{rIU_ihHwvIxA_sAppCsziq3vzC}", 34);
printf("\nIntroduce tu licencia: ");
__isoc99_scanf("%s", v3);
encode((__int64)v3);
for ( i = 0; i <= 33; ++i )
{
if ( v3[i] != *((_BYTE *)v4 + i) )
{
puts("\n\x1B[31mTu licencia es incorrecta\x1B[37m\n");
return 0LL;
}
}
puts("\n\x1B[32mEres un crack, lo conseguiste\x1B[37m");
return 1LL;
}
// 4010B0: using guessed type __int64 __isoc99_scanf(const char *, ...);
// 4013DB: using guessed type char var_60[48];
//----- (00000000004014CE) ----------------------------------------------------
int banner()
{
puts(" ___________OPCIONES___________");
puts(" | 1: Comprar licencia premium |");
puts(" | 2: Validar clave de licencia |");
puts(" | 3: Salir |");
puts(" ------------------------------");
return printf("> ");
}
//----- (0000000000401526) ----------------------------------------------------
int comprar()
{
return puts(aDirigaseANuest);
}
//----- (0000000000401540) ----------------------------------------------------
void __fastcall _libc_csu_init(unsigned int a1, __int64 a2, __int64 a3)
{
signed __int64 v3; // rbp
__int64 i; // rbx
init_proc();
v3 = &_do_global_dtors_aux_fini_array_entry - &_frame_dummy_init_array_entry;
if ( v3 )
{
for ( i = 0LL; i != v3; ++i )
(*(&_frame_dummy_init_array_entry + i))();
}
}
// 403E10: using guessed type __int64 (__fastcall *_frame_dummy_init_array_entry)();
// 403E18: using guessed type __int64 (__fastcall *_do_global_dtors_aux_fini_array_entry)();
//----- (00000000004015B0) ----------------------------------------------------
void _libc_csu_fini(void)
{
;
}
//----- (00000000004015B8) ----------------------------------------------------
void term_proc()
{
;
}
// nfuncs=33 queued=21 decompiled=21 lumina nreq=0 worse=0 better=0
// ALL OK, 21 function(s) have been successfully decompiled
Para resolver el juego y obtener una licencia válida, nos fijamos en el proceso de validación que se encuentra en la función validar (líneas 237 a 258). Esta función compara una entrada de licencia codificada con una licencia codificada almacenada en el programa.
La licencia almacenada es "RisgAv{rIU_ihHwvIxA_sAppCsziq3vzC}", y se utiliza la función encode (líneas 207 a 234) para codificar la entrada del usuario antes de compararla. La función encode aplica un cifrado simple a la entrada, alterando los caracteres alfabéticos según una fórmula específica.
La función de cifrado encode realiza lo siguiente:
- Si el carácter es una letra minúscula (a-z), se convierte según la fórmula
(5 * (char - 97) + 8) % 26 + 97. - Si el carácter es una letra mayúscula (A-Z), se convierte según la fórmula
(5 * (char - 65) + 8) % 26 + 65.
Nos construimos una función en Python para decodificar la Flag y reto superado.
def decode(encoded_char):
if 'a' <= encoded_char <= 'z':
original_char = chr(((ord(encoded_char) - 97 - 8) * 21) % 26 + 97)
elif 'A' <= encoded_char <= 'Z':
original_char = chr(((ord(encoded_char) - 65 - 8) * 21) % 26 + 65)
else:
original_char = encoded_char
return original_char
encoded_license = "RisgAv{rIU_ihHwvIxA_sAppCsziq3vzC}"
decoded_license = "".join(decode(char) for char in encoded_license)
print("Licencia descifrada:", decoded_license)
List of file signatures for file carving

File carving is the process of reassembling computer files from fragments in the absence of filesystem metadata. Wikipedia.
«File carving», literalmente tallado de archivos aunque lo traduciremos como extracción, es el proceso de re-ensamblado de archivos extraídos de un conjunto de mayor tamaño.
Índice
- Image files / Archivos de imagen
- Microsoft Office >2007
- Open Office
- Autocad
- Others / Otros
- Links / Enlaces
List of headers and tails / Lista de cabeceras y pies
Header = Cabecera
Footer or tail = Pie
Image files / Archivos de imagen
- JPEG
- Header: FFD8
- Footer: FFD9
- GIF87a
- Header: 47 49 46 38 37 61
- Footer: 00 3B
- GIF89a
- Header: 47 49 46 38 39 61
- Footer: 00 3B
- BMP
- Header: 42 4D
- Footer: Don’t have footer, but size is in bytes 2,3,4,5 in little-endian order (low byte first).
- Example: 00 00 C0 38 == 49208 bytes
- PNG
- Header: 89 50 4E 47 0D 0A 1A 0A
- Footer: 49 45 4E 44 AE 42 60 82
Microsoft Office >2007
All this documents have the same header and footer, because of this, we need search the middle bytes. This type uses a ZIP file package.
Los documentos de Microsoft Office >2007 tienen la misma cabecera y pie, por lo que necesitamos bytes intermedios para distinguirlos. Usan encapsulado ZIP.
- DOCX
- Header: 50 4B 03 04 14 00 06 00
- Middle: 77 6F 72 64 (word)
- Footer: 50 4B 05 06 (PK..) followed by 18 additional bytes at the end of the file.
- Header: 50 4B 03 04 14 00 06 00
- XLSX
- Header: 50 4B 03 04 14 00 06 00
- Middle: 77 6F 72 6B 73 68 65 65 74 73 (worksheets)
- Footer: 50 4B 05 06 (PK..) followed by 18 additional bytes at the end of the file.
- Header: 50 4B 03 04 14 00 06 00
- PPTX
- Header: 50 4B 03 04 14 00 06 00
- Middle: 70 72 65 73 65 6E 74 61 74 69 6F 6E (presentation)
- Footer: 50 4B 05 06 (PK..) followed by 18 additional bytes at the end of the file.
- Header: 50 4B 03 04 14 00 06 00
- MDB / ACCDB
- Header: 00 01 00 00 53 74 61 6E 64 61 72 64 20 4A 65 74 20 44 42 (….Standard Jet DB)
- Footer: Don’t have footer.
Open Office
All this documents have the same header and footer, because of this, we need some bytes to differentiate them. In this case we can do this jumping 73 bytes from header. This type uses a ZIP file package.
Los documentos de OpenOffice tienen la misma cabecera y pie, por lo que necesitamos bytes intermedios para distinguirlos. Usan encapsulado ZIP.
- ODS
- Header: 50 4B 03 04 14 (PK..) jump +73 (0x49) bytes and 73 70 72 65 (spre)
- Footer: 6D 61 6E 69 66 65 73 74 2E 78 6D 6C 50 4B 05 06 (manifest.xmlPK) followed by 18 additional bytes.
- ODT
- Header: 50 4B 03 04 14 (PK..) jump +73 (0x49) bytes and 74 65 78 64 (text)
- Footer: 6D 61 6E 69 66 65 73 74 2E 78 6D 6C 50 4B 05 06 (manifest.xmlPK) followed by 18 additional bytes.
- ODB
- Header: 50 4B 03 04 14 (PK..) jump +73 (0x49) bytes and 62 61 73 65 (base)
- Footer: 6D 61 6E 69 66 65 73 74 2E 78 6D 6C 50 4B 05 06 (manifest.xmlPK) followed by 18 additional bytes.
- ODG
- Header: 50 4B 03 04 14 (PK..) jump +73 (0x49) bytes and 67 72 61 70 (grap)
- Footer: 6D 61 6E 69 66 65 73 74 2E 78 6D 6C 50 4B 05 06 (manifest.xmlPK) followed by 18 additional bytes.
- ODF
- Header: 50 4B 03 04 14 (PK..) jump +73 (0x49) bytes and 66 6F 72 6D (form)
- Tail: 6D 61 6E 69 66 65 73 74 2E 78 6D 6C 50 4B 05 06 (manifest.xmlPK) followed by 18 additional bytes.
- ODP
- Header: 50 4B 03 04 14 (PK..) jump +73 (0x49) bytes and 70 72 65 73 (pres)
- Footer: 6D 61 6E 69 66 65 73 74 2E 78 6D 6C 50 4B 05 06 (manifest.xmlPK) followed by 18 additional bytes.
Autocad
- DWG (R11/R12 versions)
- Header: 41 43 31 30 30 39
- Footer: CD 06 B2 F5 1F E6
- DWG (R14 version)
- Header: 41 43 31 30 31 34
- Footer: 62 A8 35 C0 62 BB EF D4
- DWG (2000 version)
- Header: 41 43 31 30 31 34
- Footer: DB BF F6 ED C3 55 FE
- DWG (>2007 versions)
- Header: 41 43 31 30 XX XX
- Footer: Don’t have
Note: >2007 versions have two patterns and the key is the position 0x80. If in this position we get the bytes «68 40 F8 F7 92», we need to search again for this bytes and displace 107 bytes to find the end of the file. If in the position 0x80 we get another different bytes, we need to search again this bytes and displace 1024 bytes to find the end of the file.
Nota: Las versiones >2007 siguen dos patrones y la clave está en la posición 0x80. Si en la posicion 0x80 obtenemos los bytes «68 40 F8 F7 92», los buscamos una segunda vez y ha 107 bytes encontramos el final del archivo. Si en la posición 0x80 obtenemos otros bytes diferentes a los del primer caso, los volvemos a buscar y a 1024 bytes hallaremos el final del archivo.
Others / Otros
- PDF
- Header: 25 50 44 46 (%PDF)
- Footers:
- 0A 25 25 45 4F 46 (.%%EOF) or
- 0A 25 25 45 4F 46 0A (.%%EOF.) or
- 0D 0A 25 25 45 4F 46 0D 0A (..%%EOF..) or
- 0D 25 25 45 4F 46 0D (.%%EOF.)
- ZIP
- Header: 50 4B 03 04
- Footer: 50 4B 05 06 (PK..) followed by 18 additional bytes at the end of the file.
- RAR (< 4.x version)
- Header: 52 61 72 21 1A 07 00
- Tail: C4 3D 7B 00 40 07 00
- 7ZIP
- Header: 37 7A BC AF 27 1C 00 03 (7z¼¯’…)
- Footer: 01 15 06 01 00 20 followed by 5 additional bytes at the end of the file.
- RTF
- Header: 7B 5C 72 74 66 31
- Footer: 5C 70 61 72 20 7D
Links / Enlaces
Blooper Tech Movie XI – El Coche Fantástico

Intro
Hace poco me reencontré con esta entrañable serie que tanto me entretuvo cuando era pequeño y para mi sorpresa, me percaté de que nunca había visto el episodio piloto. La nostalgia me llevó a tragarme el episodio entero y a disfrutar a lo grande de la parafernalia técnica de la que hace gala para justificar la creación que da nombre a la serie.
La visión tecnológica de los años 80
Esto hay que analizarlo con perspectiva. Estamos en los años 80 y nos están presentando un coche capaz de mantener una conversación, es decir, nos están presentando una inteligencia artificial (IA) llamada KITT. Puede parecer que el término inteligencia artificial es nuevo pero realmente se acuño en 1956 por John McCarthy. A partir de ese momento surgieron líneas de estudio e hipótesis pero a partir de los 70 se puede considerar que la investigación sobre la IA perdió financiación y quedó en el congelador hasta los años 90. Dicho esto, cuando nos presentan a KITT lo hacen de la siguiente manera:
Devon Miles: Está totalmente controlado por microprocesadores que hacen físicamente imposible que se vea implicado en ningún tipo de colisión o percance a no ser que se lo ordene su piloto específicamente
Michael Knight: ¿Piloto?, no me diga que esta cosa vuela
Devon Miles: ¡No!, pero piensa
Michael Knight: ¿Piensa?, ¿mi coche piensa?
Intel daba a conocer el primer microprocesador allá por el 71 y la serie se estrenó en el 82 lo que le da credibilidad en ese aspecto, aunque dudo que el público de esa época supiera que era un microprocesador, un ordenador y menos una IA.
Los Chips
La serie arranca con un grupo de personas realizando espionaje industrial donde nos muestran las hojas de datos de dos chips Japoneses como son el PD8257-5 y el PD780. Un aplauso para los guionistas y sus asesores ya que el PD8257-5 es una interfaz de comunicaciones y el PD780 un microprocesador de 8 bits.

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

A continuación un detalle de las capturas realizadas:






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











Los diálogos
Llaman la atención mucho los diálogos centrados en el microprocesador como si de un ser superior se tratase, éste es la referencia continua y la parte central del guion de los dos primeros capítulos. Curiosamente aparecen en pantalla multitud de imágenes de circuitos integrados pero no se llega a ver ningún microprocesador. Por otro lado, es interesante el esfuerzo que hacen los guionistas por que llamemos a KITT él en vez de ello, convirtiendo al coche en un personaje más.
Otra cosa que llama mucho la atención son los tópicos de los que hace gala como la asociación de los microprocesadores a los videojuegos o que la empresa villana esté afincada en Silicon Valley. Incluso el nombre KITT es un tópico ya que las siglas vienen de Knight Industries Two Thousand que en cristiano quiere decir Industrias Knight 2000. Y es que en mi opinión el año 2000 se imaginaba como una barrera lejana en la que todo iba a ser tecnológicamente más avanzado.
Conclusiones
Tengo que reconocer que me ha sorprendido que dieran realismo a los chips mostrados teniendo en cuenta que aparecen muy pocos segundos en pantalla y podían haber puesto cualquier cosa.
Por otro lado, la realidad es que en el año 2022 aún nos queda recorrido para llegar a tener un coche fantástico y lo más parecido que tenemos hoy día sería un Tesla con Alexa.
Enlaces de interés
- El coche fantástico [IMDB]
- Cronología del computador [Wikipedia]
- Hoja de datos PD780
- Hoja de datos PD8257-5
- Origen del concepto de Inteligencia Artificial [Agencia B12]
- Breve historia visual de la inteligencia artificial [National Geographic]
ThisIsLegal.com – Realistic Challenge 5

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
Analizando a la víctima
Echamos un vistazo a la web y lo único interesante que vemos es un buscador.
Miramos el código fuente y vemos una ruta interesante.
Ahora fijémonos en el menú productos. Pinchamos sobre cualquier producto y a continuación en la imagen para ampliarla, veremos el siguiente enlace.
Explotando la víctima
Vamos a ver si podemos explotar «i.php«. Probamos a obtener información sensible del servidor.
Probamos «http://www.thisislegal.com/nc/i.php?img=adm/login.pwd» y nos da error, seguramente por que está anexionando la extensión de la imagen, es decir, el script está interpretando esto:
Vamos a anularlo con un caracter nulo. Probamos y ahora si.
El password está en base64. Lo decodificamos online, nos logueamos y reto superado.






































