diff options
| -rw-r--r-- | config-default/rules.xml | 2 | ||||
| -rw-r--r-- | modules/classes.pl | 44 | ||||
| -rw-r--r-- | modules/event.pl | 32 | ||||
| -rw-r--r-- | modules/util.pl | 81 |
4 files changed, 133 insertions, 26 deletions
diff --git a/config-default/rules.xml b/config-default/rules.xml index a9e3d6f..9b5d0c1 100644 --- a/config-default/rules.xml +++ b/config-default/rules.xml @@ -14,4 +14,6 @@ <event id="phishing1" class="re" override="notice" reason="trying to steal passwords (v1)" risk="high" type="notice">identify.*/msg .* identify <password></event> <event id="phishing2" class="re" override="notice" reason="trying to steal passwords (v2)" risk="high" type="notice">^This nickname is registered</event> <event id="proxylist" class="proxy" reason="IP is blacklisted" risk="info" type="join">lolz</event> + <event id="banevade" class="banevade" reason="appears to be ban evading" risk="debug" type="join">contentisuseless</event> + <event id="joinfloodquiet" class="floodqueue2" reason="join flood (3 joins in 90 seconds) by quieted user" risk="debug" type="join">5:30</event> </events> diff --git a/modules/classes.pl b/modules/classes.pl index fc8e9e7..4fbfb94 100644 --- a/modules/classes.pl +++ b/modules/classes.pl @@ -4,6 +4,7 @@ use strict; use warnings; use Text::LevenshteinXS qw(distance); use Data::Dumper; +use Regexp::Wildcards; my %sf = (); @@ -15,6 +16,7 @@ sub new "strbl" => \&strbl, "dnsbl" => \&dnsbl, "floodqueue" => \&floodqueue, + "floodqueue2" => \&floodqueue2, "nickspam" => \&nickspam, "splitflood" => \&splitflood, "advsplitflood" => \&advsplitflood, @@ -31,7 +33,8 @@ sub new "asciiflood" => \&asciiflood, "joinmsgquit" => \&joinmsgquit, "garbagemeter" => \&garbagemeter, - "cyclebotnet" => \&cyclebotnet + "cyclebotnet" => \&cyclebotnet, + "banevade" => \&banevade }; $self->{ftbl} = $tbl; bless($self); @@ -91,6 +94,18 @@ sub nickbl } return 0; } + +sub banevade +{ + my ($chk, $id, $event, $chan, $rev) = @_; + my $ip = ASM::Util->getNickIP($event->{nick}); + return 0 unless defined($ip); + if (defined($::sc{lc $chan}{ipbans}{$ip})) { + return 1; + } + return 0; +} + sub proxy { my ($chk, $id, $event, $chan, $rev) = @_; @@ -180,6 +195,33 @@ sub dnsbl return 0; } +sub floodqueue2 { + my ($chk, $id, $event, $chan, $rev) = @_; + my @cut = split(/:/, $chk->{content}); + + my $cvt = Regexp::Wildcards->new(type => 'jokers'); + my $hit = 0; + foreach my $mask ( keys %{$::sc{lc $chan}{quiets}}) { + if ($mask !~ /^\$/) { + my @div = split(/\$/, $mask); + my $regex = $cvt->convert($div[0]); + if (lc $event->{from} =~ lc $regex) { + $hit = 1; + } + } elsif ( (defined($::sn{lc $event->{nick}}{account})) && ($mask =~ /^\$a:(.*)/)) { + my @div = split(/\$/, $mask); + my $regex = $cvt->convert($div[0]); + if (lc ($::sn{lc $event->{nick}}{account}) =~ lc $regex) { + $hit = 1; + } + } + } + return 0 unless $hit; + + return 1 if ( flood_add( $chan, $id, $event->{host}, int($cut[1]) ) == int($cut[0]) ); + return 0; +} + sub floodqueue { my ($chk, $id, $event, $chan, $rev) = @_; my @cut = split(/:/, $chk->{content}); diff --git a/modules/event.pl b/modules/event.pl index bd76fb1..b74c4d0 100644 --- a/modules/event.pl +++ b/modules/event.pl @@ -596,9 +596,19 @@ sub on_mode $::log->sqlIncident( $chan, $idx ) if $idx; } } + if ($ex[1] =~ /^\*\!\*\@(.*)$/) { + my $ip = ASM::Util->getHostIP($1); + $::sc{$chan}{ipbans}{$ip} = { bannedBy => $event->{from}, bannedOn => time } if defined($ip); + } + } + } + elsif ( $ex[0] eq '-b' ) { + delete $::sc{$chan}{bans}{$ex[1]}; + if ($ex[1] =~ /^\*\!\*\@(.*)$/) { + my $ip = ASM::Util->getHostIP($1); + delete $::sc{$chan}{ipbans}{$ip} if defined($ip); } } - elsif ( $ex[0] eq '-b' ) { delete $::sc{$chan}{bans}{$ex[1]}; } elsif ( $ex[0] eq '+q' ) { $::sc{$chan}{quiets}{$ex[1]} = { bannedBy => $event->{from}, bannedOn => time }; @@ -610,9 +620,19 @@ sub on_mode $::log->sqlIncident( $chan, $idx ) if $idx; } } + if ($ex[1] =~ /^\*\!\*\@(.*)$/) { + my $ip = ASM::Util->getHostIP($1); + $::sc{$chan}{ipquiets}{$ip} = { bannedBy => $event->{from}, bannedOn => time } if defined($ip); + } + } + } + elsif ( $ex[0] eq '-q' ) { + delete $::sc{$chan}{quiets}{$ex[1]}; + if ($ex[1] =~ /^\*\!\*\@(.*)$/) { + my $ip = ASM::Util->getHostIP($1); + delete $::sc{$chan}{ipquiets}{$ip} if defined($ip); } } - elsif ( $ex[0] eq '-q' ) { delete $::sc{$chan}{quiets}{$ex[1]}; } else { my ($what, $mode) = split (//, $ex[0]); @@ -652,6 +672,10 @@ sub on_banlist my ($conn, $event) = @_; my ($me, $chan, $ban, $banner, $bantime) = @{$event->{args}}; $::sc{lc $chan}{bans}{$ban} = { bannedBy => $banner, bannedOn => $bantime }; + if ($ban =~ /^\*\!\*\@(.*)$/) { + my $ip = ASM::Util->getHostIP($1); + $::sc{lc $chan}{ipbans}{$ip} = { bannedBy => $banner, bannedOn => $bantime } if defined($ip); + } } sub on_quietlist @@ -659,6 +683,10 @@ sub on_quietlist my ($conn, $event) = @_; my ($me, $chan, $mode, $ban, $banner, $bantime) = @{$event->{args}}; $::sc{lc $chan}{quiets}{$ban} = { bannedBy => $banner, bannedOn => $bantime }; + if ($ban =~ /^\*\!\*\@(.*)$/) { + my $ip = ASM::Util->getHostIP($1); + $::sc{lc $chan}{ipquiets}{$ip} = { bannedBy => $banner, bannedOn => $bantime } if defined($ip); + } } sub on_channelurlis diff --git a/modules/util.pl b/modules/util.pl index 54e25a6..9a104c1 100644 --- a/modules/util.pl +++ b/modules/util.pl @@ -4,6 +4,7 @@ use POSIX qw(strftime); use warnings; use strict; use Term::ANSIColor qw (:constants); +use Socket qw( inet_aton inet_ntoa ); %::RISKS = ( @@ -183,45 +184,79 @@ sub dprint { print STDERR $text, "\n"; } + +sub intToDottedQuad { + my ($module, $num) = @_; + return inet_ntoa(pack('N', $num)); +} + sub dottedQuadToInt { my ($module, $dottedquad) = @_; - my $ip_number = 0; - my @octets = split(/\./, $dottedquad); - foreach my $octet (@octets) { - $ip_number <<= 8; - $ip_number |= $octet; - } - return $ip_number; +# my $ip_number = 0; +# my @octets = split(/\./, $dottedquad); +# foreach my $octet (@octets) { +# $ip_number <<= 8; +# $ip_number |= $octet; +# } +# return $ip_number; + return unpack('N', inet_aton($dottedquad)); } -sub getNickIP +sub getHostIP { - my ($module, $nick) = @_; - $nick = lc $nick; - return unless defined($::sn{$nick}); - if (defined($::sn{$nick}{ip})) { - return $::sn{$nick}{ip}; - } - my $host = $::sn{$nick}{host}; + my ($module, $host) = @_; if ( ($host =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) or ($host =~ /^gateway\/web\/freenode\/ip\.(\d+)\.(\d+)\.(\d+)\.(\d+)$/) ) { - #yay, easy IP! - $::sn{$nick}{ip} = dottedQuadToInt(undef, "$1.$2.$3.$4"); - return $::sn{$nick}{ip}; + #yay, easy IP! + return dottedQuadToInt(undef, "$1.$2.$3.$4"); } elsif (index($host, '/') != -1) { return; } elsif ($host =~ /^2001:0:/) { my @splitip = split(/:/, $host); + return unless defined($splitip[6]) && defined($splitip[7]); #I think I can just do (hex($splitip[6] . $splitip[7]) ^ hex('ffffffff')) here but meh my $host = join('.', unpack('C4', pack('N', (hex($splitip[6] . $splitip[7])^hex('ffffffff'))))); - $::sn{$nick}{ip} = dottedQuadToInt(undef, $host); - return $::sn{$nick}{ip}; + return dottedQuadToInt(undef, $host); } - my @resolve = gethostbyname($::sn{$nick}{host}); + my @resolve = gethostbyname($host); return unless @resolve; - $::sn{$nick}{ip} = dottedQuadToInt(undef, join('.', unpack('C4', $resolve[4]))); - return $::sn{$nick}{ip}; + return dottedQuadToInt(undef, join('.', unpack('C4', $resolve[4]))); +} + +sub getNickIP +{ + my ($module, $nick) = @_; + $nick = lc $nick; + return unless defined($::sn{$nick}); + if (defined($::sn{$nick}{ip})) { + return $::sn{$nick}{ip}; + } + my $host = $::sn{$nick}{host}; + my $ip = getHostIP(undef, $host); + if (defined($ip)) { + $::sn{$nick}{ip} = $ip; + return $ip; + } + return; +# if ( ($host =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) or +# ($host =~ /^gateway\/web\/freenode\/ip\.(\d+)\.(\d+)\.(\d+)\.(\d+)$/) ) { +# #yay, easy IP! +# $::sn{$nick}{ip} = dottedQuadToInt(undef, "$1.$2.$3.$4"); +# return $::sn{$nick}{ip}; +# } elsif (index($host, '/') != -1) { +# return; +# } elsif ($host =~ /^2001:0:/) { +# my @splitip = split(/:/, $host); +# #I think I can just do (hex($splitip[6] . $splitip[7]) ^ hex('ffffffff')) here but meh +# my $host = join('.', unpack('C4', pack('N', (hex($splitip[6] . $splitip[7])^hex('ffffffff'))))); +# $::sn{$nick}{ip} = dottedQuadToInt(undef, $host); +# return $::sn{$nick}{ip}; +# } +# my @resolve = gethostbyname($::sn{$nick}{host}); +# return unless @resolve; +# $::sn{$nick}{ip} = dottedQuadToInt(undef, join('.', unpack('C4', $resolve[4]))); +# return $::sn{$nick}{ip}; } sub notRestricted { |
