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