Creating an IRC Botnet has two main parts: (1) establishing an IRC server and (2) generating the bots.

Part 2: Generating the bots

Credit and kudos to Sean @LinuxAcademy for originally writing the template I used here.

BLUF (Bottom Line Upfront)

Here’s the entire Python3 script for the impatient folks. Scroll below for a breakdown of what each major section means.

# vim ./bot.py
#!/usr/bin/python3
import socket

ircsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server = "<your IRC servers IP address>"
channel = "#terminators"
botnick = "bot01"
botmaster = "cyberdyne"
killswitch = "die " + botnick

ircsocket.connect((server, 6667))
ircsocket.send(bytes("USER "+ botnick +" "+ botnick +" "+ botnick +" "+ botnick +"\n", "UTF-8"))
ircsocket.send(bytes("NICK "+ botnick +"\n", "UTF-8"))

def joinchan(channel):
	ircsocket.send(bytes("JOIN "+ channel +"\n", "UTF-8"))
	ircmsg = ""
	
	while ircmsg.find("End of /NAMES list.") == -1:
		ircmsg = ircsocket.recv(2048).decode("UTF-8")
		ircmsg = ircmsg.strip('\n\r')
		print(ircmsg)

def ping():
	ircsocket.send(bytes("PONG :pingis\n", "UTF-8"))

def sendmsg(msg, target=channel):
	ircsocket.send(bytes("PRIVMSG "+ target +" :"+ msg +"\n", "UTF-8"))

def main():
	joinchan(channel)

	while 1:		
		ircmsg = ircsocket.recv(2048).decode("UTF-8")
		ircmsg = ircmsg.strip('\n\r')
		print(ircmsg)

		if ircmsg.find('PRIVMSG') != -1:
			
			name = ircmsg.split('!',1)[0][1:]
			message = ircmsg.split('PRIVMSG', 1)[1].split(':',1)[1]
	
			if len(name) < 17:
				
				if message.find("Hi " + botnick) != -1:
					sendmsg("Hello " + name + "!")
		
				if name.lower() == botmaster.lower() and message.rstrip() == killswitch:
					sendmsg(Affirmative, powering down.)
					ircsocket.send(bytes("QUIT \n", "UTF-8"))
					return

	else:
		if ircmsg.find("PING :") != -1:
			ping()
main()

How the bot works

As I mentioned, this bot (script) is written in Python3. To start, the first two lines identify what binary (or version of Python) and libraries to use.

#!/usr/bin/python3
import socket

Next, you have your global variables. Make sure to use the correct IP address of your IRC server. Also, toggle the names of your IRC channel, botnick, botmaster, and kill-switch as necessary. If it was not obvious, your botnick identifies the nick-name or your bot. Your botmaster nick will be the one used to control the bots in your IRC channel, or chat-room. Finally, your killswitch can be anything really. Again, modify these few parameters as desired.

ircsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server = "<your IRC server’s IP address>"
channel = "#terminators"
botnick = "bot01"
botmaster = "cyberdyne"
killswitch = "die " + botnick

The only Python library imported was socket. It serves as the backbone of the bot. The first line here makes the initial connection/socket to your IRC server while the other two handle the login process (the third line specifically identifies the nick-name of your bot while on the server.

ircsocket.connect((server, 6667))
ircsocket.send(bytes("USER "+ botnick +" "+ botnick +" "+ botnick +" "+ botnick +"\n", "UTF-8"))
ircsocket.send(bytes("NICK "+ botnick +"\n", "UTF-8"))

The next few snippets of code define various functions like joining a specific IRC channel on your server, replying to IRC server (“are you alive?”) pings, and sending messages.

For example, this function takes in one of the global variables from the top of the script and uses it to send the correct data required for joining the IRC channel of choice. The while loop is used to let you know who else is already in the channel.

def joinchan(channel):
	ircsocket.send(bytes("JOIN "+ channel +"\n", "UTF-8"))
	ircmsg = ""
	
	while ircmsg.find("End of /NAMES list.") == -1:
		ircmsg = ircsocket.recv(2048).decode("UTF-8")
		ircmsg = ircmsg.strip('\n\r')
		print(ircmsg)

As mentioned, a function to reply to IRC server pings is necessary to maintaining your connection.

def ping():
	ircsocket.send(bytes("PONG :pingis\n", "UTF-8"))

Here is an example of a function you may either want to swap-out or expand upon, depending upon your use-case for this botnet. I used this as a function to verify my bot can “communicate” when provoked.

def sendmsg(msg, target=channel):
	ircsocket.send(bytes("PRIVMSG "+ target +" :"+ msg +"\n", "UTF-8"))

Putting these functions aside for a moment, we define the next major section with the meat & potatoes (guts) of the bot - starting with the infamous main() function.

After calling on the joinchan() function defined above, we have a while loop, comprised of two sub-sections: one for initial data processing, another for responding to any IRC messages aimed at the bot itself.

def main():	
	joinchan(channel)

The data handling sub-section specifies 2048 bytes (decoded in the UTF-8 character format) can be consumed by the bot at one time. It then strips any new-line and carriage-return characters and spits out the results onto the console.

	while 1:
		ircmsg = ircsocket.recv(2048).decode("UTF-8")
		ircmsg = ircmsg.strip('\n\r')
		print(ircmsg)

The other sub-section here looks for the key-word ’PRIVMSG’. If found, it parses the messenger’s nick-name and their message into two separate variables (called name and message). Then, if the name is less than 17 characters (a common naming convention for popular IRC servers), it either replies back or stops running. Under this specific if len(name) < 17: statement is where you can fit in more practical functions for the bot.

		if ircmsg.find('PRIVMSG') != -1:
			name = ircmsg.split('!',1)[0][1:]
			message = ircmsg.split('PRIVMSG', 1)[1].split(':',1)[1]
	
			if len(name) < 17:	
				if message.find("Hi " + botnick) != -1:
					sendmsg("Hello " + name + "!")
				if name.lower() == botmaster.lower() and message.rstrip() == killswitch:
					sendmsg("Affirmative, powering down.")
					ircsocket.send(bytes("QUIT \n", "UTF-8"))
					return

To add some context, the following is an example of what is thrown at the bot whenever a message is received:
:connor!~connor@1.1.1.1 PRIVMSG #terminators :Hi bot01
As you can see, it’s easier to understand and react to what’s going on by delineating the messenger’s nick-name from their message.

Anyway, we finally end our bot’s script by instructing it to reply to IRC server pings whenever it’s not looking for a message to react to.

	else:
		if ircmsg.find("PING :") != -1:
			ping()
main()