C++ Winsockets como reconectar un cliente al server

Iniciado por Grado 33, 21 Agosto 2017, 18:35 PM

0 Miembros y 1 Visitante están viendo este tema.

Grado 33

Muy buenas, he estado aprendiendo algo de sockets en windows, y trasteando, me he dado cuenta de como podría hacer un RAT (remote administration tool) a base de comandos.

Pero, me gustaría saber como puedo hacer que el CLIENTE, estando conectado al servidor, detecte si el servidor de repente ha cortado la comunicación con el cliente (bien porque yo haya manualmente cerrado el servidor, o por ejemplo porque apague el PC), y de ser así, que el cliente intente RECONECTARSE al servidor hasta que lo consiga.

Se me ha ocurrido hacer un thread que, en paralelo al main, haga una especie de ping y si el servidor no responde, el cliente intenta reconectarse al servidor tras un sleep o el intervalo de tiempo que sea. El "problema", es que no se como hacer ese ping (olvidense de system ping) o si hay otra manera de hacerlo más eficiente...

perdonad si la pregunta es muy obvia, muchas gracias...

Yuki

Ese es uno de los problemas mas generales al usar sockets, en Windows cuando un socket se cierra por lo general se puede detectar de varias maneras, como por ejemplo cuando se deja de recibir datos de una conexión o estos son inválidos.

Si estas usando un lenguaje de alto nivel (como VB.NET, C#, Java, Python) podrías llegar a encontrar un evento especifico para este trabajo (socket_close).

Y por tu mensaje puedo entender que estas escribiendo un RAT de conexión directa, te recomendaría hacerlo de conexión inversa, pero cada quien con sus gustos.

También te dejo un poco de información extra.

Grado 33

Estoy en C++ compilando con Dev C++, y estoy haciendo uno de conexion inversa... (o eso creo lol)
ahora miro el link y te comento, gracias

fary

Aquí te dejo un pequeño escrito de E0N, seguramente te servirá de ayuda.

http://foro.elhacker.net/analisis_y_diseno_de_malware/creando_un_troyano_en_vb6_c-t177919.0.html

Código sacado del enlace que te eh adjuntado:

Código (cpp) [Seleccionar]
while (len!=0) //Mientras que permanezcamoos conectados
   {
      len = recv(sock,Buffer,1023,0); //Recibimos los datos que envie

      if (len>0)  //Si seguimos conectados...
  {

Buffer[len]=0; //Ponemos los datos recibidos al final de la cadena

            //Aki hay q poner el conjunto de if's para las acciones

          }
    }


saludos.
Un byte a la izquierda.

Grado 33

#4
Código (cpp) [Seleccionar]
 

int recv_size;



 
     while(1)
    {
    comando = 0;
   //Recibir respuesta del servidor
   if((recv_size = recv(s , (char*)&comando , sizeof(int) , 0)) == SOCKET_ERROR)
   {
       puts("recv fail, reconectando");
       closesocket(s);
       if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
   {
       printf("No se pudo crear el socket : %d" , WSAGetLastError());
   }
        while (connect(s , (struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
   {
       puts("Conexion fallida. Reconectando");
       closesocket(s);
       if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
       connect(s , (struct sockaddr *)&server , sizeof(server));
       Sleep(3000);
       
   }
   }
    else
   {
   puts("Comando recibido\n");
   }  


   std::cout << comando;
   
   switch(comando)
   {
   
   case 1: funcion();
   break;
   case 2: funcion2();
//etc...
   break;
   default: break;
   }
}




Que les parece... esto me ha servido

Yuki

Lo ideal seria (en Cramel):

Código (vb) [Seleccionar]
Var hSock:Entero
Repetir
    hSock = TCPConectar("ip/host",666)
    Si hSock Entonces
        Repetir
            Var Datos:Cadena
            Datos = TCPRecibir(hSock,1024)
            Seleccionar Datos
                Caso "mostrar mensaje"
                    Mensaje("Se ha recibido un mensaje del cliente!")
                Caso Otro ' Si los datos son equivocados o nulos salimos del bucle.
                   TCPDesconectar(hSock) ' Cerramos por si las moscas...
                   Salir Repetir
             FinSeleccionar
        PorSiempre
    FinSi
PorSiempre


Creo que es obvio, pero por si no se entendió, intentamos conectar desde un bucle infinito, si se conectó recibimos datos hasta que estos sean equivocados o nulos, si esto ultimo sucede, salimos del segundo bucle y se intentará conectar automáticamente.

De esta manera no vas a necesitar que el cliente este enviando o verificando si el servidor sigue vivo ya que el estado es absoluto.

Grado 33

#6
Puedes comentar mi codigo??

Grado 33

Cita de: Yuki en 26 Agosto 2017, 03:44 AM
Lo ideal seria (en Cramel):

Código (vb) [Seleccionar]
Var hSock:Entero
Repetir
    hSock = TCPConectar("ip/host",666)
    Si hSock Entonces
        Repetir
            Var Datos:Cadena
            Datos = TCPRecibir(hSock,1024)
            Seleccionar Datos
                Caso "mostrar mensaje"
                    Mensaje("Se ha recibido un mensaje del cliente!")
                Caso Otro ' Si los datos son equivocados o nulos salimos del bucle.
                   TCPDesconectar(hSock) ' Cerramos por si las moscas...
                   Salir Repetir
             FinSeleccionar
        PorSiempre
    FinSi
PorSiempre


Creo que es obvio, pero por si no se entendió, intentamos conectar desde un bucle infinito, si se conectó recibimos datos hasta que estos sean equivocados o nulos, si esto ultimo sucede, salimos del segundo bucle y se intentará conectar automáticamente.

De esta manera no vas a necesitar que el cliente este enviando o verificando si el servidor sigue vivo ya que el estado es absoluto.

Oye y los troyanos son """"simplemente"""" eso?? enviar un comando, que no es mas que un numero o una string (en definitiva un dato/variable) y dependiendo de cual sea, el cliente ejecuta una acción u otra??

dapz

Cita de: Grado 33 en 26 Agosto 2017, 04:15 AM
Oye y los troyanos son """"simplemente"""" eso?? enviar un comando, que no es mas que un numero o una string (en definitiva un dato/variable) y dependiendo de cual sea, el cliente ejecuta una acción u otra??

a muy grosso modo si, son eso, una aplicación cliente-servidor. Sin embargo hoy en día las cosas no son tan simples. El cliente del troyano tiene que esconderse por razones obvias. Tiene que esconder llaves del registro, archivos, procesos etc, y eso se consigue con dlls que al fin y al cabo son una forma de ejecutable, necesarios para hacer hooks en windows
C/C++ ASM