[INVESTIGACION] Carga de archivos desde HDD [REVELADA CLAVE PUBLICA]

En caso de publicación en otro foro, por favor, no olvides poner la fuente y el autor

[xbox 360] Me he decidido a revelar la clave publica RSA y el sistema de cifrado usado para cargar archivos PIRS desde el disco duro para que la gente pueda hacer sus propias investigaciones (Es el primer paso para cargar cualquier PIRS desde el disco duro sin JTAG/RGH)

Siempre me ha gustado modificar juegos del PC, coches...mapas...skins...vamos, darle un toque personal al juego, pero con mi XBOX simplemente no puedo por la dichosa firma de Microsoft, pero es algo que siempre he querido hacer, y por fin me he decidido a intentarlo. En caso de modificación del archivo hay que generar un nuevo SHA1, pero como ya hay aplicaciones que lo hacen, me voy a centrar en su funcionamiento offline y la firma del archivo.

Lo del funcionamiento offline es para poder usar un DLC modificado, ya sea la música, ropa, coches, o lo que sea y que se pueda jugar sin que Microsoft se entere, que seguro que no le gusta que se modifiquen estos archivos (Aunque sea para mejor).

Como poseo algunos conocimientos de cifrado, y en alguna otra ocasión he conseguido cifrar y descifrar mensajes RSA sin saber la clave privada, pues me he decido a intentar esta "salvajada".

0.- CIFRADO RSA
Vamos con una pequeña explicación del algoritmo RSA para quienes no lo conozcan. Tenemos de partida dos números primos muy grandes (quizás de 200 cifras de largo), a los que llamaremos "p" y "q". Estos números son privados, y el conseguir obtenerlos supondría haber roto la clave.
El siguiente número es "phi(n)", que no es más que multiplicar "p"-1 por "q"-1, y este "phi(n)" también es privado.
Tenemos otro numero llamado "n", que se obtiene de multiplicar "p" y "q". Este número "n" es el modulo y es parte de la clave pública.
Y por ultimo tenemos los exponentes "e" y "d". El exponente "e" es también parte de la clave pública y suele emplearse el numero 65537.
Y el exponente "d" tiene que cumplir que al multiplicarlo por "e" y dividirlo entre "phi(n)" el resto sea 1.
No es extraño que después de efectuar los cálculos necesarios se destruyan casi todos los números, quedando solo "e", "d", y "n", ya que son los empleados en el cifrado/descifrado.
Clave pública los números "e" y "n"
Clave privada los números "d" y "n"

CIFRADO:
Tenemos un mensaje "m", pues lo elevamos al número "e" y lo dividimos entre "n", y el resto es el mensaje cifrado, que llamaremos "c"
DESCIFRADO:
Desde el mensaje cifrado "c" lo elevamos a la "d" y dividimos entre "n", y el resto es el mensaje sin cifrar llamado "m"

Aunque así pueda parecer bastante sencillo el algoritmo es muy fuerte y el punto de partida es tener la clave pública, tanto el modulo "n" como el exponente "e", ya que desde ahí partirá cualquier intento de romper el cifrado y de comprobación de cualquier tipo.

A partir de este punto llamaremos al resto de una división módulo, de tal forma que 19 mod 5 = 4, ya que 19 entre 5 es 3 y nos sobran 4.

1.- LOS DLC's

1.1.- ANALIZANDO DLC's
He tenido la gran suerte de tener los DLC's del Mafia II que necesitaban un perfil especifico para funcionar, y que luego, dichos DLC's fueron editados en DVD y, por lo tanto, funcionaban en cualquier consola como un juego más, pues tenía un gran punto de partida, ya que podía comparar los DLC's LIVE con los del DVD y comprobar diferencias.

Lo primero que hice fue pasar ambos ficheros por un programa que me indica las diferencias en bytes entre ellos con los siguientes resultados (A la izquierda LIVE y a la derecha DVD, que, de ahora en adelante, llamaremos PIRS):
1.1.a) 2FB11BBF146E8654171C4C5912519AD76876868A54 - Vegas Pack (257 bytes diferentes)
http://imageshack.us/photo/my-images/52/1a1ah.jpg/
1.1.b) 9FE613DEEC585142474A3A2AA07CC063DD03AAF754 - Joe's Adventure (272 bytes diferentes)
http://imageshack.us/photo/my-images/829/1b1w.jpg/
http://imageshack.us/photo/my-images/835/1b2v.jpg/
1.1.c) 26471AA1DC2FEEFF65C1DF2CDA427E7852553D2754 - Jimmy's Vendetta (269 bytes diferentes)
http://imageshack.us/photo/my-images/6/1c1j.jpg/
http://imageshack.us/photo/my-images/40/1c2t.jpg/
1.1.d) 61408E568A04473F48D18E5041340EF216E1ACDA54 - Renegade Pack (No he encontrado el LIVE)
1.1.e) A0E2C50D5FB619CF11255EE9415589FB3AE2ECCF54 - The Betrayal of Jimmy (No he encontrado el LIVE)
1.1.f) A33EC174FB2BB1D942274DBC0A060F5EAD35B40554 - Made Man Pack (No he encontrado el PIRS)
1.1.g) F4AE109F615E7F240BC1D97BAD04C5ACC30C958254 - Greaser Pack (259 bytes diferentes)
http://imageshack.us/photo/my-images/190/1g1g.jpg/
1.1.h) F29F8510F984A05FE08728CB28611E3FFED39CE654 - War Hero Pack (258 bytes diferentes)
http://imageshack.us/photo/my-images/824/1h1m.jpg/

1.2.- SACANDO CONCLUSIONES
1.2.a) Los 4 primeros bytes pasan de 4C 49 56 45 (LIVE) a 50 49 52 53 (PIRS)
1.2.b) Los 256 bytes siguientes parecen ser la firma del archivo
1.2.c) En los DLC's que son juegos en sí, cambia desde 0x22c hasta 0x233, que pasa a ser todo "FF" en los PIRS, que coincide con los PIRS que no son juegos.
1.2.d) En los DLC's que son juegos en sí, cambia 0x237 que pasa a ser 01 (Valor igual para todos los PIRS)
1.2.e) En los DLC's que son juegos en sí, cambian algunos valores entre 0x23B y 0x32B que pasan a ser "00" (Valor igual para todos los PIRS)

