new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / contrib / ossectop.pl
1 #!/usr/bin/perl -w
2 #use strict;
3 #use Socket;
4 #use POSIX 'setsid';
5 use Regexp::IPv6 qw($IPv6_re);
6 # ---------------------------------------------------------------------------
7 # Author: Meir Michanie (meirm@riunx.com)
8 # File: ossectop.pl
9 # Version 0.1 (09/2006)
10 #
11 # ---------------------------------------------------------------------------
12 # License
13 # ---------------------------------------------------------------------------
14 #
15 # This program is free software; you can redistribute it and/or
16 # modify it under the terms of the GNU General Public License
17 # as published by the Free Software Foundation; either version 2
18 # of the License, or (at your option) any later version.
19 #
20 # This program is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 # GNU General Public License for more details.
24 #
25 # You should have received a copy of the GNU General Public License
26 # along with this program; if not, write to the Free Software
27 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
28 #
29 # ---------------------------------------------------------------------------
30 # About OSSEC HIDS
31 # ---------------------------------------------------------------------------
32 #
33 # OSSEC HIDS is an Open Source Host-based Intrusion Detection System.
34 # It performs log analysis and correlation, integrity checking,
35 # rootkit detection, time-based alerting and active response.
36 # http://www.ossec.net
37 #
38 # ---------------------------------------------------------------------------
39
40 # ---------------------------------------------------------------------------
41 # Parameters
42 # ---------------------------------------------------------------------------
43 $SIG{TERM} = sub { &gracefulend('TERM')};
44 $SIG{INT} = sub { &gracefulend('INT')};
45
46 my %conf;
47 $conf{resolve}=1;
48
49
50 my($OCT) = '(?:25[012345]|2[0-4]\d|1?\d\d?)';
51
52 my($IP) = $OCT . '\.' . $OCT . '\.' . $OCT . '\.' . $OCT . '\|' . $IPv6_re;
53
54 my $VERSION="0.1";
55 my $sig_class_id=1;
56 my $dump=0;
57 my ($hids_id,$hids,$hids_interface,$last_cid)=(undef, 'localhost', 'ossec',0);
58 my ($tempvar,$VERBOSE)=(0,0);
59 # ---------------------------------------------------------------------------
60 #  Arguments parsing
61 # ---------------------------------------------------------------------------
62  
63 while (@ARGV){
64         $_= shift @ARGV;
65         if ( m/^-h$|^--help$/){
66                 &help();
67         }elsif ( m/^-n$|^--noname$/){
68                 $conf{'resolve'}=0;
69         }
70 }
71
72
73 my $newrecord=0;
74 my %stats;
75 my %resolv;
76 my ($timestamp,$sec,$mail,$date,$alerthost,$alerthostip,$datasource,$rule,$level,$description,
77         $srcip,$dstip,$user,$text)=();
78 my $lasttimestamp=0;
79 my $delta=0;
80 ########################################################
81 my $datepath=`date "+%Y/%b/ossec-alerts-%d.log"`;
82 my $LOG='/var/ossec/logs/alerts/'. $datepath;
83 chomp $LOG;
84 $date='';
85 format TOPREPORT =
86  ==========================================================================================================================
87 |                                                  OSSEC-HIDS TOP                                                          |
88  ==========================================================================================================================
89 | Alert  |  Date                 | SRC          | DST          | LVL | Name                                                |
90  ==========================================================================================================================
91 .
92 format REPORT =
93 |@<<<<<  |@<<<<<<<<<<<<<<<<<<<<< |@<<<<<<<<<<<< |@<<<<<<<<<<<< |@<<< |@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< |
94 $rule,$date,$srcip,$dstip,$level,$description
95 .
96 #$~='REPORT';
97 #$~='TOPREPORT';
98
99 &taillog();
100 ###############################################################
101 sub taillog {
102    my($offset, $line, $stall) = '';
103
104    $offset = (-s $LOG); # Don't start at beginning, go to end
105
106         my $count=10;
107    while (1==1) {
108        sleep(1);
109         %resolv=();
110        $| = 1;
111        $stall += 1;
112         $datepath=`date "+%Y/%b/ossec-alerts-%d.log"`;
113         $LOG='/var/ossec/logs/alerts/'. $datepath;
114         chomp $LOG;
115         unless ( -f $LOG){print "Error -f $LOG\n"; next; }
116        if ((-s $LOG) < $offset) {
117            $offset = 0;
118        }
119
120         unless (open(TAIL, $LOG)){ print "Error opening $LOG: $!\n";next ;}
121
122         if (seek(TAIL, $offset, 0)) {
123            # found offset, log not rotated
124        } else {
125            # log reset, follow
126            $offset=0;
127            seek(TAIL, $offset, 0);
128        }
129        while (<TAIL>) {
130         if (m/^$/){
131                 $newrecord=1;
132                 next unless $timestamp;
133                 $count++;
134                 if ($count>10){
135                         system ("clear");
136                         $~='TOPREPORT';
137                         write;
138                         $count=0;
139                 }
140
141                 $alerthostip=$alerthost if $alerthost=~ m/^$IP$/;
142                 if ($alerthostip){
143                         $dstip=$alerthostip;
144                         $resolv{$alerthost}=$dstip;
145                 }else{
146                         if (exists $resolv{$alerthost}){
147                                 $dstip=$resolv{$alerthost};
148                         }else{
149                                 if ($conf{'resolve'}){
150                                         $dstip=`host $alerthost 2>/dev/null | grep 'has address\|has IPv6 address' `;
151                                         if ($dstip =~m/($IP)/ ){
152                                                 $dstip=$1;
153                                         }else{
154                                                 $dstip=$srcip;
155                                         }
156                                 }else{
157                                         $dstip=$alerthost;
158                                 }
159                                 $resolv{$alerthost}=$dstip;
160                                 
161                         }
162                 }
163                 $~='REPORT';
164                 write;
165                 ($timestamp,$sec,$mail,$date,$alerthost,$alerthostip,$datasource,$rule,$level,$description,
166                 $srcip,$dstip,$user,$text)=();
167                 next ;
168         }
169         if (m/^\*\* Alert ([0-9]+).([0-9]+):(.*)$/){
170                 $timestamp=$1;
171                 if ( $timestamp == $lasttimestamp){
172                         $delta++;
173                 }else{
174                         $delta=0;
175                         $lasttimestamp=$timestamp;
176                 }
177                 $sec=$2;
178                 $mail=$3;
179                 $mail=$mail ? $mail : 'nomail';
180 #2006 Aug 29 17:19:52 firewall -> /var/log/messages
181 #2006 Aug 30 11:52:14 192.168.0.45->/var/log/secure
182 #
183         }elsif ( m/^([0-9]+\s\w+\s[0-9]+\s[0-9]+:[0-9]+:[0-9]+)\s+(\S+)\s*->(.*)$/){
184                 $date=$1;
185                 $alerthost=$2;
186                 $datasource=$3;
187 #2006 Aug 29 17:33:31 (recepcao) 10.0.3.154 -> syscheck
188         }elsif ( m/^([0-9]+\s\w+\s[0-9]+\s[0-9]+:[0-9]+:[0-9]+)\s+\((.*?)\)\s+(\S+)\s*->(.*)$/){
189                 $date=$1;
190                 $alerthost=$2;
191                 $alerthostip=$3;
192                 $datasource=$4;
193         }elsif ( m/^([0-9]+\s\w+\s[0-9]+\s[0-9]+:[0-9]+:[0-9]+)\s(.*?)$/){
194                 $date=$1;
195                 $alerthost='localhost';
196                 $datasource=$2;
197         }elsif ( m/Rule: ([0-9]+) \(level ([0-9]+)\) -> '(.*)'$/ ){
198                 $rule=$1;
199                 $level=$2;
200                 $description= $3;
201         }elsif ( m/Src IP:/){
202                 if ( m/Src IP: (\S+)/){
203                         $srcip=$1;
204                 }else{
205                         $srcip='';
206                 }
207         }elsif ( m/User: (.*)$/){
208                 $user=$1;
209         }elsif( m/(.*)$/){
210                 $text .=$1;
211         }
212                 
213
214        } # End while read line
215        $offset=tell(TAIL);
216        close(TAIL);
217    }
218 }
219
220 sub version(){
221         print "OSSEC report tool $VERSION\n";
222         print "Licensed under GPL\n";
223         print "Contributor Meir Michanie\n";
224 }
225
226 sub help(){
227         &version();
228         print "List alerts generated by ossec."
229         . " More info in the doc directory .\n";
230         print "Usage:\n";
231         print "$0 [-h|--help] # This text you read now\n";
232         print "Options:\n";
233         print "\t-n|--noname\n";
234         
235         exit 0;
236 }
237
238
239 sub gracefulend(){
240         my ($signal)=@_;
241         close TAIL;
242         close STDOUT;
243         close STDERR;
244         exit 0;
245 }