Autor
|
Tema: C# - Hackear una contrasena de un servidor (Leído 10,375 veces)
|
TickTack
Desconectado
Mensajes: 434
CipherX
|
Hola, quiero presentarles el siguiente escenario: En una computadora hay un servidor y en otra un cliente. Con el cliente queria hackear la contrasena del servidor. Si el cliente sabe la contrasena escribe en el servidor /login <contrasena>. Codigo del Servidor: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Servidor { class Program { static void Main(string[] args) { Servidor_Chat chat = new Servidor_Chat (); } } }
Clase Servidor_Chat del servidor: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; using System.Net.Sockets; using System.IO; using System.Net; namespace Servidor { class Servidor_Chat { /* TcpListener--------> Espera la conexion del Cliente. TcpClient----------> Proporciona la Conexion entre el Servidor y el Cliente. NetworkStream------> Se encarga de enviar mensajes atravez de los sockets. */ private TcpListener server; private TcpClient client = new TcpClient (); private IPEndPoint ipendpoint = new IPEndPoint (IPAddress .Any, 8000); private List <Connection > list = new List <Connection >(); private string contrasena; Connection con; private struct Connection { public NetworkStream stream; public StreamWriter streamw; public StreamReader streamr; public string nick; } public Servidor_Chat() { Inicio(); } public void Inicio() { foreach (string line in File.ReadLines(@"Password.txt", Encoding.UTF8)) { contrasena = line.Substring(12); } Console.WriteLine("Servidor OK!"); server = new TcpListener (ipendpoint ); server.Start(); while (true) { client = server.AcceptTcpClient(); con.stream = client.GetStream(); con .streamr = new StreamReader (con .stream); con .streamw = new StreamWriter (con .stream); con.nick = con.streamr.ReadLine(); list.Add(con); Console.WriteLine(con.nick + " se a conectado."); Thread t = new Thread (Escuchar_conexion ); t.Start(); } } void Escuchar_conexion() { Connection hcon = con; do { try { string tmp = hcon.streamr.ReadLine(); Console.WriteLine(hcon.nick + ": " + tmp); foreach (Connection c in list) { try { if(tmp == "/login " + contrasena) { c.streamw.WriteLine(hcon.nick + ", ahora eres administrador!"); c.streamw.Flush(); } else { c.streamw.WriteLine(hcon.nick + ": " + tmp); c.streamw.Flush(); } } catch { } } } catch { list.Remove(hcon); Console.WriteLine(con.nick + " se a desconectado."); break; } } while (true); } } }
Bueno, si es necesario poner el codigo del cliente, avisenme. No se si lo puedo llamar inyeccion de codigo pero lo hare hasta que ustedes me digan que es incorrecto llamarlo asi a esto. Bueno trate de hacer una inyeccion de codigo poniendo en el texto de enviar del cliente: /login "" + contrasena + "" y despues, al ver que no funciono, envie: /login " + contrasena ". Yo crei que el servidor, al recibir un texto, tiene lo recibido entre comillas. Por eso trate de cerrar las comillas (") luego de poner variable que contiene la contrasena (+ contrasena +) y luego de abrir otra comilla mas para cerrar la supuesta comilla final. Si ustedes no me entienden debido a que me expreso mal quiero saber solo una cosa entonces. Puedo hackear la contrasena desde la computadora cliente o tengo que hackear la computadora en donde esta el servidor para obtener la contrasena? Esto lo estaba testeando en mi computadora. Gracias y saludos
|
|
« Última modificación: 23 Julio 2017, 20:49 pm por engel lex »
|
En línea
|
|
|
|
engel lex
|
no es una inyección de codigo, es simplemente envío de datos D: tmp == "/login " + contrasena es decir si la contraseña es 1234 el login espera /login "" + contrasena + "" no se nada de c# pero ese codigo debió dar error, si te fijas bien no estás poniendo comillas dentro de comillas... estás abriendo y cerrando comillas justo inmediatamente es decir, un string vacío para que se entienda mejor if(vacio == "") console.log("es vacio") por otro lado se está enviando (no se si interpreta la variable, lo dudo) es decir, el servidor está recibiendo exactamente eso escrito arriba tienes que usar tal cual está en el servidor prueba = "/login " + contrasena Puedo hackear la contrasena desde la computadora cliente o tengo que hackear la computadora en donde esta el servidor para obtener la contrasena? desde donde puedas enviar la contraseña al servidor
|
|
|
En línea
|
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.
|
|
|
Eleкtro
Ex-Staff
Desconectado
Mensajes: 9.866
|
No se si lo puedo llamar inyeccion de codigo pero lo hare hasta que ustedes me digan que es incorrecto llamarlo asi a esto. Lo que estás haciendo se denomina IPC (Inter-Process Communication). Inyección de código... no lo es xD.
Si te lias con las comillas y con el operador de concatenación de C#, recuerda que siempre tienes a tu disposición una herramienta muy útil de formato... precisamente para evitar la escritura excesiva (y horriblemente ininteligible cuando se usa en exceso) de comillas y de +++++. Me estoy refiriendo a la función String.Fromat(): string str = string.Format("/login {0}", this.contrasena)
Saludos
|
|
« Última modificación: 23 Julio 2017, 22:43 pm por Eleкtro »
|
En línea
|
|
|
|
TickTack
Desconectado
Mensajes: 434
CipherX
|
Hola engel lex, que bueno verte en la sección .NET de Programacion en General. Das muy buenos aportes siempre, al igual que Elektro. no se nada de c# pero ese codigo debió dar error, si te fijas bien no estás poniendo comillas dentro de comillas...
En serio... o... que error.. o.. porque no me da error a mi. Solamente que no logro logearme con esa contrasena sin poner esa contrasena.... Dices que lo tengo que enviar asi:? prueba = "/login " + contrasena Pero no funciona. O dices que lo tenga que enviar asi:? /login + contrasena Asi tampoco funciona porque el servidor toma + contrasena como un string y no como una variable. La idea era enviar /login + un envio de datos que permitiese al servidor interpretar contrasena no como un string sino como una variable. Gracias y saludos Hola Elektro, muchas gracias por la recomendacion. Veo que me interprete mal. Ok miren: Descarganse el servidor: http://www.mediafire.com/file/z7n27mai7p3upfo/Servidor.exeDescarganse este documento de texto (ponganlo en donde este el servidor): http://www.mediafire.com/file/jhqxcdupl40mnqe/Password.txt Y descarganse el cliente: http://www.mediafire.com/file/o4lden8adjzd4ja/Cliente.exeAhora abran el servidor. Y luego el cliente. Ponen un nombre y denle a conectar. Para loguearse escriban /login <contrasena>. Lo que yo queria es loguearme sin saber la contrasena. Osea queria de una forma escribir /login contrasena o algo parecido para que el servidor intreprete contrasena no como un string sino como una variable para lograr loguearme como administrador sin poner la contrasena y sin cambiar el codigo fuente del servidor. Gracias y saludos
|
|
|
En línea
|
|
|
|
Serapis
|
algunos consejos:
No suele ser muy útil, que el administrador se loguee de la misma forma que un cliente cualquiera.
De entrada si, hay una base de datos (clientes registrados), además de la contraseña, debería requerirse también el alias del usuario. Y por supuesto el admin, no debe llamarse 'admin', por mucho que en los routers venga así de mal...
Tampoco es buena idea registrar a cualquier cliente con una única contraseña. Añade un método de 'AddCliente', donde el usuario especifique 3 cosas: - Alias de registro. (login) - Contraseña de registro. (login) - Nombre de interfaz. (interfaz)
Rechaza el registro si: - Alias o nombre tiene menos de 'x' caracteres. Usa una constantes c_MinCharsAlias = 6 (por ejemplo) - Contraseña tiene menos de 'y' caracteres. ídem sobre la constante - Alias y nombre son idénticos. - Alias, nombre o contraseña, contienen caracteres que al caso considerares 'ilegales'... Esto es, debe tener un string con los caracteres legales "LegalChars = "ABCDEFGHIJK... abcdrfghijkl...01234...", una función debe chequear si algún carácter en un string recibido contiene un carácter que no aparece en LegalChars en cuyo caso devolver FALSE... - Alias y/o nombre ya existen. - Al patrón de la contraseña es fácilmente reconocible: por ejemplo "qwerty" "QWERTY", "123456", "PASSWORD", password"... Esto puede ser máso menos complejo, pero al menos hazte con una lista de las 100 contraseñas más frecuentes, las metes en un array y si coinciden lo recghazas... es lo mínimo. algo más potente es contabilizar los caracteres: mayusculas, minúsculas, números, espaciadores, simbolos. Exige que al menos haya caracteres en 3 de esos grupos, y que excepto el grupo con más caracteres (de la contraseña), sumen al menos 3 caracteres... ejemplos: ---------- "ahsdfjktovuirmncv3" solo está el grupo minúsculas y en números solo contiene 1, rechazar no hay caracteres para 3 grupos al menos. --------- "1845763W938564n" hay 3 grupos, pero aparte del más numeroso, solo hay 2 caracteres del resto, rechazar... En fin puede complicarse más, pero algo similar, debe ser lo mínimo exigible.
El administrador, podría ser el único capacitado para encender el servidor. Esto exige que sea el primero en loguearse. Luego el servidor debe rechazar un login 'efectivo', si hay 0 usuarios logueados y éste no es administrador. al hacerlo así, implica que va a ser imposible que alguien se loguee como el administrador, toda vez que el servidor solo atiende cuando el administrador enciende el servidor. esta solución no siempre va a poder ser adecuada, especialmente cuando el administrador está en una máquina y el servidor reside en otra. El administrador podría ser automático, esto es cuando un cliente intenta loguearse, si hay 0 usuarios logueados, primero loguear internamente al administrador y luego al cliente. Y el administrador (remoto), cuando se loguee como un usuario cualquiera, el servidor debería poder reconocerle y reasignarle el administrador 'precargado'. Así ese administrador aparecerá como si fuera duplicado, esto es consta como un cliente normal y como administrador, pero tiene funciones y roles de administradro, ya que el servidor lo ha reconocido como tal.
Si todo es solo un proyecto de pruebas, tampoco hace falta que te compliques tanto con la seguridad, aunque algo mínimo debes hacer y tenerlo siempre presente la importancia de la seguridad.
Nunca almacenes las credenciales crudas, es decir si el alias de registro es: Tick-Tack y la contraseña: "pSd8F4 0a17Zh4", genera el hash de ambos y concaténalos y asocia un ID al azar y crea un hash también para ese ID (para crerar este hash toma el ID y le concatenas algún caracter del hash anterior, delante, detrás..), ... esos 3 campos es lo que debes guardar en tu BD. Así un usuario que se loguea, sigue el mismo patrón, se hashea su alias y contraseña y se concatenan, luego se busca si ese hash existe en la base de datos (debe devolver el ID si se encontró), si es así se da por válido el login, si no, que devuelva como ID = -1. Si fue validado, al cliente entrégale un hash del ID (3º campo guardado). En lo sucesivo (mientras el user esté logueado), será esa referencia la identificación del usuario. Yendo un poco más lejos, este hash entregado debería crearse nuevo cada vez que un usuario se loguea, así no hay posibilidad de que si alguien tomo tu 'referencia' pueda usarla en un futuro... Cada usuario logueado, añade su referencia a una tabla, así cualquier petición de un usuario antes de ser atendida, se verifica que existe en esa tabla...
En fin la seguridad dependerá mucho de como hagas las cosas.
|
|
|
En línea
|
|
|
|
TickTack
Desconectado
Mensajes: 434
CipherX
|
Muchas gracias NEBIRE por tus puntos importantes para tomar medidas de seguridad a lo hora de crear o disenar un servidor de chat. Estaria bastante tiempo en todo lo que mencionaste...
Pero.. me intereso eso de crear un hash y concatenar sus datos.... Asi que... manos a la obra!!!
Pero antes...
Viste el servidor y cliente que subi a internet?
Antes queria saber si el cliente puede loguearse como administrador sin saber la contrasena.
Mas arriba postee el codigo del servidor.
Existe un vulnerabilidad de poder loguearse como administrador sin saber la contrasena en el servidor que hice?
Gracias y saludos
|
|
|
En línea
|
|
|
|
Serapis
|
Los he descargado, pero no se ejecutan aquí tengo win-XP (32 bits). --------------------- Respecto del login... fíjate que recurres a usar una contraseña que yace en un fichero de texto. Así, que en teoría eso lo hace altamente vulnerable. Además, ya te he comentado, que usar una sola y misma contraseña para todos es una malña solución. -------------------- Si tu chat solo va a admitir un administrador, haz que sea el primero que se loguee, es decir él y solo él prende el servidor, y nadie más pueda loguearse como administrador. Si el administrador no se loguea, no existe el chat, porque no se crea. Pero para poder loguear como administrador... en realidad para poder manejar diferentes usuarios con permisos diferentes, hay que separar los roles de usuario. Cuando te puse tiempo atrás un pseudocódigo sobre un chat, realmente allí te puse cosas muy útiles, bien que luego no hayas sabido aplicarlas. Los roles se pueden resumir en sus permisos-privilegios, y se puede reducir a su mínima expresión en una propiedad de tipo string (de solo lectura como cliente, lectura y escritura para los administradores). Entonces para un usuario, lo mínimo como Rol, es una propiedad de solo lectura con ese nombre Rol y cuyo contenido sea una cadena de texto. Unos simples caracteres, así un ejemplo de los roles de un usuario podría ser algo tan sencillo como esto: cliente.Rol = "LSER", cuyo significado simple podría ser:puede Loguearse (ideal para retirarlo cuando se banea a un usuario), puede crear Salas, puede Enviar mensajes, puede Recibir mensajes. En cambio el rol de Admin podrá usar muchos más métodos, luego su Rol, tendría un string, mucho más 'largo': Admin.Rol = "LSERXBPVG..." X = puede eliminar user B = puede Banear un usuario (al hacerlo se le retira a ese usaurio de su rol, la "L") P = puede otorgar privilegios de administrador (admin restringido) a usuarios normales y retirar privilegios de administrador... V = puede reiniciar el serVidor (pero no encender ni apagar) G = Administrador Global. Ningún usuario puede tener este atributo, excepto el dueño del chat. Es decir el resto de administradores, habrá cosas que no pueden hacer. Solo quien tenga el privilegio G, podría apagar, encender el servidor ... = etc, etc... es cuestión de ver que quieres que haga. Si un usuario (cliente) invoca un método, se verifica si su rol contiene el 'carácter' asociado a ese método, si es que sí, se permite la ejecución del método, si no, no. algunos métodos, en cambio los valida el servidor... Al crearse un usuario se le añaden un rol básico... al crear el administrador su rol es completo. Te pego el pseudocódigo de la clase servidor que te puse la otra vez (algo muy resumido, pero que te puede servir de orientación)... (este foro no admite spoilers, así que los mensajes a veces pueden quedar largos). Date cuenta, que en este código, aparece Privilegios, como sinónimo de Rol, y por ejemplo: el privilegio "CreateSala" (que lo puse así por claridad), puede ser "S" (como aparece en el ejemplo más arriba), es decir resumido a un sólo carácter... Clase Servidor // Instancias de clases. TablaHash Clientes Privado ConEventos TablaHash ClientesOcultos Privado ConEventos // clientes privilegiados, admins TablaHash Salas Privado ConEventos Sala SalaRaiz Privado ConEventos Cliente ClienteRaiz Privado ConEventos
Buleano Existe
Entero = Propiedad Sololectura NumClientes Publico Numclientes = Clientes.Cantidad Fin Propiedad
Entero = Propiedad SoloLectura NumclientesOcultos Publico // o admins NumClientesOcultos = ClientesOcultos.Cantidad Fin Propiedad Entero = Propiedad SoloLectura NumSalas Publico Numsalas = Salas.Cantidad Fin Propiedad
Buleano = Propiedad SePermiteCrearSalas Oculto //lectura y escritura
// Esta función se invoca para crear el servidor, que luego es público y permite la conexión... crea además, la primera sala y el resto de objetos necesarios. Funcion Nuevo(x,y,z) Oculta ' parámetros que requiriese para crear el servidor Clientes = Nueva TablaHash ClientesOcultos = Nueva TablaHash Salas = NuevaTablaHash
SalaRaiz= Nueva Sala ClienteRaiz = Nuevo Cliente(Alias, Invisible, Privilegios) Salas.Add(SalaRaiz) Clientes.Add(ClienteRaiz) ClientesOcultos.Add(ClienteRaiz)
Existe = TRUE Fin Funcion // El ciente cuando se conecta al servidor, se añade a la lista de clientes. // Y también se le añade a la salaRaiz, y se le devuelve una referencia a esa sala. Sala = Funcion Conectar(Cliente Cli) Publico Si SalaRaiz.AdmiteClientes = TRUE luego //podría filtrarse aquí comparando con una lista de clientes/IPs, baneadas, pero quizás no sea muy efectiva... Si SalaRaiz.Add(cli) = TRUE // solo debería devolver false si ya existe un cliente con el mismo alias. Devolver SalaRaiz Fin si Fin si Fin Funcion
Sala = Funcion CrearSala(Cliente Cli, String NombreSala, Entero MasUsers) Si (SePermiteCrearSalas = TRUE) luego Si (Clientes.Existe(cli) = TRUE ) luego // Todos los clientes, incluso los ocultos, constan en la colección Clientes. Si (Salas.Existe(NombreSala) = FALSE) luego Sala = Nueva Sala(Cli, Nombresala, MaxUsers, This) Salas.Add(sala) //allí se dispara un evento de 'SalaCreada(Sala.nombre)' que le llega a todos los clientes.
Devolver Sala Fin Si Fin si Fin si
// Ó si solo se permite a clientes ocultos (admins). Si (ClientesOcultos.Existe(cli) = TRUE ) luego ... ....
// Ó si solo se permite a cliente con privilegios Si (cli.Privilegios.Contiene("CreateSala")) luego Si (Clientes.Existe(cli) = TRUE ) luego ... .... Fin si Fin Funcion
// Otras funciones que tenga el servidor... (especialmente resolver los eventos de las intancias de las clases: Clientes, ClientesOcultos, Salas, SalaRaiz, ClienteRaiz Fin Clase
Fíjate comno en este ejemplo, la instancia del servidor cuando se crea, es creada por el administrador cuando invoca el New(x,y,z) x,y,z representa los parámetros que vayan a ser necesarios durante la creación de la instancia.. fíjate que luego en ese mismo métodos se concreta: ClienteRaiz = Nuevo Cliente(Alias, Invisible, Privilegios) ...Alias, invisible y privilegios, serían parámetros de entrada (al margen de otros parámetros más fueren precisos). Y al caso, el admin, ni siquiera precisa una contraseña. Ya que es él quien crea la instancia, es el poseedor de la misma, el método New, es el constructor de la instancia, solo puede ser invocado una única vez y además al inicio antes que nada suceda, luego nadie puede usurpar el administrador-absoluto (si no hay métodos para un login posterior de administrador, por ejemplo), a lo sumo podrán crear otras instancias del servidor (...si lograran acceso al terminal que lo contiene)... Digo administrador absoluto, porque en un chat, suele ser frecuente que haya otros usuarios con roles de administrador (restringido)... en tal caso, es el Administrador absoluto, quien sólo puede otorgar-retirar privilegios de Administrador (restringido)...
|
|
« Última modificación: 24 Julio 2017, 19:44 pm por NEBIRE »
|
En línea
|
|
|
|
TickTack
Desconectado
Mensajes: 434
CipherX
|
Hola NEBIRE, ahhh.. vale. Muchas gracias. Bueno... mas notas que apuntar y un codigo que traducir...... Que haria sin esta buena paginas:? http://converter.telerik.com/Bueno. Te queria preguntar de que maneras uno se podria aprovechar de la vulnerabilidad de que la contrasena estuviera en un fichero de texto? Y unas preguntas mas: 1) A lo que en realidad iba en todo este post era esto: En realidad que haria lograr loguearme al servidor sin saber la contrasena usando algo como una interpolacion de string. Osea que pudiera escribir esto: /login "$"{contrasena} Pero no funciona. Trato de hacer una referencia a la variable contrasena despues de haber escrito /login para poder loguearme sin saber la contrasena. Pero como puedo hacer esto? No se como incluir dentro de un string una referencia de una variable. 2) Los Querys solo se pueden hacer desde el cliente si el servidor es programado para recibir Querys? Gracias y saludos
|
|
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Desconectado
Mensajes: 9.866
|
Bueno... mas notas que apuntar y un codigo que traducir...... Pues apunta una nota más que no te han dicho: Cuando se trata de exponer contraseñas e información confdencial en general, en lugar de la clase System.String deberías utilizar la clase System.Security.SecureString para potenciar la seguridad de tu aplicación previniendo que los strings puedan ser almacenados por más tiempo del necesario en la memoria de la aplicación y por consiguiente intentar prevenir que un "intruso" (llámese hacker) pueda obtener dicha información mediante estrategias de ing. inversa que impliquen leer secciones de memoria. Al utilizar la clase System.Security.SecureString para almacenar un string confidencial, el string se almacena en un bloque de memoria no administrada, se cifra el bloque de memoria mediante la función Win32 RtlEncryptMemory (u otra función no documentada), y cuando el string ya no es necesario internamente se llama a la función Win32 ZeroMemory para llenar el bloque de memoria con ceros, es decir, para limpiar el bloque de memoria de cualquier rastro de nuestra información confidencial. Todo ello lo puedes comprobar analizando la referencia del código fuente de .NET Framework: Aparte, si hablamos de un escenario donde hay un cliente y un servidor, y tú envias la contraseña descifrada pues... creo que el riesgo de intercepción de datos es más que evidente. Una idea genial y eficiente al 100% (sino al 99,9%) sería cifrar el string de nuestra instancia SecureString mediante una clave pública otorgada por el servidor, de esta manera el string original nunca se vería expuesto en la transmisión de datos remota entre cliente y servidor, ni en la memoria administrada de la aplicación, por ende tampoco en el GarbageCollector de .NET, y solamente el servidor podria descifrar el string cifrado mediante la clave pública otorgada. Esta sugerencia que acabo de explicar es exactamente lo que hace Microsoft en el mimebro PSRemotingCryptoHelper.EncryptSecureStringCore().
En fin. Dicha clase, System.Security.SecureString tiene ciertas diferencias de uso en comparación con la clase System.String, de hecho no se asemejan en nada. Para que te hagas una idea, se asemenja bastante más a la clase System.Text.StringBuilder en el modo de empleo. Saludos
|
|
« Última modificación: 25 Julio 2017, 11:31 am por Eleкtro »
|
En línea
|
|
|
|
TickTack
Desconectado
Mensajes: 434
CipherX
|
Hola mis amigos!!!!!!!!!!! Tanto tiempo!!!!
Y si!! Ya hice mi servidor!!!!
La parte mas put* era la de concatenar algunos datos con un hash. Esa parte no la hice. Me era demasiado trabajo. Sin agregar que no tengo nada de experiencia en hacer esas cosas no el conocimiento..... Suficiente con los otros complicados puntos para mi que ustedes me mencionaron......
Pero ahora me interesa lo que menciono Elektro...
Como puedo yo obtener strings almacenados en la memoria de una aplicacion mediante sockets o TCP usando estragias de ingenieria inversa que impliquen leer secciones de memoria?
Existen tales estrategias en relidad? Realmente se puede de esta manera interceptar datos?
Porque para me es inpensable que se pueda. Y si se puede... entonces cómo?
Me intereso bastante lo que escribiste....
Gracias y saludos
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Hackear contraseña router mediante http
Hacking
|
Dailokis
|
7
|
29,373
|
19 Febrero 2010, 17:41 pm
por Dailokis
|
|
|
hackear contraseña de hide folder o acender a archivos protegidos
Hacking
|
felix6193
|
2
|
6,324
|
25 Abril 2013, 16:26 pm
por felix6193
|
|
|
Para que sirve hackear/obtener la contraseña del SSL de una web?
Seguridad
|
JollyRoyer
|
0
|
2,972
|
5 Noviembre 2014, 20:14 pm
por JollyRoyer
|
|
|
HACKEAR SERVIDOR DE MAIL
Seguridad
|
ANNE ELLIOT
|
2
|
4,764
|
5 Septiembre 2016, 19:10 pm
por warcry.
|
|
|
[AYUDA] Quitar contraseña a un RAR (SIN HACKEAR)
Software
|
axelnieves2012
|
1
|
1,797
|
12 Febrero 2018, 18:29 pm
por MCKSys Argentina
|
|