Solución al PGC Official KeygenMe

Introducción
Siguiendo con los crackmes que contienen RSA, esta vez tenemos un Keygenme del grupo PGC (Pirates Gone Crazy) que incluso servía para ser admitido en el grupo si mandabas la solución. Como veremos usa RSA32 + MD5 y en la parte de RSA ni siquiera usa el descifrado por lo que es de los sencillitos.
Resumen RSA
Parámetros
p = Primer número primo
q = Segundo número primo
e = Exponente público que cumpla MCD(e,(p-1)*(q-1))==1
n = Módulo público siendo n=p*q
d = Exponente privado que cumpla d=e^(-1) mod ((p-1)*(q-1))
De este modo e y n son la parte pública de la clave y d y n la parte privada. Los número primos p y q se utilizan solo para generar los parámetros y de ahí en adelante se pueden desechar.
Funciones de Cifrado/Descifrado
cifrado = descifrado ^ e mod n
descifrado = cifrado ^ d mod n
Debug
En las referencias de texto se ven a simple vista el exponente público e (10001) y el módulo n (8e701a4c793eb8b739166bb23b49e421)
Text strings referenced in RSA32+MD:.text
Address Disassembly Text string
00401848 PUSH RSA32+MD.00404104 ASCII "%.8x%.8x%.8x%.8x"
00401A72 PUSH RSA32+MD.0040429C ASCII "[PGCTRiAL/2oo2]"
00401AEE PUSH RSA32+MD.00404275 ASCII "10001"
00401AFE PUSH RSA32+MD.0040427B ASCII "8e701a4c793eb8b739166bb23b49e421"
00401B43 PUSH RSA32+MD.00404404 ASCII "Name Must Be >= 1 Character."
00401B57 PUSH RSA32+MD.00404421 ASCII "Key Must Be >= 1 Character."
00401B6D PUSH RSA32+MD.0040443D ASCII "Congratulations!"
00401B72 PUSH RSA32+MD.0040444E ASCII " You've done it!
Please send your keygen along with
source code to pgc@dangerous-minds.com
if you would like to be considered as
a new member of PGC."
00401BE7 PUSH 0 (Initial CPU selection)
00401C47 MOV [DWORD SS:EBP-24],RSA32+MD.00404119 ASCII "PGCWinClass"
00401C7C MOV [DWORD SS:EBP-24],RSA32+MD.0040424E ASCII "STATIC"
00401CDB PUSH RSA32+MD.00404115 ASCII "PGC"
00401CE0 PUSH RSA32+MD.00404119 ASCII "PGCWinClass"
00401D13 PUSH RSA32+MD.00404125 ASCII "EDIT"
00401D46 PUSH RSA32+MD.00404125 ASCII "EDIT"
00401DFB PUSH RSA32+MD.00404115 ASCII "PGC"
00401E00 PUSH RSA32+MD.0040424E ASCII "STATIC"
Rutina de comprobación
00401A0E /$ 53 PUSH EBX
00401A0F |. 57 PUSH EDI
00401A10 |. 56 PUSH ESI
00401A11 |. 6A 11 PUSH 11 ; /Count = 11 (17.)
00401A13 |. 68 AC424000 PUSH RSA32+MD.004042AC ; |Buffer = RSA32+MD.004042AC
00401A18 |. FF35 94454000 PUSH [DWORD DS:404594] ; |hWnd = NULL
00401A1E |. E8 49080000 CALL <JMP.&USER32.GetWindowTextA> ; \GetWindowTextA
00401A23 |. 83F8 01 CMP EAX,1
00401A26 |. 0F8C 17010000 JL RSA32+MD.00401B43
00401A2C |. A3 6D424000 MOV [DWORD DS:40426D],EAX
00401A31 |. 6A 22 PUSH 22 ; /Count = 22 (34.)
00401A33 |. 68 BD424000 PUSH RSA32+MD.004042BD ; |Buffer = RSA32+MD.004042BD
00401A38 |. FF35 98454000 PUSH [DWORD DS:404598] ; |hWnd = NULL
00401A3E |. E8 29080000 CALL <JMP.&USER32.GetWindowTextA> ; \GetWindowTextA
00401A43 |. 83F8 01 CMP EAX,1
00401A46 |. 0F8C 0B010000 JL RSA32+MD.00401B57
00401A4C |. A3 71424000 MOV [DWORD DS:404271],EAX
00401A51 |. 6A 00 PUSH 0
00401A53 |. E8 C8080000 CALL RSA32+MD.00402320
00401A58 |. A3 69424000 MOV [DWORD DS:404269],EAX
00401A5D |. A1 71424000 MOV EAX,[DWORD DS:404271]
00401A62 |. FF35 69424000 PUSH [DWORD DS:404269] ; /Arg2 = 00000000
00401A68 |. 68 BD424000 PUSH RSA32+MD.004042BD ; |Arg1 = 004042BD
00401A6D |. E8 510A0000 CALL RSA32+MD.004024C3 ; \RSA32+MD.004024C3
00401A72 |. 68 9C424000 PUSH RSA32+MD.0040429C ; /StringToAdd = "[PGCTRiAL/2oo2]"
00401A77 |. 68 AC424000 PUSH RSA32+MD.004042AC ; |ConcatString = ""
00401A7C |. E8 51080000 CALL <JMP.&KERNEL32.lstrcatA> ; \lstrcatA
00401A81 |. 68 AC424000 PUSH RSA32+MD.004042AC ; /String = ""
00401A86 |. E8 4D080000 CALL <JMP.&KERNEL32.lstrlenA> ; \lstrlenA
00401A8B |. 68 DF424000 PUSH RSA32+MD.004042DF ; /Arg4 = 004042DF
00401A90 |. 68 10454000 PUSH RSA32+MD.00404510 ; |Arg3 = 00404510
00401A95 |. 50 PUSH EAX ; |Arg2
00401A96 |. 68 AC424000 PUSH RSA32+MD.004042AC ; |Arg1 = 004042AC
00401A9B |. E8 60F5FFFF CALL RSA32+MD.00401000 ; \RSA32+MD.00401000
00401AA0 |. 6A 00 PUSH 0
00401AA2 |. E8 79080000 CALL RSA32+MD.00402320
00401AA7 |. A3 5D424000 MOV [DWORD DS:40425D],EAX
00401AAC |. 6A 00 PUSH 0
00401AAE |. E8 6D080000 CALL RSA32+MD.00402320
00401AB3 |. A3 59424000 MOV [DWORD DS:404259],EAX
00401AB8 |. 6A 00 PUSH 0
00401ABA |. E8 61080000 CALL RSA32+MD.00402320
00401ABF |. A3 61424000 MOV [DWORD DS:404261],EAX
00401AC4 |. 6A 00 PUSH 0
00401AC6 |. E8 55080000 CALL RSA32+MD.00402320
00401ACB |. A3 65424000 MOV [DWORD DS:404265],EAX
00401AD0 |. B8 02000000 MOV EAX,2
00401AD5 |. C1E0 04 SHL EAX,4
00401AD8 |. FF35 5D424000 PUSH [DWORD DS:40425D] ; /Arg2 = 00000000
00401ADE |. 68 DF424000 PUSH RSA32+MD.004042DF ; |Arg1 = 004042DF
00401AE3 |. E8 DB090000 CALL RSA32+MD.004024C3 ; \RSA32+MD.004024C3
00401AE8 |. FF35 65424000 PUSH [DWORD DS:404265] ; /Arg2 = 00000000
00401AEE |. 68 75424000 PUSH RSA32+MD.00404275 ; |Arg1 = 00404275 ASCII "10001"
00401AF3 |. E8 CB090000 CALL RSA32+MD.004024C3 ; \RSA32+MD.004024C3
00401AF8 |. FF35 61424000 PUSH [DWORD DS:404261] ; /Arg2 = 00000000
00401AFE |. 68 7B424000 PUSH RSA32+MD.0040427B ; |Arg1 = 0040427B ASCII "8e701a4c793eb8b739166bb23b49e421"
00401B03 |. E8 BB090000 CALL RSA32+MD.004024C3 ; \RSA32+MD.004024C3
00401B08 |. FF35 59424000 PUSH [DWORD DS:404259]
00401B0E |. FF35 61424000 PUSH [DWORD DS:404261]
00401B14 |. FF35 65424000 PUSH [DWORD DS:404265]
00401B1A |. FF35 5D424000 PUSH [DWORD DS:40425D]
00401B20 |. E8 87120000 CALL RSA32+MD.00402DAC
00401B25 |. FF35 69424000 PUSH [DWORD DS:404269]
00401B2B |. FF35 59424000 PUSH [DWORD DS:404259]
00401B31 |. E8 61080000 CALL RSA32+MD.00402397
00401B36 |. 85C0 TEST EAX,EAX
00401B38 |. 74 31 JE SHORT RSA32+MD.00401B6B
00401B3A |. E8 85000000 CALL RSA32+MD.00401BC4
00401B3F |. 5E POP ESI
00401B40 |. 5F POP EDI
00401B41 |. 5B POP EBX
00401B42 |. C3 RET
00401B43 |> 68 04444000 PUSH RSA32+MD.00404404 ; /Text = "Name Must Be >= 1 Character."
00401B48 |. FF35 98454000 PUSH [DWORD DS:404598] ; |hWnd = NULL
00401B4E |. E8 5B070000 CALL <JMP.&USER32.SetWindowTextA> ; \SetWindowTextA
00401B53 |. 5E POP ESI
00401B54 |. 5F POP EDI
00401B55 |. 5B POP EBX
00401B56 |. C3 RET
00401B57 |> 68 21444000 PUSH RSA32+MD.00404421 ; /Text = "Key Must Be >= 1 Character."
00401B5C |. FF35 98454000 PUSH [DWORD DS:404598] ; |hWnd = NULL
00401B62 |. E8 47070000 CALL <JMP.&USER32.SetWindowTextA> ; \SetWindowTextA
00401B67 |. 5E POP ESI
00401B68 |. 5F POP EDI
00401B69 |. 5B POP EBX
00401B6A |. C3 RET
00401B6B |> 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
00401B6D |. 68 3D444000 PUSH RSA32+MD.0040443D ; |Title = "Congratulations!"
00401B72 |. 68 4E444000 PUSH RSA32+MD.0040444E ; |Text = " You've done it!
Please send your keygen along with
source code to pgc@dangerous-minds.com
if you would like to be considered as
a new member of PGC."
00401B77 |. FF35 8C454000 PUSH [DWORD DS:40458C] ; |hOwner = NULL
00401B7D |. E8 02070000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA
00401B82 |. EB 00 JMP SHORT RSA32+MD.00401B84
00401B84 |> FF35 5D424000 PUSH [DWORD DS:40425D]
00401B8A |. E8 BE070000 CALL RSA32+MD.0040234D
00401B8F |. FF35 59424000 PUSH [DWORD DS:404259]
00401B95 |. E8 B3070000 CALL RSA32+MD.0040234D
00401B9A |. FF35 61424000 PUSH [DWORD DS:404261]
00401BA0 |. E8 A8070000 CALL RSA32+MD.0040234D
00401BA5 |. FF35 65424000 PUSH [DWORD DS:404265]
00401BAB |. E8 9D070000 CALL RSA32+MD.0040234D
00401BB0 |. FF35 69424000 PUSH [DWORD DS:404269]
00401BB6 |. E8 92070000 CALL RSA32+MD.0040234D
00401BBB |. E8 04000000 CALL RSA32+MD.00401BC4
00401BC0 |. 5E POP ESI
00401BC1 |. 5F POP EDI
00401BC2 |. 5B POP EBX
00401BC3 \. C3 RET
Como vemos comprueba que tanto el nombre como el número de serie tengan al menos un dígito y a continuación comienza el chequeo del serial. El chequeo es muy sencillo ya que ni siquiera tenemos que buscar los números primos p y q y a continuación n, simplemente podemos obtener el número de serie con la parte pública de la clave (par de número e y n). Lo resumimos a continuación:
- Concatena nuestro nombre con la cadena «[PGCTRiAL/2oo2]»
- Crea el hash MD5 de la cadena concatenada.
- Cifra el hash usando el par de números e y n obtenidos en las referencias de texto.
1. deurus[PGCTRiAL/2oo2] 2. md5(deurus[PGCTRiAL/2oo2]) = dc8a39282da8539d11b8a6aec000c45a 3. dc8a39282da8539d11b8a6aec000c45a^10001 mod 8e701a4c793eb8b739166bb23b49e421 = 1FF83ECC5A65334DA2BC93C675A9BA15 Nombre: deurus Serial: 1FF83ECC5A65334DA2BC93C675A9BA15
Keygen
//
// md5(deurus[PGCTRiAL/2oo2]) = dc8a39282da8539d11b8a6aec000c45a
//
var c = BigInt("0xdc8a39282da8539d11b8a6aec000c45a");
var e = BigInt("0x10001");
var n = BigInt("0x8e701a4c793eb8b739166bb23b49e421");
//
var serial = BigInt(0);
serial = powmod(c, e, n);
document.write(serial.toString(16));
//
//POWMOD
//
function powmod(base, exp, modulus) {
var accum = BigInt("1");
var i = BigInt("0");
var basepow2 = BigInt(base);
while ((BigInt(exp) >> BigInt(i) > BigInt(0))) {
if (((BigInt(exp) >> BigInt(i)) & BigInt(1)) == BigInt(1)) {
accum = (BigInt(accum) * BigInt(basepow2)) % BigInt(modulus);
}
basepow2 = (BigInt(basepow2) * BigInt(basepow2)) % BigInt(modulus);
i++;
}
return BigInt(accum);
}
Enlaces
- RSA (wikipedia)
- Exponenciación modular (wikipedia)
- Big Integer Calculator v1.14
- Crackme
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
VideoTutorial – Desempacando Aspack 2.1, Pe-Pack 1.0 y UPX del Crackme Sweeet Dream 1.0 de 2Sweeet

