Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
botnet-hackpack — Construire un botnet de commande et contrôle de base en C | Kitploit
Outils/GitHubGitHub/treehacks/botnet-hackpack
Mécanismes de PersistanceAnalyse de MalwareCommandement et ContrôleApprentissage et ÉducationRed TeamingDéveloppement de Charges Utiles
GitHubtreehacks/botnet-hackpack

botnet-hackpack

Construire un botnet de commande et contrôle de base en C

Voir le dépôt
403954il y a 7 ansVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

BOTNET C&C SIMPLE

Ce hackpack vous guidera dans l’implémentation d’un cadre simple qui caractérise fondamentalement un botnet. Cela peut vous aider si vous avez déjà travaillé avec le C. Si vous avez aimé ce tutoriel, n’oubliez pas de mettre une étoile sur ce dépôt !

Remarque : N’utilisez rien de ce que vous apprenez ici à des fins malveillantes. Ce hackpack est uniquement une étude de cas de botnets à des fins éducatives. Les concepts appris dans ce hackpack ont des cas d’utilisation très vastes (essentiellement tout ce qui touche au réseau). Plus important encore, ce hackpack est destiné à être testé et déployé localement (ne partagez donc rien de ce que vous construisez en lien avec ce hackpack avec d’autres hackers). La vie privée est importante, veuillez la respecter.

Qu’est-ce qu’un botnet ?

Avant de construire un botnet, il est important de comprendre ce qu’est un botnet. Un botnet est un réseau d’ordinateurs capables de recevoir des commandes à distance et de les déployer localement. Facultativement, ils peuvent choisir de relayer des informations vers d’autres nœuds du réseau. Ils ont été utilisés pour tout, des attaques par déni de service distribué au déploiement généralisé de logiciels espions. Vous avez peut-être entendu parler de nombreux botnets dans le passé. Les plus célèbres sont peut-être Mirai et Gameover Zeus, qui contrôlaient respectivement 3,8 mille et 3,6 millions d’appareils IoT. Il existe beaucoup de différences dans la manière dont les botnets implémentent certaines tâches. Mais pour construire notre botnet avec succès, nous devons garantir les fonctionnalités suivantes dans notre réseau fonctionnel.

Notre botnet doit :

  1. Inclure un nœud maître qui contrôle tous les autres nœuds du réseau
  2. Déployer des logiciels malveillants déguisés / des nœuds esclaves sur les ordinateurs hôtes
  3. Transmettre des commandes du nœud maître au nœud esclave, les exécuter et renvoyer une sortie au maître

Cette structure est caractéristique de ce qu’on appelle les botnets de type Command & Control. Ces botnets ont un serveur maître et de nombreux serveurs esclaves. Cependant, ce style de botnets est obsolète et peut facilement être démantelé en coupant l’accès au domaine maître. Les botnets plus récents et sophistiqués suivent une architecture pair-à-pair, où les droits d’administration sont répartis sur tous les nœuds ou un sous-ensemble de nœuds du réseau. Ces botnets posent un sérieux casse-tête aux experts en sécurité car il n’y a pas de point de contrôle central et ils peuvent atteindre des millions de nœuds. Démonter de tels botnets est une lecture intéressante en soi. Cependant, pour les besoins de ce hackpack, restons simples. Nous allons implémenter un nœud esclave simple pour un botnet C&C.

alt tag

Implémentation

Maître

Ce hackpack traitera principalement de l’implémentation du logiciel malveillant client. Pour le serveur maître, nous pouvons utiliser un serveur TCP open source appelé Netcat. Netcat n’a rien à voir avec les botnets. C’est simplement un outil pratique et établi que nous pouvons réutiliser pour envoyer des paquets texte vers et depuis les clients (ce qu’est fondamentalement un maître). J’ai légèrement ajusté le serveur netcat et l’ai compilé en un binaire nommé « master ». Pas plus de travail nécessaire ici ! Notre maître est prêt à être utilisé.

Esclave

Passons maintenant à la partie la plus intéressante : recevoir et exécuter des commandes à distance (nous nous occuperons plus tard du déguisement de notre malware). L’objectif ici est de rendre notre nœud esclave aussi simple que possible et de respecter les exigences détaillées ci-dessus. Notez que de nombreuses constantes ont été définies dans lib/macros.h ; n’hésitez pas à les utiliser. Toutes les signatures de fonctions implémentées se trouvent dans lib/connect.h ou lib/utils.h.

1. Initiation