1.3.- CONVIRTIENDO DE LIVE A PIRS (Sin firmar)

1.3.a) Cambiar los 4 primeros bytes a "50 49 52 53"
1.3.b) Cambiar de 0x22C a 0x233 todo "FF"
1.3.c) Cambiar 0x237 a "01"
1.3.d) Cambiar de 0x23B a 0x32B todo a "00"
1.3.e) El nombre del archivo debe ser el valor de SHA-1 almacenado en 0x32c añadiéndole al final un "54"

*Llegados a este punto tenemos el DLC solo a falta de la firma para que
funcione (Se supone que las modificaciones del archivo como cambiar una canción, por ejemplo, ya estarían efectuadas con cualquiera de los programas que existen para ello). En otras palabras, lo fácil ya está hecho, ahora viene lo más complicado de todo.

2.- LA FIRMA

2.1.- ANALIZANDO LAS FIRMAS
Las firmas son de 256 bytes, lo que puede indicar que se ha utilizado RSA-2048.
Como RSA usa una clave privada y una pública, lo más lógico es que la clave privada esté en los servidores de Microsoft y que la clave publica esté en nuestra consola, y que Microsoft utilice la clave privada para firmar el contenido, y nuestra consola use la clave pública para desencriptar el
contenido y comprobar si el resultado es correcto.

Como los PIRS funcionan en cualquier consola sin modificar nada, es de lógica que todas las consolas tienen la misma clave pública.

De otros estudios se sabe que el cifrado es aplicado al SHA1 del archivo (http://www.free60.org/STFS#Header), que está guardado en 0x32c y ocupa 20 bytes.
Analizando el KV.bin, que tiene claves RSA obtenemos varias claves, pero todas son RSA-1024, por lo que no parece que se use ninguna de las claves del KV.bin (http://robeweb.dyndns.org/XBOX/XBOX%20Hexadecimal.xml). Sin embargo todas las claves comparten el exponente "AQAB", que es 65537 en decimal, y además es un exponente público muy utilizado en RSA.

Después de indagar un poco más por varios sitios de internet, parece ser que la clave RSA está guardada en la CPU, pero no especifican si es la clave usada para cargar los DLC's o simplemente para los 1BL y demás, y, dado que en muchos sitios de internet se dice que disponen de la clave
publica, pero no figura en ninguno de estos sitios, y directamente pegan malas contestaciones a las personas que solicitan dicha clave, pues me veo obligado a averiguar la clave por mi cuenta.

Tras muchísimas pruebas (casi un año) sin resultados, decidí atacar el problema desde otro punto de vista, llegando a la conclusión de que las firmas están "invertidas". Por "invertidas" me refiero a que si la firma RSA es, por ejemplo, "7A DE 3F 01 14", ésta se escribe en el archivo como "14 01 3F DE 7A". Este array de bytes yo lo manejaba a la inversa, por lo que los resultados obtenidos no fueron satisfactorios.

Otro de los resultados de las pruebas realizadas indica que los archivos son firmados de la siguiente manera:
- Se halla el SHA1 desde 0x22c hasta 0x343 (280 bytes en total)
- Al resultado anterior se le añade un relleno y un ID del algoritmo SHA1 quedando de la siguiente forma:

0001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 + <3021300906052B0E03021A05000414> + <SHA1>


De tal manera que al aplicar la clave publica a la firma "invertida" (llamada "c") se obtiene el resultado descrito (llamado "m").

2.2.- OBTENIENDO EL MODULO Y EL EXPONENTE
Al disponer del origen y de la firma, se podría intentar obtener el modulo partiendo del exponente. Por regla general se usa el exponente 65537 (Otra de las conclusiones las que llegué tras el año de pruebas, es que el exponente no es 65537, sino otro distinto), así que voy a usar dicho exponente en la ecuación de RSA y lo aplico a todos los archivos:
(c^e)mod(n)=m <=> xn-m=c^e <=> xn=(c^e)-m

Primero calculo c^e para luego restar m y obtener así el valor del modulo "a lo bruto", y después de varias horas de tener a mi ordenador currando ininterrumpidamente obtengo los valores de xn. Como el modulo tiene que ser de 256 bytes tengo que buscar un número entero x para que se cumpla:
(xn)/x=número entero y de 512 dígitos Hex

Dado que todos los xn que he obtenido tienen como divisor el modulo RSA, busco el máximo común divisor de todos los xn con el algoritmo de Euclides (Este no lo voy a explicar), y , después de un rato de tener al ordenador currando ininterrumpidamente obtengo un numero, que cumple los requisitos.

Como curiosidad indico que dada la complejidad computacional con números tan grandes y el excesivo tiempo requerido, me he visto obligado a modificar algunas librerías de JAVA (Sí, he utilizado JAVA) haciéndolas CUSTOM para poder trabajar con más comodidad (Mayor control de las funciones, sistema de backup…).

2.3.- COMPROBANDO EL MODULO OBTENIDO
Si el exponente elegido es correcto y no he metido la pata al hallar n, se debería cumplir (c^e)mod(n)=m para todos los DLC's descritos arriba y algunos otros más:
2.3.a) Vegas Pack <=> SE CUMPLE
2.3.b) Joe's Adventure <=> SE CUMPLE
2.3.c) Jimmy's Vendetta <=> SE CUMPLE
2.3.e) Greaser Pack <=> SE CUMPLE
2.3.f) Renegade Pack <=> SE CUMPLE
2.3.g) The betrayal of Jimmy <=> SE CUMPLE
2.3.h) War Hero Pack <=> SE CUMPLE
2.3.i) Resident Evil (Spanish Voice Pack) <=> SE CUMPLE
2.3.j) Resident Evil (Italian Voice Pack) <=> SE CUMPLE
2.3.k) Resident Evil (German Voice Pack) <=> SE CUMPLE
2.3.l) Resident Evil (French Voice Pack) <=> SE CUMPLE

Comprobado este número con todos los PIRS que aquí figuran, y cumpliéndose la norma en todos, puedo afirmar sin ningún temor a equivocarme que he hallado la clave pública usada por la Xbox para desencriptar los archivos PIRS.