Keygen para el CrackMe #1 de ECloZion

Intro
Hoy nos enfrentamos a un crackme realizado en Delphi con un algoritmo bastante sencillo. Está empacado con UPX pero aquí no vamos a explicar como desempacarlo ya que UPX es un reductor de tamaño más que un empacador, incluso con el propio empacador podemos desempacarlo.
Nota: Si queréis ver el proceso completo de desempacado ver el siguiente video (http://youtu.be/c4CNY902SAE).
El algoritmo
Abrimos Olly y vamos a las string references, localizamos los mensajes de error y éxito y pulsamos sobre cualquiera.
Encima de los mensajes tenemos la rutina de comprobación del serial. En la primera imagen vemos que comprueba que no dejemos ningún campo vacío y a continuación se mete de lleno con el serial.
Analicemos la rutina del serial.
00454882 |> /8B15 4C6C4500 /MOV EDX,DWORD PTR DS:[456C4C] ; Concatena name + ECloZion + pronom <--- 00454888 |. |8B0D 506C4500 |MOV ECX,DWORD PTR DS:[456C50] 0045488E |. |0FB6540A FF |MOVZX EDX,BYTE PTR DS:[EDX+ECX-1] ; Coje el dígito que toque 00454893 |. |8916 |MOV DWORD PTR DS:[ESI],EDX ; Mueve EDX a TEMP (inicialmente vale FFFFFFFF) 00454895 |. |833E 5F |CMP DWORD PTR DS:[ESI],5F 00454898 |. |75 06 |JNZ SHORT ECloZion.004548A0 0045489A |. |C706 20000000 |MOV DWORD PTR DS:[ESI],20 004548A0 |> |8B17 |MOV EDX,DWORD PTR DS:[EDI] 004548A2 |. |3116 |XOR DWORD PTR DS:[ESI],EDX ; TEMP = TEMP xor digito 004548A4 |. |8136 CE9A5614 |XOR DWORD PTR DS:[ESI],14569ACE ; TEMP = TEMP xor 14569ACE 004548AA |. |8B16 |MOV EDX,DWORD PTR DS:[ESI] 004548AC |. |8917 |MOV DWORD PTR DS:[EDI],EDX 004548AE |. |FF05 506C4500 |INC DWORD PTR DS:[456C50] 004548B4 |. |48 |DEC EAX ; EAX = longitud del concatenado = contador del bucle. 004548B5 |.^\75 CB \JNZ SHORT ECloZion.00454882 ; Bucle ---> 004548B7 |> 8137 F0BD6434 XOR DWORD PTR DS:[EDI],3464BDF0 ; TEMP 0 TEMP xor 3464BDF0
Ejemplo:
Nom: deurus Prenom: any d e u r u s E C l o Z i o n a n y 64 65 75 72 75 73 45 43 6C 6F 5A 69 6F 6E 61 6E 79 FFFFFFFF xor 64 = FFFFFF9B xor 14569ACE = EBA96555 EBA96555 xor 65 = EBA96530 xor 14569ACE = FFFFFFFE FFFFFFFE xor 75 = FFFFFF8B xor 14569ACE = EBA96545 EBA96545 xor 72 = EBA96537 xor 14569ACE = FFFFFFF9 FFFFFFF9 xor 75 = FFFFFF8C xor 14569ACE = EBA96542 EBA96542 xor 73 = EBA96531 xor 14569ACE = FFFFFFFF FFFFFFFF xor 45 = FFFFFFBA xor 14569ACE = EBA96574 EBA96574 xor 43 = EBA96537 xor 14569ACE = FFFFFFF9 FFFFFFF9 xor 6C = FFFFFF95 xor 14569ACE = EBA9655B EBA9655B xor 6F = EBA96534 xor 14569ACE = FFFFFFFA FFFFFFFA xor 5A = FFFFFFA0 xor 14569ACE = EBA9656E EBA9656E xor 69 = EBA96507 xor 14569ACE = FFFFFFC9 FFFFFFC9 xor 6F = FFFFFFA6 xor 14569ACE = EBA96568 EBA96568 xor 6E = EBA96506 xor 14569ACE = FFFFFFC8 FFFFFFC8 xor 61 = FFFFFFA9 xor 14569ACE = EBA96567 EBA96567 xor 6E = EBA96509 xor 14569ACE = FFFFFFC7 FFFFFFC7 xor 79 = FFFFFFBE xor 14569ACE = EBA96570 -------------------------------------------------- Resultado = EBA96570 EBA96570 xor 3464BDF0 = DFCDD880 = 3754809472 --> nuestra serial
KeyGen en C++
char Nombre[20];
GetWindowText(hwndEdit1, Nombre, 20);
char prenom[20];
GetWindowText(hwndEdit2, prenom, 20);
char Serial[20];
char concatenado[48];
wsprintf(concatenado,"%sECloZion%s",Nombre,prenom);
int len = strlen(concatenado);
unsigned int suma = 0xFFFFFFFF;
for(int i = 0; i < len; i = i + 1)
{
suma = suma ^ concatenado[i];
suma = suma ^ 0x14569ACE;
}
suma = suma ^ 0x3464BDF0;
wsprintf(Serial,"%u",suma);
SetWindowText(hwndEdit3, TEXT(Serial));
Links
Reto Stego 1 de Hacker Games

Cambio de extensión (paso opcional)
Al descargar la imagen de la web del reto vemos que tiene la extensión php y lo más probable es que no nos abra correctamente.
... <br/> <img src="steg1img.php"/> <br/> ...
Abrimos la imagen con nuestro editor hexadecimal favorito y nos fijamos en la cabecera.
00000000h: 89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 ; ‰PNG........IHDR
Renombramos entonces la extensión a png y continuamos.
Imagen oculta
Esta parte la afrontaremos con Steganabara, una herramienta muy útil que siempre uso cuando me enfrento a un reto «stego». En esta ocasión utilizaremos el análisis de color. Para ello pulsamos sobre «Analyse > Color table«.
En la tabla de colores tenemos la descomposición de colores RGBA y su frecuencia de aparición. Ordenamos por frecuencia descendiente y hacemos doble clic sobre la fila para abrir la imagen resultante.
A continuación un resumen de las imágenes obtenidas.
Como podéis observar, la imagen oculta es un código QR. Lo escaneamos con nuestra app preferida y obtenemos un texto encriptado.
dtsfwqutisvqtesymkuvabbujwhfecuvlshwopcyeghguywjvlaibflcacyahckyqvypjntfhihgtvyxeqakjwouldltuiuhbhjumgkxuugqahvwhotduqtahcknheypjetxpvlhxtlrpjagyjzcgijgfjmcupsslkzpuxegaillytlfbygeptzjtuzlvlwkzdznxqwpabbe
Descifrando el mensaje
A partir de aquí el reto pasa a ser de encriptación. Con el tiempo diferenciareis fácilmente el tipo de cifrado con sólo ver el texto. En este caso lo primero que se nos ocurre es comprobar dos cifrados clásicos como son el cifrado César y el Vigenere.
Tras desestimar el cifrado César realizamos un ataque de «fuerza bruta» al cifrado Vigenere mediante análisis estadístico. En la imagen que muestro a continuación se puede ver que la clave está cerca de ser «HPHQTC» pero todavía no se lee correctamente.
Ya que la fuerza bruta de por sí no termina de darnos la respuesta correcta, pasamos a probar algo muy útil, esto es, descifrar por fuerza bruta pero dándole una palabra para comparar. En este caso en concreto vemos que una posible palabra que pudiera estar en el texto encriptado es «PASSWORD», probamos y reto terminado.
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]
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.
Al poco tiempo ya vemos que vamos bien encaminados.
Finalmente no nos cuesta dar con la solución.
Links
- Web del reto
- Steganabara
- Steganabara explained (english)
- Esteganografía: Ocultando el uso de LSB (securityartwork.es)
ThisIsLegal.com – User Challenge 1 (Javascript)

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
Este es el típico reto de Javascript, no tiene mucha complicación pero he decidido dedicarle una entrada por que me llamó la atención lo que utiliza de usuario y clave.
El Script
function getStyle(el,styleProp)
{
var x = document.getElementById(el);
if (x.currentStyle)
var y = x.currentStyle[styleProp];
else if (window.getComputedStyle)
var y = document.defaultView.getComputedStyle(x,null).getPropertyValue(styleProp);
if (y.substr(0, 1) == "#"){ return y; } else {
var value = y.split(',');
var R = value[0].substr(4);
var G = value[1];
var B = value[2].substr(0, value[2].length-1);
var RGB = "#" + toHex(R)+ toHex(G)+toHex(B);
return RGB;
}
}
function toHex(N) {
if (N==null) return "00";
N=parseInt(N); if (N==0 || isNaN(N)) return "00";
N=Math.max(0,N); N=Math.min(N,255); N=Math.round(N);
return "0123456789ABCDEF".charAt((N-N%16)/16)
+ "0123456789ABCDEF".charAt(N%16);
}
function pw (form)
{
var d1, d2, d3;
if (navigator.appName == "Netscape"){
d1= getStyle('content', 'background-color');
} else {
d1= getStyle('content', 'backgroundColor');
}
d2=form.Name.value;
d3=form.Password.value;
if (d2==d1.length) {
if (d3==d1) {
window.open ("../" + d1.substr(1, 10), "_self")
} else {
alert("Muhaha! Wrong!")
}
} else {
alert("Muhaha! Wrong!")
}
}
El Formulario
<div class="chal_box" style="padding:10px;">
<form name="form" action="" method="post">
Username<br />
<input id="inputd2" type="text" name="Name" value="" size="30" maxlength="30"><br />
Password<br />
<input id="inputd1" type="text" name="Password" value="" size="30" maxlength="30"><br /><br />
<input type="button" name="Only a button" value="Enter Site" id="Only a button" class="btn" onclick="pw(this.form)">
</form>
</div>
Interpretando el Script
En el formulario vemos que llama a la función «pw» y ésta a su vez llama a la función «getStyle«, bueno, pués es tan simple como poner un «alert();» dentro de la función «pw» para cazar la clave. Con éste método podemos cazar la clave del 90% de este tipo de pruebas.
Con esto ya tenemos la clave. El usuario responde a la siguiente sentencia «d2==d1.length«, es decir, es el número de dígitos de la clave.
¿Fácil no?































