Snort Alert Log: Simple Analysis and Daily Reporting with Arnold and Petit

Background

This script was developed last year to give a quick and dirty analysis of the Snort alert log. In typical fashion, it’s is far from perfect, but approximately right is better than absolutely wrong. Obviously, the intersects could be combined in new and creative ways, this is just one that works for us. Also, notice that petit is used to graph the snort alerts to give an idea of when the attacks signatures are occurring.

Basics

The first intersect is between snort alerts and critical ports.

We only watch for a specific list of ports in which have access granted through the firewall and which have actively running ports. This list is hand generated with an nmap scan externally to our network.

  1. Snort Alerts: This is a full list of alerts that are generated each day. Our snort sensor is located on a span port which listens to every piece of traffic coming in and out of our network.
  2. Critical Ports: This is a manually generated list of ports which we know are open on the firewall and have services actively running.

The second intersect is between the three major types mentioned below

  1. Known Aggressors: Several Known Aggressors lists are published on the Internet. For the writing of this script, I currently use DSheild, but the choice is arbitrary. The point is to get a list of known aggressors which are connecting to your network and tripping snort’s attack signitures.
  2. Scanners: This list is auto generated by searching the snort alert log and gathering a list of IP Addresses that have scanned our network in the last 24 hours
  3. Critical Addresses: This is a list of

Scripts

Script: arnold.sh

#!/bin/bash
#
# Written: Scott McCary
# Date: 10/2009
# Description: Snort reporting script which displays all events which correlate
# a list of known aggressors, external IP addresses and critical poorts.
#
# Aggressors: List of top IP addresses which have been identified as origins
# of viruses, trojans, hackers, etc
#
# Ports: List of ports known to be open through our firewall. These are verified with
# port scans into our network.
#
# Scanners: List of IP addresses which have scanned our network within the last XX
# timeframe.
#
#

# Variables
alert_log="/var/log/snort/alert"
reports_file="/tmp/arnold.reports"
terminator="__none__"
aggressors=""
ports=""

# Source the keychain
source /root/.keychain/$HOSTNAME-sh

# Gather list for top aggressors on the Internet
for line in `curl -q http://www.dshield.org/feeds/topips.txt 2>/dev/null| awk '{print $1}'`
do  
    aggressors="${aggressors}${line}|"
done
aggressors="${aggressors}${terminator}"

# Gather list of critical ports to watch for
for line in `cat /usr/local/arnold/etc/ports.txt`
do
    ports="${ports}${line}\$|"
done
ports="${ports}${terminator}"

# Gather list of previous port scans
for line in `(cat ${alert_log};zcat ${alert_log}.*.gz) | grep portscan | sed -e s/.*PROTO:255}// | awk '{print $3}' | petit --hash --nofilter | awk '{print $2}'`
do
    scanners="${scanners}${line}|"
done
scanners="${scanners}${terminator}"

# Gather list of critical ip addresses
for line in `cat /usr/local/arnold/etc/addresses.txt`
do
    addresses="${addresses}${line}|"
done
addresses="${addresses}${terminator}"


#cat /var/log/snort/alert | egrep "$ports"
report1="cat ${alert_log} | egrep \"$ports\" | egrep \"$aggressors\" "
report2="cat ${alert_log} | egrep \"$ports\" | egrep \"$scanners\" | grep -v \"(portscan)\" "
report3="cat ${alert_log} | egrep \"$ports\" | egrep \"$addresses\" | grep \"Priority: 3\" "


# Clean up old reports file
rm -f $reports_file

eval $report1 >> $reports_file
eval $report2 >> $reports_file
eval $report3 >> $reports_file

if cat $reports_file | grep Priority &>/dev/null
then

    # Set IFS to \n
    OIFS=$IFS
    IFS=$'\n'

    echo "Daily Snort Report"
    (zcat /var/log/snort/alert.2.gz;zcat /var/log/snort/alert.1.gz;cat /var/log/snort/alert) | grep `/bin/date -d 'yesterday' +"%m/%d"` | petit --hgraph --wide

    for line in `cat /tmp/arnold.reports | petit --hash --allsample`
    do
        sid=`echo $line | awk '{print $3}' | cut -f2 -d":"`
        echo $line
        grep "sid:$sid;" /etc/snort/rules/*
        echo ""
    done

    # Set IFS back
    IFS=$OIFS

    # Exit with error code
    exit 1

else
    # Reporting
    echo "No important events found"
    echo ""
    echo "Aggressors:"
    echo "$aggressors"
    echo ""
    echo "Ports:"
    echo "$ports"
    echo ""
    echo "Previous Scanners:"
    echo "$scanners"
    echo ""
    echo "Critical Servers:"
    echo "$servers"
    exit 0
fi

Output: arnold.sh Output

Daily Snort Report

                                      #        
                                      #        
                                      #        
                                      #        
# # # # # # # # # # # # # # # # # # # # # # #  
# # # # # # # # # # # # # # # # # # # # # # # #
00                      12                    23  

Start Time:     2010-06-22 00:00:00             Minimum Value: 115
End Time:       2010-06-22 23:00:00             Maximum Value: 24866
Duration:       24 hours                        Scale: 4125.16666667

2:      [**] [1:486:5] ICMP Destination Unreachable Communication with Destination Host is Administratively Prohibited [**] [Classification: Misc activity] [Priority: 3] {ICMP} 208.79.157.169 -> 125.230.74.222
/etc/snort/rules/icmp.rules:alert icmp any any -> any any (msg:"ICMP Destination Unreachable Communication with Destination Host is Administratively Prohibited"; icode:10; itype:3; classtype:misc-activity; sid:486; rev:5;)

1:      [**] [1:483:6] ICMP PING CyberKit 2.2 Windows [**] [Classification: Misc activity] [Priority: 3] {ICMP} 208.79.59.227 -> 208.79.157.153
/etc/snort/rules/icmp.rules:alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"ICMP PING CyberKit 2.2 Windows"; itype:8; content:"|AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA|"; depth:32

Script: arnold_convert_addresses.sh

This script helps generate a list of critical addresses on each server. We use this to manually generate our list of critical IP addresses.

#!/bin/bash
#
# Date: 7/2010
# Written By: Scott McCarty
# Description: Used to convert internal addresses to external addresses

for name in `cat /usr/local/arnold/etc/servers.txt`
do

    for internal_address in `ssh root@${name} ifconfig | grep Bcast | sed -e 's/inet addr\://' | awk '{print $1}' | grep 10.0`
    do

        external_address=`cat cisco_firewall.config | grep "static" | grep $internal_address | awk '{print $3}'`
        if [ "$external_address" != "" ]
        then
            #echo "Server: $name"
            #echo "Internal Address: $internal_address"
            #echo "External Address: $external_address"
                        echo $external_address
        fi
    done
done

Tags: , , , ,

Trackbacks/Pingbacks

  1. Monitoring and Dealing With Snort Alerts | Wazi - October 7, 2011

    […] can also find self-rolled script options online. In general, however, it’s best for productivity, usability, and […]

Leave a Reply