CLAVE PÚBLICA RSA-2048 XBOX 360 PARA CARGAR PIRS:

(EN DECIMAL)
MODULO:
17661946096927428880018687687519554222346387998386674749439126372717750406323
07060671643668450647975474317819462292616976627854486641760891076788782549621
61912322309701904992145957584398090797731146197754981933232949066577876300320
48519982660030398113790748461815621813092619362680460222583163739419452794455
39259726150760598690047541200517411791604385438817211921665153660127235499206
07292144105766600566090259053092221694080043745350514468167457519187266838898
34943038011327744188881589447518161341915478112600554089968515099834362012946
18606728664027347340773917137439061431362735447351145922289602202140807676695
1

EXPONENTE: 3

(EN HEXADECIMAL)
MODULO:
0x8BE8D920F205E07057A868B461F41BC640D24EA6C611041BBD477C90DD88121784F7B0F64B
8EF089C7E5CEAAECDE48A0A43730115183BDF7A21027962F9FA93D322579360EF4ED194A02A
ED4D837CFA6EB87E6D1FBB366FC09062A61202CF872FE48FF283D10BB9EB33D032560C87A59
4D84B9189799AC00224E1324D3C157DFBCA4AA1C474BF4979C2751CF4B347A35BE66492FAE2
0A476456046BC36E11771C5A79B08112EA064D0F89102A6E77D77114A802472057A63E67C63
0EAF4CF7E7FC02AB77BAC8E674B2B0AE9769EBFE71A658EBB6A3C4A3EEBA0385B51A3E25F98
EBA8EBC1A90AC20DE0D184072D6E3469DFC5C7241945847E63B32B28D9E9EE7

EXPONENTE: 0x3


Como su propio nombre indica, esta clave es PÚBLICA por lo que no se infringe ninguna ley ni nada parecido al ser publicada. Otra cosa seria crackear esta clave o conseguir y/o publicar el exponente privado, el cual, por ahora, se desconoce, y lo que se necesitaría para poder firmar las modificaciones de los juegos.

2.4.- REFIRMANDO LOS PIRS
Mediante un sencillo sistema de "acotacion" he podido ir "arrinconando" poco a poco la clave privada. El problema con este sistema es que el tiempo necesario es exponencial cuanto mas se quiera acotar la clave privada. Ahora mismo tengo hallados 307 digitos de 617 que tiene la clave privada. El exponente privado por ahora es el siguiente (Como es logico, las "x" son los numeros que me faltan por hallar):

11774630731284952586679125125013036148230925332257783166292750915145166937548
71373781095778967098650316211879641528411317751902991094507260717859188366414
41274881539801269994763971722932060531820764131836654622155299377718584200213
6567998844002026540919383230787708120872841290845364014838877582627963519630x
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
x


Mi PC sigue currando las 24 horas de manera ininterrumpida, según vaya obteniendo mas resultados, los iré publicando.

MADE by $3@!_ a.k.a robeweb

P.D.: Quiero agradecer tanto a la gente que me dio ánimos desde el principio como a la gente que no, ya que ambos han conseguido que quiera llegar hasta el final en este proyecto.

[EDITADO 20/11/2012] - Añadida información descubierta sobre la firma y HASH SHA1. Publicado hallazgo de clave publica RSA-2048.
[EDITADO 21/11/2012] - Añadido "subtitulo" explicando las consecuencias de haber descubierto la clave.
[EDITADO 14/03/2013] - Publicada clave pública ante la falta de resulados de hallar la clave privada.
[EDITADO 20/03/2013] - Publicada la parte hallada de la clave privada.
aunque yo no te puedo ayudar,te escribo para darte animos y decirte que gente con ganas como tu son las que hacen falta en estos sitios.
Gran trabajo el que has empezado, espero que no desesperes y consigas tener exito, yo poco te puedo ayudar en este tema, pero te agradezco que pierdas tu tiempo en estas cosas, ya que de gente como tu sale todo lo que se ha podido conseguir de la XBOX.

Gracias.
Estaria muy bien poder personalizar los juegos, ya lo hacia en los de wii y lo que mas me gustaria seria poder disfrutar de un dragon ball con la OST original jajaja.


Animo compañero, sigue asi, ojala fuera de mas ayuda.
Aaaaaaaaaaaaamigo como te salga esto.... Mucha suerte y (por lo que entendi) paciencia. [oki]
estaremos atentos a tus progresos suerte con la investigacion compañero!
Siento ser de los que da una respuesta de las que no quieres, pero como se ve que entiendes y conoces perfectamente el tema ya sabes de antemano que con los recursos computacionales a tu alcance es practicamente imposible que consigas nada en un plazo razonable .... digamos que razonable sería menos de un año.

Aunque posible es. Hace tiempo en unos foros muy conocidos sobre crackeo de sistemas sat, en la sección para averiguar la CW de NBATV que usaba el sistema BISS, con una clave infinitamente más simple que esta que hablas, nos juntamos unos 60 foreros machacando claves con fuerza bruta en nuestros equipos, asignándonos rangos a cada uno.

Yo por aquella época pude dedicar un chasis blade del curro aun sin estar en explotación con 14 equipos, cada uno con 2 CPU's de 4 cores (112 hilos de ejecución simultáneos) trabajando las 24 horas. Como es lógico fui yo quien encontró la CW al cabo de unos 21 días, y cuando fuimos a probarla los tios cachondos de NBATV ya la habían cambiado .... :(

Pero vamos, ánimo en el intento. Yo como soy muy bruto le veo pocos visos de éxito.

Saludos.
popoff escribió:Siento ser de los que da una respuesta de las que no quieres, pero como se ve que entiendes y conoces perfectamente el tema ya sabes de antemano que con los recursos computacionales a tu alcance es practicamente imposible que consigas nada en un plazo razonable .... digamos que razonable sería menos de un año.

Aunque posible es. Hace tiempo en unos foros muy conocidos sobre crackeo de sistemas sat, en la sección para averiguar la CW de NBATV que usaba el sistema BISS, con una clave infinitamente más simple que esta que hablas, nos juntamos unos 60 foreros machacando claves con fuerza bruta en nuestros equipos, asignándonos rangos a cada uno.

