#!/bin/bash# nmap-scanner.sh V1.0# My friend N8 had the great idea of nmaping a netblock and then running a diff to see if any new ports (HACKERS!!)# appeared on his network or any old ports had vanished (daemon died!!). He posted about it on his blog page at# http://www.mybrainhurts.com/blog/2009/03/automated-nmap-scans.html# I really liked his idea but struggled a little with the implementation since i wanted the script to be noisy# at first (for testing) and quiet later. I started hacking in commandline switches and changing the generic# Bourne shell code into BASH code, and here is the no longer terse result.##REQUIREMENTS# *Nmap# *Cron (for automation)##INSTALL# The first time you run the script you need to start it with the -i option to initilize the data files. You will get an error otherwise.# This script is designed to be placed in your root crontab file (via crontab -e), here is an example entry (the -q makes it quiet).# 32 15 * * * /usr/local/bin/nmap-scanner.sh -q# The following 4 options are overwriteable via commandline switches, run script with -h for options.

EMAIL=""# Optional email address to notify, defaults to STDOUT if none listedBASE_DIR="/var/log/nmap/scans"# Directory to store the nmap logfilesNETWORKS=(127.0.0.1192.168.0.1-254)# Networks to scan, space delimited for multiple networksINIT=0# Set to 1 via -i option upon first run of script to seed the logfile

#Check that nmap is installed and in their current pathif! which nmap >/dev/null 2>&1;then
die "Sorry $0 requires NMAP to be installed and in your path of ($PATH)"fi

mkdir -p "${BASE_DIR}" >/dev/null 2>&1

TODAY=$(date +%Y%m%d-%s)for NETWORK in${NETWORKS[@]};doDIR="$BASE_DIR/${NETWORK}"mkdir-p"$DIR/state/"#create a directory for each network to be scanned, and a state directory for tracking last scan symlinksif!mv-f${DIR}/state/new ${DIR}/state/old;then#Rename the symlink for the newest scan to old (overwriting the old symlink in the process)if[[${INIT}-eq0]];then
die "An error occured while trying to roll off the log of the last scan. If this is first time running $0 use the --init option to override"fifiif[[-z$QUIET]];thenecho -ne "\nScanning network:${NETWORK}:\n"fiif nmap -R -sS ${NETWORK} -oN $DIR/${TODAY}.nmap >/dev/null 2>&1;then#Actually perform the nmap scan
ln -fs ${DIR}/${TODAY}.nmap ${DIR}/state/new #create the .new symlink for this networkif[[${INIT}-eq1]];then
ln -fs ${DIR}/${TODAY}.nmap ${DIR}/state/old #if this is the first run (--init) then seed old with newfielse
die "An errror occured while trying to nmap the network:${NETWORK}"fi

#check for diffrences between this run and the last runDIFF=$(diff -C0 --show-function-line='Interesting' --ignore-matching-lines='^#'${DIR}/state/new ${DIR}/state/old |grep -v '\*\*\*'|grep -v '\-\-\-')if[[$?-eq2]];then
die "the diff of ( ${DIR}/state/new ${DIR}/state/old) failed to execute properly"fi

if[[-n${DIFF}]];then#if there are diffrences alert the userif[[-n${EMAIL}]];thenecho${DIFF}| mail -s"Change Detected for ${NETWORK}"${EMAIL}elseecho"The following changes were detected for network: ${NETWORK}"echo"${DIFF}"fifidone