Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
botnet-hackpack — Создание базового ботнета Command & Control на C | Kitploit
Инструменты/GitHubGitHub/treehacks/botnet-hackpack
Механизмы персистентностиАнализ вредоносных программКомандование и УправлениеОбучение и ОбразованиеRed TeamingРазработка Полезной Нагрузки
GitHubtreehacks/botnet-hackpack

botnet-hackpack

Создание базового ботнета Command & Control на C

Репозиторий
4039547 лет назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

ПРОСТОЙ БОТНЕТ C&C

Этот хакпак проведет вас через реализацию базового фреймворка, который фундаментально характеризует ботнет. Возможно, будет полезно, если вы уже работали с C. Если вам понравился этот учебник, не забудьте поставить звезду этому репозиторию!

Примечание: Не используйте ничего из того, что вы узнаете здесь, в злонамеренных целях. Этот хакпак предназначен исключительно для изучения ботнетов в образовательных целях. Концепции, изученные в этом хакпаке, имеют широкие области применения (в основном все, что связано с сетями). Самое главное, этот хакпак предназначен для тестирования и развертывания локально (поэтому, пожалуйста, не делитесь тем, что вы создали в рамках этого хакпака, с другими хакерами). Конфиденциальность важна, поэтому, пожалуйста, уважайте ее.

Что такое ботнет?

Прежде чем создавать ботнет, важно понять, что такое ботнет. Ботнет — это сеть компьютеров, способных получать команды удаленно и выполнять их локально. При желании они могут передавать информацию обратно другим узлам сети. Они использовались для всего: от распределенных атак типа «отказ в обслуживании» до массового развертывания шпионского ПО. Возможно, вы слышали о многих ботнетах в прошлом. Наиболее известными являются, пожалуй, Mirai и Gameover Zeus, которые контролировали 3,8 тысячи и 3,6 миллиона устройств IoT соответственно. Существует много различий в том, как ботнеты реализуют определенные задачи. Но для успешного построения нашего ботнета необходимо обеспечить следующие функции в нашей рабочей сети.

Наш ботнет должен:

  1. Включать главный узел, который управляет всеми остальными узлами в сети.
  2. Развертывать замаскированное вредоносное ПО/ведомые узлы на хост-компьютерах.
  3. Передавать команды от главного узла ведомому, выполнять и возвращать результат обратно главному узлу.

Эта структура характерна для так называемых ботнетов Command & Control. У таких ботнетов есть один главный сервер и множество ведомых серверов. Однако такой стиль ботнетов устарел и может быть легко выведен из строя путем отключения доступа к главному домену. Более современные и сложные ботнеты используют одноранговую архитектуру (peer-to-peer), где права администратора распределены по всем узлам или подмножеству узлов сети. Эти ботнеты доставляют большие головные боли специалистам по безопасности, поскольку у них нет центральной точки управления, и они могут разрастаться до миллионов узлов. Ликвидация таких ботнетов — интересная тема сама по себе. Однако для целей этого хакпака давайте не будем усложнять. Мы реализуем простой ведомый узел для ботнета C&C.

alt tag

Реализация

Мастер

Этот хакпак в основном будет посвящен реализации клиентского вредоносного ПО. Для главного сервера мы можем использовать открытый TCP-сервер под названием Netcat. Netcat не имеет никакого отношения к ботнетам. Это просто удобный, проверенный инструмент, который мы можем приспособить для отправки текстовых пакетов от клиентов и к ним (а это, по сути, и есть мастер). Я немного доработал сервер Netcat и скомпилировал его в бинарник с именем «master». Больше никакой работы здесь не требуется! Наш мастер готов к использованию.

Ведомый

Перейдем к более интересной части: получению и выполнению удаленных команд (о маскировке нашего вредоносного ПО мы позаботимся позже). Цель здесь — сделать наш ведомый узел максимально простым и соответствующим требованиям, описанным выше. Обратите внимание, что многие константы уже определены в lib/macros.h, так что можете их использовать. Все сигнатуры реализованных функций можно найти в lib/connect.h или lib/utils.h.

1. Инициализация