Yo por aquella época pude dedicar un chasis blade del curro aun sin estar en explotación con 14 equipos, cada uno con 2 CPU's de 4 cores (112 hilos de ejecución simultáneos) trabajando las 24 horas. Como es lógico fui yo quien encontró la CW al cabo de unos 21 días, y cuando fuimos a probarla los tios cachondos de NBATV ya la habían cambiado .... :(

Pero vamos, ánimo en el intento. Yo como soy muy bruto le veo pocos visos de éxito.

Saludos.


Lo de obtener la clave privada es mi objetivo final, pero mi objetivo principal ahora mismo es hallar la clave publica, porque sino no puedo avanzar hasta la clave final. Obtener esa clave final me puede llevar miles de años a mi solo, pero si obtengo la clave publica (espero que en poco mas de una semana) y la puedo compartir por ser publica, puedo dar un punto de partida a gente que sepa mas de criptografia que yo, y a la cual se le presento el mismo problema que a mi, que no figuraba la dichosa clave en ningun sitio de internet, y ellos pueden seguir el camino desde el punto al que yo llegué.

c0d3m4st4 escribió:Supongo que habrás echado un vistazo a esto:

http://en.wikipedia.org/wiki/RSA#Using_ ... _algorithm


En el punto desde el que parto, no me puedo aprovechar el agoritmo chino del resto. Cuando avance un poco mas en el calculo de numeros ya si, que tengo programado un pequeño programita que lo usa.
robeweb hace tempo me tope con este hilo de eol exale un ojo tambien hablan de la clave publica

hilo_se-sabe-la-clave-publica-de-ms-usada-en-la-firma-de-xex_777639
draqen escribió:robeweb hace tempo me tope con este hilo de eol exale un ojo tambien hablan de la clave publica

hilo_se-sabe-la-clave-publica-de-ms-usada-en-la-firma-de-xex_777639


Estoy en las mismas, se dice que se conoce la clave pública pero que no se ha compartido, y se necesita la dichosa clave para poder avanzar, ya sea intentando romperla, o comprobar metodos alternativos como el cifrado ciclico o cualquier otra cosa.
me podrias pasar algun link donde se deca eso ara ver mas info y tal, ya tengo time libre me gustaria revisar google d arriba abajo pero no se como buscar o con que palabras buscar xd

mirastes tambien la app Wxpirs es para ver el contenido de los archivos live y CON
http://gael360.free.fr/wxPirs.php
draqen escribió:me podrias pasar algun link donde se deca eso ara ver mas info y tal, ya tengo time libre me gustaria revisar google d arriba abajo pero no se como buscar o con que palabras buscar xd

mirastes tambien la app Wxpirs es para ver el contenido de los archivos live y CON
http://gael360.free.fr/wxPirs.php


Con wxPirs pasa lo mismo que con Le Fluffie, pueden manejar los archivos e incluso modificarlos y firmarlos, pero la firma aplicada no vale para consolas retail (La que todos tenemos).

Una explicacion de RSA (De todas formas editaré el hilo para incluir información basica del funcionamiento del cifrado):
http://es.wikipedia.org/wiki/RSA
Una explicacion de los archivos LIVE/PIRS, de como están estructurados y esas cosas:
http://www.free60.org/STFS
aqui cn la colaboracion de todos y de mas seguro qe se puede conseguir algo curioso
ya tienes un seguidor mas... animo, ojala lo logres...

ojala pudiera ayudarte en algo.... saludos...


...
draqen escribió:algo nuevo??

Me temo que no, yo contaba con que el algoritmo que he preparado acabara el sobre el día 17, pero se ve que he tirado muy por lo bajo y ahora no puedo decir fecha de cuando acabara.

El calculo que estoy haciendo es elevar la firma a la potencia 65537, y por ahora se llega por la potencia 32768, que tiene 16.768.610 cifras en hexadecimal y lleva desde el día 13 calculando la siguiente potencia, que es 65536. Como comprenderas, con esta salvajada de numeros, las fechas en las que espero obtener resultados son un poco...imprecisas (Yo me estoy empezando a impacientar con mi propio programa por que esta tardando mas de lo que calcule).

Te prometo que en cuanto el calculo termine actualizo el post para ir publicando los avances conseguidos.
Primero hola a todos, llevo tiempo leyendo este foro pero es la primera vez que me animo a postear.

Primero lo negativo. Una RSA de 2048 es una RSA fuerte fuerte y no sabes si está en conjunción con otro tipo de cifrado como una triple DES u otra (algo al estilo PGP). Ahora bien, creo que una posible solución (quitando el tiempo de desarrollo que desde luego no sería trivial, la capacidad matemática para crear un algoritmo elegante y la imprescindible dosis de potra) pasaría por aumentar exponencialmente tu capacidad de computación. Si conoces los sistemas que utiliza el SETI (plataforma BOINC) se podría escribir algo parecido (sin un GUI tan elaborado y partiendo de código ya existente) para que cada cliente se encargara de una parte del problema. Muchos usuarios participarían en cuanto supieran para que se está usando. Por supuesto el envío debería ser redundante para así cotejar resultados pero creo que sería la única manera de tener una mínima posibilidad de reventar una RSA a lo bestia.

En otro orden de cosas me preguntaba si te has planteado alguna variante de birthday attack para firmas...

Un saludo
ciberdim escribió:Primero hola a todos, llevo tiempo leyendo este foro pero es la primera vez que me animo a postear.

Primero lo negativo. Una RSA de 2048 es una RSA fuerte fuerte y no sabes si está en conjunción con otro tipo de cifrado como una triple DES u otra (algo al estilo PGP). Ahora bien, creo que una posible solución (quitando el tiempo de desarrollo que desde luego no sería trivial, la capacidad matemática para crear un algoritmo elegante y la imprescindible dosis de potra) pasaría por aumentar exponencialmente tu capacidad de computación. Si conoces los sistemas que utiliza el SETI (plataforma BOINC) se podría escribir algo parecido (sin un GUI tan elaborado y partiendo de código ya existente) para que cada cliente se encargara de una parte del problema. Muchos usuarios participarían en cuanto supieran para que se está usando. Por supuesto el envío debería ser redundante para así cotejar resultados pero creo que sería la única manera de tener una mínima posibilidad de reventar una RSA a lo bestia.

