Hello all,

I have created a bash script to visualize attack data from OSSEC DB on a 
world map by geolocating attackers IPs (using MaxMind's GeoIP db and tools) 
and calculating Top N attacking countries.
Not sure if this is a novel idea, but I couldn't find anything to do this 
the way I wanted it, so I decided to quickly hack together a little script.
This is what the output html looks like:


<https://lh3.googleusercontent.com/-wbPYWRLZ-94/VeJLuN6rU7I/AAAAAAAABFo/thlpjlAmiBU/s1600/Screenshot%2B2015-08-30%2B01.29.51.png>


By clicking the toggle button, you'll see the list of all unique, 
geolocalized attackers IPs found in your OSSEC database, sorted by the 
number of attaks (actually the times they appear in the DB) they ran on 
you. Something like this:

157 attacks     : 1.2.3.4 (*Russia*)
140 attacks     : 5.6.7.8 (*China*)
etc.

If anybody is interested, the script is attached. Feel free to modify it in 
any way you please. Make sure you read the notes at the beginning and 
change the appropriate values in the configuration section.

Disclaimer: I wrote this script quickly and in my spare time, just to get 
some insight on the attack sources on my infrastructure. The HTML output is 
probably fugly by today's standards, there's very little sanity checking, 
and next to no code optimization or cleanup in here, so if you feel so 
inclined, improve or rewrite it in a faster language and share it for 
others to enjoy it.

Hope you find it useful.

Take care,
nitefood

-- 

--- 
You received this message because you are subscribed to the Google Groups 
"ossec-list" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
#!/bin/bash
#
# ----------------------------------------------------------------------------------------------------------
# OSSEC Attack Map script by nitefood [2015]
#
# This script fetches attackers IP list from OSSEC DB and produces an attack visualization map in html format.
# Tested against OSSEC v2.8.2
# 
# The script is provided as is, without warranty of any kind. Feel free to modify it to suit your needs.
#
# ----------------------------------------------------------------------------------------------------------
#
# Some first-run notes:
#
# - This script requires MaxMind's GeoIP database and binaries:
# 	Option 1 [NOT RECOMMENDED]: apt-get install geoip-bin geoip-database
# 	Note: DB is not up to date, and many country lookups will be wrong or will just plain fail. Uses the geoiplookup tool.
#
# 	Option 2 [RECOMMENDED]: I have used the updated GeoIP DB versions, with the mmdblookup tool.
# 	Installation instructions: 
#		Get maxmind db format library and mmdblookup Tool:
#			https://github.com/maxmind/libmaxminddb#from-the-git-repository
#		And get the geoipupdate tool: 
#			https://dev.maxmind.com/geoip/geoipupdate/
#
#		Once you've installed both, and executed the geoipupdate command successfully,
#		you should have an up-to-date GeoIP DB in /usr/local/share/GeoIP/GeoLite2-City.mmdb
#		(on Debian/Ubuntu, check for yourself on other distros), and the mmdblookup tool 
#		should work without problems.
#		To check your setup, run the command:
#			mmdblookup -f /usr/local/share/GeoIP/GeoLite2-City.mmdb --ip 8.8.8.8 country names en
#		if you see no errors (the ip should resolve to "United States"), you're good to go.
#		
#
# - Map produced using Google's Geo Charts js, more info at: https://developers.google.com/chart/interactive/docs/gallery/geochart
#


### Configuration ###

# OSSEC DB connection
mysql_host="localhost"
mysql_db="ossec"
mysql_user="ossec"
mysql_password="***CHANGE_ME***"

# GeoIP DB to use for ip address lookup. Used only with the mmdblookup tool.
geoip_db="/usr/local/share/GeoIP/GeoLite2-City.mmdb"

# How many attack sources to show in Top N attack sources
top_x=15

# IPs not to be considered attack sources (pipe-separated).
# You may want to list here any hosts (like your own nessus scanners, etc.) that would otherwise generate a false positive.
# example: excluded_ips="127.0.0.1|1.2.3.4"
excluded_ips="127.0.0.1"

# Output file (html format)
outhtml="/var/www/attackmap.html"

### End Configuration - you shouldn't need to modify anything below this line ###






before="$(date +%s)"

# Check if we have a geolocalization tool installed. Prefer mmdblookup over geoiplookup.
echo -e -n "\n- Checking for geoip tool presence..."

mmdblookup_tool=$(which mmdblookup)
geoiplookup_tool=$(which geoiplookup)

if [ "$mmdblookup_tool" != "" ]; then
	echo -n "OK (found mmdblookup)"
	geoiptool="mmdblookup"
elif [ "$geoiplookup_tool" != "" ]; then
	echo -n "OK (found geoiplookup)"
	geoiptool="geoiplookup"
else
	echo -e "\n\nERROR: no geolocalization tools found. Please read the not at the beginning of this script.\n"
	exit 1
fi

if [ "$geoiptool" == "mmdblookup" ]; then
	echo -e -n "\n- Checking if GeoIP DB exists..."

	# We are using mmdblookup: check if our GeoIP DB exists
	if [ -a "$geoip_db" ]; then
		echo -n "OK"
	else
		echo -e "\n\nERROR: the GeoIP DB file you specified does not exist. Please check the geoip_db configuration variable.\n"
		exit 1
	fi
fi

SaveIFS=$IFS
IFS=$'\n'

# Extract IP list from OSSEC DB
echo -e -n "\n- Extracting OSSEC data from database..."

iplist=$(mysql -h$mysql_host -u$mysql_user -p$mysql_password --skip-column-names $mysql_db -e "select INET_NTOA(src_ip) from alert,signature where alert.rule_id=signature.rule_id and signature.level >= 8 AND src_ip != 0;")

if [ "$iplist" == "" ]; then
	echo -e "\n\nERROR: db connection failed or empty data set. Check your mysql configuration parameters.\n\n"
	IFS=$SaveIFS
	exit 1
fi

if [ "$excluded_ips" != "" ]; then
	iplist_filtered=$(echo -e "$iplist" | grep -Ev "$excluded_ips")
else
	iplist_filtered=$iplist
fi
iplist_unique=$(echo -e "$iplist_filtered" | sort |uniq)

echo -e -n "OK\n- Geolocating IPs..."

locdb=""

for ip in $(echo "$iplist_unique"); do
	if [ "$geoiptool" == "geoiplookup" ]; then
		location=$(geoiplookup $ip | sed -e 's/, /\n/;s/.*\n//' )
		if [ "$location" == "GeoIP Country Edition: IP Address not found" ]; then
			location="Unknown Location (try using <a href=\"https://github.com/maxmind/libmaxminddb#from-the-git-repository\"; target=\"_new\">mmdblookup</a> instead!)"
		fi
	elif [ "$geoiptool" == "mmdblookup" ]; then
		location=$(mmdblookup -f $geoip_db --ip $ip country names en 2>/dev/null | cut -d \" -f 2 | grep -v "^$")
		if [ "$location" == "" ]; then
        	        location="Unknown Location"
	        fi
	else
		echo -e "\n\nERROR: choose a valid geoip lookup tool (\"mmdblookup\" or \"geoiplookup\") in the configuration section\n"
		IFS=$SaveIFS
		exit 1
	fi

	locdb=$(echo -e "$locdb\n$location")

	numattacks=$(echo "$iplist_filtered" | grep -c "$ip")

	if [ $numattacks == "1" ]; then
		numatt_str="attack"
	else
		numatt_str="attacks"
	fi

        ipdb=$(printf "$ipdb\n$numattacks $numatt_str\t: %15s (<i>$location</i>)" "$ip")
done

echo -e -n "OK\n- Calculating attack source locations..."

# Sort location list to find top n locations
locdb_sorted=$(echo "$locdb" | sort | uniq)

attackdb=""
mapdb="['Country', 'Attacks']"

for loc in $(echo "$locdb_sorted"); do
	numattacks=$(echo "$locdb" | grep -c "$loc")
	# Calculate total attacks from single country
	attacksfromloc=0
	for attacksfromip in $(printf "$ipdb" | grep $loc); do
		attacksfromip=$(echo "$attacksfromip" | awk {'print $1'})
		attacksfromloc=$(echo $(($attacksfromloc+$attacksfromip))) 
	done
	
        if [ $numattacks == "1" ]; then
                numatt_str="attack"
        else
                numatt_str="attacks"
        fi
	attackdb=$(echo -e "$attackdb\n$attacksfromloc\t$numatt_str from:\t<b>$loc</b> ($numattacks unique IPs)");
	if [ "$loc" != "Unknown Location" ]; then
		mapdb=$(echo -e "$mapdb,\n['$loc', $attacksfromloc]")
	fi
done

# Produce Top n ranking by sorting the country attackdb by number of attacks
ranking=$(echo "$attackdb" | sort -r -n | head -n +$top_x)

echo -e -n "OK\n- Generating HTML..."

# Create final html

ipdb_html=$(echo "$ipdb" | sort -r -n | sed -e 's/\n/<br \/>/g')

now=$(date)
echo -e "
   <html> 
    <head> 
	<h1>Global Attacks Map</h1> 
     <script type=\"text/javascript\" src=\"https://www.google.com/jsapi\";></script> 
     <script type=\"text/javascript\"> 
      google.load(\"visualization\", \"1\", {packages:[\"geochart\"]}); 
      google.setOnLoadCallback(drawRegionsMap); 

      function drawRegionsMap() { 

        var data = google.visualization.arrayToDataTable([ 
$mapdb 
        ]); 

        var options = { 
		colorAxis: {colors: ['yellow', 'red']}, 
	}; 

        var chart = new google.visualization.GeoChart(document.getElementById('regions_div')); 

        chart.draw(data, options); 
      } 
    </script>

    <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\";></script>
    <script>
	\$(document).ready(function(){
	    \$(\"button\").click(function(){
	        \$(\".toggle1\").toggle();
	    });
	});
    </script>

  </head> 
  <body> 
    <div id=\"regions_div\" style=\"width: 900px; height: 500px;\"></div>
    <pre><b><u>TOP $top_x ATTACK SOURCES:</u></b><br /><br />$ranking</pre>
    <button>Toggle full attackers IP list</button>
    <div class=\"toggle1\" style=\"display:none;\">
        <p>
	<pre>
$ipdb_html
	</pre>
        </p>
    </div>

    <br /><br /><i>Last updated: $now<br />Source: <a href=\"http://www.ossec.net\"; target=\"_new\">OSSEC</a></i> 
  </body>
 </html>" > $outhtml


IFS=$SaveIFS

after="$(date +%s)"

echo -e "OK\n\nFinished in $(expr $after - $before) seconds.\nOutput file is: $outhtml\n"

Reply via email to