Index: docs/README.dronebl
===================================================================
--- docs/README.dronebl	(revision 0)
+++ docs/README.dronebl	(revision 0)
@@ -0,0 +1,112 @@
+##############################################################################
+#               DroneBL / dnsbl module for IRC Defender                      #
+#         written by Alexander Maassen <outsider@scarynet.org>               #
+##############################################################################
+
+INSTALLATION:
+
+	copy dronebl.pm to Modules/Scan/
+	copy dronebl.conf to the main folder of defender
+	copy this file to the docs/ folder
+
+	open defender.conf and add the following line:
+		dronebl_rpckey=<your rpc key here>
+
+	If you do not have a dronebl rpc key yet then obtain one on irc at:
+		irc://irc.staticbox.net/dronebl
+
+REQUIREMENTS:
+
+	In order to make things work the module will need additional PERL
+	modules which you can either install using CPAN or your favourite
+	package manager.
+	The following modules are required in order for the module to work:
+	Socket, Config::General(::Extended), Tie::IxHash and HTTP::Request
+	Socket:
+		is needed in order to convert host into ip and perform the
+		dns lookups against the various dnsbl systems
+	Config::General(::Extended):
+		is needed in order to read and parse the config file.
+	Tie::IxHash:
+		also needed for configuration readment and ensuring that the
+		order in which the dnsbl servers are configured is respected
+		because of eventual reporting to dronebl.
+	Request:
+		used in order to make the rpc call towards dronebl until they
+		have a new method to send reports.
+
+OPERATION:
+
+	The module works as following, in order to reduce impact on system
+	performance on startup, the module starts to work AFTER the servers
+	have acknowledged netbursts.
+	Upon connect the module will first check at dronebl in order to see
+	if a user is known there or not, should the user not be listed there
+	then the check will be performed against the in the configuration
+	defined list of dnsbl servers and in case dronebl is interrested in
+	these types, also reported to dronebl in order to speed up detection
+	for the next time.
+
+THE CONFIG FILE:
+
+	The structure of the config file is very easy to read and modify.
+	Each section is named after the dnsbl server to use to check against.
+
+	After this the so called reply section follows using this format:
+	incoming digit = outgoing digit:human readable type reply
+	where incoming digit is the xx part in the reply 127.0.0.xx
+	where outgoing digit is the type as used by the dronebl system
+	the rest of this config line speaks for itself.
+	Please use type 4 as reply in case this is a type the dronebl
+	system no longer wants to receive. If in doubt, contact them and ask.
+	Don't bitch at me if your rpc key got revoked because you reported
+	types they don't want in their list.
+
+	reason is the part that comes AFTER the human readable type and could
+	provide an url to a page where people can get more information
+	about their IP's listing, put $ip where you want the ip of the user.
+
+	duration is the gline duration in seconds and needs to be defined.
+
+	report is an optional config option that enables dronebl reporting
+	for replies coming from that dnsbl server, and again, make sure
+	you mask away unwanted replies as type 4 in replies or your rpc key
+	*WILL* get revoked, and again, ask them about if they want replies
+	from that dns server or not.
+
+SYSTEM IMPACT:
+
+	since irc defender does not run in a threaded mode and parses stuff
+	one by one delays of the operation of defender might occur depending
+	on your networks connection rates, the speed of your dns resolving
+	etc. On small networks you should not have any issues with this 
+	system. Tested it myself on an old P3-866 with 512Mb ram and a heavy
+	load and still it captured the creeps fast enough. Should you want
+	to improve perfomance, then I suggest to start a mirror for the
+	several dnsbl servers in order to speed up dnsbl lookups. You will
+	both improve performance on your side and the rest of the world
+	taking advantage of dnsbl systems.
+
+DISCLAIMERS:
+
+	this module only provides a method of supporting dnsbl mechanisms to
+	the irc defender system. The author is in no way part of the
+	development team of either dronebl/defender at the moment of this
+	writing. Also the author is not responsible for any impact the use
+	of this module might have on your network/systems, use this module
+	at your own risk. Although the author has tested this module as
+	thorough as possible he cannot make any claims about it working
+	on every system/configuration on this planet.
+
+LICENSE:
+
+	this module is open source and available to the masses. there is no
+	specific license attached to it. In case you make modifications to
+	it that would improve the code or its speed, the author would like
+	a copy of the patch in order to make it available to the other users
+	of this module. Should you base any code on this module, then please
+	be so kind to at least put some credits.
+
+COPYRIGHTS:
+
+	all mentioned trademarks are owned by their respectfull owners.
Index: Modules/Scan/dronebl.pm
===================================================================
--- Modules/Scan/dronebl.pm	(revision 0)
+++ Modules/Scan/dronebl.pm	(revision 0)
@@ -0,0 +1,134 @@
+# dronebl.pm by OUTsider
+# Permission is granted to modify and/or distribute this file in any way, 
+# providing that this notice is left intact.
+# $Id: dnsbl.pm,v 1.20 2008/04/06 12:01:50 brain Exp $
+
+package Modules::Scan::dronebl;
+
+use strict;
+use warnings;
+use Socket;
+use Config::General;
+use Tie::IxHash;
+require HTTP::Request;
+
+my $droneblconnects = 0;
+my $droneblkilled = 0;
+my $dronebl_rpckey = '';
+
+tie my %dnsbls, "Tie::IxHash";
+
+sub handle_topic {}
+sub handle_mode {}
+sub handle_join {}
+sub handle_part {}
+
+sub stats {
+	my $percent = $droneblconnects ? $droneblkilled/$droneblconnects*100 : 0;
+	$percent = $percent ? sprintf("%.3f", $percent) : 0;
+
+	main::message("Total clients killed: \002$droneblkilled\002");
+	main::message("Total connecting clients scanned: \002$droneblconnects\002");
+	main::message("Percentage of akilled clients: $percent%");
+}
+
+sub scan_user {
+	my($ident, $host, $serv, $nick, $fullname, $print_always) = @_;
+	# return if ($main::NETJOIN == 1);
+	$droneblconnects++;
+	my $ipaddr = gethostbyname($host);
+	if(defined $ipaddr) {
+		my $ip = inet_ntoa($ipaddr);
+		my $arpa  = join '.', reverse split /\./, $ip;
+		my $res1 = gethostbyname("$arpa.dnsbl.dronebl.org");
+		if(defined $res1) {
+			my ($ver1, $ver2, $ver3, $ipres) = split(/\./,inet_ntoa($res1));
+			if ($ver1 != "127" && $ver2 != "0" && $ver3 != "0") {
+				main::message("DNS Resolve through DroneBL returned an invalid reply (".
+					inet_ntoa($res1).")!");
+			} else {
+				my $info = "Unknown type $ipres";
+				if ($ipres eq "3") {
+					$info = "IRC spam drone (litmus/sdbot/fyle)";
+				} elsif ($ipres eq "5") {
+					$info = "Bottler (experimental)";
+				} elsif ($ipres eq "6") {
+					$info = "Unknown worm or spambot";
+				} elsif ($ipres eq "7") {
+				        $info = "DDoS drone";
+				} elsif ($ipres eq "8") {
+				        $info = "Open SOCKS proxy";
+				} elsif ($ipres eq "9") {
+				        $info = "Open HTTP proxy";
+				} elsif ($ipres eq "10") {
+				        $info = "Proxychain";
+				} elsif ($ipres eq "13") {
+				        $info = "Automated dictionary attacks";
+				} elsif ($ipres eq "14") {
+				        $info = "Open WINGATE proxy";
+				} elsif ($ipres eq "15") {
+				        $info = "Compromised router / gateway";
+				} elsif ($ipres eq "255") {
+					$info = "Uncategorized threat class";
+				}
+
+				main::message("User $host ($ip) matches on DroneBL ($info)!");
+				main::gline("*\@$ip",7200,"You have a host listed in the DroneBL. $info.".
+						"For more information, visit http://dronebl.org/lookup.do?ip=$ip");
+				$droneblkilled++;
+				return;
+			}
+		} else {
+			foreach my $dnsbl (keys %dnsbls) {
+				my $res2 = gethostbyname("$arpa.$dnsbl");
+				if(defined $res2) {
+					my($ver1, $ver2, $ver3, $ipres) = split(/\./,inet_ntoa($res2));
+					if ($ver1 != 127 && $ver2 != 0 && $ver3 != 0) {
+						main::message("DNS Resolve through $dnsbl returned an invalid reply (".
+							inet_ntoa($res2).")!");
+					} else {
+						my($type, $desc) = split(/:/,$dnsbls{$dnsbl}{'reply'}{$ipres},2);
+						my $reason = $dnsbls{$dnsbl}{'reason'};
+						$reason =~ s/\$ip/$ip/;
+						main::message("User $host ($ip) matches on $dnsbl ($desc)!");
+						main::gline("*\@$ip",$dnsbls{$dnsbl}{'duration'},"$desc $reason");
+						if ($dnsbls{$dnsbl}{'report'} == 1 && $type != 4) {
+							my $report = HTTP::Request->new("POST","http://dronebl.org/RPC2",
+								     "Content-Type: application/x-www-form-urlencoded",
+								     "<?xml version=\"1.0\"?>\n".
+								     "<request key=\"".$dronebl_rpckey."\">\n".
+								     "<add ip=\"".$ip."\" type=\"".$type."\" />\n".
+								     "</request>\n");
+						}
+						$droneblkilled++;
+						return;
+					}
+				}
+			}
+		}
+	}
+}
+
+sub handle_notice { }
+sub handle_privmsg { }
+
+sub init {
+        if (!main::depends("core-v1")) {
+                print "This module requires version 1.x of defender.\n";
+                exit(0);
+        }
+        main::provides("dronebl");
+
+	$dronebl_rpckey = $main::dataValues{"dronebl_rpckey"};
+	my $conf = new Config::General(
+		-ConfigFile	=> "$main::dir/dronebl.conf",
+		-ExtendedAccess	=> 1,
+		-LowerCaseNames => 1,
+		-BackslashEscape => 1,
+		-Tie		=> "Tie::IxHash"
+	);
+	%dnsbls = $conf->getall;
+}
+
+# Thou shalt not forget to end thy modules with 1.
+1;
Index: dronebl.conf
===================================================================
--- dronebl.conf	(revision 0)
+++ dronebl.conf	(revision 0)
@@ -0,0 +1,57 @@
+<dnsbl.ahbl.org>
+	<reply>
+		3	= 9:Open Proxy
+		10	= 4:Marked as Shoot on Sight
+		14	= 7:Compromised System - DDoS
+		15	= 4:Compromised System - Relay
+		16	= 13:Compromised System - Autorooter/Scanner
+		17	= 6:Compromised System - Worm or mass mailing virus
+		18	= 6:Compromised System - Other virus
+		19	= 9:Open Proxy
+		20	= 255:Blog/Wiki/Comment Spammer
+		127	= 255:Other form of abuse
+	</reply>
+	reason		= See http://ahbl.org/lookup?ip=$ip
+	duration	= 7200
+	report		= 1
+</dnsbl.ahbl.org>
+
+<rbl.efnetrbl.org>
+	<reply>
+		1	= 9:Open Proxy
+		2	= 6:Trojan Spreader
+		3	= 6:Trojan Infected Client
+		4	= 4:Tor Exit Server
+		5	= 7:Drones / Flooding
+	</reply>
+	reason		= Check http://ircnet.com/cgi-bin/bl.cgi?ip=$ip
+	duration 	= 7200
+	report		= 1
+</rbl.efnetrbl.org>
+
+<ircbl.ahbl.org>
+	<reply>
+		2	= 9:Open Proxy
+	</reply>
+	reason		= See http://ahbl.org/lookup?ip=$ip
+	duration	= 7200
+	report		= 1
+</ircbl.ahbl.org>
+
+<tor.kewlio.net.uk>
+	<reply>
+		100	= 4:Tor Exit Server
+	</reply>
+	reason		= Not allowed at the moment
+	duration	= 7200
+</tor.kewlio.net.uk>
+
+<tor.ahbl.org>
+	<reply>
+		2	= 4:Host running TOR (either as a transit node or exit point).
+		3	= 4:Host running a TOR exit node.
+		4	= 4:Host recently seen running a TOR exit node on EFNet.
+	</reply>
+	reason		= See http://ahbl.org/lookup?ip=$ip
+	duration	= 7200
+</tor.ahbl.org>

