-[ 0x0A ]-------------------------------------------------------------------- -[ ROMPIENDO EL ARJ ]-------------------------------------------------------- -[ by Falken ]--------------------------------------------------------SET-14- ROMPIENDO EL .o. ooooooooo. oooo .888. `888 `Y88. `888 .8"888. 888 .d88' 888 .8' `888. 888ooo88P' 888 .88ooo8888. 888`88b. 888 .8' `888. 888 `88b. 888 o88o o8888o o888o o888o .o. 88P `Y888P En SET 13 un lector nos comentaba que tenia problemas, pues habia copiado en unos CDs algunos programas y juegos, compriendolos con el ARJ. A estos archivos les habia puesto una password, y posteriormente se habia olvidado de cual era. Asi que os escribia para preguntarnos como podia obtener la clave. Puestos manos a la obra, vamos a desvelar cual es el metodo que usa ARJ para encriptar los archivos, de forma que podais realizar por vosotros mismos un programa capaz de romper el sistema. En esta aventura criptoanalitica contaremos tan solo con el ARJ en su version 2.50, la documentacion que incluye, y un editor hexadecimal cualquiera. Baste decir que para el caso que nos ocupa se uso el Hacker's View por comodidad, y el debug del MS-DOS para realizar los volcados. ENTENDIENDO EL ARJ =-=-=-=-=-=-=-=-=- Lo primero, es leer la documentacion. Aqui vemos una referencia tecnica en la que se nos explica cual es la estructura del archivo ARJ. Veamosla con mas calma, aplicando un ejemplo que luego nos sera de utilidad a la hora de realizar el criptoanalisis. Como ejemplo, generamos un archivo llamado CLARO.ARJ, en el que solo incluimos un fichero, el UNO.TXT, cuyo contenido es la cadena "SET working on ARJ". El metodo de compresion sera simplemente el almacenamiento, para mayor comodidad a la hora del analisis. Ahora veamos la estructura del archivo ARJ, aplicada al caso particular de CLARO.ARJ. Para ello, tenemos el siguiente volcado hexadecimal del mismo: 1BE8:0100 60 EA 29 00 1E 07 01 00-10 00 02 47 47 BF 8D 24 `.)........GG..$ 1BE8:0110 47 BF 8D 24 00 00 00 00-00 00 00 00 00 00 00 00 G..$............ 1BE8:0120 00 00 43 4C 41 52 4F 2E-41 52 4A 00 00 3F 2F 04 ..CLARO.ARJ..?/. 1BE8:0130 1B 00 00 60 EA 27 00 1E-07 01 00 10 00 00 47 FA ...`.'........G. 1BE8:0140 BE 8D 24 12 00 00 00 12-00 00 00 2B 5B DD 85 00 ..$........+[... 1BE8:0150 00 20 00 00 00 55 4E 4F-2E 54 58 54 00 00 F4 3B . ...UNO.TXT...; 1BE8:0160 39 D8 00 00 53 45 54 20-77 6F 72 6B 69 6E 67 20 9...SET working 1BE8:0170 6F 6E 20 41 52 4A 60 EA-00 00 on ARJ`... Bien, comencemos. La estructura de un archivo ARJ se compone de dos partes fundamentales: - La cabecera principal del archivo. - La cabecera del fichero local. La cabecera del fichero local aparecera tantas veces como ficheros hayan en el archivo. Asi, si hay dos ficheros comprimidos en el archivo, habra dos cabeceras de fichero local, una por cada fichero. Pues para empezar, veamos la cabecera principal del archivo. .---------------------. | Bytes | Descripcion | |--------------------------------------------------------------------------. | 2 | ID de la cabecera (principal y local) = 0x60 0xEA | | 2 | Tama€o de la cabecera basica: | | | first_hdr_size + strlen (nombre) + 1 + strlen (comentario) + 1 | | | 0 -> Si es el final del archivo | | | Tama€o maximo -> 2600 | | 1 | first_hdr_size | | 1 | Numero de version del archivador | | 1 | Version minima del archivador a extraer | | 1 | OS [0 = MSDOS.1 = PRIMOS....2 = UNIX......3 = AMIGA..4 = MAC-OS] | | | [5 = OS/2..6 = APPLE GS..7 = ATARI ST..8 = NEXT..9 = VAX VMS] | | 1 | Indicadores ARJ: | | | [0x01 = NO USADO] | | | [0x02 = OLD_SECURED_FLAG] | | | [0x04 = VOLUME_FLAG] Indica la existencia de otro volumen | | | [0x08 = NO USADO] | | | [0x10 = PATHSYM_FLAG] Indica cambio de \ a / en el path | | | [0x20 = BACKUP_FLAG] Indica que se trata de un backup | | | [0x40 = SECURED_FLAG] | | 1 | Version de seguridad (2 = actual) | | 1 | Tipo de fichero. Igual a 2 siempre. | | 1 | Reservado | | 4 | Fecha y hora del archivo original. | | 4 | Fecha y hora de la ultima modificacion. | | 4 | Tama€o del archivo. | | 4 | Posicion de la envuelta de seguridad. | | 2 | ??? | | 2 | Longitud en bytes de la envuelta de seguridad. | | 2 | No usado actualmente | | ? | Actualmente nada. | | ? | Nombre del archivo cuando se creo, terminado en null (0x00) | | ? | Comentario del archivo, terminado en null (0x00) | | 4 | CRC de la cabecera. | | 2 | Tama€o de la primera cabecera extendida (0 si no hay) | | ? | Primera cabecera extendida | | 4 | CRC de la primera cabecera extendida. | | | No presente si no hay cabecera extendida. | `--------------------------------------------------------------------------' En nuestro ejemplo, esto se corresponde con: 1BE8:0100 60 EA 29 00 1E 07 01 00-10 00 02 47 47 BF 8D 24 `.)........GG..$ 1BE8:0110 47 BF 8D 24 00 00 00 00-00 00 00 00 00 00 00 00 G..$............ 1BE8:0120 00 00 43 4C 41 52 4F 2E-41 52 4A 00 00 3F 2F 04 ..CLARO.ARJ..?/. 1BE8:0130 1B 00 00 ... Para los que tengais curiosidad, la fecha y hora se almacena en el siguiente formato: .-----------------------------------------------------. | 31 30 29 28 27 26 25 | 24 23 22 21 | 20 19 18 17 16 | | <--- a€o - 1980 ---> | <-- mes --> | <--- dia ----> | |-----------------------------------------------------| | 15 14 13 12 11 | 10 09 08 07 06 05 | 04 03 02 01 00 | | <--- hora ---> | <--- minutos ---> | <-- segs/2 --> | `-----------------------------------------------------' Asi que para detalle, la fecha de creacion del archivo es 0x248DBF47 (recordad que se invierte el orden al almacenarlo), o lo que es lo mismo: 0010010 -> 18 + 1980 -> 1998 \ 0100 -> 4 -> Abril | 01101 -> 13 \ Creado el 13 de Abril de 1998 10111 -> 23 / a las 23h 58m 14s 111010 -> 58 | P'a que luego digan que no trabajamos 00111 -> 7 * 2 -> 14 / hasta el cierre de edicion ;) Sigamos ahora con la cabecera del fichero local: .---------------------. | Bytes | Descripcion | |--------------------------------------------------------------------------. | 2 | ID de la cabecera (principal y local) = 0x60 0xEA | | 2 | Tama€o de la cabecera basica: | | | first_hdr_size + strlen (nombre) + 1 + strlen (comentario) + 1 | | | 0 -> Si es el final del archivo | | | Tama€o maximo -> 2600 | | 1 | first_hdr_size | | 1 | Numero de version del archivador | | 1 | Version minima del archivador a extraer | | 1 | OS [0 = MSDOS.1 = PRIMOS....2 = UNIX......3 = AMIGA..4 = MAC-OS] | | | [5 = OS/2..6 = APPLE GS..7 = ATARI ST..8 = NEXT..9 = VAX VMS] | | 1 | Indicadores ARJ: | | | [0x01 = GARBLED_FLAG] Indica un fichero encriptado. | | | [0x02 = NO USADO] | | | [0x04 = VOLUME_FLAG] Indica la que el fihero esta cortado. | | | [0x08 = EXTFILE_FLAG] Indica la posicion de continuacion en | | | ficheros cortados. | | | [0x10 = PATHSYM_FLAG] Indica cambio de \ a / en el path | | | [0x20 = BACKUP_FLAG] Indica que se trata de un backup | | 1 | Metodo de compresion: 0 = almacenado. | | | 1 = Maxima compresion | | | ... | | | 4 = Compresion rapida. | | 1 | Tipo de fichero: 0 = Binario | | | 1 = Texto en 7 bits | | | 2 = Directorio | | | 3 = Etiqueta de volumen | | 1 | Reservado | | 4 | Fecha y hora de la ultima modificacion. | | 4 | Tama€o del archivo comprimido. | | 4 | Tama€o del archivo original. | | 4 | CRC del archivo original. | | 2 | ??? | | 2 | Modo de acceso al fichero. | | 2 | Datos de la maquina (no usado actualmente) | | ? | Datos extra. | | | 4 bytes para el punto de comienzo de los ficheros extendidos | | | cuando se requiere (EXTFILE_FLAG) | | | 0 bytes en cualquier otro caso. | | ? | Nombre del archivo cuando se creo, terminado en null (0x00) | | ? | Comentario del archivo, terminado en null (0x00) | | 4 | CRC de la cabecera. | | 2 | Tama€o de la primera cabecera extendida (0 si no hay) | | ? | Primera cabecera extendida | | 4 | CRC de la primera cabecera extendida. | | | No presente si no hay cabecera extendida. | | ... | ... | | ? | Fichero comprimido | `--------------------------------------------------------------------------' Y para el ejemplo que estamos siguiendo, sera: 1BE8:0130 60 EA 27 00 1E-07 01 00 10 00 00 47 FA `.'........G. 1BE8:0140 BE 8D 24 12 00 00 00 12-00 00 00 2B 5B DD 85 00 ..$........+[... 1BE8:0150 00 20 00 00 00 55 4E 4F-2E 54 58 54 00 00 F4 3B . ...UNO.TXT...; 1BE8:0160 39 D8 00 00 53 45 54 20-77 6F 72 6B 69 6E 67 20 9...SET working 1BE8:0170 6F 6E 20 41 52 4A on ARJ Despues, aparece 0x60 0xEA 0x00 0x00, que indica el final del archivo. Vemos aqui claramente donde comienza el fichero archivado. Asi, Lo que encriptaremos, ira desde la posicion 0x163 a la posicion 0x175. Nos falta algo por leer en la documentacion que acompa€a al ARJ. Y es que nos dice textualmente: ARJ does NOT use DES encryption algorithms. It uses a combination of simple exclusive-or operations. He dicho que era textual, no? ;) Vale, sere bueno y lo traducire. Dice que el ARJ no usa DES como metodo de encriptacion. Que solo usa una combinacion de simples XOR. A ver, alguno no sabe lo que es una operacion XOR? Pues no es ni mas ni menos que un OR-eXclusivo. (Y me he quedado tan ancho ;) ). Bueno, una operacion XOR consiste, como ya he dicho, en una o logica exclusiva, o lo que se puede leer de la siguiente manera: "O uno u otro, pero no ambos a la vez". En logica binaria, tenemos la siguiente tabla de la verdad para una operacion XOR, representado como en lenguaje C (^): 0 ^ 0 = 0 0 ^ 1 = 1 1 ^ 0 = 1 1 ^ 1 = 0 Ha quedado claro ya? Como alguien me diga que esto es de un nivel alto, lo hago del club de fans de Bill Gates. Lo juro por el pinguino de Linux. Creo que ya estamos en condiciones de afrontar el reto. CRIPTOANALIZANDO ARJ =-=-=-=-=-=-=-=-=-=- Pues para comenzar el criptoanalisis, y ver que metodo usa el ARJ, debemos tener un archivo encriptado. Vamos, creo yo, no? ;) Asi que vamos a coger el archivo CLARO.ARJ, y lo vamos a copiar como TEST1.ARJ, encriptando este ultimo con la clave: CLAVE. Despues de todo esto, obtenemos un archivo tal que asi: 1BE8:0100 60 EA 29 00 1E 07 01 00-10 00 02 47 47 BF 8D 24 `.)........GG..$ 1BE8:0110 78 BF 8D 24 00 00 00 00-00 00 00 00 00 00 00 00 x..$............ 1BE8:0120 00 00 43 4C 41 52 4F 2E-41 52 4A 00 00 6E 72 96 ..CLARO.ARJ..nr. 1BE8:0130 17 00 00 60 EA 27 00 1E-07 01 00 11 00 00 78 FA ...`.'........x. 1BE8:0140 BE 8D 24 12 00 00 00 12-00 00 00 2B 5B DD 85 00 ..$........+[... 1BE8:0150 00 20 00 00 00 55 4E 4F-2E 54 58 54 00 00 C6 B9 . ...UNO.TXT.... 1BE8:0160 CD 6B 00 00 E8 81 ED EE-CA D4 B6 D2 A7 D3 DC E4 .k.............. 1BE8:0170 D6 A0 9D FA 96 F3 60 EA-00 00 ......`... Antes de pasar a la accion, conviene ver que valores han cambiado en el archivo encriptado respecto al archivo en claro. Es evidente, que la clave, o lo que sea que almacena el ARJ como clave, estara en alguno de estos bytes. 1BE8:0100 1BE8:0110 78 x 1BE8:0120 6E 72 96 nr. 1BE8:0130 17 11 78 . . x 1BE8:0140 1BE8:0150 C6 B9 .. 1BE8:0160 CD 6B E8 81 ED EE-CA D4 B6 D2 A7 D3 DC E4 .k ............ 1BE8:0170 D6 A0 9D FA 96 F3 ...... Veamos que es cada byte del archivo TEST1.ARJ que difiere del CLARO.ARJ: .---------------------------------------------------------------------. | 78 | Pertenece a la Fecha y hora de ultima modificacion: | | | 78 BF 8D 24 | | 6E 72 96 17 | Se trata del CRC de la cabecera. | | 11 | Son los flags ARJ. Indican que se trata de un archivo | | | encriptado. | | 78 | Reservado (Uhmmm! Interesante) | | C6 B9 CD 6B | El CRC de la cabecera del fichero local. | | E8 81 ... | El fichero encriptado. | `---------------------------------------------------------------------' Ya podemos ponernos a trabajar con el archivo. En la documentacion del ARJ, se nos avisaba de que el proceso de cifrado era una simple combinacion de operaciones XOR. Pues por si no lo recordais, o no lo sabiais, para la operacion XOR, se cumple: A ^ B = C ---> B ^ C = A Y como tenemos el texto en claro (arhivo sin codificar), y el encriptado, pues puede que si lo XOReamos obtengamos la clave, no? Y como ya tenemos la clave, pues sera facil comprobar si es este el metodo usado por el ARJ. Por cierto, un metodo bastante absurdo. Texto cifrado : E8 81 ED EE CA D4 B6 D2 A7 D3 DC E4 D6 A0 9D FA 96 F3 Texto en claro : 53 45 54 20 77 6F 72 6B 69 6E 67 20 6F 6E 20 41 52 4A ^ ------------------------------------------------------- Resultado : BB C4 B9 CE BD BB C4 B9 CE BD BB C4 B9 CE BD BB C4 B9 Pues no, parece que no es tan simple... Resulta que nuestra clave (CLAVE) es 43 4C 41 56 45. Aunque algo curioso si se ve... No parece extra€o que en el resultado se repita la cadena BB C4 B9 CE BD? Ademas, tiene la misma longitud que la clave. Hagamos una hipotesis. Se hace alguna operacion con la clave original, y despues, se XORea el resultado con el archivo original. Esa operacion puede que sea un XOR de la clave con alguna constante. Ademas, resulta que esa cadena (BB C4 B9 CE BD) no se ve en ninguna parte del archivo cifrado. Y menos en los bytes que difieren de un archivo a otro, que son los que interesan. De acuerdo, hagamos un XOR de la clave con lo que nos ha salido, a ver que sale: Clave original : 43 4C 41 56 45 Clave de cifrado : BB C4 B9 CE BD ^ ---------------- Resultado : F8 88 F8 98 F8 Vaya, vaya. Parece que se repite mucho el byte F8, eh? Pero no aparece en el archivo cifrado. Quizas sea una cadena interna del ARJ, no? Pues para probar, utilizaremos otro archivo cifrado nuevo: TEST2.ARJ. Usaremos la misma clave, pues si sale el mismo archivo, sabremos que se trata de un valor constante, o de que los valores dependen de la clave: 1BE8:0100 60 EA 29 00 1E 07 01 00-10 00 02 47 47 BF 8D 24 `.)........GG..$ 1BE8:0110 7A BF 8D 24 00 00 00 00-00 00 00 00 00 00 00 00 z..$............ 1BE8:0120 00 00 43 4C 41 52 4F 2E-41 52 4A 00 00 26 C0 99 ..CLARO.ARJ..&.. 1BE8:0130 D1 00 00 60 EA 27 00 1E-07 01 00 11 00 00 7A FA ...`.'........z. 1BE8:0140 BE 8D 24 12 00 00 00 12-00 00 00 2B 5B DD 85 00 ..$........+[... 1BE8:0150 00 20 00 00 00 55 4E 4F-2E 54 58 54 00 00 D3 B4 . ...UNO.TXT.... 1BE8:0160 08 53 00 00 EE 83 EF F0-C8 D2 B4 D0 B9 D1 DA E6 .S.............. 1BE8:0170 D4 BE 9F FC 94 F1 60 EA-00 00 ......`... Fijandonos bien, nos damos cuenta de que nos es igual al TEST1.ARJ, por que parece que alguno de los valores usados para camuflar la clave dependen del momento en que se cifra, o son aleatorios (que para el caso, pues es casi lo mismo). Y por ende, estos valores debieran almacenarse en el archivo, verdad. Resulta que analizando TEST2.ARJ, vemos que los bytes que varian de un archivo a otro ocupan las mismas posiciones que en TEST1.ARJ, asi que no hara falta separarlos para que los veais, verdad? Bien, pues vamos ahora a realizar la misma operacion anterior, es decir XORear, el texto en claro con el cifrado Texto cifrado : EE 83 EF F0 C8 D2 B4 D0 B9 D1 DA E6 D4 BE 9F FC 94 F1 Texto en claro : 53 45 54 20 77 6F 72 6B 69 6E 67 20 6F 6E 20 41 52 4A ^ ------------------------------------------------------- Resultado : BD C6 BB D0 BF BD C6 BB D0 BF BD C6 BB D0 BF BD C6 BB Ondia. Resulta que tambien se repite una misma cadena de 5 bytes, la misma longitud que la clave. Pues XOReemos esta cadena con la clave tambien: Clave original : 43 4C 41 56 45 Clave de cifrado : BD C6 BB D0 BF ^ ---------------- Resultado : FE 8A FA 86 FA Pues vaya. Resulta que no da lo mismo. O sea, que tengo el mismo archivo encriptado dos veces con la misma clave, en momentos diferentes (Siempre sera un momento diferente). Y nos da un resultado que no es el mismo. Es decir. La clave se modifica en funcion de algo aleatorio. Algo que quizas dependa del tiempo. Y para mas recochineo, ninguno de los bytes resultado de XORear las dos claves aparece en el archivo correspondiente. Me parece que esto ya lo he dicho antes, no? ;) Aunque... si nos fijamos bien... las claves de cifrado usadas en ambos casos se parecen, no? Visto que nuestra primera hipotesis no se cumple, hipoteticemos de nuevo. (Que bien suena. Si hasta parece politico y todo ;) ) Supongamos en esta ocasion que la clave se oculta en funcion del tiempo. Si nos damos cuenta, TEST2.ARJ fue creado despues que TEST1.ARJ. Pongamos las dos claves de cifrado juntas, a ver si salta algo por casualidad. Clave de cifrado TEST1.ARJ : BB C4 B9 CE BD Clave de cifrado TEST2.ARJ : BD C6 BB D0 BF Espera, no puede ser. Creo que lo estoy viendo. Joers, si es que despues de todo, me vino bien aprenderme aquellas tablas de multiplicacion, division, suma y resta en hexadecimal. Todo, para que luego te llegue un profesor, y te diga que no se puede multiplicar en hexadecimal... Bueno, que yo recuerde de mis clases de matematicas, los calculos se pueden hacer en cualquier base numerica. Solo hay que saberse las tablas basicas de la base. A ver, todos juntos: 1 * 1 es 1, 1 * 2, 2... 2 * F, es 1E... Me parece que estoy desvariando un poquito... A lo que ibamos. Si mirais atentamente, os dareis cuenta que la clave de cifrado usada en TEST2.ARJ es igual a la clave usada en TEST1.ARJ, mas 0x02, y si no, mirad: BB C4 B9 CE BD 02 02 02 02 02 + ---------------- BD C6 BB D0 BF Asi que puede que lo que estemos buscando, sea algo cuyo valor sea diferente en 0x02 entre TEST2.ARJ y TEST1.ARJ. Y ademas, debe ser uno de esos bytes que son diferentes respecto a CLARO.ARJ. Veamos el volcado de TEST2.ARJ - TEST1.ARJ: 1BE8:0100 1BE8:0110 02 . 1BE8:0120 F8 4E 03 .N. 1BE8:0130 BA 00 02 . . z 1BE8:0140 1BE8:0150 0D FD .. 1BE8:0160 3B E8 .. .. .. .. .. .. .. .. .. .. .. .. ;............... 1BE8:0170 .. .. .. .. .. .. ...... Uhmm! Aparece dos veces. Una en el campo de de la fecha y hora de la ultima modificacion... Y la otra en un byte marcado como... reservado. Me parece que lo tengo... Asi que en ese byte se almacena como con que ocultar la clave. Ahora nos falta saber el como. Y quizas, si ponemos la clave original, la clave de cifrado y este dichoso byte juntos, se nos ocurra algo. Vamos a verlo para TEST1.ARJ: Clave de cifrado : BB C4 B9 CE BD Clave original : 43 4C 41 56 45 Mardito byte : 78 78 78 78 78 Alguien lo ha descubierto ya. Me parece que no habeis hecho vuestros deberes. Y aquellas tablas numericas que habia que aprenderse para hoy? Repasemos todos juntos... BB - 78 = 43; C4 - 78 = 4C... Creo que no hacen falta mas explicaciones. Pero por si todavia no os habeis dado cuenta, lo contare por palabros. De la fecha de ultima modificacion, o para ser exactos, en el momento en el que incluye la clave, se toma un byte que se almacena en la posicion reservada esa. Ademas, es el byte correpondiente al menos significativo de la fecha y hora de encriptado. Ahora, el usuario normalito y corriente, introduce una password, a la que se le suma este byte. Y con ello, obtenemos la clave con la que se cifrara el fichero original. Tan simple como esto. Y EL ARJ, COMO SABE QUE DESCIFRA BIEN? =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Tan sencillo como descrifrar aplicando el mismo procedimiento que para cifrar. O sea, el usuario introduce la password que cree que es, y el fichero se encripta siguiendo el procedimiento anterior. Como A ^ B ^ A = B, entonces solo si la clave es correcta, obtendremos el fichero original. Vale, todo esto es muy bonito. Pero... Como diantres se las apa€a el ARJ para saber que la clave es correcta. Pues el propio ARJ nos da una muy buena pista. Si le metemos una password erronea, que hace? Decirnos que se ha producido un error de CRC. Asi que si pensamos un poco, nos daremos cuenta de que lo unico que tiene que hacer es comprobar el CRC del fichero que se obtiene con el CRC del fichero original, que va almacenado en el archivo, tal y como ya hemos visto. Y SI TENGO MAS DE UN FICHERO EN EL ARJ? =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Veamoslo con un ejemplo practico. Esta vez tenemos el archivo sin cifrar CLARO2.ARJ, y el archivo cifrado TEST21.ARJ, encriptado con la clave: SET El archivo CLAR2.ARJ es como sigue: 1BE8:0100 60 EA 2A 00 1E 07 01 00-10 00 02 05 05 00 8E 24 `.*............$ 1BE8:0110 05 00 8E 24 00 00 00 00-00 00 00 00 00 00 00 00 ...$............ 1BE8:0120 00 00 43 4C 41 52 4F 32-2E 41 52 4A 00 00 BE 81 ..CLARO2.ARJ.... 1BE8:0130 82 E2 00 00 60 EA 27 00-1E 07 01 00 10 00 00 05 ....`.'......... 1BE8:0140 FA BE 8D 24 12 00 00 00-12 00 00 00 2B 5B DD 85 ...$........+[.. 1BE8:0150 00 00 20 00 00 00 55 4E-4F 2E 54 58 54 00 00 45 .. ...UNO.TXT..E 1BE8:0160 8D 99 95 00 00 53 45 54-20 77 6F 72 6B 69 6E 67 .....SET working 1BE8:0170 20 6F 6E 20 41 52 4A 60-EA 27 00 1E 07 01 00 10 on ARJ`.'...... 1BE8:0180 00 00 05 14 BF 8D 24 06-00 00 00 06 00 00 00 0D ......$......... 1BE8:0190 15 A7 1B 00 00 20 00 00-00 44 4F 53 2E 54 58 54 ..... ...DOS.TXT 1BE8:01A0 00 00 D8 63 7E D3 00 00-45 55 52 45 4B 41 60 EA ...c~...EUREKA`. 1BE8:01B0 00 00 .. Aqui vemos que hay dos ficheros almacenados: UNO.TXT y DOS.TXT Y ahora vamos con el aspecto del archivo encriptado: 1BE8:0100 60 EA 2A 00 1E 07 01 00-10 00 02 05 05 00 8E 24 `.*............$ 1BE8:0110 49 00 8E 24 00 00 00 00-00 00 00 00 00 00 00 00 I..$............ 1BE8:0120 00 00 43 4C 41 52 4F 32-2E 41 52 4A 00 00 D6 E5 ..CLARO2.ARJ.... 1BE8:0130 B6 33 00 00 60 EA 27 00-1E 07 01 00 11 00 00 49 .3..`.'........I 1BE8:0140 FA BE 8D 24 12 00 00 00-12 00 00 00 2B 5B DD 85 ...$........+[.. 1BE8:0150 00 00 20 00 00 00 55 4E-4F 2E 54 58 54 00 00 57 .. ...UNO.TXT..W 1BE8:0160 0F FC BD 00 00 CF CB C9-BC F9 F2 EE E5 F4 F2 E9 ................ 1BE8:0170 BD F3 E0 BD DD DC D7 60-EA 27 00 1E 07 01 00 11 .......`.'...... 1BE8:0180 00 00 49 14 BF 8D 24 06-00 00 00 06 00 00 00 0D ..I...$......... 1BE8:0190 15 A7 1B 00 00 20 00 00-00 44 4F 53 2E 54 58 54 ..... ...DOS.TXT 1BE8:01A0 00 00 CA E1 1B FB 00 00-D9 DB CF D9 C5 DC 60 EA ..............`. 1BE8:01B0 00 00 .. Si hacemos la comprobacion, veremos que la clave de cifrado es 53 45 54 (SET) + 49, o sea 9C 8E 9D. Y ademas ha resultado que es la misma para los dos ficheros. Lo que si que nos queda claro despues de todo este rollo, es que ya sabemos como encripta el ARJ, como romperlo, y que no es nada seguro. Y ESO DEL CRC, QUE ES? =-=-=-=-=-=-=-=--=-=-= Bueno, pues el CRC no es ni mas ni menos que el Codigo de Redundancia Ciclica. A que suena bonito, eh? ;) CRCs hay de muchos tipos. El que nos interesa en esta ocasion, es el CRC de 32 bits, pues es el que usa el ARJ. En si, es un valor, resultado de una funcion, usado para comprobar la integridad de unos datos, como puede ser un fichero. Con esto nos comprobamos casi con total seguridad que los datos estan tal y como se crearon. Tambien se usa en las lineas de comunicacion de datos. Para calcular el CRC, se usa un polinomio, que en el caso del ARJ, es el 0xEDB88320, que casualmente es el mismo que el usado en el PKZIP y otras aplicaciones. Lo del polinomio, es para indicar que bits de la secuencia se usan en la funcion. Asi el polinomio X^5 + x^3, es lo mismo que 0x14, ya que el bit 0 o menos significativo es en esta ocasion el bit 1. La forma mas rapida de calcular el CRC de un fichero, es usar este peque€o programa que os doy a continuacion: <++> set_014/arj/crc32.c /* CRC-32b version 1.03 by Craig Bruce, 27-Jan-94 ** ** Based on "File Verification Using CRC" by Mark R. Nelson in Dr. Dobb's ** Journal, May 1992, pp. 64-67. This program DOES generate the same CRC ** values as ZMODEM and PKZIP ** ** v1.00: original release. ** v1.01: fixed printf formats. ** v1.02: fixed something else. ** v1.03: replaced CRC constant table by generator function. */ #include int main(); unsigned long getcrc(); void crcgen(); unsigned long crcTable[256]; /****************************************************************************/ int main( argc, argv ) int argc; char *argv[]; { int i; FILE *fp; unsigned long crc; crcgen(); if (argc < 2) { crc = getcrc( stdin ); printf("crc32 = %08lx for \n", crc); } else { for (i=1; i>8) & 0x00FFFFFF) ^ crcTable[ (crc^c) & 0xFF ]; } return( crc^0xFFFFFFFF ); } /****************************************************************************/ void crcgen( ) { unsigned long crc, poly; int i, j; poly = 0xEDB88320L; for (i=0; i<256; i++) { crc = i; for (j=8; j>0; j--) { if (crc&1) { crc = (crc >> 1) ^ poly; } else { crc >>= 1; } } crcTable[i] = crc; } } <--> Con el podreis calcular el CRC de un fichero, y si sois avispados, vuestro propio programa que obtenga claves de archivos ARJ. (Si, se que se llaman crackeadores, pero no me gusta ese nombre) PUES YO USO ZIP =-=-=-=-=-=-=-= Pues vale, pues me alegro. Puer mira que bien. Si te crees que por eso tienes mas seguridad... me temo que estas equivocado. Como regalito, aqui va un esquema rapido de como encripta el PKZIP (version 2.04g). Primeramente, usa tres claves, inicializadas a los siguientes valores: - K0 = 0x12345678 - K1 = 0x23456789 - K2 = 0x34567890 Andaaaa! Que integilentes, esto gintelitentes, es decir, ingelitentes. No, no era asi. Era... inteligenetes... uhmm... Ah! Inteligentes Pero su inteligencia no queda ahi. El proceso de cifrado supera al del ARJ. Eso tenemos que reconocerselo. Claro. PKWare es una empresa mas o menos potente. Y como es logico, han usado un poco mas sus neuronas. Pero solo un poco, que luego les duele la cabeza ;) Veamos el procedimiento, tal y como si fuera codigo fuente en C: Ci = Pi ^ K3 K0 = crc32 (K0, Pi) K1 = K1 + (K0 & 0x000000FF) K1 = K1 * 0x8088405 + 1 K2 = crc32 (K2, K1 >> 24) K3 = ((K2 | 2) * ((K2 | 2) ^ 1)) >> 8 Aqui, Ci es el byte cifrado, y Pi el correspondiente byte antes de cifrar. El proceso cuando se mete una clave es pasar la clave por el algoritmo de cifrado como si de algo a encriptar se tratara. De esta forma se actualizan K0, K1, K2 y K3. Evidentemente, el resultado de este cifrado se descarta. Ademas, se le a€aden 12 bytes aleatorios a la cabecera de cada fichero. Pero esto no da mayor seguridad, verdad? Asi pues, solo tenemos que presuponer de 40 a 200 bytes del archivo original, lo que segun los expertos es una complejidad de 2^27. Para desencriptar, pues se pasa el archivo de nuevo por el cifrador, y como con el ARJ, se comprueba el CRC. Si coincide, la clave es correcta. Creo que se ve que es bastante facil romper la criptografia tanto del ARJ como del PKZIP. Alguien afronta el reto? DESPEDIDA =-=-=-=-= Pues nada, que eso ha sido todo. Que ya se ve como de la propia documentacion de un programa, con algo de ganas, mas paciencia todavia, y tiempo, podemos descubrir cualquier cosa. Y por muy basica que parezca, lo unico que teneis que pensar es que lo habeis hecho con vuestros propios medios. Asi, cuando alguien vaya de cool porque sabe manejar un nuke (un boink, etc.) vosotros podreis decir que sabeis como funciona, e incluso podreis llegar a realizar vuestras propias modificaciones y mejoras. Bueno, nada mas por el momento. Y como diria el autor del programa que os he ofrecido (el del CRC): Keep on hackin' Falken