Ouvrez le fichier bot.c. Lors du démarrage d’un nouveau nœud sur notre serveur, nous devrions probablement le nommer afin que le maître sache à quels clients déployer des commandes. Il existe de nombreuses conventions de nommage. Utiliser une adresse IP est probablement la meilleure car c’est un identifiant unique pour chaque client. Cependant, pour rendre les choses plus lisibles pour les humains ordinaires, utilisons le nom d’utilisateur de l’ordinateur. En utilisant la fonction C getenv() avec l’argument "USER", on obtient ce que l’ordinateur a stocké dans la variable d’environnement USER. C’est un endroit où le nom d’utilisateur est stocké, alors utilisons-le. Aussi, maintenant que votre esclave tourne, trouvons le maître. Pour ce faire, nous devons connaître l’adresse IP de notre maître. Chaque périphérique réseau a une adresse IP. Elle est responsable de l’identification des autres nœuds et de l’adressage de localisation. De plus, le maître peut avoir plusieurs serveurs fonctionnant sur différents ports. Donc, non seulement nous devons nous connecter au maître, mais nous devons aussi spécifier le bon port. Ce port est choisi par le maître mais peut être modifié. Dans ce hackpack, nous voulons tester localement. Nous utiliserons donc votre ordinateur comme notre réseau. L’adresse IP locale de chaque ordinateur (que « localhost » résout également) est "127.0.0.1". Dans le maître, j’ai spécifié qu’il devait tourner sur le port 9999. Avec ces trois éléments (adresse IP du maître, port du maître et nom de l’esclave), nous pouvons établir un pipeline de communication entre le serveur et le client appelé socket. Passez ces trois arguments dans la fonction init_socket() pour créer un socket. init_socket() n’est pas une commande C intégrée. Nous devons plutôt l’implémenter. Ensuite, nous devons allouer un espace sur la pile pour contenir les messages entrants. Soyons assez généreux et utilisons environ 10 Ko d’espace de pile. Appelez ce pointeur de pile msg. Enfin, une instruction printf indique que tout se passe bien.

root@kitploit:~
char* name = // Récupérez le nom d’utilisateur du client et stockez-le dans name
int channel = // initialisez un canal avec SERVER, PORT et name ;
// Allouez un espace de pile de taille CMD_LENGTH pour contenir des données de type char. Appelez le pointeur de pile msg
printf("%s rejoignant le botnet\n", name);

Passez maintenant à lib/connect.c. Implémentons init_channel(). J’ai d’abord défini un tampon char de pile appelé msg de longueur CMD_LENGTH et une construction réseau spéciale C appelée server qui contient des informations sur notre connexion au maître. Convertissez d’abord l’adresse IP que vous avez passée d’un format lisible par l’humain (avec des chiffres et des points) en un format binaire dans l’ordre des octets du réseau. Cela se fait avec une fonction C spéciale appelée inet_addr() de la bibliothèque socket. Elle prend simplement une adresse IP et la restitue dans un format binaire utilisable par le réseau. En C, on peut facilement spécifier un réseau en remplissant les champs d’une structure appelée sockaddr_in. Notre instance de cette structure s’appelle server. Nous devons remplir 3 champs de cette structure : server.sin_addr.s_addr (l’adresse IP du maître), server.sin_family (une valeur de 1 octet spécifiant le domaine de communication) et server.sin_port (le port auquel nous nous connecterons sur le maître). Le sin_family peut être fourni par des macros C de la bibliothèque socket. Généralement, comme dans ce cas, nous définissons ce champ à AF_INET. Cela signifie que notre connexion identifie les nœuds du réseau par leurs adresses IP, ce que nous voulons. Cependant, il est aussi possible d’utiliser PF_INET qui est similaire à AF_INET mais spécifie que le réseau peut utiliser tout ce qui est dans le protocole pour identifier des nœuds spécifiques. Il existe aussi de nombreuses raisons historiques présumées pour lesquelles les deux existent mais c’est quelque chose que je ne connais pas vraiment et qui ne m’intéresse pas vraiment. Utilisez simplement AF_INET. Enfin, lors du réglage du port du serveur, nous devons passer port à travers une fonction spéciale appelée htons() (host to network short). Cela convertit les données de l’ordre des octets de l’hôte à l’ordre des octets du réseau. Ce désordre d’ordre des octets a à voir avec quelque chose appelé Endianness. Vous pouvez en lire plus ici.

