C# - Hackear una contrasena de un servidor

Iniciado por TickTack, 23 Julio 2017, 20:41 PM

0 Miembros y 2 Visitantes están viendo este tema.

TickTack

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:

Código (csharp) [Seleccionar]

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:

Código (csharp) [Seleccionar]

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 = new Connection();
               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
Citar
"Ninguna mentira puede inventarse lo suficientemente patán: el pueblo hispanohablante la cree. Por una consigna que se les dio, persiguieron a sus compatriotas con mayor encarnizamiento que a sus verdaderos enemigos."

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 1234

/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
/login " + contrasena ".

se está enviando (no se si interpreta la variable, lo dudo)

/login  + contrasena

es decir, el servidor está recibiendo exactamente eso escrito arriba

tienes que usar tal cual está en el servidor
prueba = "/login " + contrasena

CitarPuedo 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
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

#2
Cita de: TickTack en 23 Julio 2017, 20:41 PMNo 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():

Código (csharp) [Seleccionar]
string str = string.Format("/login {0}", this.contrasena)

Saludos








TickTack

Hola engel lex,

que bueno verte en la sección .NET de Programacion en General. Das muy buenos aportes siempre,
al igual que Elektro.

Citar
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.exe
Descarganse 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.exe

Ahora 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
Citar
"Ninguna mentira puede inventarse lo suficientemente patán: el pueblo hispanohablante la cree. Por una consigna que se les dio, persiguieron a sus compatriotas con mayor encarnizamiento que a sus verdaderos enemigos."

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.




TickTack

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
Citar
"Ninguna mentira puede inventarse lo suficientemente patán: el pueblo hispanohablante la cree. Por una consigna que se les dio, persiguieron a sus compatriotas con mayor encarnizamiento que a sus verdaderos enemigos."

Serapis

#6
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)...

TickTack

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
Citar
"Ninguna mentira puede inventarse lo suficientemente patán: el pueblo hispanohablante la cree. Por una consigna que se les dio, persiguieron a sus compatriotas con mayor encarnizamiento que a sus verdaderos enemigos."

Eleкtro

#8
Cita de: TickTack en 24 Julio 2017, 21:19 PMBueno... 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








TickTack

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

Citar
"Ninguna mentira puede inventarse lo suficientemente patán: el pueblo hispanohablante la cree. Por una consigna que se les dio, persiguieron a sus compatriotas con mayor encarnizamiento que a sus verdaderos enemigos."