Re: Does snortsnarf work?

Ed Davison <[email protected]> Thu, 13 Feb 2003 11:54:01 -0600
Newsgroups gmane.comp.security.ids.snort.snarf
Message-ID <[email protected]>
--y0ulUmNC+osPPQO6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Thu, Feb 13, 2003 at 11:02:53AM -0600, Paul Schmehl wrote:
> On Thu, 2003-02-13 at 10:48, James Hoagland wrote:
> > 
> > Try running it from the command line and observe its memory and CPU 
> > use.  If these increase, it is working on processing alerts.  If 
> > there are alot of alerts to process, SnortSnarf can take a while. 
> > But it should eventually complete successfully.
> 
> I've done it from the commandline.  Just trying to process one day from
> the database takes at least two hours, and memory consumption
> continually increases until it's reached the limit.  (I'm using a 1.3
> GHz processor/1GB RAM FreeBSD box.)  I even ran it through cron last
> night.  No errors - no output.
> 
> One time when I ran it, I saw some warning messages about uninitialized
> values (coming from a perl module), but those aren't fatal, so they
> shouldn't keep it from finishing.
> 
> I'll try it again today and see if I can take a smaller sample.
> 

I do not know how much difference it will make or even what version
of the SnortDBInput.pm code you are running but I have made some changes
that I have been meaning to post to James Hoagland for inclusion in the
newer versions of the code.  I am going to attach it here and make sure
that it is on my website so that it is now publicly available.  Work has
been done to switch it to a more compatible DBI codebase and there has
been some speedup code added.  The speed of the queries is a big deal
but have never seen NO output from the code.  I will see what I can do
to help with this as well.

Ed Davison


--y0ulUmNC+osPPQO6
Content-Type: application/x-perl
Content-Disposition: attachment; filename="SnortDBInput.pm"
Content-Transfer-Encoding: quoted-printable

#!/usr/bin/perl =0A=0A# The SnortDBInput v.2=0A# original author Ed Davison=
 [[email protected]]=0A# modified by Aaron DeLashmutt [awd@awdonlin=
e.com]=0A=0A# SnortDBInput is an implentation of the SnortSnarf Input API w=
hich reads=0A# its input from databases produced by Snort using the databas=
e output plugin.=0A# Currently SnortDBInput is capable of accessing MySQL a=
nd Oracle through the=0A# DBI/DBD perl interface modules.=0A# http://search=
.cpan.org/author/TIMB/DBI-1.30/DBI.pm=0A# http://search.cpan.org/author/TIM=
B/DBD-Oracle-1.12/Oracle.pm=0A# http://search.cpan.org/author/JWIED/Msql-My=
sql-modules-1.2219/mysql/lib/DBD/mysql.pm=0A=0A# To use SnortDBInput, pass =
database information to SnortSnarf in the format=0A# user:password@database=
@host:port=0A# EX : snortsnarf.pl snort:@[email protected]=0A=0A# Please send=
 complaints, kudos, and especially =0A# improvements and bugfixes to awd@aw=