Откройте файл bot.c. При запуске нового узла в нашем сервере нам, вероятно, стоит дать ему имя, чтобы мастер знал, на какие клиенты отправлять команды. Существует множество соглашений об именах. Использование IP-адреса, вероятно, лучше всего, так как это уникальный идентификатор для каждого клиента. Однако для большей читаемости для обычных людей давайте использовать имя пользователя компьютера. Используя функцию C getenv() с аргументом "USER", мы получаем то, что хранится в переменной окружения USER на компьютере. Это одно из мест, где хранится имя пользователя, так что воспользуемся этим. Также, теперь, когда ваш ведомый запущен, давайте найдем мастера. Для этого мы должны знать IP-адрес нашего мастера. Каждое сетевое устройство имеет IP-адрес. Он отвечает за идентификацию других узлов и адресацию местоположения. Кроме того, мастер может иметь множество серверов, работающих на разных портах. Поэтому нам нужно не только подключиться к мастеру, но и указать правильный порт. Этот порт выбирается мастером, но может быть изменен. В этом хакпаке мы хотим тестировать локально. Итак, мы будем использовать ваш компьютер в качестве нашей сети. Локальный IP-адрес каждого компьютера (на который также разрешается «localhost») — "127.0.0.1". В мастере я указал, что он работает на порту 9999. Имея эти три элемента (IP-адрес мастера, порт мастера и имя ведомого), мы можем запустить канал связи между сервером и клиентом, называемый сокетом. Передайте эти три аргумента в функцию init_socket(), чтобы создать сокет. init_socket() не является встроенной командой C. Скорее, нам нужно реализовать ее. Затем нам нужно выделить немного места в стеке для хранения входящих сообщений. Будем щедры и используем около 10 КБ стекового пространства. Назовем этот указатель стека msg. Наконец, есть оператор printf, который указывает, что все идет хорошо.

root@kitploit:~
char* name = //Get the client's username and store it in name
int channel = //initiate a channel given SERVER, PORT, and name;
//Allocate stack space of size CMD_LENGTH to hold data of type char. Call the stack pointer msg
printf("%s joining the botnet\n", name);

Теперь переключитесь на lib/connect.c. Давайте реализуем init_channel(). Сначала я определил стековый буфер типа char с именем msg длиной CMD_LENGTH и специальную конструкцию C для работы с сетью, называемую server, которая содержит информацию о нашем подключении к мастеру. Сначала преобразуйте переданный IP-адрес из удобочитаемого формата (с числами и точками) в двоичный формат в сетевом порядке байтов. Это делается с помощью специальной функции C inet_addr() из библиотеки сокетов. Она принимает IP-адрес и выдает его в используемом сетью двоичном формате. В C мы можем легко задать сеть, заполнив поля структуры sockaddr_in. Наш экземпляр этой структуры называется server. Нам нужно заполнить 3 поля этой структуры: server.sin_addr.s_addr (IP-адрес мастера), server.sin_family (однобайтовое значение, определяющее домен связи) и server.sin_port (порт, к которому мы будем подключаться на мастере). sin_family можно задать с помощью C-макросов, предоставляемых библиотекой сокетов. Обычно, как и в этом случае, мы устанавливаем это поле в AF_INET. Это означает, что наше соединение идентифицирует сетевые узлы через их IP-адреса, что нам и нужно. Однако также возможно использовать PF_INET, который похож на AF_INET, но указывает, что сеть может использовать что угодно в рамках протокола для идентификации конкретных узлов. Есть также множество якобы исторических причин, почему существуют оба, но это то, о чем я не особо знаю и не очень забочусь. Просто используйте . Наконец, при установке порта сервера мы должны передать через специальную функцию (host to network short). Она преобразует данные из порядка байтов хоста в порядок байтов сети. Эта путаница с порядком байтов связана с так называемым Endianness. Подробнее об этом можно прочитать .

