#!/usr/bin/perl print "Content-type: text/html \n\n"; use Time::Local; use Time::localtime; use Fcntl; ######################################### # There are modules: # # sub ip_to_num IP to number # # sub num_to_ip number to IP # # sub tm_to_td time-mark to time-date # # sub dt_to_tm # # sub lined # line conversion # # sub ip_ill # # sub L_record Length>250 # # sub rec_len # # sub avr_rms # # sub rec_dens > 3 requests per sec # # sub slash # # sub delta # # sub ill_tex # # sub graph # ######################################### sub rec_dens { # High request density. The fact is detected outside # rec_dens($line,\$ipd); $line=$_[0]; print "li=",$line,"\n"; local *ipd=$_[1]; my @L=split/\s+/,$line; # Split request line into words $ip=$L[0]; # fix IP if(exists($ipd{$ip})) { # length-hash updating<># $ipd{$ip}=$ipd{$ip}+1; # } # else{$ipd{$ip}=1;} # hash init print "IP=",$ip," n=",$ipd{$ip},"\n"; return(%ipd); } sub graph { # Making up a picture from the file # use graf_dec; use Fcntl; $path1="/home/httpd/htdocs/saturn/attacks/ids1/rec_len.png"; $pa="/home/httpd/htdocs/saturn/attacks/ids/"; # input path $in_file="lengths.txt"; #$img = &vert_diagr(15,600,400,15,'/home/httpd/htdocs/saturn/attacks/ids/lengths.txt',$path1,1,7,3,$img,25); my $file=$pa.$in_file; #print "name=",$file,"\n"; $img = &vert_diagr(15,600,400,15,$file,$path1,1,7,3,$img,25); sysopen(PICTURE, $path1, O_RDWR|O_CREAT) or die ("Cannot open file for writing"); binmode PICTURE; print PICTURE $img->png; close PICTURE; $path2='/home/httpd/htdocs/saturn/attacks/ids1/long_req.png'; $img = &vert_diagr(15,600,400,15,'/home/httpd/htdocs/saturn/attacks/ids/long_req.txt',$path2,1,7,3,$img,25); sysopen(PICTURE,$path2, O_RDWR|O_CREAT) or die("Cannot open file for writing"); binmode PICTURE; print PICTURE $img->png; close PICTURE; use Chart::Gnuplot; # Plot the data set on the chart #print "GNUPLOT\n"; my $chart = Chart::Gnuplot->new( output => "/home/semenov/delta1.ps" ); my $dataSet=Chart::Gnuplot::DataSet->new( datafile => "/home/httpd/htdocs/saturn/attacks/ids/delta.txt", style => "boxes" ); return(); } sub avr_rms { use Fcntl; my $i; my @lengths; $p=$_[0]; # path to $pp=$_[1]; # path to for($i=0;$i<2000;$i++) {$lengths[$i]=0;} # The output file # Opening the output file sysopen(FH, $pp, O_RDWR|O_TRUNC|O_CREAT) or die "Can't start tst1: $! \n"; # Output distribution ################################################################# # Average record length and root mean square # # diviation calculation # # Opening the input file (input parameter) # # Output is and # ################################################################# my $k; my $line; my $len; my $num; my $D=10000; my $sigm=10000; my $len_avr=10000; my $step=50; sysopen(FHH, $p, O_RDWR|O_CREAT) or die "Can't start tst2: $!\n"; # input rec_leng.txt my $s_length=0; my $tot_num=0; while (!eof(FHH)) { # Cycle for -file ######### $line=readline(FHH); # @L=split/\s+/,$line; # $len=$L[0]; # record length # $num=$L[1]; # number of such records # $s_length=$s_length+$len*$num; # $tot_num=$tot_num+$num; # $k=int($len/$step); # $lengths[$k]=$lengths[$k]+$num; # } # end of WHILE ######### if($tot_num>0) { my $len_avr=$s_length/$tot_num; } #print "S_len=",$s_length," N_num=",$tot_num," avr=",$len_avr,"\n"; close(FHH); sysopen(FHH, $p, O_RDWR|O_CREAT) or die$!; while (!eof(FHH)) { # for rec_leng.txt ######### $line=readline(FHH); # my @L=split/\s+/,$line; # $len=$L[0]; # record length # $num=$L[1]; # number of such records # $s_length=$s_length+($len-$len_avr)*($len-$len_avr)*$num; # } # end of WHILE ######### if($tot_num>0) { my $D=$s_length/$tot_num; # length dispersion } if($D>0) { my $sigm=sqrt($D); # root mean square deviation } for($k=0;$k<40;$k++) { print FH $k*50," ",$lengths[$k],"\n"; } $p_reqv="/home/httpd/htdocs/saturn/attacks/ids1/req_num.txt"; # Output total rec_num & total length sysopen(Freq, $p_reqv, O_RDWR|O_TRUNC|O_CREAT) or die "Can't start tst3: $!\n"; # print Freq $sigm," ",$len_avr,"\n"; # writing into the file #print "D=",$sigm," AVR=",$len_avr,"\n"; close(Freq); # close close(FH); # close close(FHH); # close return; } sub rec_len { # rec_len($length); # Request length distribution calculation my $length=$_[0]; *len=$_[1]; if(exists($len{$length})) { # length-hash updating ## $len{$length}=$len{$length}+1; # #print "len=",$length," n=",$len{$length},"\n"; # } ######### else{$len{$length}=1;} # hash init ######### #print "len=",$length," n=",$len{$length},"\n"; # return; } sub L_record { # L_record($line); # IP-distribution for requests longer than 250 symbols # buffer overflow attacks $line=$_[0]; *long_req=$_[1]; @L=split/\s+/,$line; # Split request line into words $ip=$L[0]; # IP-address $length=$L[3]; # request length if($length>250) { # Too long record development ### if(exists($long_req{$ip})) { # # #print "L=",$length," IP=", $ip,"\n"; $long_req{$ip}=$long_req{$ip}+1; # # } # # else{$long_req{$ip}=1;} # hash init # } ######### return(); } sub ip_ill { # illegal HTTP-methods detection # input: $line -> current record; %ipb; # ip_ill($line,\%ipa); IP - number for ANY ill-method my $nm; @forbid=('PUT','TRACE','DELETE','OPTIONS','PROPFIND'); my $line=$_[0]; my @L=split/\s+/,$line; # Split request line # $ip=$L[0]; # extract IP *ipa=$_[1]; # output hash-array my $meth=$L[2]; for($nm=0;$nm<$#forbid+1;$nm++) { ## cycle for forbid meth ######### if($meth eq $forbid[$nm]) { ######### # #print "meth=", $meth," forb=",$forbid[$nm],"\n"; # # if(exists($ipa{$ip})) { # IP-hash updating ######### # # $ipa{$ip}=$ipa{$ip}+1; # # # } ######### # # else{$ipa{$ip}=1;} } # hash init ######### # } ######### return; } ######################################### sub lined { # Input = access_log line # Output= Ip TM method length pass_traversal_flag (0= no; 1= pass_trav) my $where=0; $line=$_[0]; my @L=split//,$line; # Split request line my $lin=""; my $length=$#L; # Symbols number @L=split/\s+/,$line; # Split request line into words $ip=$L[0]; $li[0]=$ip; my $d_t=$L[3]; # date-time $d_t=substr $d_t,1,20; $tm=dt_to_tm($d_t); $li[1]=$tm; $meth=$L[5]; my $meth=substr $meth,1; #print "meth=",$meth,"\n"; $li[2]=$meth; $where=index($line,"////"); # look for path traversal if($where==-1) {$where=0;} else{$where=1;} $li[4]=$where; # $li[3]=$length; $lin=$lin.$li[0]." ".$li[1]." ".$li[2]." ".$li[3]." ".$li[4]; #print "LIN=",$lin,"\n"; return $lin; } sub slash { # slash($line,\%ipb); # PASS TRAVERSAL attack distribution (Slash attack) my $line=$_[0]; *ipb=$_[1]; my @L=split/\s+/,$line; # Split request line into words my $ip=$L[0]; #print "Ip=",$ip,"\n"; $where=$L[4]; # look for path traversal if($where==1) { ######### if(exists($ipb{$ip})){ # IP-hash updating ######### # $ipb{$ip}=$ipb{$ip}+1; # # # } ######### # else{$ipb{$ip}=1;} # HASH INIT # } # end for WHERE!=-1 ######### return; } sub ill_tex { my $nm; # wtiting request lines with ill-methods into file #my $il; #my @ill; @forbid=('PUT','TRACE','DELETE','OPTIONS','PROPFIND'); my $line=$_[0]; $ip=$L[0]; # IP-address $lin=$_[1]; # coverted request line my @L=split/\s+/,$lin; # Split request line# $il=$_[2]; *ill=$_[3]; $meth=$L[2]; for($nm=0;$nm<$#forbid+1;$nm++) { ## cycle for forbid methods #### if($meth eq $forbid[$nm]) { ######### forbidden method print "LINE=",$line,"\n"; $ill[$il]=$line; # # ???? print "IL=",$ill[0],"\n"; $il++; # # } ######################### # } ################# return(@ill); } ######################################################################### sub ip_to_num # { # ######################################### # # IP-address to a number conversion # # ######################################### # my @Lm; # my ($s)=$_[0]; # @Lm=split/\./,$s; # if($#Lm < 3) {return -1;} # else { return ((((($Lm[0]<<8)+$Lm[1])<<8)+$Lm[2])<<8)+$Lm[3]; # } # } ######### ######################################################################### # A number to IP-address conversion # ######################################################################### sub num_to_ip ######### { # $n=$_[0]; # my $ip=$n>>24; # the first number # $ip=$ip.".".($n>>16)%256; # the second number # $ip=$ip.".".($n>>8)%256; # the third number # $ip=$ip.".".$n%256; # return($ip); # } ######### ######################################################################### # Time-mark to Date and Time conversion # ######################################################################### sub tm_to_td ######### { # use Time::localtime; # my @mon=("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"); my $tk=$_[0]; # $tm=localtime($tk); # $seconds=$tm->sec; # $mins=$tm->min; # $hour=$tm->hour; # $year=$tm->year+1900; # $month=$tm->mon; # $month=$mon[$month]; # $day=$tm->mday; # $dt=$day."/".$month."/".$year.":".$hour.":".$mins.":".$seconds;# return($dt); # } # ######################################################################### ######################################################## # Date-Time conversion to TM (TM=time-mark) # # additional output - mins from the day beginning # ######################################################## sub dt_to_tm ######### { # use Time::Local; # my $i; # @mon=("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"); my $date_time=$_[0]; # my @MMM=split(/\:/,$date_time); # if($#MMM==3){ # date terms number control # my $date=$MMM[0]; # my @NNN=split(/\//,$date); # if(!(defined$NNN[0])) {$NNN[0]=1;} # my $mday=$NNN[0]; # if(!(defined$NNN[1])) {$NNN[1]=1;} # my $month=$NNN[1]; # for($i=0;$i<12;$i++){if($month eq $mon[$i]){$month=$i;}} # if(!(defined$NNN[2])) {$NNN[2]=2;} # my $year=$NNN[2]; # $year=$year-1900; # if(!(defined$MMM[1])) {$MMM[1]=1;} # my $hours=$MMM[1]; # if(!(defined$MMM[2])) {$MMM[2]=1;} # my $minutes=$MMM[2]; # if(!(defined$MMM[3])) {$MMM[3]=1;} # my $seconds=$MMM[3]; # my $cur_TIME=timelocal($seconds,$minutes,$hours,$mday,$month,$year); return ($cur_TIME); # } # } ######### sub delta { ######################################### # and # ######################################### use Fcntl; my $i; my $star_TIME=$_[0]; local *bins=$_[1]; my $p_rec="/home/httpd/htdocs/saturn/attacks/ids/"; # form the pass for the file my $p_del=$p_rec."delta.txt"; # /home/httpd/htdocs/saturn/attacks/ids/delta.txt my $p1_del="/home/httpd/htdocs/saturn/attacks/ids/delta1.txt"; sysopen(AFT,$p_del,O_RDWR|O_TRUNC|O_CREAT) or die$!; sysopen(AFT1, $p1_del, O_RDWR|O_TRUNC|O_CREAT) or die$!; for($i=0;$i<1440;$i++) { # minute intervals ######### $tm[$i]=$star_TIME+($i)*60+30; # if($bins[$i] eq "") {$bins[$i]=0;} # print AFT1 $tm[$i]," ",$bins[$i],"\n"; # print AFT $i," ",$bins[$i],"\n"; # growth rate evolution # } ######### close(AFT); # close file close(AFT1); # close file return; }