• [C#] Creacion de un IRC Bot

 #457331  por Doddy
 03 Oct 2014, 18:09
[Titulo] : Creacion de un IRC Bot
[Lenguaje] : C#
[Autor] : Doddy Hackman

[Temario]

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

0x01 : Introduccion
0x02 : Conectando con el servidor
0x03 : Listando usuarios
0x04 : Mandar mensajes
0x05 : Recibir privados
0x06 : Reconocer comandos
0x07 : Testeando

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

0x01 : Introduccion

Para comenzar esta breve manual sobre como hacer un IRC Bot en C# les aclaro que eh probado todo esto en Visual Studio 2010 usando como servidor IRC mi propia computadora usando IRC Plus para ello , lo pueden conseguir facilmente en internet y al parecer es compatible con Seven.
Los IRC Bot usados normalmente como spam tambien son usados para irc botnet o incluso como hacking tools , en este manual les enseñare a hacer spam y reconocer comandos
para hacking tools.

Comencemos ...

Primero tenemos que crear un proyecto de tipo "Aplicacion de Consola" pongan el NET Framework a 2.0 y pongan de nombre de proyecto "irc" como en la siguiente imagen :



Con el proyecto ya creado pasemos al siguiente punto.

0x02 : Conectando con el servidor

Para poder realizar la conexion vamos a necesitar los siguientes namespaces de esta forma :
Código: [ Debe registrarse para ver este enlace ]
using System.Net; // Lo usamos para realizar la conexion
using System.Net.Sockets; // Lo mismo que la anterior
using System.IO; // Lo usamos para el manejo con los streams
using System.Text.RegularExpressions; // No es vital pero me encantan el uso de las expresiones regulares
Para poder realizar la conexion usamos los sockets de la siguiente forma :
Código: [ Debe registrarse para ver este enlace ]
NetworkStream conexion; // Establecemos la variable conexion como NetworkStream
TcpClient irc; // Establecemos la variable irc como TcpClient
StreamReader leer_datos; // Establecemos la variable leer_datos como StreamReader
StreamWriter mandar_datos; // Establecemos la variable mandar_datos como SteamWriter

string host = "localhost"; // Establecemos la variable string host para tener el host del canal IRC
string nickname = "ClapTrap"; // Establecemos la variable nickname con el nick del bot
string canal = "#locos"; // Establecemos la variable canal con el nombre del canal
string code = ""; // Creamos la variable string que vamos a usar para leer los sockets
            
irc = new TcpClient(host, 6667); // Realizamos la conexion con el canal usando el host y el puerto 6667
conexion = irc.GetStream(); // Cargamos la conexion para poder leer los datos
leer_datos = new StreamReader(conexion); // Lo necesario para leer los datos de la conexion 
mandar_datos = new StreamWriter(conexion); // Lo necesario para mandar comandos al canal IRC

mandar_datos.WriteLine("NICK " + nickname); // Usamos el comando NICK para entrar al canal usando el nick antes declarado
mandar_datos.Flush(); // Actualizamos la conexion

mandar_datos.WriteLine("USER " + nickname + " 1 1 1 1"); // Usamos el comando USER para confirmar el nickname
mandar_datos.Flush(); // ..

mandar_datos.WriteLine("JOIN " + canal); // Usamos el comando JOIN para entrar al canal
mandar_datos.Flush(); // ..
Si quieren probar en otro servidor IRC pueden cambiar los datos de las variables host,nickname,canal para poder acceder a su canal.

Una vez conectados creamos un blucle enterno para capturar los datos y terminar de realizar la conexion con el famoso ping pong el cual nos hace el servidor para poder terminar de conectarnos , resolvemos este tema de la siguiente forma :
Código: [ Debe registrarse para ver este enlace ]
while (true) // Mi bucle eterno
{
	while ((code = leer_datos.ReadLine()) != null) // Leemos la conexion con la variable code
	{
		Console.WriteLine("Code : " + code); // No es necesario pero es para ver las respuestas del servidor

		Match regex = Regex.Match(code, "PING(.*)", RegexOptions.IgnoreCase); // Detectamos el clasico PING para el PING PONG
		// que nos hara el servidor IRC para verificar que estemos ahi y entrar al canal , aunque lo sigo haciendo despues
		// para ver que no estemos muerto o algo asi xD
		if (regex.Success) // Si se encontro algo
		{
			string te_doy_pong = "PONG " + regex.Groups[1].Value; // Capturamos lo que esta despues del ping y le damos al pong con los datos
			mandar_datos.WriteLine(te_doy_pong); // Mandamos el comando de la variable anterior
			mandar_datos.Flush(); // ..
		}
	}
}
Con esto ya estamos conectados.

0x03 : Listando usuarios

Para poder listar los usuarios agregamos la variabe global "usuarios" al inicio del codigo de la siguiente forma :
Código: [ Debe registrarse para ver este enlace ]
static string[] usuarios; // Creamos el string[] usuarios para tener todos los nicks que estan en el canal
Entonces volvemos al bucle eterno que hicimos con while y agregamos despues del ping pong el siguiente codigo :
Código: [ Debe registrarse para ver este enlace ]
regex = Regex.Match(code,":(.*) 353 (.*) = (.*) :(.*)", RegexOptions.IgnoreCase); // Capturamos los usuarios de todo el canal
// con el poder de las expresiones regulares
if (regex.Success) // Si los encontraron
{
	string usuarios_lista = regex.Groups[4].Value; // Tenemos la variable con todos los nicks
	usuarios = usuarios_lista.Split(' '); // Para mayor comodidad usamos un split para separar todos los espacios vacios que estan entre
	// cada nick del canal para despues hacer una lista , que es la primera que declare en el codigo
	foreach (string usuario in usuarios) // Usamos un for each para leer la lista usuarios y mostrar cada nick en la variable usuario
	{
		Console.WriteLine("[+] User : "+usuario); // Mostramos cada user
	}
}
Como ven usamos las expresion regulares para buscar en el stream que nos manda la conexion con el servidor irc para despues seperar con split el resultado obtenido por espacios en blanco ' ' , despues usamos foreach para listar todos los usuarios en la consola.

0x04 : Mandar mensajes

Esta es una parte corta , para mandar un mensaje al canal de forma publica tenemos que usar el siguiente comando :
Código: [ Debe registrarse para ver este enlace ]
PRIVMSG #locos Mensaje
Un ejemplo usando C# al cual deben agregar obviamente despues del blucle while() :
Código: [ Debe registrarse para ver este enlace ]
mandar_datos.WriteLine("PRIVMSG" + " " + canal + " " + "Hi World"); // Mandamos un mensaje al canal 
mandar_datos.Flush(); // ..
0x05 : Recibir privados

Bueno esta parte es un poco mas complicada , para poder detectar los mensajes privados que nos mandan tenemos que leer el stream que nos manda el canal y ver el comando PRIVMSG , en el comando PRIVMSG le seguira la procedencia , si es el canal sera un mensaje publico pero si no es el canal es un mensaje privado , eso lo podemos detectar con el siguiente codigo al cual vamos agregar despues del bucle while() :
Código: [ Debe registrarse para ver este enlace ]
regex = Regex.Match(code, ":(.*)!(.*) PRIVMSG (.*) :(.*)", RegexOptions.IgnoreCase); // Lo usamos para detectar los mensajes privados y publicos
if (regex.Success) // Si se encontro algo
{

	mandar_datos.WriteLine("PRIVMSG" + " " + canal + " " + "Hi World"); // Mandamos un mensaje al canal 
	mandar_datos.Flush(); // ..

	string dedonde = regex.Groups[1].Value; // Se detecta la procedencia del mensaje
	string mensaje = regex.Groups[4].Value; // El mensaje en si
	if (dedonde != canal) // Si la procedencia del mensaje no es el canal en si activamos esta condicion , cabe aclarar que si es el canal
	// el que nos mando el mensaje es un mensaje PUBLICO , caso contrario es PRIVADO
	{
		Console.WriteLine("[+] "+dedonde+" dice : "+mensaje); // Mostramos el dueño del mensaje y el mensaje
	}
}


Como ven detectamos los mensajes privados y los mostramos en la consola como lo hace mirc , mostrando el nick que nos esta hablando y despues el mensaje.

0x06 : Reconocer comandos

Para poder reconocer comandos para HackingTools lo vamos hacer con mensajes privados , el administrador del bot le habla al mismo a traves de mensajes privados con los comandos , despues el bot le responde con la respuesta del comando que le dijimos , un ejemplo de eso es este codigo el cual deben agregar despues del bucle :
Código: [ Debe registrarse para ver este enlace ]
regex = Regex.Match(code, ":(.*)!(.*) PRIVMSG (.*) :(.*)", RegexOptions.IgnoreCase); // Lo usamos para detectar los mensajes privados y publicos
if (regex.Success) // Si se encontro algo
{
	string dedonde = regex.Groups[1].Value; // Se detecta la procedencia del mensaje
	string mensaje = regex.Groups[4].Value; // El mensaje en si
	if (dedonde != canal) // Si la procedencia del mensaje no es el canal en si activamos esta condicion , cabe aclarar que si es el canal
	// el que nos mando el mensaje es un mensaje PUBLICO , caso contrario es PRIVADO
	{
		Match regex_ordenes = Regex.Match(mensaje, "!spam (.*) (.*)", RegexOptions.IgnoreCase); // Esta es la orden !spam con los (.*)
		// detectamos los dos comandos que son <nick> <mensaje>
		if (regex_ordenes.Success) // Si se encontro algo
		{
			mandar_datos.WriteLine("PRIVMSG" + " " + dedonde + " " + "[+] Sure"); // Le decimos al nick dueño del bot que si
			mandar_datos.Flush(); // ..
			System.Threading.Thread.Sleep(5000); // Usamos Thread.Sleep para esperar 5 segundos y fingir que hacemos algo interesante xD
			mandar_datos.WriteLine("PRIVMSG" + " " + regex_ordenes.Groups[1].Value + " " + regex_ordenes.Groups[2].Value); // Mandamos
			// un mensaje al usuario especificado con el mensaje que pedimos
			mandar_datos.Flush(); // ..
			mandar_datos.WriteLine("PRIVMSG" + " " + dedonde + " " + "[+] Finished"); // Le decimos al dueño del bot que terminamos
			mandar_datos.Flush(); // ..
		}
	}
}
Como ven nuestro comando es !spam , simplemente usa esta formato "!spam <nick> <texto>" y el bot le hablara a la persona del canal que quieran con el mensaje que quieran.

0x07 : Testeando

Hemos llegado al final de este corto manual , les deberia haber quedado el codigo de esta forma :
Código: [ Debe registrarse para ver este enlace ]
// Ejemplo de IRC Bot
// Written By Doddy Hackman in the year 2014

using System;
using System.Collections.Generic;
using System.Text;

using System.Net; // Lo usamos para realizar la conexion
using System.Net.Sockets; // Lo mismo que la anterior
using System.IO; // Lo usamos para el manejo con los streams
using System.Text.RegularExpressions; // No es vital pero me encantan el uso de las expresiones regulares

namespace irc
{
    class Program
    {
        static string[] usuarios; // Creamos el string[] usuarios para tener todos los nicks que estan en el canal

        static void Main(string[] args)
        {
            NetworkStream conexion; // Establecemos la variable conexion como NetworkStream
            TcpClient irc; // Establecemos la variable irc como TcpClient
            StreamReader leer_datos; // Establecemos la variable leer_datos como StreamReader
            StreamWriter mandar_datos; // Establecemos la variable mandar_datos como SteamWriter

            string host = "localhost"; // Establecemos la variable string host para tener el host del canal IRC
            string nickname = "ClapTrap"; // Establecemos la variable nickname con el nick del bot
            string canal = "#locos"; // Establecemos la variable canal con el nombre del canal
            string code = ""; // Creamos la variable string que vamos a usar para leer los sockets
            
            irc = new TcpClient(host, 6667); // Realizamos la conexion con el canal usando el host y el puerto 6667
            conexion = irc.GetStream(); // Cargamos la conexion para poder leer los datos
            leer_datos = new StreamReader(conexion); // Lo necesario para leer los datos de la conexion 
            mandar_datos = new StreamWriter(conexion); // Lo necesario para mandar comandos al canal IRC

            mandar_datos.WriteLine("NICK " + nickname); // Usamos el comando NICK para entrar al canal usando el nick antes declarado
            mandar_datos.Flush(); // Actualizamos la conexion

            mandar_datos.WriteLine("USER " + nickname + " 1 1 1 1"); // Usamos el comando USER para confirmar el nickname
            mandar_datos.Flush(); // ..

            mandar_datos.WriteLine("JOIN " + canal); // Usamos el comando JOIN para entrar al canal
            mandar_datos.Flush(); // ..

            while (true) // Mi bucle enterno
            {
                while ((code = leer_datos.ReadLine()) != null) // Leemos la conexion con la variable code
                {
                    Console.WriteLine("Code : " + code); // No es necesario pero es para ver las respuestas del servidor

                    Match regex = Regex.Match(code, "PING(.*)", RegexOptions.IgnoreCase); // Detectamos el clasico PING para el PING PONG
                    // que nos hara el servidor IRC para verificar que estemos ahi y entrar al canal , aunque lo sigo haciendo despues
                    // para ver que no estemos muerto o algo asi xD
                    if (regex.Success) // Si se encontro algo
                    {
                        string te_doy_pong = "PONG " + regex.Groups[1].Value; // Capturamos lo que esta despues del ping y le damos al pong con los datos
                        mandar_datos.WriteLine(te_doy_pong); // Mandamos el comando de la variable anterior
                        mandar_datos.Flush(); // ..
                    }

                    regex = Regex.Match(code,":(.*) 353 (.*) = (.*) :(.*)", RegexOptions.IgnoreCase); // Capturamos los usuarios de todo el canal
                    // con el poder de las expresiones regulares
                    if (regex.Success) // Si los encontraron
                    {
                        string usuarios_lista = regex.Groups[4].Value; // Tenemos la variable con todos los nicks
                        usuarios = usuarios_lista.Split(' '); // Para mayor comodidad usamos un split para separar todos los espacios vacios que estan entre
                        // cada nick del canal para despues hacer una lista , que es la primera que declare en el codigo
                        foreach (string usuario in usuarios) // Usamos un for each para leer la lista usuarios y mostrar cada nick en la variable usuario
                        {
                            Console.WriteLine("[+] User : "+usuario); // Mostramos cada user
                        }
                    }

                    regex = Regex.Match(code, ":(.*)!(.*) PRIVMSG (.*) :(.*)", RegexOptions.IgnoreCase); // Lo usamos para detectar los mensajes privados y publicos
                    if (regex.Success) // Si se encontro algo
                    {

                        mandar_datos.WriteLine("PRIVMSG" + " " + canal + " " + "Hi World"); // Mandamos un mensaje al canal 
                        mandar_datos.Flush(); // ..

                        string dedonde = regex.Groups[1].Value; // Se detecta la procedencia del mensaje
                        string mensaje = regex.Groups[4].Value; // El mensaje en si
                        if (dedonde != canal) // Si la procedencia del mensaje no es el canal en si activamos esta condicion , cabe aclarar que si es el canal
                        // el que nos mando el mensaje es un mensaje PUBLICO , caso contrario es PRIVADO
                        {
                            Console.WriteLine("[+] "+dedonde+" dice : "+mensaje); // Mostramos el dueño del mensaje y el mensaje
                            Match regex_ordenes = Regex.Match(mensaje, "!spam (.*) (.*)", RegexOptions.IgnoreCase); // Esta es la orden !spam con los (.*)
                            // detectamos los dos comandos que son <nick> <mensaje>
                            if (regex_ordenes.Success) // Si se encontro algo
                            {
                                mandar_datos.WriteLine("PRIVMSG" + " " + regex_ordenes.Groups[1].Value + " " + regex_ordenes.Groups[2].Value); // Mandamos
                                // un mensaje al usuario especificado con el mensaje que pedimos
                                mandar_datos.Flush(); // ..
                            }
                        }
                    }
                }
            }
        }
    }
}

// The End ?
Unas imagenes :







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

[ Debe registrarse para ver este enlace ].

Version VideoTutorial



Eso es todo.
 #457332  por Blau
 03 Oct 2014, 18:44
Precioso tutorial como siempre, Doddy.
using System.Text.RegularExpressions; // No es vital pero me encantan el uso de las expresiones regulares
Yo a veces llego a odiarlas mucho jaja