En otro orden de cosas me preguntaba si te has planteado alguna variante de birthday attack para firmas...

Un saludo


Mi principal objetivo ahora mismo no es obtener la clave privada, ni phi(n), ni los numeros primos...Solo la publica, ya que seria el punto de partida de todo lo demas. Con la documentación que he podido encontrar en distintos sitios se supone que solo es un cifrado RSA-2048 del SHA-1 del archivo, por eso estoy tratando de obtener la clave publica y comprobar si esto es cierto o, como bien dices, se aplica junto con otro tipo de cifrado. En muchos sitios se dice que se tiene la clave publica, pero en ninguno lo facilitan.

Respecto a lo de un ataque distribuido ya me propuso la idea draqen y me parecio una gran idea, pero para un ataque directo al algoritmo (ya se vera con que metodo), y para eso vuelvo al problema de que necesito la clave publica (Lo que estoy calculando a lo bruto), asi que por ahora es una idea que queda temporalmente aparcada hasta que tenga "un punto de partida viable".

Un saludo.
Creo que mejor se deveria tratar de hacer arrancar el freeboot con el Glitch hack, ahi que lograr que el CD arranque, y tiene comprobaciones de SHA1 :D
aqui esta una parte del archivo build.py usado en el reset glitch dice como desencrypta y encrypta partes de la nand como el CD el CB_B y toda la leche dice que usa Rc4 cmbinada creo con el cpu key asi saca la secret 1BL y con eso deberia de sacar creo que la public key supongo.

#if secret_1BL is None:
#   secret_1BL = open("key_1BL.bin", "rb").read()

# Import Psyco if available
try:
   import psyco
   psyco.full()
except ImportError:
   pass

# first, unpack base input image. We are ignoring any updates here
import hmac, sha, struct, sys, binascii
try:
   import Crypto.Cipher.ARC4 as RC4
except ImportError:
   print "Error importing Crypto.Cipher.ARC4 - please install python-crypto!"
   print "You can get it from http://www.dlitz.net/software/pycrypto/"
   sys.exit(-1)

def unpack_base_image(image):
   global SMC, CB_A, CB_B, CD, CE, Keyvault

   if image[0x205] == "\xFF" or image[0x415] == "\xFF" or image[0x200] == "\xFF":
      print "ECC'ed - will unecc."
      res = ""
      for s in range(0, len(image), 528):
         res += image[s:s+512]
      image = res

   unpackstring = "!HHLLL64s5LLLLLLLL"
   (id1, build, flags, bloffset, size0, copyright, z0, z1, z2, z3, r7, size1, r3, r4, z5, z6, smc_len, smc_start) = struct.unpack(unpackstring, image[:struct.calcsize(unpackstring)])
   #assert not (z0 or z1 or z2 or z3 or z5 or z6), "zeros are not zero."

   block_offset = bloffset

   SMC = image[smc_start:smc_start+smc_len]
   Keyvault = image[0x4000:0x8000]

   assert smc_len == 0x3000, "never saw an SMC != 0x3000 bytes"
   semi = 0
   for block in range(30):
      (block_id, block_build, block_flags, block_entry_point, block_size) = struct.unpack("!2sHLLL", image[block_offset:block_offset+16])
      block_size += 0xF
      block_size &= ~0xF
      id = ord(block_id[1]) & 0xF

      print "Found %dBL (build %d) at %08x" % (id, block_build, block_offset)
      data = image[block_offset:block_offset+block_size]
      
      if id == 2:
         if semi == 0:
            CB_A = data
            semi = 1
         elif semi ==1:
            CB_B = data
            semi = 0

      elif id == 4:
         CD = data
      elif id == 5:
         CE = data
      
      block_offset += block_size

      if id == 5:
         break

   assert CB_A and CD

def unpack_update(image):
   global CF, CG
   
   block_offset = 0
   for block in range(30):
      (block_id, block_build, block_flags, block_entry_point, block_size) = struct.unpack("!2sHLLL", image[block_offset:block_offset+16])
      block_size += 0xF
      block_size &= ~0xF
      id = ord(block_id[1]) & 0xF

      print "Found %dBL (build %d) at %08x" % (id, block_build, block_offset)
      data = image[block_offset:block_offset+block_size]
      
      if id == 6:
         CF = data
      elif id == 7:
         CG = data

      block_offset += block_size

      if id == 7:
         break

def build(data):
   return struct.unpack(">H", data[2:4])[0]

def decrypt_CB(CB):
   secret = secret_1BL
   key = hmac.new(secret, CB[0x10:0x20], sha).digest()[0:0x10]
   CB = CB[0:0x10] + key + RC4.new(key).decrypt(CB[0x20:])
   return CB

def decrypt_CB_Cpu(CB):
   assert cpukey
   secret = CB_A[0x10:0x20]
   h = hmac.new(secret,None, sha);
   h.update(CB[0x10:0x20]);
   h.update(cpukey);
   key = h.digest()[0:0x10]
   CB = CB[0:0x10] +key+ RC4.new(key).decrypt(CB[0x20:])
   return CB

def decrypt_CD(CD, CB):
# enable this code if you want to extract CD from a flash image and you know the cup key.
# disable this when this is a zero-paired image.
#   assert cpukey or build(CD) < 1920
   secret = CB[0x10:0x20]
   key = hmac.new(secret, CD[0x10:0x20], sha).digest()[0:0x10]
#   if build(CD) >= 1920:
#      key = hmac.new(cpukey, key, sha).digest()[0:0x10]
   CD = CD[0:0x10] + key + RC4.new(key).decrypt(CD[0x20:])
   return CD

def decrypt_CE(CE, CD):
   secret = CD[0x10:0x20]
   key = hmac.new(secret, CE[0x10:0x20], sha).digest()[0:0x10]
   CE = CE[0:0x10] + key + RC4.new(key).decrypt(CE[0x20:])
   return CE

def decrypt_CF(CF):
   secret = secret_1BL
   key = hmac.new(secret, CF[0x20:0x30], sha).digest()[0:0x10]
   CF = CF[0:0x20] + key + RC4.new(key).decrypt(CF[0x30:])
   return CF