Enfin, nous devons définir la connexion réelle entre le maître et l’esclave ! Pour cela, définissez un socket réseau à travers lequel les données peuvent être envoyées. Pensez au maître ayant de nombreuses « prises électriques ». Maintenant, nous devons construire une « fiche » sur l’esclave qui s’adapte aux « prises murales » du maître. Nous pouvons le faire avec la fonction socket() de la bibliothèque socket. Comme c’est pratique ! socket() prend 3 arguments : le domaine de communication, le type de socket et un protocole. Pour le domaine de communication, vous avez probablement déjà deviné : AF_INET. Pour le type de socket, nous voulons que notre socket soit un simple flux de données dans les deux directions. Utilisez donc la macro donnée SOCK_STREAM. Ne nous soucions pas du protocole de socket. C’est un réseau assez fondamental, utilisons donc une valeur de 0 pour le protocole par défaut. La fonction retourne un int représentant le socket. Stockez cette valeur dans channel. Ensuite, nous voulons démarrer notre socket (brancher l’esclave dans la prise murale du maître). Appelez la fonction C connect(). Elle prend trois arguments : le canal, la structure sockaddr et la taille de la structure en octets. Si connect() retourne un entier positif, votre connexion avec le maître est réussie ! Pour tester notre nouvelle connexion, envoyons un message de bienvenue au maître ! Remplissez notre tampon de message et utilisez respond() (pas encore implémentée) pour envoyer msg à travers le canal vers le maître. Enfin, nous voulons que la fonction init_channel() retourne cette connexion réussie.

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

	server.sin_addr.s_addr = // convertissez l’ip dans l’ordre des octets du réseau
	server.sin_family = // définissez le domaine de communication du serveur
  server.sin_port = // convertissez le port dans l’ordre des octets du réseau
  
  int channel = // définissez un socket SOCK_STREAM
  
  if(channel < 0) {
    perror ("socket:");
    exit(1);
  }
  
  int connection_status = // utilisez le canal défini pour connecter l’esclave au serveur maître
  
  if (connection_status < 0) {
    perror ("connect:");
    exit(1);
  }

  // envoyez un message de bienvenue au maître en chargeant une chaîne dans msg (indice : snprintf sera utile)
  respond (channel, msg);
  return channel;
}

2. Écoute des messages

Une fois que l’esclave est connecté au maître, il doit constamment écouter les messages et agir immédiatement sur une commande. Utilisons donc une boucle while infinie pour recevoir et analyser ces messages. Dans bot.c, après l’instruction printf, ajoutez une boucle while infinie qui appelle deux fonctions : recieve() et parse() dans cet ordre. Les deux fonctions prennent le channel et le tampon de pile msg comme arguments. Vous pouvez trouver leurs signatures de fonction dans lib/utils.h. Cela devrait ressembler à :

root@kitploit:~
Boucle Infinie {
  recieve(...);
  parse(...);
}

Allez dans utils.c pour implémenter recieve() et respond(). recieve() récupère les messages du canal et respond() envoie des messages à travers le canal. Les paramètres de respond() sont l’adresse du socket, s, et notre tampon de pile, msg_buf. Nous voulons utiliser la fonction C write() pour écrire ce que contient le tampon de pile dans le canal et retourner son statut. write() a besoin de 3 arguments : l’adresse du socket, le tampon de message et la longueur du message.

root@kitploit:~
int respond(int s, char *msg_buf) {
    // écrivez le contenu de msg_buf dans le socket s et retournez le statut
}

recieve() est aussi un simple assistant. Réinitialisez le tampon msg (indice : utilisez memset()). Appelez maintenant la fonction de bibliothèque socket read() pour lire msg. read() prend 3 arguments : l’adresse du socket, le tampon de message et la longueur maximale attendue du message.

root@kitploit:~
int recieve(int s, char *msg) {
    // réinitialisez le tampon msg
    int read_status = // lisez le contenu du socket s dans msg
    if (read_status) {
      perror("log:");
      exit(1);
    }
    return 0;
}

3. Exécution des commandes

Presque terminé ! Notre botnet est assez ennuyeux pour l’instant. Il ne peut que recevoir et transmettre des messages via un socket. Faisons-lui exécuter ce qu’il reçoit sur le terminal. Nous implémentons d’abord la fonction parse(). Elle fait exactement ce que son nom indique : analyser la commande. Nous pourrions faire une simple vérification d’erreur pour voir si un message est mal formé. Aussi, nous voulons ignorer silencieusement les messages qui ont été reçus mais qui ne lui étaient pas destinés. Le message sera formaté par le maître comme (nom du botnet):(commande à exécuter). J’ai fait la première vérification pour vous. Si les deux vérifications passent, passons la commande à la fonction execute().