Наконец, нам нужно определить собственно соединение между мастером и ведомым! Для этого определите сетевой сокет, через который могут передаваться данные. Представьте, что у мастера много «электрических розеток». Теперь нам нужно создать «вилку» на ведомом, которая подходит к «настенным розеткам» мастера. Мы можем сделать это с помощью функции socket() из библиотеки сокетов. Как удобно! socket() принимает 3 аргумента: домен связи, тип сокета и протокол. Для домена связи вы, вероятно, уже догадались: AF_INET. Для типа сокета мы хотим, чтобы наш сокет просто передавал данные в обоих направлениях. Следовательно, используйте данный макрос SOCK_STREAM. Давайте не будем беспокоиться о протоколе сокета. Это довольно фундаментальная сеть, поэтому используем значение 0, обозначающее протокол по умолчанию. Функция возвращает int, представляющий сокет. Сохраните это значение в channel. Затем мы хотим запустить наш сокет (подключить ведомого к розетке мастера). Вызовите функцию C connect(). Она принимает три аргумента: канал (channel), структуру sockaddr и размер структуры в байтах. Если connect() возвращает положительное целое число, ваше соединение с мастером успешно! Чтобы протестировать наше новое соединение, давайте отправим приветствие мастеру! Заполните наш буфер сообщения и используйте respond() (еще предстоит реализовать), чтобы отправить msg через channel обратно мастеру. Наконец, мы хотим, чтобы функция возвращала это успешное соединение.

root@kitploit:~
int init_channel (char *ip, int port, char *name) {
	char msg[CMD_LENGTH];
	struct sockaddr_in server;

	server.sin_addr.s_addr = //convert the ip to network byte order
	server.sin_family = //set the server's communications domain
  server.sin_port = //convert port to network byte order
  
  int channel = //define a SOCK_STREAM socket
  
  if(channel < 0) {
    perror ("socket:");
    exit(1);
  }
  
  int connection_status = //use the defined channel to connect the slave to the master server
  
  if (connection_status < 0) {
    perror ("connect:");
    exit(1);
  }

  //send a greeting message back to master by loading a string into msg (hint: snprintf will come in handy)
  respond (channel, msg);
  return channel;
}

2. Прослушивание сообщений

После того, как ведомый подключился к мастеру, он должен постоянно прослушивать сообщения и немедленно реагировать на команду. Итак, давайте используем бесконечный цикл while для получения и разбора этих сообщений. В bot.c после оператора printf добавьте бесконечный цикл while, который вызывает две функции: recieve() и parse() в таком порядке. Обе функции принимают channel и стековый буфер msg в качестве аргументов. Вы можете найти их сигнатуры функций в lib/utils.h. Это должно выглядеть примерно так:

root@kitploit:~
Infinite Loop {
  recieve(...);
  parse(...);
}

Перейдите в utils.c, чтобы реализовать recieve() и respond(). recieve() получает сообщения из канала, а respond() отправляет сообщения обратно через канал. Параметры respond(): адрес сокета s и наш стековый буфер msg_buf. Мы хотим использовать функцию C write() для записи того, что содержит стековый буфер, в канал и вернуть ее статус. write() требует 3 аргумента: адрес сокета, буфер сообщения и длину сообщения.

root@kitploit:~
int respond(int s, char *msg_buf) {
    //write the contents of msg_buf into socket s and return status
}

recieve() — такой же простой помощник. Сбросьте буфер msg (подсказка: используйте memset()). Теперь вызовите функцию read() из библиотеки сокетов, чтобы прочитать msg. read() принимает 3 аргумента: адрес сокета, буфер сообщения и максимальную ожидаемую длину сообщения.

root@kitploit:~
int recieve(int s, char *msg) {
    //reset the msg buffer
    int read_status = //read contents of socket s into msg
    if (read_status) {
      perror("log:");
      exit(1);
    }
    return 0;
}

3. Выполнение команд

Почти готово! Наш ботнет пока довольно скучный. Он может только получать и передавать сообщения через сокет. Давайте заставим его выполнять то, что он получает, в терминале. Сначала мы реализуем функцию parse(). Она делает именно то, что подразумевает название: разбирает команду. Мы могли бы выполнить некоторую простую проверку ошибок, чтобы увидеть, правильно ли сформировано сообщение. Также мы хотим молча игнорировать сообщения, которые были получены, но не предназначены для него. Сообщение будет отформатировано мастером как (имя ботнета):(команда для выполнения). Первое я сделал за вас. Если две проверки пройдены, давайте передадим команду функции execute().

