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"