root@kitploit:~
int parse (int s, char *msg, char* name) {
  char *target = msg;
  
  // vérifiez si le msg était destiné à ce client. Si non, ignorez silencieusement le paquet en retournant 0
  
  char *cmd = strchr(msg, ':');
  if (cmd == NULL) {
    printf("Format incorrect. Référence : CIBLE: commande");
    return -1;
  }
 
  // ajustez le pointeur cmd au début de la commande réelle
  // ajustez le caractère de terminaison à la fin de la commande
  // affichez une instruction locale détaillant la commande reçue
  
  execute (s, cmd);
  return 0;
}

Maintenant, la partie cool. execute() doit rediriger toute commande reçue dans le terminal et écrire toute sortie dans le socket vers le maître. Créez un tampon de pile pour stocker chaque ligne d’entrée. Utilisez ensuite la fonction C popen() pour exécuter l’entrée et stocker la sortie dans le fichier f (il existe de nombreuses façons de procéder à ce stade. Vous pouvez personnaliser votre botnet pour faire des choses vraiment cool avec l’entrée du maître et effectuer des collaborations/mises à jour autonomes avec d’autres nœuds du botnet. N’hésitez pas à être aussi créatif que vous le souhaitez. Nous nous en tiendrons pour l’instant à notre objectif vanilla). Analysez f ligne par ligne et envoyez tout via votre socket. Fermez f et vous avez terminé !

root@kitploit:~
int execute (int s, char *cmd) {
  FILE *f = // utilisez popen pour exécuter la commande localement
  if (!f) return -1;
  while (!feof (f)) {
    // analysez f ligne par ligne et renvoyez toute sortie au maître
  }
  fclose(f);
  return 0;
}

Compilez votre nouveau botnet avec la commande terminal suivante :

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

Exécutez bin/master dans une fenêtre de terminal et bin/slave dans d’autres fenêtres. Saisissez les commandes comme (nom d’utilisateur esclave):(commande terminal à distance). Félicitations ! Vous venez de construire un botnet !

4. Déguisement de votre malware

Il y a des choses vraiment cool que vous pouvez faire pour déguiser et déployer des malwares. En fait, c’est un domaine à part entière. Un exemple de ce que vous pouvez faire est de masquer le malware en image. Utilisons une image d’un panda. J’ai ajouté une fonction simple dans utils.c qui récupère une image d’un panda et la présente dans Preview. Cela donne à l’utilisateur l’impression d’ouvrir une image d’un panda alors qu’en réalité, l’utilisateur exécute votre malware. Pour ajouter cela, incluez les lignes de code suivantes dans bot.c :

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

Ensuite, faites un clic droit sur n’importe quelle image et choisissez Lire les informations. Faites de même pour bin/slave. Glissez la vignette de l’image sur la vignette exécutable de bin/slave. Cela devrait changer son apparence sur le bureau. Cependant, il manque toujours la terminaison caractéristique .png. Renommez votre exécutable en

root@kitploit:~
panda⒈png

Maintenant, cela ressemble à un fichier png. Cependant, nous utilisons le caractère Unicode « 1. » au lieu de « . » pour cacher que c’est toujours un exécutable Unix. Il existe de nombreuses astuces Unix plus crédibles qui peuvent être utilisées, comme le caractère LEFT-TO-RIGHT OVERRIDE pour masquer les noms de fichiers exécutables. Dans des cas plus extrêmes, vous pouvez intégrer du code dans des images et des macros de fichiers pour qu’ils s’exécutent en même temps que l’hôte est ouvert (un peu comme un cheval de Troie…). Cependant, comme personne chez TreeHacks n’est un cybercriminel, ces techniques ne devraient pas beaucoup nous intéresser ;).

5. Extensions

Maintenant que vous avez un botnet complètement fonctionnel, il existe de nombreuses extensions avec lesquelles vous pouvez vous challenger. Notre botnet est encore assez peu intéressant. Il ne peut pas faire grand-chose à moins que l’utilisateur ne clique dessus à chaque fois. Voici quelques suggestions :

1. Obtenir de la persistance.