root@kitploit:~
int parse (int s, char *msg, char* name) {
  char *target = msg;
  
  //check whether the msg was targetted for this client. If no, then silently drop the packet by returning 0
  
  char *cmd = strchr(msg, ':');
  if (cmd == NULL) {
    printf("Incorrect formatting. Reference: TARGET: command");
    return -1;
  }
 
  //adjust the cmd pointer to the start of the actual command
  //adjust the terminated character to the end of the command
  //print a local statement detailing what command was recieved
  
  execute (s, cmd);
  return 0;
}

Теперь самое интересное. execute() должна направить любую полученную команду в терминал и записать любой вывод в сокет обратно мастеру. Создайте стековый буфер для хранения каждой строки ввода. Затем используйте функцию C popen(), чтобы выполнить ввод и сохранить вывод в файле f (на этом этапе есть много способов добиться этого. Вы можете настроить свой ботнет на выполнение действительно крутых вещей с вводом от мастера и выполнять автономные совместные действия/обновления с другими узлами в ботнете. Не стесняйтесь проявить творческий подход. Мы пока будем придерживаться нашей базовой цели). Разбирайте f построчно и отправляйте все через ваш сокет. Закройте f, и готово!

root@kitploit:~
int execute (int s, char *cmd) {
  FILE *f = //use popen to run the command locally
  if (!f) return -1;
  while (!feof (f)) {
    //parse through f line by line and send any output back to master
  }
  fclose(f);
  return 0;
}

Скомпилируйте ваш новый ботнет следующей командой в терминале:

root@kitploit:~
gcc -lcurl lib/connect.c lib/utils.c bot.c -o bin/slave

Запустите bin/master в одном окне терминала и bin/slave в других окнах. Вводите команды в формате (имя ведомого):(удаленная команда терминала). Поздравляю! Вы только что создали ботнет!

4. Маскировка вредоносного ПО

Существуют действительно крутые вещи, которые можно сделать для маскировки и развертывания вредоносного ПО. На самом деле, это целая область сама по себе. Один из примеров того, что можно сделать, — замаскировать вредоносное ПО под изображение. Давайте используем изображение панды. Я добавил простую функцию в utils.c, которая загружает изображение панды через curl и открывает его в Preview. Это создает у пользователя впечатление, что он открывает изображение панды, хотя на самом деле он запускает ваше вредоносное ПО. Чтобы добавить это, включите следующие строки кода в bot.c:

root@kitploit:~
char* open_cmd = alias_img();
system(open_cmd);
free(open_cmd);

Затем щелкните правой кнопкой мыши по любому изображению и выберите «Свойства» (Get Info). Проделайте то же самое с bin/slave. Перетащите миниатюру изображения на миниатюру исполняемого файла bin/slave. Это должно изменить его внешний вид на рабочем столе. Однако нам все еще не хватает характерного окончания .png. Переименуйте ваш исполняемый файл в

root@kitploit:~
panda⒈png

Теперь это выглядит как png-файл. Однако мы используем символ Юникода «1.» вместо «.», чтобы скрыть тот факт, что это все еще исполняемый файл Unix. Существует множество более правдоподобных трюков Unix, которые можно применить, например, символ LEFT-TO-RIGHT OVERRIDE для маскировки имен исполняемых файлов. В более экстремальных случаях вы можете встраивать код в изображения и макросы файлов, чтобы он выполнялся одновременно с открытием файла (что-то вроде троянского коня...). Однако, поскольку никто в TreeHacks не является киберпреступником, мы не должны слишком заботиться об этих техниках ;).

5. Расширения

Теперь, когда у вас есть полностью работающий ботнет, есть много расширений, которыми вы можете себя занять. Наш ботнет все еще довольно неинтересный. Он мало что может сделать, если пользователь не нажимает на него каждый раз. Вот несколько предложений:

1. Достижение постоянства.

