#!/bin/ksh
#
# alert.sh: ver 1.4.2
# Lance Spitzner lance@spitzner.net
#
# Parse, log, and react to FW-1 User Defined Alerts
# For more information, please review the README
#


#################################################################
# 		BEGIN CUSTOMIZING SCRIPT HERE			#
#################################################################

# INSTALL DIRECTORY
# Define the directory that this script is in.
# Do NOT put a slash at the end.
# EXAMPLE: dir=/home/fwadmin/alert_1.4.2
dir=

# FW ADMIN
# Define the name of who gets the email alerts
# EXAMPLE: user=fwadmin@example.com
user=

# SCAN LIMIT
# Define maixmum number of scans/email alerts
limit=5

# EMAIL REMOTE SYSTEM
# Define as "true" if you want to automatically email
# the remote admin when you reach your scan limit.
email=false

# SAM
# Define as "true" if you want to autotmatically block
# the source if you reach your scan limit.
sam=false

# SAM TIMEOUT
# How long do you want the source blocked
# Default is 3600 seconds (1 hour).
timeout=3600


#################################################################
# 		FINISH CUSTOMIZING SCRIPT HERE			#
#################################################################



#################################################################
#                   DEFINE SYSTEM VARIABLES HERE	        #
#################################################################


### Script variables
message=/tmp/.message_$$
send=/tmp/.send_$$
MAIL=mail

### Good code is secure code
umask=177
PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin
export PATH

if [ -f $message ]; then
	rm $message
fi

if [ -f $send ]; then
	rm $send
fi

### Set trap in case of abrupt exit
trap "rm $send $message ; exit 5" 1 2 15

### Grab User Defined Alert log, pipe to $message.
cat - | tail -1 > $message

### Determine number of scans.
ip=`awk '{print $10}' $message`
number=`grep -c $ip $dir/alert.log`
scan=`expr $number + 1`

### Check number of scans.  If we have reached our limit, lets bail
### now and save CPU cycles.
if [ $scan -gt $limit ];then
	cat $message >> $dir/alert.log
        rm $message 
        exit 10  
fi

### Parse log file
date=`awk '{print $1}' $message`
time=`awk '{print $2}' $message`
dst=`awk '{print $12}' $message`

### Determine service (check some variables first)
#Determine if "Valid Address" is in log files for NAT
nat_check=`grep -c "(Valid Address)" $message`

#Determine if protocol is icmp
icmp_check=`grep -c " icmp " $message`

if [ "$nat_check" -eq 0 ];then
        if [ "$icmp_check" -eq 0 ];then
                service=`awk '{print $14}' $message`
        else
                service=`awk '{print $15,$16,$17,$18}' $message`
        fi
else
        if [ "$icmp_check" -eq 0 ];then
                service=`awk '{print $16}' $message`
        else
                service=`awk '{print $17,$18,$19,$20}' $message`
        fi
fi

#################################################################
# 			    FUNCTIONS   			#
#								#
#   Build your own modules here, such as paging or snmp_trap	#
#   alerts, then add them to Phase 3 in the script.		#
#################################################################


## This function checks to see if the source is an IP or hostname.
## If the source is an IP, it is resolved to a domain name.

Resolve () {

	echo $ip | awk -F"." '{print $NF }' | grep [0-9]

	if [ "$?" -eq 0 ]; then
		tmp=`nslookup $ip | grep Name: | awk '{print $2 }'`

		if [ "$tmp" != "" ]; then
			src=$tmp
		else
			src=$ip
		fi
	else
		src=$ip
	fi
	 

}

### This function determines who the admin is of the remote system
### and emails them about the scan.  Works only for .com, .edu, .net
### .mil, and .org.

TrackDown () {

# Define variables
dom=`echo $src | awk -F"." '{print $NF }'`
full_dom=`echo $src | awk -F"." '{print $(NF-1) }'`.$dom

# Start script, 1st check if it is a gTLD, if so, execute the following.
	if [ $dom = net ] || [ $dom = com ] || [ $dom = edu ] || [ $dom = org ] || [ $dom = mil ] || [ $dom = gov ]; then
		admin=`whois $full_dom | grep "@" | awk '{print $NF}' | head -1`
		tech=`whois $full_dom | grep "@" | awk '{print $NF}' | head -2 | tail -1`


$MAIL $admin,$tech,$user <<EOF
Subject: Your system $src may be scanning the Internet.

I logged your system $src scanning my network.
It looks like they are scanning for the $service vulnerability.
I recommend you research this, as $src
may be scanning other networks as well.  Please respond to this
message informing me what you have found.  If you require
assistance from me, I would be more then happy to provide it.  
Below is an example one of the multiple connections I received
from $src.

--- Logged Information ---

Source:   $src
Date:     $date
Time:     $time
Service:  $service

--- snip snip ---

This notification has been sent to 
$admin
$tech 
abuse@$full_dom

Please respond to $user for any issues concerning this.  
If you received this message in error, I apologize.

Thank you
EOF

	fi

}

## This function blocks the source IP scanning/probing our 
## network.  Edit 'fw sam' command to your taste.  For more
## info, typte 'fw sam'.

Block () {
	$FWDIR/bin/fw sam -t $timeout -i src $src

cat <<EOF >> $send
	WARNING
	Intruder $src has been temporarily blocked at the Firewall
	$src will be blocked for the next $timeout seconds
	To enable $src, type the following command on the Firewall
	$FWDIR/bin/fw sam -t $timeout -C -i src $src
EOF
}

#################################################################
# 			   THE SCRIPT   			#
#################################################################


### Resolve the IP address of $src if it is still in IP format.
### You may want to disable this to improve performance.
Resolve


### Build Email Alert
### This builds our email alert.  This happens for
### every alert, until we exceed our $limit.  If we exceed
### our limit, the script never gets to this point, because
### it will have already exited (see around line 95).

cat <<EOF > $send

You have received this message because someone is potentially 
scanning your systems.  The information below is the packet 
that was denied and logged by the Firewall. This is email alert
number $scan, with a limit of $limit from $src. 

	----- CRITICAL INFORMATION -----

	Date:        $date
	Time:        $time
	Source:      $src
	Destination: $dst
	Service:     $service

	----- ACTUAL FW-1 LOG ENTRY -----

`cat $message` 
EOF




### PHASES START: 
### What to do in addition to email alerts, depending on
### the number of scans.

# ##### PHASE 1 #####
# First unauthorized connection from the remote system.

if [ $scan -eq 1 ]; then

	## Add this system to our scan database file alert.uniq
	echo "$src	$date	$time 	$service" >> $dir/alert.uniq

# ##### PHASE 2 #####
# Second to $limit connections from the remote system

elif [ $scan -gt 1 ] && [ $scan -lt $limit ]; then

	## Add anything you would like for this.
	:

# ##### PHASE 3 #####
# We are pretty sure this is a port scan or probe, since the
# same source has connected to us $limit number of times.

else

	### Track down and email the admin of the remote system
	if [ $email = true ]; then
		TrackDown
	fi

	### Block source 
	if [ $sam = true ]; then
		Block
	fi
	
	echo "\nThis is alert number $scan, you have reached your" >> $send
	echo "maximum threshold. You will not receive anymore alerts". >> $send	

fi


### Send email alert and save log to alert.log

$MAIL -s "#### SCAN ALERT ####" $user < $send
cat $message >> $dir/alert.log

## All done, lets clean up after ourselves, just like Mom taught us :)
rm $message
rm $send

exit 0