Les botnets peuvent véritablement devenir des sources fiables d’activité malveillante pour les attaquants s’ils parviennent à rester sur un ordinateur même après un arrêt. Essayez de jouer avec la façon dont vous pouvez relancer votre esclave à chaque fois au démarrage. Ainsi, une fois qu’un utilisateur a cliqué sur le malware, son ordinateur est infecté jusqu’à ce qu’il le nettoie. Une suggestion pour y parvenir est de transformer votre processus exécutable en un démon. Ensuite, générez un fichier de configuration qui ajoute votre exécutable à une liste de démons qui doivent être exécutés au démarrage (les applications de stockage cloud, les plateformes de messagerie d’équipe, etc. le font déjà). Apprenez-en plus ici.

2. Implémenter un réseau pair-à-pair

Implémenter un réseau pair-à-pair n’est rien d’autre que réarranger la conception du réseau. Cependant, la clé d’un réseau P2P est que l’administrateur/attaquant peut obtenir le contrôle maître via n’importe quel nœud du réseau. Ainsi, l’attaquant doit avoir une sorte de clé maître et une connexion cryptée qui permet le contrôle maître de n’importe quel nœud. En savoir plus sur le fonctionnement des réseaux pair-à-pair ici.

3. Ajouter plusieurs niveaux de diversion

La structure maître-esclave que vous avez implémentée n’est pas très sécurisée. Les esclaves peuvent facilement être libérés en tuant le nœud maître. Idéalement, vous passeriez à une conception P2P. Cependant, vous pouvez aussi légèrement augmenter la sécurité du maître en dirigeant ses commandes de manière aléatoire à travers une série de bots contrôlés par l’attaquant avant qu’elles ne soient déployées sur le botnet. Cela rend plus difficile pour les experts de localiser le centre de commande et de tracer les appels du botnet entre les nœuds attaquants et les nœuds clients.

4. Explorer les protocoles réseau appropriés

Peut-être plus important encore, vous voulez jouer davantage avec la mise en réseau. Notre réseau est aussi simple que possible. À bien des égards, il est extrêmement faible et certainement pas rigoureux. Vous voudrez donc peut-être explorer des protocoles établis pour les réseaux comme Internet Relay Chat (IRC) pour construire un réseau plus approprié. Bien que cela prenne du temps, c’est extrêmement éducatif et un investissement bien fait. En savoir plus ici : https://oramind.com/tutorial-how-to-make-an-irc-server-connection/.

5. Essayez d’implémenter votre propre maître

Dans ce hackpack, nous avons utilisé un projet open source librement disponible pour remplacer notre serveur maître. Cependant, il y a de nombreux inconvénients. Premièrement, nous ne pouvons pas personnaliser notre serveur maître pour envoyer des commandes automatisées à travers notre réseau. Il est uniquement limité à l’utilisation de l’entrée de la ligne de commande. Deuxièmement, vous avez peut-être remarqué que tous les esclaves du botnet reçoivent chaque commande. Notre condition d’exécution est de vérifier si le nom de la cible correspond au nom de l’esclave. Si faux, la commande est silencieusement ignorée. C’est ce qu’on appelle un réseau de diffusion. Quelque chose de plus optimal pourrait être un réseau de multidiffusion. Dans un réseau de diffusion, un nœud relaie les paquets à tous ses nœuds connectés. Dans un système de multidiffusion, un certain sous-ensemble de nœuds peut être spécifié pour recevoir les paquets. De plus, utiliser un réseau de multidiffusion déplace l’affectation des commandes du client vers le serveur maître, où elle doit être. Implémentez votre propre maître pour faire passer le botnet de la diffusion à la multidiffusion.

Pour un guide complet de la programmation réseau, référez-vous à ceci : http://beej.us/guide/bgnet/output/html/multipage/index.html.

J’espère que vous vous êtes amusé !

Licence

MIT

À propos des HackPacks 🌲

Les HackPacks sont construits par l’équipe TreeHacks pour aider les hackers à construire de super projets lors de notre hackathon qui a lieu chaque février à Stanford. Nous croyons que tout le monde, quel que soit son niveau de compétence, peut apprendre à faire des choses géniales, et c’est une des façons dont nous contribuons à la culture hacker. Nous open-sourçons nos hackpacks (ainsi que notre technologie interne) pour que tout le monde puisse en apprendre et les utiliser ! N’hésitez pas à les utiliser pour vos propres hackathons, ateliers, et tout ce qui favorise la construction :)

Si vous êtes intéressé à participer à TreeHacks, vous pouvez postuler sur notre site web pendant la période de candidature.

Vous pouvez nous suivre ici sur GitHub pour voir tout le travail open source que nous faisons (nous adorons les issues, les contributions et les retours de toute sorte !), et sur Facebook, Twitter, et Instagram pour voir les actualités générales de TreeHacks.

Télécharger l’outil