Ботнеты могут стать по-настоящему надежными источниками вредоносной активности для злоумышленников, если они каким-то образом остаются на компьютере, даже когда он выключается. Попробуйте поиграть с тем, как можно запускать вашего ведомого снова при каждом запуске системы. Таким образом, как только пользователь нажимает на вредоносное ПО, его компьютер заражен, пока он его не очистит. Одно из предложений для достижения этого — превратить ваш исполняемый процесс в демона. Затем сгенерируйте конфигурационный файл, который добавляет ваш исполняемый файл в список демонов, которые должны запускаться при старте системы (облачные приложения для хранения, платформы командных сообщений и т. д. уже делают это). Узнайте больше об этом здесь.

2. Реализация одноранговой сети (P2P)

Реализация одноранговой сети — это не более чем перестройка сетевой архитектуры. Однако ключ к P2P-сети заключается в том, что администратор/злоумышленник может получить контроль над мастером через любой узел сети. Таким образом, у злоумышленника должен быть какой-то главный ключ и зашифрованный вход, позволяющий управлять любым узлом как мастером. Узнайте больше о том, как работают одноранговые сети, здесь.

3. Добавление нескольких уровней дезинформации

Структура «мастер-ведомый», которую вы реализовали, не очень безопасна. Ведомые могут быть легко освобождены уничтожением главного узла. Оптимально было бы переключиться на P2P-дизайн. Однако вы также можете немного повысить безопасность мастера, направляя его команды случайным образом через серию контролируемых злоумышленником ботов, прежде чем они будут развернуты в ботнете. Это усложняет экспертам задачу определения центра управления и отслеживания вызовов ботнета между узлами злоумышленника и узлами клиентов.

4. Изучение правильных сетевых протоколов

Возможно, что еще более важно, вам стоит больше поэкспериментировать с сетями. Наша сеть максимально проста. Во многих отношениях она чрезвычайно слаба и определенно не является строгой. Поэтому вы можете захотеть изучить устоявшиеся протоколы для сетей, такие как Internet Relay Chat (IRC), чтобы построить более правильную сеть. Хотя это занимает время, это чрезвычайно познавательно и стоит потраченных усилий. Узнайте больше об этом здесь: https://oramind.com/tutorial-how-to-make-an-irc-server-connection/.

5. Попробуйте реализовать собственный мастер

В этом хакпаке мы использовали свободно доступный открытый проект в качестве замены нашего главного сервера. Однако есть много недостатков. Во-первых, мы не можем настроить наш главный сервер для отправки автоматических команд по нашей сети. Он ограничен использованием ввода из командной строки. Во-вторых, вы могли заметить, что все ведомые в ботнете получают каждую команду. Наше условие выполнения — проверить, совпадает ли имя цели с именем ведомого. Если нет, команда молча игнорируется. Это называется широковещательной сетью (broadcast). Более оптимальным может быть многоадресная сеть (multicast). В широковещательной сети узел ретранслирует пакеты всем подключенным узлам. В многоадресной системе можно указать определенное подмножество узлов для получения пакетов. Кроме того, использование многоадресной сети переносит назначение команд с клиента на главный сервер, где ему и место. Реализуйте собственный мастер, чтобы переключить ботнет с широковещательной на многоадресную сеть.

Для всестороннего руководства по сетевому программированию обратитесь к этому: http://beej.us/guide/bgnet/output/html/multipage/index.html.

Надеюсь, вам было весело!

Лицензия

MIT

О HackPacks 🌲

HackPacks созданы командой TreeHacks, чтобы помочь хакерам создавать отличные проекты на нашем хакатоне, который проходит каждый февраль в Стэнфорде. Мы верим, что каждый, независимо от уровня навыков, может научиться создавать потрясающие вещи, и это один из способов, которым мы помогаем развивать хакерскую культуру. Мы публикуем наши хакпаки (а также наши внутренние технологии) в открытом доступе, чтобы каждый мог учиться и использовать их! Не стесняйтесь использовать их на своих хакатонах, воркшопах и любых других мероприятиях, способствующих созиданию :)

Если вы заинтересованы в участии в TreeHacks, вы можете подать заявку на нашем веб-сайте в период приема заявок.

Вы можете следить за нами здесь, на GitHub, чтобы видеть всю нашу работу с открытым исходным кодом (мы любим issues, вклады и любые отзывы!), а также на Facebook, Twitter и Instagram, чтобы получать общие новости от TreeHacks.

Скачать инструмент
AF_INET
port
htons()
здесь
init_channel()