def decrypt_CG(CG, CF):
   secret = CF[0x330:0x330+0x10]
   key = hmac.new(secret, CG[0x10:0x20], sha).digest()[0:0x10]
   CG = CG[:0x10] + key + RC4.new(key).decrypt(CG[0x20:])
   return CG

def decrypt_SMC(SMC):
   key = [0x42, 0x75, 0x4e, 0x79]
   res = ""
   for i in range(len(SMC)):
      j = ord(SMC[i])
      mod = j * 0xFB
      res += chr(j ^ (key[i&3] & 0xFF))
      key[(i+1)&3] += mod
      key[(i+2)&3] += mod >> 8
   return res

def encrypt_CB(CB, random):
   secret = secret_1BL
   key = hmac.new(secret, random, sha).digest()[0:0x10]
   CB = CB[0:0x10] + random + RC4.new(key).encrypt(CB[0x20:])
   return CB, key

def encrypt_CB_Cpu(CB):
   assert cpukey
   secret = CB_A[0x10:0x20]
   h = hmac.new(secret,None, sha);
   h.update(CB[0x10:0x20]);
   h.update(cpukey);
   key = h.digest()[0:0x10]
   CB = CB[0:0x20] + RC4.new(key).encrypt(CB[0x20:])
   return CB, key

def encrypt_CD(CD, CB_key, random):
   secret = CB_key
   key = hmac.new(secret, random, sha).digest()[0:0x10]
   CD = CD[0:0x10] + random + RC4.new(key).encrypt(CD[0x20:])
   return CD, key

def encrypt_CE(CE, CD_key, random):
   secret = CD_key
   key = hmac.new(secret, random, sha).digest()[0:0x10]
   CE = CE[0:0x10] + random + RC4.new(key).encrypt(CE[0x20:])
   return CE

def encrypt_CF(CF, random):
   secret = secret_1BL
   key = hmac.new(secret, random, sha).digest()[0:0x10]
   CF_key = CF[0x330:0x330+0x10]
   CF = CF[0:0x20] + random + RC4.new(key).encrypt(CF[0x30:])
   return CF, CF_key

def encrypt_CG(CG, CF_key, random):
   secret = CF_key
   key = hmac.new(secret, random, sha).digest()[0:0x10]
   CG = CG[:0x10] + random + RC4.new(key).encrypt(CG[0x20:])
   return CG

def encrypt_SMC(SMC):
   key = [0x42, 0x75, 0x4e, 0x79]
   res = ""
   for i in range(len(SMC)):
      j = ord(SMC[i]) ^ (key[i&3] & 0xFF)
      mod = j * 0xFB
      res += chr(j)
      key[(i+1)&3] += mod
      key[(i+2)&3] += mod >> 8
   return res
draqen escribió:aqui esta una parte del archivo build.py usado en el reset glitch dice como desencrypta y encrypta partes de la nand como el CD el CB_B y toda la leche dice que usa Rc4 cmbinada creo con el cpu key asi saca la secret 1BL y con eso deberia de sacar creo que la public key supongo.

#if secret_1BL is None:
#   secret_1BL = open("key_1BL.bin", "rb").read()

# Import Psyco if available
try:
   import psyco
   psyco.full()
except ImportError:
   pass

# first, unpack base input image. We are ignoring any updates here
import hmac, sha, struct, sys, binascii
try:
   import Crypto.Cipher.ARC4 as RC4
except ImportError:
   print "Error importing Crypto.Cipher.ARC4 - please install python-crypto!"
   print "You can get it from http://www.dlitz.net/software/pycrypto/"
   sys.exit(-1)

def unpack_base_image(image):
   global SMC, CB_A, CB_B, CD, CE, Keyvault

   if image[0x205] == "\xFF" or image[0x415] == "\xFF" or image[0x200] == "\xFF":
      print "ECC'ed - will unecc."
      res = ""
      for s in range(0, len(image), 528):
         res += image[s:s+512]
      image = res

   unpackstring = "!HHLLL64s5LLLLLLLL"
   (id1, build, flags, bloffset, size0, copyright, z0, z1, z2, z3, r7, size1, r3, r4, z5, z6, smc_len, smc_start) = struct.unpack(unpackstring, image[:struct.calcsize(unpackstring)])
   #assert not (z0 or z1 or z2 or z3 or z5 or z6), "zeros are not zero."

   block_offset = bloffset

   SMC = image[smc_start:smc_start+smc_len]
   Keyvault = image[0x4000:0x8000]

   assert smc_len == 0x3000, "never saw an SMC != 0x3000 bytes"
   semi = 0
   for block in range(30):
      (block_id, block_build, block_flags, block_entry_point, block_size) = struct.unpack("!2sHLLL", image[block_offset:block_offset+16])
      block_size += 0xF
      block_size &= ~0xF
      id = ord(block_id[1]) & 0xF

      print "Found %dBL (build %d) at %08x" % (id, block_build, block_offset)
      data = image[block_offset:block_offset+block_size]
      
      if id == 2:
         if semi == 0:
            CB_A = data
            semi = 1
         elif semi ==1:
            CB_B = data
            semi = 0

      elif id == 4:
         CD = data
      elif id == 5:
         CE = data
      
      block_offset += block_size

      if id == 5:
         break

   assert CB_A and CD

def unpack_update(image):
   global CF, CG
   
   block_offset = 0
   for block in range(30):
      (block_id, block_build, block_flags, block_entry_point, block_size) = struct.unpack("!2sHLLL", image[block_offset:block_offset+16])
      block_size += 0xF
      block_size &= ~0xF
      id = ord(block_id[1]) & 0xF

      print "Found %dBL (build %d) at %08x" % (id, block_build, block_offset)
      data = image[block_offset:block_offset+block_size]
      
      if id == 6:
         CF = data
      elif id == 7:
         CG = data

      block_offset += block_size

      if id == 7:
         break

def build(data):
   return struct.unpack(">H", data[2:4])[0]

def decrypt_CB(CB):
   secret = secret_1BL
   key = hmac.new(secret, CB[0x10:0x20], sha).digest()[0:0x10]
   CB = CB[0:0x10] + key + RC4.new(key).decrypt(CB[0x20:])
   return CB

