Files
bpfire/html/cgi-bin/logs.cgi/ids.dat
Peter Müller 66c3619872 Early spring clean: Remove trailing whitespaces, and correct licence headers
Bumping across one of our scripts with very long trailing whitespaces, I
thought it might be a good idea to clean these up. Doing so, some
missing or inconsistent licence headers were fixed.

There is no need in shipping all these files en bloc, as their
functionality won't change.

Signed-off-by: Peter Müller <peter.mueller@ipfire.org>
2022-02-18 23:54:57 +00:00

495 lines
14 KiB
Perl

#!/usr/bin/perl
#
# SmoothWall CGIs
#
# This code is distributed under the terms of the GPL
#
# (c) The SmoothWall Team
#
# Copyright (C) 18-03-2002 Mark Wormgoor <mark@wormgoor.com>
# - Added links to Snort database and ipinfo.cgi
#
# $Id: ids.dat,v 1.6.2.16 2005/06/14 08:25:30 eoberlander Exp $
#
use strict;
# enable only the following on debugging purpose
#use warnings;
#use CGI::Carp 'fatalsToBrowser';
require '/var/ipfire/general-functions.pl';
require "${General::swroot}/lang.pl";
require "${General::swroot}/header.pl";
my %color = ();
my %mainsettings = ();
&General::readhash("${General::swroot}/main/settings", \%mainsettings);
&General::readhash("/srv/web/ipfire/html/themes/ipfire/include/colors.txt", \%color);
use POSIX();
#workaround to suppress a warning when a variable is used only once
my @dummy = ( ${Header::table1colour}, ${Header::table2colour} );
undef (@dummy);
my %cgiparams=();
my %logsettings=();
my @log=();
my $errormessage = '';
my @shortmonths = ( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug',
'Sep', 'Oct', 'Nov', 'Dec' );
my @longmonths = ( $Lang::tr{'january'}, $Lang::tr{'february'}, $Lang::tr{'march'},
$Lang::tr{'april'}, $Lang::tr{'may'}, $Lang::tr{'june'}, $Lang::tr{'july'}, $Lang::tr{'august'},
$Lang::tr{'september'}, $Lang::tr{'october'}, $Lang::tr{'november'},
$Lang::tr{'december'} );
my @now = localtime(time);
my $dow = $now[6];
my $doy = $now[7];
my $tdoy = $now[7];
my $year = $now[5]+1900;
$cgiparams{'DAY'} = $now[3];
$cgiparams{'MONTH'} = $now[4];
$cgiparams{'ACTION'} = '';
&Header::getcgihash(\%cgiparams);
$logsettings{'LOGVIEW_REVERSE'} = 'off';
&General::readhash("${General::swroot}/logging/settings", \%logsettings);
${Header::viewsize} = defined ($logsettings{'LOGVIEW_VIEWSIZE'}) ? $logsettings{'LOGVIEW_VIEWSIZE'} : 150;
$Header::viewsize /= 5; # each ids is displayed on 5 lines
$now[4] = $cgiparams{'MONTH'}+1;
if($now[4] < 10) {
$now[4] = "0$now[4]"; }
my $start = -1;
if ($ENV{'QUERY_STRING'} && $cgiparams{'ACTION'} ne $Lang::tr{'update'})
{
my @temp = split(',',$ ENV{'QUERY_STRING'});
$start = $temp[0];
$cgiparams{'MONTH'} = $temp[1];
$cgiparams{'DAY'} = $temp[2];
}
if (!($cgiparams{'MONTH'} =~ /^(0|1|2|3|4|5|6|7|8|9|10|11)$/) ||
!($cgiparams{'DAY'} =~ /^(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31)$/))
{
$cgiparams{'DAY'} = $now[3];
$cgiparams{'MONTH'} = $now[4];
}
elsif($cgiparams{'ACTION'} eq '>>')
{
my @temp_then=();
my @temp_now = localtime(time);
$temp_now[4] = $cgiparams{'MONTH'};
$temp_now[3] = $cgiparams{'DAY'};
@temp_then = localtime(POSIX::mktime(@temp_now) + 86400);
## Retrieve the same time on the next day +
## 86400 seconds in a day
$cgiparams{'MONTH'} = $temp_then[4];
$cgiparams{'DAY'} = $temp_then[3];
}
elsif($cgiparams{'ACTION'} eq '<<')
{
my @temp_then=();
my @temp_now = localtime(time);
$temp_now[4] = $cgiparams{'MONTH'};
$temp_now[3] = $cgiparams{'DAY'};
@temp_then = localtime(POSIX::mktime(@temp_now) - 86400);
## Retrieve the same time on the previous day -
## 86400 seconds in a day
$cgiparams{'MONTH'} = $temp_then[4];
$cgiparams{'DAY'} = $temp_then[3];
}
if (($cgiparams{'DAY'} ne $now[3]) || ($cgiparams{'MONTH'} ne $now[4]))
{
my @then = ();
if ( ( $cgiparams{'MONTH'} eq $now[4]) && ($cgiparams{'DAY'} > $now[3]) ||
( $cgiparams{'MONTH'} > $now[4] ) ) {
@then = localtime(POSIX::mktime( 0, 0, 0, $cgiparams{'DAY'}, $cgiparams{'MONTH'}, $year - 1901 ));
} else {
@then = localtime(POSIX::mktime( 0, 0, 0, $cgiparams{'DAY'}, $cgiparams{'MONTH'}, $year - 1900 ));
}
$tdoy = $then[7];
my $lastleap=($year-1)%4;
if ($tdoy>$doy) {
if ($lastleap == 0 && $tdoy < 60) {
$doy=$doy+366;
} else {
$doy=$doy+365;
}
}
}
my $datediff=0;
my $dowd=0;
my $multifile=0;
if ($tdoy ne $doy) {
$datediff=int(($doy-$tdoy)/7);
$dowd=($doy-$tdoy)%7;
if (($dow-$dowd)<1) {
$datediff=$datediff+1;
}
if (($dow-$dowd)==0) {
$multifile=1;
}
}
my $longmonthstr = $longmonths[$cgiparams{'MONTH'}];
my $monthnum = $cgiparams{'MONTH'} + 1;
my $monthstr = $monthnum <= 9 ? "0$monthnum" : "$monthnum";
my $daystr = $cgiparams{'DAY'} <= 9 ? "0$cgiparams{'DAY'}" : "$cgiparams{'DAY'}";
my $lines = 0;
my ($title,$classification,$priority,$date,$time,$srcip,$srcport,$destip,$destport, $sid, @refs);
&processevent;
if ($multifile) {
$datediff=$datediff-1;
&processevent;
}
if ($cgiparams{'ACTION'} eq $Lang::tr{'export'})
{
print "Content-type: text/plain\n\n";
print "IPFire IPS log\r\n";
print "Date: $cgiparams{'DAY'} $longmonths[$cgiparams{'MONTH'}]\r\n";
print "\r\n";
if ($logsettings{'LOGVIEW_REVERSE'} eq 'on') { @log = reverse @log; }
foreach $_ (@log)
{
my ($datetime,$title,$priority,$classification,$srcip,$srcport,$destip,$destport,$sid,$refs) = split(/\|/);
$refs =~ s/,$//;
# Skip event if no datetime and title are available.
next unless (($datetime) && ($title));
print "Date: $datetime\n";
print "Name: $title\n";
print "Priority: $priority\n";
print "Type: $classification\n";
print "IP Info: ";
print "$srcip";
if ($srcport != "n/a") {
print ":$srcport";
}
print " -> ";
print "$destip";
if ($destport != "n/a") {
print ":$destport";
}
print "\n";
print "SID: $sid\n";
print "Refs: $refs\n\n";
}
exit;
}
&Header::showhttpheaders();
&Header::openpage($Lang::tr{'ids log viewer'}, 1, '');
&Header::openbigbox('100%', 'left', '', $errormessage);
if ($errormessage) {
&Header::openbox('100%', 'left', $Lang::tr{'error messages'});
print "<font class='base'>$errormessage&nbsp;</font>\n";
&Header::closebox();
}
&Header::openbox('100%', 'left', "$Lang::tr{'settings'}:");
print <<END
<form method='post' action="$ENV{'SCRIPT_NAME'}">
<table width='100%'>
<tr>
<td width='10%' class='base'>$Lang::tr{'month'}:&nbsp;</td>
<td width='10%'>
<select name='MONTH'>
END
;
for (my $month = 0; $month < 12; $month++)
{
print "\t<option ";
if ($month == $cgiparams{'MONTH'}) {
print 'selected="selected" '; }
print "value='$month'>$longmonths[$month]</option>\n";
}
print <<END
</select>
</td>
<td width='10%' class='base' align='right'>&nbsp;$Lang::tr{'day'}:&nbsp;</td>
<td width='40%'>
<select name='DAY'>
END
;
for (my $day = 1; $day <= 31; $day++)
{
print "\t<option ";
if ($day == $cgiparams{'DAY'}) {
print 'selected="selected" '; }
print "value='$day'>$day</option>\n";
}
print <<END
</select>
</td>
<td width='5%' align='center'><input type='submit' name='ACTION' title='$Lang::tr{'day before'}' value='&lt;&lt;' /></td>
<td width='5%' align='center'><input type='submit' name='ACTION' title='$Lang::tr{'day after'}' value='&gt;&gt;' /></td>
<td width='10%' align='center'><input type='submit' name='ACTION' value='$Lang::tr{'update'}' /></td>
<td width='10%' align='center'><input type='submit' name='ACTION' value='$Lang::tr{'export'}' /></td>
</tr>
</table>
</form>
END
;
&Header::closebox();
&Header::openbox('100%', 'left', $Lang::tr{'log'});
print "<p><b>$Lang::tr{'ids log hits'} $longmonthstr $daystr: $lines</b></p>";
if ($start == -1) {
$start = $lines - ${Header::viewsize}; }
if ($start >= $lines - ${Header::viewsize}) { $start = $lines - ${Header::viewsize}; };
if ($start < 0) { $start = 0; }
my $prev = $start - ${Header::viewsize};
my $next = $start + ${Header::viewsize};
if ($prev < 0) { $prev = 0; }
if ($next >= $lines) { $next = -1 }
if ($start == 0) { $prev = -1; }
my @slice = splice(@log, $start, ${Header::viewsize});
if ($logsettings{'LOGVIEW_REVERSE'} eq 'on') { @slice = reverse @slice; }
if ($lines != 0) {
&oldernewer();
$lines = 0;
print <<END
<table width='100%'>
END
;
foreach $_ (@slice)
{
if ($lines % 2) {
print "<tr bgcolor='$color{'color20'}'><td>\n"; }
else {
print "<tr bgcolor='$color{'color22'}'><td>\n"; }
my ($datetime,$title,$priority,$classification,$srcip,$srcport,$destip,$destport,$sid,$refs) = split(/\|/);
# Only show the current event if at least datetime and title are available.
next unless (($datetime) && ($title));
print <<END
<table width='100%'>
<tr>
<td width='15%'><b>$Lang::tr{'date'}:</b></td><td width='25%'>$datetime</td>
<td width='10%'><b>$Lang::tr{'name'}:</b></td><td width='50%'>$title</td>
</tr>
<tr><td><b>$Lang::tr{'priority'}:</b></td><td>$priority</td>
<td><b>$Lang::tr{'type'}:</b></td><td>$classification</td>
</tr>
<tr><td><b>$Lang::tr{'ipinfo'}:</b></td>
<td colspan='3'>
END
;
if ($srcip ne "n/a") {
print "<a href='/cgi-bin/ipinfo.cgi?ip=$srcip'>$srcip</a>";
} else {
print "$srcip";
}
print ":$srcport -&gt; ";
if ($destip ne "n/a") {
print "<a href='/cgi-bin/ipinfo.cgi?ip=$destip'>$destip</a>";
} else {
print "$destip";
}
print ":$destport";
print <<END
</td>
</tr>
<tr><td valign='top'><b>$Lang::tr{'references'}:</b></td><td valign='top'>
END
;
foreach my $ref (split(/,/,$refs)) {
if ($ref =~ m/url (.*)/) {
print "<a href='http://$1'>$1</a><br />";
} elsif ($ref =~ m/cve (.*)/) {
print "<a href='http://cve.mitre.org/cgi-bin/cvename.cgi?name=$1'>$1</a><br />";
} elsif ($ref =~ m/nessus (.*)/) {
print "<a href='http://cgi.nessus.org/plugins/dump.php3?id=$1'>Nessus $1</a><br />";
} elsif ($ref =~ m/bugtraq (.*)/) {
print "<a href='http://www.securityfocus.com/bid/$1'>Bugtraq $1</a><br />";
} else {
print "$ref<br />";
}
}
print $Lang::tr{'none found'} unless $refs =~ /,/;
print <<END
<td valign='top'><b>SID:</b></td>
<td valign='top'>
END
;
if ($sid eq "n/a") {
print $sid;
} elsif ($sid < 1000000) {
# Link to sourcefire if the the rule sid is less than 1000000.
print "<a href='https://www.snort.org/rule_docs/1-$sid' ";
print "target='_blank'>$sid</a></td>\n";
} elsif ($sid >= 2000000 and $sid < 3000000) {
# Link to emergingthreats if the rule sid is between 2000000 and 3000000.
print "<a href='https://threatintel.proofpoint.com/sid/$sid' ";
print "target='_blank'>$sid</a></td>\n";
} else {
# No external link for user defined rules
print $sid;
}
print <<END
</tr>
</table><br>
</td></tr>
END
;
$lines++;
}
print "</table>";
}
&oldernewer();
&Header::closebox();
&Header::closebigbox();
&Header::closepage();
sub processevent
{
our ($title,$classification,$priority,$date,$time,$srcip,$srcport,$destip,$destport, $sid, @refs);
my $filestr='';
if ($datediff==0) {
# If there is no datediff, directly assign the suricata fast.log.
$filestr="/var/log/suricata/fast.log";
} else {
# If there is a datediff, assign the datediff to the filestring.
$filestr="/var/log/suricata/fast.log.$datediff";
# The files are compressed add the extension to the filestring.
$filestr="$filestr.gz";
# If the file does not exist, try to fallback to legacy snort alert file.
unless (-f $filestr) {
# Assign snort alert file, the datediff and extension for compressed file.
$filestr = "/var/log/snort/alert.$datediff";
$filestr = "$filestr.gz";
}
}
if (!(open (LOG,($filestr =~ /.gz$/ ? "gzip -dc $filestr |" : $filestr)))) {
$errormessage="$errormessage$Lang::tr{'date not in logs'}: $filestr $Lang::tr{'could not be opened'}";
} else {
my $line = 0;
while(<LOG>) {
$line++;
if ($_ =~ m/\[\*\*\]/) {
unless ($line == 1 || $date ne "$monthstr/$daystr") {
&append;
$line = 1;
}
($title,$classification,$priority,$date,$time,$srcip,$srcport,$destip,$destport,$sid) = ("n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a", "n/a");
@refs = ();
$_ =~ m/:([0-9]{1,5})\] (.*) \[\*\*\]/;
$title = &Header::cleanhtml($2,"y");
}
if ($_ =~ m/Classification: (.*)\] \[Priority: (\d)\]/) {
$classification = &Header::cleanhtml($1,"y");
$priority = $2;
}
if ($_ =~ m/([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3}) \-\> ([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/) {
$srcip = $1 . "." . $2 . "." . $3 . "." . $4;
$destip = $5 . "." . $6 . "." . $7 . "." . $8;
}
if ($_ =~ m/([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\:([0-9]{1,6}) \-\> ([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\:([0-9]{1,6})/) {
$srcip = $1 . "." . $2 . "." . $3 . "." . $4;
$srcport = $5;
$destip = $6 . "." . $7 . "." . $8 . "." . $9;
$destport = $10;
}
if ($_ =~ m/^([0-9\/]{3,5})(\/\d+)?\-([0-9\:]{5,8})\.([0-9]{1,14})/) {
($date,$time) = ($1,$3);
}
if ($_ =~ m/\[Xref \=\>.*\]/) {
$_ =~ s/\]\[Xref \=\> /, /g;
$_ =~ m/\[Xref \=\> (.*)\]/;
push(@refs, $1);
}
if ($_ =~ m/\[1:([0-9]+):[0-9]+\]/) {
$sid = $1;
}
}
$line++;
# Check if all data is collected and the date of the event fits the desired date to
# get displayed.
if ($line gt 1 && $date eq "$monthstr/$daystr") { &append; }
close(LOG);
}
}
sub append
{
our ($title,$classification,$priority,$date,$time,$srcip,$srcport,$destip,$destport, $sid, @refs);
$log[$lines] = "$date $time|$title|$priority|$classification|$srcip|$srcport|$destip|$destport|$sid|";
foreach $_ (@refs) {
$log[$lines] = "$log[$lines]$_,"; }
$lines++;
}
sub oldernewer
{
print <<END
<table width='100%'>
<tr>
END
;
print "<td align='center' width='50%'>";
if ($prev != -1) {
print "<a href='/cgi-bin/logs.cgi/ids.dat?$prev,$cgiparams{'MONTH'},$cgiparams{'DAY'}'>$Lang::tr{'older'}</a>"; }
else {
print "$Lang::tr{'older'}"; }
print "</td>\n";
print "<td align='center' width='50%'>";
if ($next != -1) {
print "<a href='/cgi-bin/logs.cgi/ids.dat?$next,$cgiparams{'MONTH'},$cgiparams{'DAY'}'>$Lang::tr{'newer'}</a>"; }
else {
print "$Lang::tr{'newer'}"; }
print "</td>\n";
print <<END
</tr>
</table>
END
;
}