donline.com =0A=0A# -SnortSnarf-=0A# copyright (c) 2001 by Silicon Defense =
(http://www.silicondefense.com/)=0A# Released under GNU General Public Lice=
nse, see the COPYING file included=0A# with the distribution or http://www.=
silicondefense.com/software/snortsnarf/=0A# for details.=0A=0A=0Apackage Sn=
ortDBInput;=0A=0Ause MemAlert;=0Ause MemPacket;=0Ause Filter;=0Ause DBI;=0A=
use Socket;=0Ause Time::ParseDate;=0A=0Asub BEGIN {=0A    @cap_tasks=3D qw(=
snort spp_portscan spade);=0A    %cap_tasks=3D ();=0A    foreach (@cap_task=
s) {=0A        $cap_tasks{$_}=3D 1;=0A    }=0A}=0A=0Asub ref_to_url {=0A   =
 my($cite,$id)=3D @_;=0A    return undef unless defined($cite) && defined($=
id);=0A    if ($cite eq 'arachnids') {=0A        $id =3D~ s/^0+//;=0A      =
  return "http://whitehats.com\/IDS\/IDS$id";=0A    } elsif ($cite eq 'bugt=
raq') {=0A        return "http://www.securityfocus.com/bid/$id";=0A    } el=
sif ($cite eq 'cve') {=0A        return "http://cve.mitre.org/cgi-bin/cvena=
me.cgi?name=3D$id";=0A    } elsif ($cite eq 'mcafee') {=0A        return "h=
ttp://vil.nai.com/vil/dispVirus.asp?virus_k=3D$id";=0A    } elsif ($cite eq=
 'sid') {=0A        return "http://www.snort.org/snort-db/sid.html?id=3D$id=
";=0A    } elsif ($cite eq 'url') {=0A        return "http://$id";=0A    } =
else {=0A        return undef;=0A    }=0A}=0A=0A########## API functions ##=
############=0A=0A# API 'new' function to create an instance=0Asub new {=0A=
    my($class,$paramsref,$tasksref,$filter,@inputs)=3D @_;=0A    my(%tasks)=
=3D ();=0A    foreach (@{$tasksref}) {=0A        $tasks{$_}=3D 1 if $_ eq '=
all' || defined($cap_tasks{$_});=0A    }=0A=0A    my $dbmin =3D undef;=0A  =
  my $dbmax =3D undef;=0A    =0A    my @filters=3D (ref($filter) eq 'AndFil=
ter') ? @{$filter} : ($filter);=0A    my @unhfilters=3D ();=0A    foreach (=
@filters) {=0A        my $time=3D &Filter::known_mintime_filter($_);=0A    =
    if (defined($time)) {=0A            $dbmin=3D $time;=0A            next=
;=0A        }=0A        $time=3D &Filter::known_maxtime_filter($_);=0A     =
   if (defined($time)) {=0A            $dbmax=3D $time;=0A            next;=
=0A        }=0A        push(@unhfilters,$_);=0A    }=0A    my $myfilter=3D =
@unhfilters=0A        ? (@unhfilters > 1=0A            ? AndFilter->new(@un=
hfilters)=0A            : $unhfilters[0])=0A        : TrueFilter->new();=0A=
    =0A    my @ins=3D ();=0A    # @inputs is the text list of databases to =
grab stuff from, each in the form user:passwd@name@host:port=0A    my($lhs,=
$rhs,$user,$pass,$dbname,$hostport,$host,$port);=0A    foreach (@inputs) {=
=0A        ($lhs,$rhs)=3D split('@',$_,2);=0A        ($user,$pass)=3D split=
(':',$lhs,2);=0A        $pass=3D '' unless defined($pass);=0A        ($lhs,=
$rhs)=3D split('@',$rhs,2);=0A        if (defined($rhs)) {=0A            $d=
bname=3D $lhs;=0A            $hostport=3D $rhs;=0A        } else {=0A      =
      $dbname=3D 'snort'; =0A            $hostport=3D $lhs;=0A        }=0A =
       if ($hostport =3D~ /^(.*)\:(\d+)$/) {=0A            $host=3D $1;=0A =
           $port=3D $2;=0A        } else {=0A            $host=3D $hostport=
;=0A	    # need to default to specific database port=0A        }=0A        =
#encode the password by replacing ';' with \001; we assume \001 is not in t=
he password string=0A        $pass =3D~ tr/\;/\001/;=0A        push(@ins,jo=
in(';',$user,$pass,$dbname,$host,$port));=0A    }=0A    =0A    my $self=3D =
bless {=0A        'tasks' =3D> \%tasks, # requested tasks are the keys=0A  =
      'filter' =3D> $filter, # original filter=0A        'myfilter' =3D> $f=
ilter, # filter to apply=0A        'str' =3D> undef, # recreate string=0A  =
      'inputsleft' =3D> \@ins, # databases not yet processed, each in the f=
orm user;passwd;name;host;port=0A        'dbh' =3D> undef,=0A        'dbmin=
' =3D> $dbmin,=0A        'dbmax' =3D> $dbmax,=0A        'dbtext' =3D> '' # =
for alert 'source' fields=0A    }, $class;=0A=0A    # get opts=0A    my @pa=
rams=3D ();=0A    =0A    # if at some point there is a general user specifi=
ed option not tied to a particular =0A    # input source (for example in Sn=
ortFileInput the user can indicate how to infer an i=0A    # alerts year), =
e.g. 'foo', you would put that into the 'opts' hash with something like thi=
s=0A#    foreach (keys %$paramsref) {=0A#        if (/^foo$/) {=0A#        =
    $self->{'opt'}{$_}=3D $paramsref->{$_};=0A#        } else {=0A#        =
    warn "new: paramater $_ with value $paramsref->{$_} not understood, ign=
oring\n";=0A#            next;=0A#        }=0A#        push(@params,"$_:".$=
paramsref->{$_});=0A#    }=0A    =0A    # make the recreate string=0A    my=
 $paramstr=3D &Filter::join_strs(@params);=0A    $self->{'str'}=3D &Filter:=
:join_strs(join(',',keys %tasks),&Filter::as_str($filter),$paramstr,@inputs=
);=0A=0A    # set up per opts=0A=0A    # don't do much here, we don't even =
know if get() is going to be called, maybe on recreate_str() is=0A=0A    re=
turn $self;=0A}=0A=0A=0Asub recreate {=0A    my($class,$recreate_str)=3D @_=
;=0A    my($tasks,$filterstr,$params,@inputs)=3D &Filter::unjoin_strs($recr=
eate_str);=0A    my @tasks=3D split(',',$tasks);=0A    my $filter=3D &Filte=
r::from_str($filterstr);=0A    die "failed to recreate filter from string: =
$filterstr\n" unless defined($filter);=0A    my %params=3D map(split(':',$_=
,2),&Filter::unjoin_strs($params));=0A    return $class->new(\%params,\@tas=
ks,$filter,@inputs);=0A}=0A=0Asub recreate_str {=0A    return $_[0]->{'str'=
};=0A}=0A=0Asub task_capability {=0A    return @cap_tasks;=0A}=0A=0Asub get=
 {=0A    my $self=3D shift;=0A=0A# debug EBD=0A# print "* Entering get() ro=
utine\n";=0A# my $a =3D `free | grep Mem`;=0A# print "* $a";=0A    =0A    m=
y $got_an_alert=3D 0;=0A    do {=0A        # open a new input source unless=
 one is open (indicated by !defined($self->{'dbh'}))=0A        while (!defi=
ned($self->{'dbh'})) {=0A            # need to move to a new input source=
=0A            my $curinput=3D $self->{'curinput'}=3D shift(@{$self->{'inpu=
tsleft'}});=0A            return undef if (!defined($curinput)); # ran out =
of inputs; we're done!=0A            =0A# log the new data source=0A# open =
D, ">>.SnortDBInput.log";=0A# print D "------------------------------------=
--\n";=0A# my $d =3D `date`;=0A# print D $d . "\n\n";=0A# print D "Starting=
 new DB data source: " . $curinput . "\n";=0A# print D "Filter specified: "=
 . $self->{'filter'} . "\n";=0A# close D;=0A=0A            my ($user,$pwd,$=
db,$host,$port)=3D split(';',$curinput);=0A            $pwd =3D~ tr/\001/\;=
/; # decode encoded password=0A            $self->{'dbtext'}=3D "$user\@$db=
\@$host:$port";=0A=0A# debug EBD=0A# print "* Connecting to $host as $user\=
n";=0A=0A# this assumes an argument was passed with the default port=0A# sp=
ecific to the database. =0A	if ($port =3D=3D 3306) {=0A		$dbtype =3D "mysql=
";=0A		$dbh =3D DBI->connect("DBI:$dbtype:$db:$host:$port",$user, $pwd);=0A=
	} elsif ($port =3D=3D 1521) {=0A		$dbtype =3D "Oracle"; =0A		$dbh =3D DBI-=
>connect("DBI:$dbtype:host=3D$host;sid=3D$db;port=3D$port", $user, $pwd);=
=0A	} elsif ($port =3D=3D 5432) {=0A		$dbtype =3D "Pg"; =0A		$dbh =3D DBI->=
connect("DBI:$dbtype:host=3D$host;dbname=3D$db;port=3D$port", $user, $pwd);=
=0A	}=0A=0A            if (!defined $dbh) {=0A                warn "Error c=
onnecting to $host as $user; skipping\n";=0A                next;=0A       =
     }=0A            # got it open okay=0A            $self->{'dbh'} =3D $d=
bh;=0A            =0A            # possible todo: check to see if the datab=
ase follows the expected schema=0A            # if ($db_schema !=3D $our_sc=
hema) {=0A            #     warn "$curinput has schema $db_schema, but we o=
nly know $our_schema, we'll see how well this works";=0A            # }=0A =
           =0A            # get sth_event, num_rows, rowcount ready for cyc=
ling through the database=0A=0A            $q_event =3D "select sid, cid fr=
om event";=0A	    my $whereClause=3D'';=0A# debug EBD=0Aprint "* Staring qu=
ery: $q_event $whereClause\n";=0A            if (defined($self->{'dbmin'}))=
 {=0A                #if ($q_event =3D~ /where/) {=0A                if ($w=
hereClause =3D~ /where/) {=0A	             $whereClause .=3D " and ";	=0A  =
              } else { =0A		     $whereClause .=3D " where "; =0A		}=0A# de=
bug EBD=0Aprint "* Staring query: $q_event $whereClause\n";=0A# modify quer=
y format specific to the database.=0A	        if ($dbtype eq "mysql") {=0A =
                   $whereClause .=3D "unix_timestamp(timestamp) >=3D " . $s=
elf->{'dbmin'};=0A	        } elsif ($dbtype eq "Oracle") {=0A		    $whereCl=
ause .=3D "(to_char(timestamp,'J') -=0A        		to_char(to_date('01-JAN-19=
70','DD-MON-YYYY'),'J'))*86400 +=0A        		to_char(timestamp, 'SSSSS') >=
=3D " . $self->{'dbmin'};=0A	        } elsif ($dbtype eq "Pg") {=0A		    $w=
hereClause .=3D "(to_char(timestamp,'J') -=0A        		to_char(to_date('01-=
JAN-1970','DD-MON-YYYY'),'J'))*86400 +=0A        		to_char(timestamp, 'SSSS=
S') >=3D " . $self->{'dbmin'};=0A	        }=0A            }=0A=0A# debug EB=
D=0Aprint "* Staring query: $q_event $whereClause\n";=0A=0A            if (=
defined($self->{'dbmax'})) {=0A                #if ($q_event =3D~ /where/) =
{=0A                if ($whereClause =3D~ /where/) {=0A                    =
 $whereClause .=3D " and ";=0A                } else {=0A                  =
   $whereClause .=3D " where ";=0A                }=0A=0A# debug EBD=0Aprin=
t "* Staring query: $q_event $whereClause\n";=0A	        if ($dbtype eq "my=
sql") {=0A	    	    #$q_event .=3D " unix_timestamp(timestamp) <=3D " . $se=
lf->{'dbmax'};=0A	    	    $whereClause .=3D " unix_timestamp(timestamp) <=
=3D " . $self->{'dbmax'};=0A	    	} elsif ($dbtype eq "Oracle") {=0A       =
             $whereClause .=3D "(to_char(timestamp,'J') -=0A               =
     	to_char(to_date('01-JAN-1970','DD-MON-YYYY'),'J'))*86400 +=0A		      =
  to_char(timestamp, 'SSSSS') >=3D " . $self->{'dbmax'};=0A	    	} elsif ($=
dbtype eq "Pg") {=0A                    $whereClause .=3D "(to_char(timesta=
mp,'J') -=0A                    	to_char(to_date('01-JAN-1970','DD-MON-YYYY=
'),'J'))*86400 +=0A		        to_char(timestamp, 'SSSSS') >=3D " . $self->{'=
dbmax'};=0A		}=0A            }=0A=0A# debug EBD=0Aprint "* Staring query: $=
q_event $whereClause\n";=0A=0A	    $sth_event =3D $dbh->prepare("$q_event $=
whereClause");=0A            $sth_event->execute();=0A=0A# debug EBD=0A# pr=
int "* Complete with query\n";=0A# my $a =3D `free | grep Mem`;=0A# print "=
* $a";=0A# $state =3D "SELECT COUNT(*) FROM event $whereClause";=0A# $sth =
=3D $dbh->prepare($state);=0A# $sth->execute();=0A# $total_rows =3D $sth->f=
etchrow;=0A        =0A# debug EBD=0A# print "Total rows: $total_rows\n";=0A=
# open D, ">>.SnortDBInput.log";=0A# print D "Total rows in event table: " =
. $total_rows . "\n";=0A# close D;=0A=0A            $self->{'sth_event'} =
=3D $sth_event;=0A            $self->{'num_rows'} =3D $total_rows;=0A      =
      $self->{'rowcount'} =3D 0;=0A        } #end of do=0A=0A        my $to=
tal_rows =3D $self->{'num_rows'};=0A        my $rowcount =3D $self->{'rowco=
unt'};=0A        my $sth_event =3D $self->{'sth_event'};=0A=0A# debug EBD=
=0A# printf "* Current row =3D %d (%5.2f %%)\n", $rowcount, ($rowcount/$tot=
al_rows);=0A =0A        @query_results =3D $sth_event->fetchrow_array;=0A  =
      $self->{'rowcount'} =3D $rowcount + 1;=0A    =0A# debug EBD=0A# if ($=
rowcount > 500000) {=0A#     return undef;=0A# }=0A=0A# debug EBD=0A# if (!=
($rowcount % 50000)) {=0A# 	open D, ">>.SnortDBInput.log";=0A# 	print D "* =
Current row:" . $rowcount . "\n";=0A# 	close D;=0A# }=0A=0A        unless (=
@query_results) { # ran out of events here=0A            # clean up databas=
e here=0A            $self->{'sth_event'}=3D undef;=0A            $self->{'=
dbh'}=3D undef; # indicate that we need a new input source=0A        } else=
 {=0A            $alert =3D $self->make_alert($query_results[0],$query_resu=
lts[1]);=0A            if (defined $alert) {=0A# debug EBD=0A# print "* Ale=
rt is valid\n";=0A# print "* Alert: ".$alert."\n";=0A# $alert->debug_print(=
'*   ',STDOUT);=0A                $got_an_alert=3D=0A                    (d=
efined($self->{'tasks'}{'all'})=0A                    || defined($self->{'t=
asks'}{$alert->type()})) # make sure it matches one of our tasks=0A        =
            && $self->{'myfilter'}->test($alert); # make sure it passes our=
 filter too=0A            } else {=0A            $got_an_alert =3D undef;=
=0A            }=0A            unless ($got_an_alert) {=0A# debug EBD=0A# o=
pen D, ">>.SnortDBInput.log";=0A# print D "* alert did not pass type test o=
f the filter test\n";=0A# close D;=0A            }=0A        }=0A    } unti=
l ($got_an_alert);=0A=0A# debug EBD=0A# if (!defined $alert) {=0A# 	open D,=
 ">>.SnortDBInput.log";=0A# 	print D "* alert undefined\n";=0A# 	close D;=
=0A# }=0A        =0A    return $alert;=0A}=0A=0A########## end of API funct=
ions ##############=0A=0A=0A# if this parsed or unparsed alert is an anomal=
y report, return the anomaly=0A# score otherwise return undef=0Asub is_anom=
_rept {=0A    my($alert)=3D shift;=0A    my $text=3D ref($alert) ? $alert->=
{'sig'} : $alert;=0A    $text =3D " ";=0A    if ($text =3D~ /(spp_anomsenso=
r|Spade):\s*Anom[ao]ly threshold exceeded:\s*(\d+\.\d+)/i) {=0A        retu=
rn $2;=0A    } else {=0A        return undef;=0A    }=0A}=0A=0A# parses giv=
en sid, cid in snort db into an instance of MemAlert=0Asub make_alert {=0A =
   my($self,$sid,$cid)=3D @_;=0A=0A# debug EBD=0A# print "** Entering make_=
alert() routine\n";=0A=0A    my $aid =3D "snortdb:".$sid.":".$cid;=0A    my=
 $dbh =3D $self->{'dbh'};=0A=0A    #some default values=0A    my $src_port =
=3D 0;=0A    my $dst_port =3D 0;=0A=0A    my $alert =3D MemAlert->new($aid)=
;=0A    my $pkt =3D MemPacket->new();=0A    $alert->add_packets($pkt);=0A  =
  $alert->set('source' =3D> $self->{'dbtext'}.'-'."$sid:$cid");=0A=0A# debu=
g EBD=0A# print "** Grabbing alert for cid =3D $cid and sid =3D $sid\n";=0A=
    my $q;=0A    if ($dbtype eq "mysql") {=0A   	 $q =3D "select * from eve=
nt where cid =3D $cid and sid =3D $sid";=0A    } elsif ($dbtype eq "Oracle"=
) {=0A    	$q =3D "select sid,cid,signature,to_char(timestamp, 'yyyy-mm-dd =
hh24:mi:ss') =0A		from event where cid =3D $cid and sid =3D $sid";=0A    } =
elsif ($dbtype eq "Pg") {=0A    	$q =3D "select sid,cid,signature,to_char(t=
imestamp, 'yyyy-mm-dd hh24:mi:ss') =0A		from event where cid =3D $cid and s=
id =3D $sid";=0A    }=0A    $sth =3D $dbh->prepare($q);=0A    $sth->execute=
();=0A    my @event =3D $sth->fetchrow_array;=0A    my ($datetext,$timetext=
) =3D split / /, $event[3];=0A    my ($year,$month,$day) =3D split /-/, $da=
tetext;=0A    my $utime =3D Time::ParseDate::parsedate($event[3], 'FUZZY' =
=3D> 1);=0A    $alert->set('utime' =3D> $utime);=0A=0A# debug EBD=0A# open =
D, ">>.TimeFilter.log";=0A# print D "** utime real: ".$utime." alert value:=
 ".$alert->utime()."\n";=0A# close D;=0A        =0A# debug EBD=0A# print "S=
ID: ".$event[0]."\n";=0A# print "CID: ".$event[1]."\n";=0A# print "Date: ".=
$datetext."\n";=0A# print "Time: ".$timetext."\n";=0A=0A# debug EBD=0A# pri=
nt "** Grabbing signature data for sig_id =3D $event[2]\n";=0A=0A    $q =3D=
 "select * from signature where sig_id =3D $event[2]";=0A    $sth =3D $dbh-=
>prepare($q);=0A    $sth->execute();=0A    @signature =3D $sth->fetchrow_ar=
ray;=0A    my $sig_text =3D $signature[1];=0A    my $priority =3D $signatur=
e[3];=0A# look for snort signature reference (sid)=0A# add the reference to=
 the alert=0A    if (defined($signature[5])) {=0A	my $url=3D &ref_to_url('s=
id',$signature[5]);=0A        $alert->add_ref('sid',$signature[5],$url);=0A=
    }=0A=0A# additional code to look for other site references such=0A# as =
arachnids, cve, bugtraq, etc=0A    $q =3D "select reference.ref_tag, ref_sy=
stem_name=0A    from reference_system, sig_reference, reference, signature=
=0A    where signature.sig_id=3D$event[2] and=0A    sig_reference.ref_id=3D=
reference.ref_id and=0A    signature.sig_id=3Dsig_reference.sig_id and=0A  =
  reference.ref_system_id=3Dreference_system.ref_system_id";=0A    $sth =3D=
 $dbh->prepare($q);=0A    $sth->execute();=0A    my @extranfo;=0A    while =
((@extranfo) =3D $sth->fetchrow_array) {=0A	if (defined($extranfo[1])) {=0A=
		my $url=3D &ref_to_url($extranfo[1],$extranfo[0]);=0A		$alert->add_ref($e=
xtranfo[1],$extranfo[0],$url);=0A        }=0A    }=0A    =0A# debug EBD=0A#=
 print "** Signature: ".substr($sig_text,0,50)."\n";=0A=0A    my $anom=3D &=
is_anom_rept($sig_text);=0A    if (defined($anom)) {=0A        $pkt->set('a=
nom' =3D> $anom);=0A        $alert->set('type' =3D> 'spade');=0A    } else =
{=0A        $pkt->set('anom' =3D> undef);=0A        if ($sig_text =3D~ /spp=
_portscan/) {=0A            $alert->set('type' =3D> 'spp_portscan');=0A    =
        return undef;=0A        } else {=0A            $alert->set('type' =
=3D> 'snort');=0A        }=0A    }=0A=0A# debug EBD=0A# print "** Grabbing =
iphdr info for cid =3D $cid and sid =3D $sid\n";=0A=0A    $q =3D "select si=
d,cid,ip_src,ip_dst,ip_ver,ip_hlen,ip_tos,ip_len,=0A	  ip_id,ip_flags,ip_of=
f,ip_ttl,ip_proto,ip_csum from =0A	  iphdr where cid =3D $cid and sid =3D $=
sid";=0A    $sth =3D $dbh->prepare($q);=0A    $sth->execute();=0A    my @ip=
hdr =3D $sth->fetchrow_array;=0A    my $src_address =3D $iphdr[2];=0A    my=
 $dst_address =3D $iphdr[3];=0A# convert the hex value ip address=0A# to de=
cimal=0A    my $convert =3D sprintf "%08lx", $src_address;=0A    my $a =3D =
hex (substr ($convert,0,2));=0A    my $b =3D hex (substr ($convert,2,2));=
=0A    my $c =3D hex (substr ($convert,4,2));=0A    my $d =3D hex (substr (=
$convert,6,2));=0A    $src_address =3D "$a\.$b\.$c\.$d";=0A    $convert =3D=
 sprintf "%08lx", $dst_address;=0A    $a =3D hex (substr ($convert,0,2));=
=0A    $b =3D hex (substr ($convert,2,2));=0A    $c =3D hex (substr ($conve=
rt,4,2));=0A    $d =3D hex (substr ($convert,6,2));=0A    $dst_address =3D =
"$a\.$b\.$c\.$d";=0A=0A    my $protocol =3D $iphdr[12];=0A    my $ttlstuff =
=3D "TTL:" . $iphdr[11] . " TOS:" . $iphdr[6] . " ID:" . $iphdr[8];=0A    $=
ttlstuff =3D $ttlstuff . " IpLen:" . $iphdr[5] . " DgmLen:" . $iphdr[7];=0A=
=0A    my $otheropts=3D '';=0A    my $prototext=3D "PROT$protocol";=0A    $=
src_port=3D undef;=0A    $dst_port=3D undef;=0A    if ($protocol =3D=3D 1) =
{=0A# ICMP protocol=0A# debug EBD=0A# print "** Grabbing icmphdr for cid =
=3D $cid and sid =3D $sid\n";=0A=0A        $q =3D "select * from icmphdr wh=
ere cid =3D $cid and sid =3D $sid";=0A        $sth =3D $dbh->prepare($q);=
=0A        $sth->execute();=0A        my @icmphdr =3D $sth->fetchrow_array;=
=0A        $pkt->set('protocol' =3D> 'ICMP');=0A        $prototext =3D "ICM=
P";=0A        # add code to decode icmp_type into string=0A        $pkt->se=
t('flags' =3D> $icmphdr[2]);=0A        $otheropts =3D "Type:" . &numtext($i=
cmphdr[2]) . " Code:" . &numtext($icmphdr[3]);=0A        $otheropts =3D $ot=
heropts . " ID:" . &numtext($icmphdr[5]) .=0A                              =
  " Seq:" . &numtext($icmphdr[6]);=0A    } #end of ICMP protocol=0A=0A    i=
f ($protocol =3D=3D 6) {=0A# TCP protocol=0A# debug EBD=0A# print "** Grabb=
ing tcphdr for cid =3D $cid and sid =3D $sid\n";=0A=0A        $q =3D "selec=
t * from tcphdr where cid =3D $cid and sid =3D $sid";=0A        $sth =3D $d=
bh->prepare($q);=0A        $sth->execute();=0A        my @tcphdr =3D $sth->=
fetchrow_array;=0A        $src_port =3D $tcphdr[2];=0A        $dst_port =3D=
 $tcphdr[3];=0A        $pkt->set('protocol' =3D> 'TCP');=0A        $protote=
xt =3D "TCP";=0A        my $flags=3D &tcpflags_num_to_str($tcphdr[8]);=0A  =
      $pkt->set('flags' =3D> $flags);=0A        $otheropts =3D $flags . " S=
eq:" . &numtext($tcphdr[4]) . " Ack:" . &numtext($tcphdr[5]);=0A        $ot=
heropts =3D $otheropts . " Win:" . &numtext($tcphdr[9]);=0A    } #end of TC=
P protocol=0A    =0A    if ($protocol =3D=3D 17) {=0A# UDP protocol=0A# deb=
ug EBD=0A# print "** Grabbing udphdr for cid =3D $cid and sid =3D $sid\n";=
=0A=0A        $q =3D "select * from udphdr where cid =3D $cid and sid =3D $=
sid";=0A        $sth =3D $dbh->prepare($q);=0A        $sth->execute();=0A  =
      my @udphdr =3D $sth->fetchrow_array;=0A        $src_port =3D $udphdr[=
2];=0A        $dst_port =3D $udphdr[3];=0A        $pkt->set('protocol' =3D>=
 'UDP');=0A        $prototext =3D "UDP";=0A        $otheropts =3D "";=0A   =
 } #end of UDP protocol=0A=0A    if (defined($signature[2])) {=0A# debug EB=
D=0A# print "** Grabbing sig_class for sig_class_id =3D $signature[2]\n";=
=0A=0A        $q =3D "select * from sig_class where sig_class_id =3D $signa=
ture[2]";=0A        $sth =3D $dbh->prepare($q);=0A        $sth->execute();=
=0A        my @classinfo =3D $sth->fetchrow_array;=0A        my $classifica=
tion =3D $classinfo[1];=0A        $alert->set('classification_text' =3D> $c=
lassification);=0A    }=0A=0A    $alert->set('message' =3D> $sig_text);=0A =
   $alert->set('priority_num' =3D> $priority);=0A    $pkt->set('sip' =3D> $=
src_address, 'dip' =3D> $dst_address, =0A        'sport' =3D> $src_port, 'd=
port' =3D> $dst_port,=0A        'month' =3D> $month, 'day' =3D> $day, 'tod_=
text' =3D> $timetext,=0A        'year' =3D> $year=0A    );=0A    =0A    my =
$alert_text =3D "[**] $sig_text [**]\n";=0A    #push (@ptext, "[**] $sig_te=
xt [**]");=0A    my $pkt_text =3D "$datetext:$timetext ";#[smac] -> [dmac] =
type:[val] len:[val]\n";=0A    #push (@ptext, "$datetext:$timetext [smac] -=
> [dmac] type:[val] len:[val]");=0A    $pkt_text =3D $pkt_text . "$src_addr=
ess";=0A    $pkt_text =3D $pkt_text . ":$src_port" if defined($src_port);=
=0A    $pkt_text =3D $pkt_text . " -> $dst_address";=0A    $pkt_text =3D $p=
kt_text . ":$dst_port" if defined($src_port);=0A    $pkt_text =3D $pkt_text=
 . "\n";=0A    #push (@ptext, "$src_address:$src_port -> $dst_address:$dst_=
port ");=0A    $pkt_text =3D $pkt_text . $prototext . " " . $ttlstuff;=0A  =
  #push (@ptext, $prototext . " " . $ttlstuff);=0A    $pkt_text =3D $pkt_te=
xt . "\n" . $otheropts if length($otheropts);=0A    #push (@ptext, $otherop=
ts);=0A    $alert_text.=3D $pkt_text;=0A# print "got: $alert_text\n";=0A   =
 =0A    $pkt->set('text' =3D> $pkt_text, 'text_format' =3D> 'snortdb-full-p=
kt');=0A    $alert->set('text' =3D> $alert_text, 'text_format' =3D> 'snortd=
b-full-alert');=0A    # $pkt->set('as_text' =3D> @ptext);=0A    # $alert->s=
et('text_format' =3D> $pkt_text);=0A    =0A#    $alert->add_packets($pkt);=
=0A=0A# debug EBD=0A# print "** Leaving make_alert() routine\n";=0A=0A    r=
eturn($alert);=0A}=0A=0Asub tcpflags_num_to_str {=0A    my $flagnum=3D shif=
t;=0A    return '' unless defined($flagnum);=0A    my $str=3D '';=0A    $st=
r.=3D ($flagnum & 0x80) ? '1' : '*';=0A    $str.=3D ($flagnum & 0x40) ? '2'=
 : '*';=0A    $str.=3D ($flagnum & 0x20) ? 'U' : '*';=0A    $str.=3D ($flag=
num & 0x10) ? 'A' : '*';=0A    $str.=3D ($flagnum & 0x08) ? 'P' : '*';=0A  =
  $str.=3D ($flagnum & 0x04) ? 'R' : '*';=0A    $str.=3D ($flagnum & 0x02) =
? 'S' : '*';=0A    $str.=3D ($flagnum & 0x01) ? 'F' : '*';=0A    return $st=
r;=0A}=0A=0Asub numtext {=0A    my $num=3D shift;=0A    return $num if defi=
ned($num);=0A    return '';=0A}=0A=0A1;=0A
--y0ulUmNC+osPPQO6--