def decrypt_CB_Cpu(CB):
   assert cpukey
   secret = CB_A[0x10:0x20]
   h = hmac.new(secret,None, sha);
   h.update(CB[0x10:0x20]);
   h.update(cpukey);
   key = h.digest()[0:0x10]
   CB = CB[0:0x10] +key+ RC4.new(key).decrypt(CB[0x20:])
   return CB

def decrypt_CD(CD, CB):
# enable this code if you want to extract CD from a flash image and you know the cup key.
# disable this when this is a zero-paired image.
#   assert cpukey or build(CD) < 1920
   secret = CB[0x10:0x20]
   key = hmac.new(secret, CD[0x10:0x20], sha).digest()[0:0x10]
#   if build(CD) >= 1920:
#      key = hmac.new(cpukey, key, sha).digest()[0:0x10]
   CD = CD[0:0x10] + key + RC4.new(key).decrypt(CD[0x20:])
   return CD

def decrypt_CE(CE, CD):
   secret = CD[0x10:0x20]
   key = hmac.new(secret, CE[0x10:0x20], sha).digest()[0:0x10]
   CE = CE[0:0x10] + key + RC4.new(key).decrypt(CE[0x20:])
   return CE

def decrypt_CF(CF):
   secret = secret_1BL
   key = hmac.new(secret, CF[0x20:0x30], sha).digest()[0:0x10]
   CF = CF[0:0x20] + key + RC4.new(key).decrypt(CF[0x30:])
   return CF

def decrypt_CG(CG, CF):
   secret = CF[0x330:0x330+0x10]
   key = hmac.new(secret, CG[0x10:0x20], sha).digest()[0:0x10]
   CG = CG[:0x10] + key + RC4.new(key).decrypt(CG[0x20:])
   return CG

def decrypt_SMC(SMC):
   key = [0x42, 0x75, 0x4e, 0x79]
   res = ""
   for i in range(len(SMC)):
      j = ord(SMC[i])
      mod = j * 0xFB
      res += chr(j ^ (key[i&3] & 0xFF))
      key[(i+1)&3] += mod
      key[(i+2)&3] += mod >> 8
   return res

def encrypt_CB(CB, random):
   secret = secret_1BL
   key = hmac.new(secret, random, sha).digest()[0:0x10]
   CB = CB[0:0x10] + random + RC4.new(key).encrypt(CB[0x20:])
   return CB, key

def encrypt_CB_Cpu(CB):
   assert cpukey
   secret = CB_A[0x10:0x20]
   h = hmac.new(secret,None, sha);
   h.update(CB[0x10:0x20]);
   h.update(cpukey);
   key = h.digest()[0:0x10]
   CB = CB[0:0x20] + RC4.new(key).encrypt(CB[0x20:])
   return CB, key

def encrypt_CD(CD, CB_key, random):
   secret = CB_key
   key = hmac.new(secret, random, sha).digest()[0:0x10]
   CD = CD[0:0x10] + random + RC4.new(key).encrypt(CD[0x20:])
   return CD, key

def encrypt_CE(CE, CD_key, random):
   secret = CD_key
   key = hmac.new(secret, random, sha).digest()[0:0x10]
   CE = CE[0:0x10] + random + RC4.new(key).encrypt(CE[0x20:])
   return CE

def encrypt_CF(CF, random):
   secret = secret_1BL
   key = hmac.new(secret, random, sha).digest()[0:0x10]
   CF_key = CF[0x330:0x330+0x10]
   CF = CF[0:0x20] + random + RC4.new(key).encrypt(CF[0x30:])
   return CF, CF_key

def encrypt_CG(CG, CF_key, random):
   secret = CF_key
   key = hmac.new(secret, random, sha).digest()[0:0x10]
   CG = CG[:0x10] + random + RC4.new(key).encrypt(CG[0x20:])
   return CG

def encrypt_SMC(SMC):
   key = [0x42, 0x75, 0x4e, 0x79]
   res = ""
   for i in range(len(SMC)):
      j = ord(SMC[i]) ^ (key[i&3] & 0xFF)
      mod = j * 0xFB
      res += chr(j)
      key[(i+1)&3] += mod
      key[(i+2)&3] += mod >> 8
   return res


