From: Stefan Schantl Date: Tue, 14 Jun 2016 13:28:14 +0000 (+0200) Subject: Merge branch 'parser-snort' X-Git-Tag: 2.0~19 X-Git-Url: http://git.ipfire.org/?p=people%2Fstevee%2Fguardian.git;a=commitdiff_plain;h=945fab35dbc028da7a1b2d790abec10cb97a6edd Merge branch 'parser-snort' --- 945fab35dbc028da7a1b2d790abec10cb97a6edd diff --cc modules/Parser.pm index 5c2f53f,db54cf3..255e6cc --- a/modules/Parser.pm +++ b/modules/Parser.pm @@@ -71,127 -71,58 +71,173 @@@ sub IsSupportedParser ($) ## This subfunction is responsible for parsing sort alerts and determine if ## an action should be performed. # - sub message_parser_snort($) { + ## XXX Currently the parser only supports IPv4. Add support for IPv6 at a + ## later time. + # + sub message_parser_snort(@) { my @message = @_; - # XXX - # Currently this parser just returns a simple message. - return "$message[0] SNORT A simple Snort Message"; + # The name of the parser module. + my $name = "SNORT"; + + # Variable to store the grabbed IP-address. + my $address; + + # Default returned message in case no one could be grabbed + # from the snort alert. + my $message = "An active snort rule has matched and gained an alert."; + + # A snort alert contains multiple lines, loop through all lines + # to parse the complete alert. + foreach my $line (@message) { + # Check Priority Level and skip the alert if it is to low. + #if ($line =~ /.*\[Priority: (\d+)\].*/) { + # return unless($1 < $priority); + #} + + # Search for a line like xxx.xxx.xxx.xxx -> xxx.xxx.xxx.xxx + if ($line =~ /(\d+\.\d+\.\d+\.\d+)+ -\> (\d+\.\d+\.\d+\.\d+)+/) { + # Store the grabbed IP-address. + $address = $1; + } + + # Search for a line like xxx.xxx.xxx.xxx:xxx -> xxx.xxx.xxx.xxx:xxx + elsif ($line =~ /(\d+\.\d+\.\d+\.\d+):\d+ -\> (\d+\.\d+\.\d+\.\d+):\d+/) { + # Store the obtained IP-address. + $address = $1; + } + + # Obtain the reported reason. + if ($line =~ /.*msg:\"(.*)\".*/) { + # Store the extracted message. + $message = $1; + } + } + + # Check if at least the IP-address information are obtained from the + # provided alert. + if ($address) { + # Return the extracted values. + return "$address $name $message"; + } + + # If we got here, the alert could not be parsed correctly, return nothing. + return; } +# +## The SSH message parser. +# +## This subfunction is used for parsing and detecting different attacks +## against the SSH service. +# +sub message_parser_ssh (@) { + my @message = @_; + my @actions; + + # The name of the parser module. + my $name = "SSH"; + + # Variable to store the grabbed IP-address. + my $address; + + # Variable to store the parsed event. + my $message; + + # Loop through all lines, in case multiple one have + # been passed. + foreach my $line (@message) { + # Check for failed password attempts. + if ($line =~/.*sshd.*Failed password for (.*) from (.*) port.*/) { + # Store the grabbed IP-address. + $address = $2; + + # Set event message. + $message = "Possible SSH-Bruteforce Attack for user: $1."; + } + + # This should catch Bruteforce Attacks with enabled preauth + elsif ($line =~ /.*sshd.*Received disconnect from (.*):.*\[preauth\]/) { + # Store obtained IP-address. + $address = $1; + + # Set event message. + $message = "Possible SSH-Bruteforce Attack - failed preauth."; + } + + # Check if at least the IP-address information has been extracted. + if (defined ($address)) { + # Add the extracted values and event message for the computed + # event to the actions array. + push(@actions, "count $address $name $message"); + } + } + + # If any actions are required, return the array. + if (@actions) { + return (@actions); + } + + # If we got here, the provided message is not affected by any filter and + # therefore can be skipped. Return nothing (False) in this case. + return; +} + +# +## The HTTPD message parser. +# +## This subfunction is used for parsing and detecting different attacks +## against a running HTTPD service. +# +sub message_parser_httpd (@) { + my @message = @_; + my @actions; + + # The name of the parser module. + my $name = "HTTPD"; + + # Variable to store the grabbed IP-address. + my $address; + + # Variable to store the parsed event. + my $message; + + # Loop through all lines, in case multiple one have + # been passed. + foreach my $line (@message) { + # This will catch brute-force attacks against htaccess logins (username). + if ($line =~ /.*\[error\] \[client (.*)\] user(.*) not found:.*/) { + # Store the grabbed IP-address. + $address = $1; + + # Set event message. + $message = "Possible WUI brute-force attack, wrong user: $2."; + } + + # Detect htaccess password brute-forcing against a username. + elsif ($line =~ /.*\[error\] \[client (.*)\] user(.*): authentication failure for.*/) { + # Store the extracted IP-address. + $address = $1; + + # Set event message. + $message = "Possible WUI brute-force attack, wrong password for user: $2."; + } + + # Check if at least the IP-address information has been extracted. + if (defined ($address)) { + # Add the extracted values and event message to the actions array. + push(@actions, "count $address $name $message"); + } + } + + # If any actions are required, return the array. + if (@actions) { + return @actions; + } + + # If we got here, the provided message is not affected by any filter and + # therefore can be skipped. Return nothing (False) in this case. + return; +} + 1;