]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blobdiff - config/guardian/guardian.pl
guardian: React on BF attacks for SSH at pre-auth stage.
[people/teissler/ipfire-2.x.git] / config / guardian / guardian.pl
index 8c2e3b7046e98a3094bd1f28e8a7908dbbd7c866..34546b7135aac1f400a1895ea265fb11f43fc96f 100644 (file)
@@ -50,6 +50,8 @@ print "My gatewayaddess is: $gatewayaddr\n";
                        # destination was found.
        "$hostipaddr" => 1);
 
+&get_aliases;
+
 %sshhash = ();
 
 if ( -e $targetfile ) {
@@ -93,8 +95,21 @@ for (;;) {
        if (seek(ALERT2,0,1)){
                while (<ALERT2>) {
                        chop;
-                       if ($_=~/.*sshd.*Failed password for root from.*/) {
-                               my @array=split(/ /,$_);&checkssh ($array[10], "possible SSH-Bruteforce Attack");}
+                       if ($_=~/.*sshd.*Failed password for .* from.*/) {
+                               my @array=split(/ /,$_);
+                               my $temp = "";
+                               if ( $array[11] eq "port" ) {
+                                       $temp = $array[10];
+                               } elsif ( $array[11] eq "from" ) {
+                                       $temp = $array[12];
+                               } else {
+                                       $temp = $array[11];
+                               }
+                               &checkssh ($temp, "possible SSH-Bruteforce Attack");}
+
+                       # This should catch Bruteforce Attacks with enabled preauth
+                       if ($_ =~ /.*sshd.*Received disconnect from (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):.*\[preauth\]/) {
+                               &checkssh ($1, "possible SSH-Bruteforce Attack, failed preauth");}
                        }
        }
 
@@ -162,32 +177,36 @@ sub checkssh {
 
        return 1 if ($source eq $gatewayaddr); # or our gateway
 
-       if ($sshhash{$dest} eq "" ){
-               $sshhash{$dest} = 1;
+       return 0 if ($sshhash{$source} > 4); # allready blocked
+
+       if ( ($ignore{$source} == 1) ){
+               &write_log("Ignoring attack because $source is in my ignore list\n");
+               return 1;
        }
-       if ($sshhash{$dest} >= 3 ) {
-               &write_log ("source = $source, count $sshhash{$dest} - blocking for ssh attack.\n");
+
+       if ($sshhash{$source} == 4 ) {
+               &write_log ("source = $source, blocking for ssh attack.\n");
                &ipchain ($source, "", $type);
+               $sshhash{$source} = $sshhash{$source}+1;
+               return 0;
        }
-# you will see this if the destination was not in the $sshhash, and the
-# packet was not ignored before the target check..
-       else {
-               &write_log ("Odd.. source = $source, ssh count only $sshhash{$dest} - No action done.\n");
-               if (defined ($opt_d)) {
-                       foreach $key (keys %sshhash) {
-                               &write_log ("sshhash{$key} = %sshhash{$key}\n");
-                       }
-               }
-               $sshhash{$key} = $sshhash{$key}+1;
+
+       if ($sshhash{$source} eq "" ){
+               $sshhash{$source} = 1;
+               &write_log ("SSH Attack = $source, ssh count only $sshhash{$source} - No action done.\n");
+               return 0;
        }
+
+       $sshhash{$source} = $sshhash{$source}+1;
+       &write_log ("SSH Attack = $source, ssh count only $sshhash{$source} - No action done.\n");
 }
 
 sub ipchain {
        my ($source, $dest, $type) = @_;
        &write_log ("$source\t$type\n");
        if ($hash{$source} eq "") {
-               &write_log ("Running '$blockpath $source'\n");
-               system ("$blockpath $source");
+               &write_log ("Running '$blockpath $source $interface'\n");
+               system ("$blockpath $source $interface");
                $hash{$source} = time() + $TimeLimit;
        } else {
 # We have already blocked this one, but snort detected another attack. So
@@ -219,9 +238,9 @@ sub build_ignore_hash {
                        $count++;
                }
                close (IGNORE);
-               print "Loaded $count addresses from $ignorefile\n";
+               &write_log("Loaded $count addresses from $ignorefile\n");
        } else {
-               print "No ignore file was loaded!\n";
+               &write_log("No ignore file was loaded!\n");
        }
 }
 
@@ -244,6 +263,9 @@ sub load_conf {
                }
                if (/Interface\s+(.*)/) {
                        $interface = $1;
+                       if ( $interface eq "" ) {
+                               $interface = `cat /var/ipfire/ethernet/settings | grep RED_DEV | cut -d"=" -f2`;
+                       }
                }
                if (/AlertFile\s+(.*)/) {
                        $alert_file = $1;
@@ -265,16 +287,13 @@ sub load_conf {
                }
        }
 
-       if ($interface eq "") {
-               die "Fatal! Interface is undefined.. Please define it in $opt_o with keyword Interface\n";
-       }
        if ($alert_file eq "") {
                print "Warning! AlertFile is undefined.. Assuming /var/log/snort.alert\n";
                $alert_file="/var/log/snort.alert";
        }
        if ($hostipaddr eq "") {
                print "Warning! HostIpAddr is undefined! Attempting to guess..\n";
-               $hostipaddr = &get_ip($interface);
+               $hostipaddr = `cat /var/ipfire/red/local-ipaddress`;
                print "Got it.. your HostIpAddr is $hostipaddr\n";
        }
        if ($ignorefile eq "") {
@@ -345,30 +364,9 @@ sub daemonize {
        }
 }
 
-sub get_ip {
-       my ($interface) = $_[0];
-       my $ip;
-       open (IFCONFIG, "/bin/netstat -iee |grep $interface -A7 |");
-       while (<IFCONFIG>) {
-               if ($OS eq "FreeBSD") {
-                       if (/inet (\d+\.\d+\.\d+\.\d+)/) {
-                               $ip = $1;
-                       }
-               }
-               if ($OS eq "Linux") {
-                       if (/inet addr:(\d+\.\d+\.\d+\.\d+)/) {
-                               $ip = $1;
-                       }
-               }
-       }
-       close (IFCONFIG);
-
-       if ($ip eq "") { die "Couldn't figure out the ip address\n"; }
-               $ip;
-       }
-
 sub sig_handler_setup {
-       $SIG{TERM} = \&clean_up_and_exit; # kill
+       $SIG{INT} = \&clean_up_and_exit; # kill -2
+       $SIG{TERM} = \&clean_up_and_exit; # kill -9
        $SIG{QUIT} = \&clean_up_and_exit; # kill -3
 #  $SIG{HUP} = \&flush_and_reload; # kill -1
 }
@@ -387,7 +385,7 @@ sub remove_blocks {
 sub call_unblock {
        my ($source, $message) = @_;
        &write_log ("$message");
-       system ("$unblockpath $source");
+       system ("$unblockpath $source $interface");
 }
 
 sub clean_up_and_exit {
@@ -412,3 +410,22 @@ sub load_targetfile {
        close (TARG);
        print "Loaded $count addresses from $targetfile\n";
 }
+
+sub get_aliases {
+       my $ip;
+       print "Scanning for aliases on $interface and add them to the target hash...";
+
+       open (IFCONFIG, "/sbin/ip addr show $interface |");
+       my @lines = <IFCONFIG>;
+       close(IFCONFIG);
+
+       foreach $line (@lines) {
+               if ( $line =~ /inet (\d+\.\d+\.\d+\.\d+)/) {
+                       $ip = $1;
+                       print " got $ip on $interface ... ";
+                       $targethash{'$ip'} = "1";
+               }
+       }
+
+       print "done \n";
+}