
 Irssi's botnet description

 Copyright (c) 1999-2000 Timo Sirainen


 0. History

 draft v0.1 : 21.8.1999

	Just a first draft of my botnet design I did on a boring friday
	work afternoon :) I'll try to implement this to irssi some day, it
	feels pretty interesting now so it might be pretty soon even. Any
	comments are welcome :)

 draft v0.2 : 21.11.1999

	Exactly three months since the first draft :) Now I actually have
	some code done, just committed pretty simple botnet to irssi CVS.
	Made several changes to this document.. Still missing much details
	but the basic idea should be clear.

 draft v0.3 : 21.05.2000

	Strange, again the same day. I really didn't plan this :)
	Reformatted the text, added lots of text, implemented more of the
	stuff.


 1. General

 1.1 Description

	A small description of what botnet would do: A group of bots
	efficiently working together to perform their tasks. Like when
	someone's trying to take over your channel, bots will quickly
	decide who deops/kicks whom instead of multiple bots deopping or
	trying to kick the same people.

	Irssi's botnet is pretty much based on trust. Some malicious bot
	can quite well mess up the whole botnet. Connecting the bots to
	each other via ssh would be a good idea.

 1.2 Configuration

	example config file:

	mybotnet =
	{
	  priority=5;
	  nick=mybot;
	  uplinks = (
	    { host = "main.botnet.org"; password = "mypass"; },
	    { host = "alter.botnet.org"; password = "pass2"; }
	  );
	  downlinks = (
	    { password = "thepass"; valid_addrs = ( "192.168.0.*" ); },
	    { password = "blah"; valid_addrs = ( "*.botnet.org" ); },
	    { password = "localpass"; valid_addrs = ( "127.*" ); }
	  );
	}

	When connecting to botnet, the bot first tries to connect to the
	first bot in uplinks list, then the second, etc. Setting port to -1
	will prevent connecting to the bot, 0 uses the default.

 1.3 Botnet master

	To avoid total chaos inside botnet, the bots shouldn't do (almost)
	anything without a command from botnet's master. The master should
	know everything, and give commands to clients that can perform the
	task best.

	Master is the bot with the highest priority. If there's multiple
	with the same priority, the one that already was the master will
	stay master. When joining two botnets to one, the uplink's master
	stays. If link to master breaks, the closest bot to it will choose
	a new one.

	The priorities should be given so that the bots that have the
	fastest connections and are in the middle of the botnet have the
	highest priorities.

 1.4 Command format

	Commands that are sent inside botnet are in the following format:

	  <from_nick> <to_nick> COMMAND [command specific data..]

        If to_nick is '-', the command should be sent to everyone.


 2. Handshake

	First host checks from bots' valid_addrs who is connecting. If
	there's no matches it just disconnects the client.

	  CLIENT: PASS <password>
	  HOST  : (if error, disconnect)

	  CLIENT: NICK <nick>
	  HOST  : NICKERROR | CONNECTED

	If nick is already in use, the host sends NICKERROR and waits for
	new nick.

	Now we're connected to botnet. The commands from now on use the
	format specified in section 1.4.

	Both the client and the host sends information to other side of
	all the clients they serve (if any):

	  BOTINFO <nick> <connected_to_nick> <priority>

	BOTINFOs must be sent sorted so that connected_to_nick bot is
	always known. Like first comes the bots connected to the
	host/client, then the bots connected to them etc.

	If the client had downlinks, nick collisions might happen. The
	uplink is responsible for noticing them from BOTINFO commands.
	It should automatically replace the nicks with new ones and
	send nick change command to client and all it's downlinks. For
	example if host received:

	  BOTINFO bot highbot 10

	And the bot already exists, the BOTINFO is changed to:

	  BOTINFO bot2 highbot 10

	And the client and it's downlinks are notified:

	  BOTNICK bot2 bot

	After sending BOTINFOs, the host tells the current master:

	  MASTER <nick>

	The client now checks if it's priority is higher than the current
	master's. If it is, it will send the MASTER command without any
	parameters.


 3. Bot connections

 3.1 General

	Everyone's connections should be kept in n-way tree. Example:


                              [highuplink]
                 _____________/    |  |   \
                /                  | [h5] [h6]
              [h1]                 |     /  | \
             /    \                |   [h7] | [h8]
           [h2]   [h3]             |        |    \
                   |            [uplink]   [h9] [h10]
                  [h4]         /   |    \
                            [up2]  |   [up1]
                           /   |   |     |
                       [up3] [up4] |    [up5]
                                   |
                                  [we]
                                 /    \
                         [client1]     [client2]
                                        /     \
                                      [c3]    [c4]


	Botnet should try to keep together even if some hub in the middle
	crashes. Each bot should have at least two uplinks in case one
	dies. For example if [uplink] dies, [we] and [up1] could connect
	to [up2], and [up2] could connect to [highuplink].

	When connection is closed to some bot, a notice is sent by the
	bot's uplink:

	  BOTQUIT <nick>

	The quit notice should be sent only about the bot that was
	disconnected. Bots should figure out themselves the other bots and
	remove them too from their lists.

 3.2 Lag

	Each bot should send PING commands to their up/downlinks every
	now and then (1min?) to check that the connection is still active.
	If the PONG isn't received in 10 seconds, it's priority should be
	temporarily lowered to -1. If the PONG isn't received in 3
	minutes, the whole connection should be closed.

	Master should know lag times of every bots. It could then
	automatically raise/lower bots' priorities depending on how big
	their lag is. Master could also lower it's own priority and pass
	the master status to someone else with lower lag.

	If there's lot of lag (>3sec?) somewhere and something urgent
	happens, the botnet could split and behave independently.


 4. IRC networks

 4.1 Server connections

	When bot is connected to some irc server and is ready to take
	commands, it says:

	  IRCJOIN <tag> <ircnet> <server> <nick>

	Tag is the bot specific unique tag of the server, so that the bot
	can connect multiple times to same IRC network. All IRC related
	commands should specify the server tag where it should be sent.

	If bot quits an irc network, it says:

	  IRCQUIT <tag>

 4.2 IRC commands

	Master asks a bot to send some command to IRC server by saying:

	  CMD <id> <tag> <command>

	<command> can't really be anything, since the bot should also be
	able to reply to it. The <id> is for identifying the command/reply
	pair. Master should keep the command in memory until it receives
	the reply:

	  CMDREPLY <id> <last> <reply>

	The command could get a reply of multiple lines, so <last>
	specifies if the reply is the last line (1 or 0).

	If the command failed for some reason, the bot will reply with

	  CMDFAIL <id>

	and master should send the command to some other bot.

 4.3 Channels

	When joined/left channels, the bot says:

	  CHANJOIN <tag> <channel>
	  CHANPART <tag> <channel>

	After BOTJOIN, master tries to op the bot. When bot receives +o,
	it says:

	  CHANOP <tag> <channel>

	If it is the first opped bot in channel, master orders the bot to
	op the rest of the bots.

	If the bot is kicked, it says:

	  CHANKICK <tag> <channel>

	When master notices that bot is kicked, it first checks if there's
	any other opped bots in channel. If not, it waits for a random
	pause, 5-10sec before letting the bot join the channel again so
	that it won't get autorejoin ban.

	If bot can't join channel, it says:

	  CHANBANNED <tag> <channel>
	  (or)
	  CHANCANTJOIN <tag> <channel>

	When received BOTBANNED, master tries to unban bot or set a ban
	exception. BOTCANTJOIN results as invite to channel.

 4.4 Channel information

	When master notices that bot is the first one joined to channel,
	it asks the bot for some channel information:

	  CMD <id> <tag> NAMES <channel>
	  CMD <id> <tag> WHO <channel>
	  CMD <id> <tag> MODE <channel>
	  CMD <id> <tag> MODE b <channel>
	  CMD <id> <tag> MODE e <channel> (if IRC network supports this)
	  CMD <id> <tag> MODE I <channel> (if IRC network supports this)

	It's also possible that if several bots join immediately after the
	first bot, the commands are shared between all the bots.

	Bots should cache the information as much as possible, at least
	NAMES command.

 4.5 Channel priorities

	Every channel has a priority: LOW, NORMAL, HIGH.

	Normally LOW operates just as NORMAL channels, except when some
	channel has HIGH priority and bots are really busy, LOW channels
	just wait until there's time for them.

	In NORMAL channels, the most urgent operations (kicks, ops, deops)
	are performed quite soon even while bots are busy handling HIGH
	priority commands.

	Channels shouldn't normally be HIGH priority, but if attack
	against channel is detected (like someone comes from split, gets
	ops and gets to op someone else), it's priority is set to HIGH.
	When channel's priority is HIGH, botnet does everything it can to
	get rid of unauthorized opped people as fast as possible.

	LOW channel's priority can also be raised to HIGH, but it's
	priority is dropped back to LOW if some NORMAL channel's priority
	is raised to HIGH too.

	Master notifies about channel's priority change by saying:

	  CHANPRIORITY <ircnet> <channel> <LOW/NORMAL/HIGH>

