#!/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;
}