mi amigo tiene la Public Key, dice el que esa es conocida pero que la public key se usa para verificar y la private key es para firmar :(
Here are some keys that you use for decrypting filesystem and Cx sections in a NAND dump.

These keys were taken out of a Xenon console, but should work on other mobos too.

1BL: DD88AD0C9ED669E7B56794FB68563EFA
CPU: Unique on each console, you need to dump your own.
XEX1: A26C10F71FD935E98B99922CE9321572
XEX2: 20B185A59D28FDC340583FBB0896BF91
2 años para publicar 6 mensajes, y directamente un hilo de investigación.. no esta mal jeje, suerte!

si consigues algo seras idolotrado.. pero me da que este hilo, al igual que muchos de investigación acabaran igual..
draqen escribió:Here are some keys that you use for decrypting filesystem and Cx sections in a NAND dump.

These keys were taken out of a Xenon console, but should work on other mobos too.

1BL: DD88AD0C9ED669E7B56794FB68563EFA
CPU: Unique on each console, you need to dump your own.
XEX1: A26C10F71FD935E98B99922CE9321572
XEX2: 20B185A59D28FDC340583FBB0896BF91

ok logramos arrancar el sistema, pero dio E78 [mamaaaaa] , esas key son para descifrar partes de la nand, el 1BL descifra el 2BL, y los dos XEX son para los xex de microsoft [risita]
kvnkain escribió:
draqen escribió:Here are some keys that you use for decrypting filesystem and Cx sections in a NAND dump.

These keys were taken out of a Xenon console, but should work on other mobos too.

1BL: DD88AD0C9ED669E7B56794FB68563EFA
CPU: Unique on each console, you need to dump your own.
XEX1: A26C10F71FD935E98B99922CE9321572
XEX2: 20B185A59D28FDC340583FBB0896BF91

ok logramos arrancar el sistema, pero dio E78 [mamaaaaa] , esas key son para descifrar partes de la nand, el 1BL descifra el 2BL, y los dos XEX son para los xex de microsoft [risita]


los de los xex qe son para firmarlos o para desencryptarlos, porqe si son para firmarlos, los xex no son ejecutables??
Perdonad mi tardanza en escribir, pero he tenido un problema de disco duro que me ha obligado a instalar uno nuevo con la consiguiente perdida del trabajo realizado, pero por suerte he podido salvar gran parte de los datos ya calculados y de los codigos fuente que tenia preparados.

Respecto a todas las claves y codigos posteados los echare un vistazo, pero por ejemplo la clave XEX1: A26C10F71FD935E98B99922CE9321572 no se corresponde con RSA-2048, así que no creo que sea de utilidad en esta investigación, y el codigo del build.py tampoco me cuadra mucho respecto a la carga de DLC's, pero lo echaré un vistazo con mas calma a ver si se puede rascar algo.

Un saludo y gracias por vuestra colaboración.
kvnkain escribió:Creo que mejor se deveria tratar de hacer arrancar el freeboot con el Glitch hack, ahi que lograr que el CD arranque, y tiene comprobaciones de SHA1 :D


muy buena idea y además a mi parecer facilitaría mucho el proceso, yo también hago mis pinitos en este tema y me tiene fascinado hace ya 2 años
vamooooos!!!! joer tio si consigues hacer eso me parece que te van a hacer una religion solo para ti.
Ya fuera de cachondeo todo mi apoyo, aunque no llegues a nada, esta bien el intentar hacer cosas que en un futuro beneficiaran a todos ( a ti el primero seguro jjjj y bien que te lo abras ganado).
Sigue asi y no te desanimes.
MAESTRO! un poco menos de 1 año de trabajo pero ya se ve todo tu esfuerzo realizado... Ojala esto llege a buen puerto :)
Oye hombre esto es de gran relevancia, felicidades por tu investigación y continua asi, no te desanimes si existe alguno que que te hecha tierra, creeme que esto es un paso gigante en la scence. Contiuna en este proyecto.
Update: Ya actualizare la informacion de manera mas detalla, pero de primeras informo de que de la clave publica, que tiene 617 digitos de longitud, he consegido ir acotando hasta hallar los 311 primeros digitos.
Wow menudo trabajo y menudas claves, 617 caracteres.. Si lo he entendido bien (la mitad de esto para mi es chino) esto serviría para firmar los dlc que se bajan del online y poderlos meter en el disco, y así sin tener rgh poder instalar con una consola flasheada (imagino que tendrá que estarlo para leer ese disco) cualquier dlc y no solo los que vienen en dvd. Y aparte también para modificar esos dlc a gusto de cada uno..

Mucho ánimo con tu investigación, si necesitas potencia de cálculo (entendí que el cómputo distribuido lo puedes hacer para la fase de la clave privada ahora que tienes la pública) solo ponlo en el foro y seguro que mucha gente se une. Yo desde luego el primero :)
ánimo y mucha suerte tío, menudo currazo te tienes que estar pegando
Suerte y ánimo crack, que a más de uno le darás una alegría si consigues esto. Un Saludo!
Esperemos que puedas lograrlo, si algun dia necesitas voluntarios para lo que hablaba un compañero anteriormente de aumentar la capacidad computacional puedes ir haciendo la lista y apuntarme xDDDD aqui hay 2 pcs medianamente potentes que puedes ayudarte.
Claro! Ibamos a salir en las noticias. Miles de personas se unen compartiendo sus ordenadores para hackear las claves de la xbox 360. XD
acost91 escribió:Wow menudo trabajo y menudas claves, 617 caracteres.. Si lo he entendido bien (la mitad de esto para mi es chino) esto serviría para firmar los dlc que se bajan del online y poderlos meter en el disco, y así sin tener rgh poder instalar con una consola flasheada (imagino que tendrá que estarlo para leer ese disco) cualquier dlc y no solo los que vienen en dvd. Y aparte también para modificar esos dlc a gusto de cada uno..

Mi intención es la de modificación de DLCs, pero si, también valdria para cambiar la firma a los que se bajen del online. Basicamente todo DLC que se firme (Modicificado o no) arrancaría en cualquier consola sin necesidad de RGH.

acost91 escribió:Claro! Ibamos a salir en las noticias. Miles de personas se unen compartiendo sus ordenadores para hackear las claves de la xbox 360. XD

Creo recoradar que con la xbox vieja se hizo. Es mas, es la base de funcionamineto de BOINC que tiene proyectos como SETI y otros muchos.
He editado el post para incluir el modulo y el exponente publico.
Felicidades por tu trabajo, espero que la gente con conocimientos pueda apoyarte en tu busqueda [oki] [oki] [oki]
DrackeM escribió: [...], no te desanimes si existe alguno que que te hecha tierra, creeme que esto es un paso gigante en la scence [...]


El que le eche tierra es porque tiene el higado lleno de envidia. Porque ¿que persona dentro de la programación o este mundo no se alegra de estas cosas? Aunque no haya sido el autor, uno siempre se alegra de estos descubrimientos copón!

Así que animo y buen trabajo. Ya que la mayoria de nosotros no tenemos ni los conocimientos ni el ingenio para conseguir estas cosas. [oki]

PD: Tendríamos que tener aquí botones en plan 'me gusta' o valoraciones para los users ^^ como en muchos otros foros. Así sabríamos, quien, aun teniendo miles de mensajes, vale la pena.
a mi me parece excelente con gente asi llegara un momento que nos evitemos el trabajo tedioso del rgh y podremos acceder a la maquina mas comodamente .
Mil felicitaciones. En serio esto podia salir en portada.

+1
EDITADO: Añadida la parte hallada de la clave privada.
javidecai está baneado por "Spammer"
pufffffffffff
mis mas enhorabuena , esto sera un bombazo
suerte con la investigacion haber si llegas al final y podemos disfrutarlo todos gracias a gente como tu y muchos mas
esperemos llegues al final de esto, ya que seria una muy buena noticia para todos
deberias poner algo para conectar los ordenadores de mas peña y asi cada uno descifrar una parte, no seria mas rapido?
enhorabuena
47 respuestas