A preprocessor module for Snort that uses ML algorithms for pruning, clustering and finding correlation between alerts
Find a file
2010-10-08 14:43:33 +02:00
corr_rules New correlation rules, now installing doc and share stuff 2010-09-15 14:10:01 +02:00
htdocs Improving the embedded web server 2010-10-08 14:43:33 +02:00
include Correlation graphs, macro substitution improved 2010-09-14 19:24:03 +02:00
m4 PostgreSQL support (EXPERIMENTAL) 2010-09-16 17:11:46 +02:00
schemas (Full?) support for PostgreSQL 2010-10-05 04:01:35 +02:00
uthash First commit for spp_ai 2010-08-14 14:30:41 +02:00
aclocal.m4 Adding webserver features 2010-10-07 12:19:21 +02:00
alert_history.c Starting to support PostgreSQL for logging output 2010-10-04 17:48:07 +02:00
alert_parser.c Starting to support PostgreSQL for logging output 2010-10-04 17:48:07 +02:00
AUTHORS Authors changed 2010-09-16 17:13:40 +02:00
bayesian.c Starting to support PostgreSQL for logging output 2010-10-04 17:48:07 +02:00
ChangeLog ChangeLog and README updated 2010-09-16 17:20:20 +02:00
cluster.c Starting to support PostgreSQL for logging output 2010-10-04 17:48:07 +02:00
config.guess Fixed MacOS support, implemented regexp caching 2010-09-16 02:00:02 +02:00
config.h.in Adding webserver features 2010-10-07 12:19:21 +02:00
config.sub Fixed MacOS support, implemented regexp caching 2010-09-16 02:00:02 +02:00
configure Adding webserver features 2010-10-07 12:19:21 +02:00
configure.ac Adding webserver features 2010-10-07 12:19:21 +02:00
COPYING Using autotools now 2010-09-05 15:27:35 +02:00
correlation.c Improving the embedded web server 2010-10-08 14:43:33 +02:00
db.c Starting to support PostgreSQL for logging output 2010-10-04 17:48:07 +02:00
db.h (Full?) support for PostgreSQL 2010-10-05 04:01:35 +02:00
Doxyfile First commit for spp_ai 2010-08-14 14:30:41 +02:00
INSTALL Using autotools now 2010-09-05 15:27:35 +02:00
install-sh Fixed MacOS support, implemented regexp caching 2010-09-16 02:00:02 +02:00
ltmain.sh PostgreSQL support (EXPERIMENTAL) 2010-09-16 17:11:46 +02:00
Makefile.am Adding webserver features 2010-10-07 12:19:21 +02:00
Makefile.in Adding webserver features 2010-10-07 12:19:21 +02:00
missing Fixed MacOS support, implemented regexp caching 2010-09-16 02:00:02 +02:00
mysql.c Supporting alerts and packets info output to db 2010-10-01 19:32:34 +02:00
NEWS Using autotools now 2010-09-05 15:27:35 +02:00
outdb.c (Full?) support for PostgreSQL 2010-10-05 04:01:35 +02:00
postgresql.c (Full?) support for PostgreSQL 2010-10-05 04:01:35 +02:00
README Output database support (for MySQL) now complete 2010-10-02 17:46:15 +02:00
regex.c Adding webserver features 2010-10-07 12:19:21 +02:00
sf_preproc_info.h 10 sept 2010 commit 2010-09-11 02:12:39 +02:00
spp_ai.c Adding webserver features 2010-10-07 12:19:21 +02:00
spp_ai.h Adding webserver features 2010-10-07 12:19:21 +02:00
stream.c Starting to support PostgreSQL for logging output 2010-10-04 17:48:07 +02:00
TODO Improving the embedded web server 2010-10-08 14:43:33 +02:00
webserv.c Improving the embedded web server 2010-10-08 14:43:33 +02:00

============================================================================
   ,,_        ____                   _        _    ___ 
  o"  )~     / ___| _ __   ___  _ __| |_     / \  |_ _|
   ''''      \___ \| '_ \ / _ \| '__| __|   / _ \  | | 
              ___) | | | | (_) | |  | |_   / ___ \ | | 
             |____/|_| |_|\___/|_|   \__| /_/   \_\___|


              _ __  _ __ ___ _ __  _ __ ___   ___ ___  ___ ___  ___  _ __ 
             | '_ \| '__/ _ \ '_ \| '__/ _ \ / __/ _ \/ __/ __|/ _ \| '__|
             | |_) | | |  __/ |_) | | | (_) | (_|  __/\__ \__ \ (_) | |   
             | .__/|_|  \___| .__/|_|  \___/ \___\___||___/___/\___/|_|   
             |_|            |_|                                           

 ~ A REALLY smart preprocessor module for Snort ~
 by BlackLight <blacklight@autistici.org>, http://0x00.ath.cx
============================================================================


This document describes the AI preprocessor module for Snort.
It also describes how to get it, install it, configure it and use it correctly.

Table of contents:
	1. What's Snort AI preprocessor
	2. How to get Snort AI preprocessor
	3. Installation
		3.1 Dependancies
		3.2 Configure options
	4. Basic configuration
	5. Correlation rules
	6. Additional documentation


===============================
1. What's Snort AI preprocessor
===============================

Snort AI preprocessor is a preprocessor module for Snort whose purpose is making
the reading of Snort's alerts more comfortable, clustering false positive alarms
emphasizing  their  root  cause  in  order  to  reduce log pollution, clustering
similar  alerts  in  function  of the type and hierarchies over IP addresses and
ports  that  can  be  decided  by the user, depending on the kind of traffic and
topology  of  the  network, and constructing the flows of a multi-step attack in
function  of  correlation  rules  between  hyperalerts provided by the developer
itself,  by third parts or created by the user itself, again, in function of the
scenario  of  the  network.  It will furthermore possible, in a close future, to
correlate  the  hyperalerts  automatically,  by self-learning on the base of the
acquired alerts.


===================================
2. How to get Snort AI preprocessor
===================================

It  it strongly suggested to get the latest and always-fresh release of Snort AI
preprocessor   from   GitHub   ->   http://github.com/BlackLight/Snort_AIPreproc

git clone git://github.com/BlackLight/Snort_AIPreproc.git

If git is not available on the machine or cannot be used, from the same page you
can also choose "download source" and download the source code in tar.gz format.


===============
3. Installation
===============

The installation procedure is the usual one:

$ ./configure
$ make
$ make install

If  you did not install Snort in /usr directory you may need to use the --prefix
option with configure for selecting the directory where you installed Snort (for
 example    ./configure   --prefix=$HOME/local/snort).   If   the   prefix   was
specified  correctly,  and  it  actually  points to the location where Snort was
installed,      the      module     binaries     should     be     placed     in
$SNORT_DIR/lib/snort_dynamicpreprocessor    after    the    installation,    and
automatically  loaded  by  Snort  at  the  next start. Moreover, a new directory
named  corr_rules  will  be  created, in /etc/snort if the prefix was /usr or in
$SNORT_DIR/etc  otherwise,  containing  XML files describing default correlation
rules provided by the developer. This set can be enriched in any moment with new
XML  files,  provided  by  third parts or created by the user itself, describing
more hyperalerts.


================
3.1 Dependancies
================

Dependancies required for a correct compilation and configuration:

- pthread (REQUIRED), used for running multiple threads inside of the module. On
a Debian-based  system,  install  libpthread-dev  if  you don't already have it.

- libxml2 (REQUIRED), used for parsing XML files from corr_rules directory. On a
Debian-based   system,  install  libxml2-dev  if  you  don't  already  have  it.

- libgraphviz  (RECOMMANDED),  used  for  generating  PNG (and in future PS too)
 files    representing   hyperalert   correlation   graphs   from   .dot   files
 generated   from  the  software.  You  can  remove  this  dependancy  from  the
 compilation  process  by  specifying  --without-graphviz to ./configure, but in
 this  case  you  will  have  .dot  files, not easily understandable by a human,
 for  representing  correlation  graphs,  and  you  may  need  an external graph
 rendering  software  for  converting  them in a more easily readable format. On
 a Debian  system,  install  libgraphviz-dev  if  you  don't  already  have  it.

- libmysqlclient  (OPTIONAL),  used if you want to read alerts information saved
on MySQL DBMS, or enable MySQL support in the module. This option is disabled by
default  (if not specified otherwise, the module will read the alerts from Snort
 plain   log   files),   and   can   be   enabled   by   specifying  the  option
--with-mysql  to  ./configure.  On a Debian-based system you may need to install
libmysqlclient-dev.

- libpq  (OPTIONAL),  used  if  you  want  to  read  alerts information saved on
PostgreSQL  DBMS,  or  enable  PostgreSQL  support in the module. This option is
disabled   by  the  default,  and  can  be  enabled  by  specifying  the  option
--with-postgresql  to  ./configure.  On  a  Debian-based  system you may need to
install libpq-dev.


=====================
3.2 Configure options
=====================

You  can  pass  the  following  options  to ./configure script before compiling:

--with-mysql  -  Enables  MySQL  DBMS  support  into  the  module  (it  requires
 libmysqlclient)

--with-pq  - Enables PostgreSQL DBMS support into the module (it requires libpq)

--without-graphviz  -  Disables  Graphviz  support from the module, avoiding the
generation  of  PNG  or  PS  files  representing hyperalerts correlation as well


======================
4. Basic configuration
======================

After  installing the module in Snort installation directory a configuration for
this  is  required  in  snort.conf.  A  sample configuration may appear like the
following:


preprocessor ai: \
	hashtable_cleanup_interval 300 \
	tcp_stream_expire_interval 300 \
	alertfile "/your/snort/dir/log/alert" \
	alert_history_file "/your/snort/dir/log/alert_history" \
	alert_serialization_interval 3600 \
	alert_bufsize 30 \
	alert_clustering_interval 300 \
	bayesian_correlation_interval 1200 \
	bayesian_correlation_cache_validity 600 \
	correlation_graph_interval 300 \
	correlation_rules_dir "/your/snort/dir/etc/corr_rules" \
	correlated_alerts_dir "/your/snort/dir/log/correlated_alerts" \
	correlation_threshold_coefficient 0.5 \
	database ( type="dbtype", name="snort", user="snortusr", password="snortpass", host="dbhost" ) \
	output_database ( type="dbtype", name="snort", user="snortusr", password="snortpass", host="dbhost" ) \
	database_parsing_interval 30 \
	cluster_max_alert_interval 14400 \
	clusterfile "/your/snort/dir/log/clustered_alerts" \
	cluster ( class="dst_port", name="privileged_ports", range="1-1023" ) \
	cluster ( class="dst_port", name="unprivileged_ports", range="1024-65535" ) \
	cluster ( class="src_addr", name="local_net", range="192.168.1.0/24" ) \
	cluster ( class="src_addr", name="dmz_net", range="155.185.0.0/16" ) \
	cluster ( class="src_addr", name="vpn_net", range="10.8.0.0/24" ) \
	cluster ( class="dst_addr", name="local_net", range="192.168.1.0/24" ) \
	cluster ( class="dst_addr", name="dmz_net", range="155.185.0.0/16" ) \
	cluster ( class="dst_addr", name="vpn_net", range="10.8.0.0/24" )

The options are the following:

- alertfile:  The file where Snort saves its alerts, if they are saved to a file
and   not  to  a  database  (default  if  not  specified:  /var/log/snort/alert)


- alert_history_file:  The   file keeping track of the history, in binary format,
of   all  the  alerts  received  by  the  IDS, so that the module can build some
statistical        correlation        inferences       over       the       past


- alert_serialization_interval:   The   interval   that   should  occur  from  a
serialization  of  a  buffer  of  alerts  on  the  history file and the next one
(default if not specified: 1 hour, as it is a quite expensive operation in terms
of       resources      if      the     system     received     many     alerts)


- alert_bufsize:  Size of the buffer containing the alerts to be sent, in group,
to   the  serializer  thread.  The  buffer is sent when full and made empty even
when   the  alert_serialization_interval  parameter  is  not  expired  yet,  for
avoiding   overflows,  other  memory  problems  or  deadlocks  (default value if
not                                 specified:                               30)


- alert_clustering_interval:  The interval that should occur from the clustering
of  the  alerts  in the log according to the provided clustering hierarchies and
the     next     one     (default     if    not    specified:    300    seconds)


- bayesian_correlation_interval: Interval, in seconds, that should occur between
two  alerts  in  the  history  for  considering  them as, more or less strongly,
correlated (default: 1200 seconds). NOTE: A value of 0 will disable the bayesian
correlation.  This  setting  is  strongly suggested when your alert log is still
"learning",  i.e.  when you don't have enough alerts yet. After this period, you
can      set      the      correlation      interval      to      any     value.


- bayesian_correlation_cache_validity:  interval, in seconds, for which an entry
in  the  bayesian  correlation  hash  table  (i.e.  a  pair  of  alerts with the
 associated   historical   bayesian   correlation)   is   considered   as  valid
before         being         updated        (default:        600        seconds)


- correlation_graph_interval:  The  interval that should occur from the building
of  the correlation graph between the clustered alerts and the next one (default
 if              not             specified:             300             seconds)


- correlation_rules_dir: Directory where the correlation rules are saved, as XML
files      (default      if      not      specified:      /etc/snort/corr_rules)


- correlated_alerts_dir:  Directory  where  the  information  between correlated
alerts  will  be  saved,  as  .dot  files ready to be rendered as graphs and, if
libgraphviz  support  is  enabled, as .png and .ps files as well (default if not
 specified: /var/log/snort/clustered_alerts)


- correlation_threshold_coefficient: The threshold the software uses for stating
two   alerts   are   correlated   is   avg(correlation   coefficient)   +   k  *
std_deviation(correlation_coefficient). The value of k is specified through this
option,  whose  value  is 0.5 by default, and is dependant on how "sensible" you
want  the  correlation algorithm. A value of k=0 means "consider all the couples
of  alerts  whose  correlation  coefficient  is  greater than the average one as
correlated"  (negative values of k are allowed as well, but unless you know what
you're  doing  they're unrecommended, as some correlation constraints may appear
where  no correlation exists). When the value of k raises also the threshold for
two alerts for being considered as correlated raises. A high value of k may just
lead           to          an          empty          correlation          graph


- clusterfile:  File  where  the  clustered  alerts  will be saved by the module
(default       if      not      specified:      /var/log/snort/clustered_alerts)


- cluster_max_alert_interval:   Maximum  time  interval,  in  seconds,  occurred
between  two  alerts  for considering them as part of the same cluster (default:
14400   seconds,  i.e.  4  hours).  Specify  0  for  this  option if you want to
cluster   alerts   regardlessly   of   how   much  time  occurred  between  them


- cluster:  Clustering  hierarchy  or  list  of  hierarchies  to  be applied for
grouping     similar     alerts.     This     option     needs    to    specify:
	-- class: Class of the cluster node. It may be src_addr, dst_addr, src_port
			or dst_port
	-- name: Name for the clustering node
	-- range: Range of the clustering node. It can include a single port or IP
			address, an IP range (specified as subnet x.x.x.x/x), or a port
			range (specified as xxx-xxx)


- database:  If Snort saves its alerts to a database and the module was compiled
 with   database   support   (e.g.   --with-mysql)  this  option  specifies  the
 information   for   accessing   that   database.   The   fields   in  side  are
	-- type: DBMS to be used (so far MySQL and PostgreSQL are supported)
	-- name: Database name
	-- user: Username for accessing the database
	-- password: Password for accessing the database
	-- host: Host holding the database


- database_parsing_interval:  The  interval  that should occur between a read of
the alerts from database and the next one (default if not specified: 30 seconds)


- hashtable_cleanup_interval: The interval that should occur from the cleanup of
the  hashtable  of  TCP  streams and the next one (default if not specified: 300
 seconds)


- output_database:  Specify this option if you want to save the outputs from the
module  (correlated  alerts,  clustered  alerts,  alerts  information  and their
associated    packets   streams,   and  so  on)  to  a  relational  database  as
well  (by  default  the module only saves the alerts on static plain files). The
options    here   are   the   same   specified   for   the   'database'   option.
The  structure  of this database can be seen in the files schemas/*.sql (replace
to  * the name of your DBMS). If you want to initialize the tables needed by the
module,   just   give   the   right  file  to  your  database,  e.g.  for  MySQL
$ mysql -uusername -ppassword dbname < schemas/mysql.sql


- tcp_stream_expire_interval:  The  interval that should occur for marking a TCP
stream as "expired", if no more packets are received inside of that and it's not
"marked"    as    suspicious   (default   if   not   specified:   300   seconds)


====================
5. Correlation rules
====================

The  hyperalert  correlation  rules  are  specified in $SNORT_DIR/etc/corr_rules
directory  through a very simple XML syntax, and any user can add some new ones.
The files in there must be named like the Snort alert ID they want to model. For
example,  if  we  want  to  model  a TCP portscan alert (Snort ID: 122.1.0) as a
hyperalert,  i.e.  as  an  alert  with  pre-conditions and post-conditions to be
correlated  to  other  alerts,  then  we need to create a file named 122-1-0.xml
inside   $SNORT_DIR/etc/corr_rules   with   a   content   like   the  following:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hyperalert PUBLIC "-//blacklighth//DTD HYPERALERT SNORT MODEL//EN" "http://0x00.ath.cx/hyperalert.dtd">

<hyperalert>
	<snort-id>122.1.0</snort-id>
	<desc>(portscan) TCP Portscan</desc>

	<pre>HostExists(+DST_ADDR+)</pre>
	<post>HasService(+DST_ADDR+, +ANY_PORT+)</post>
</hyperalert>


The  <desc>  tag  is  optional,  same  for  <pre>  and <post> if an alert has no
pre-conditions and/or post-conditions, while the <snort-id> tag is mandatory for
identifying the hyperalert. In this case we say that the pre-condition for a TCP
portscan  for  being  successful  is  that the host +DST_ADDR+ exists (the macro
 +DST_ADDR+   will   automatically   be  expanded  at  runtime  and  substituted
 with   the   target   address   of  the  portscan).  The  post-condition  of  a
portscan  consists  in  the  attacker  knowing that +DST_ADDR+ runs a service on
+ANY_PORT+  (+ANY_PORT+  is another macro that will be expanded on runtime). The
hyperalerts  model  in  corr_rules  are  the knowledge base used for correlating
alerts triggered by Snort, the more information it has inside, the more accurate
and  complete  the  correlation will be. The macros recognized and automatically
expanded           from           these          XML          files          are


- +SRC_ADDR+: The IP address triggering the alert
- +DST_ADDR+: The target IP address in the alert
- +SRC_PORT+: The port from which the alert was triggered
- +DST_PORT+: The port on which the alert was triggered
- +ANY_ADDR+: Identifies any IP address
- +ANY_PORT+: Identifies any port


The correlation between two alerts A and B is made comparing the post-conditions
of  A  with  the  pre-conditions of B. If the correlaton coefficient computed in
this  way  is  greater  than  a  certain  threshold (see "Basic configuration ->
 correlation_threshold_coefficient")    then    the   alerts   are   marked   as
correlated, i.e. the alert A determines the alert B. This supports an elementary
reasoning  algorithm  for  doing inferences on the conditions. For example, if A
has  the  post-condition  "HasService(+DST_ADDR+,  +ANY_PORT+)"  and  B  has the
pre-condition "HasService(+DST_ADDR, 22)", a match between A and B is triggered.
Same   if   A   has   "HostExists(10.8.0.0/24)"  as  post-condition  and  B  has
"HostExists(10.8.0.1)" as pre-condition.

There  is  no  fixed  semantics  for  the  the  predicates in pre-conditions and
post-conditions,  any  predicates  can  be used. The only constraint is that the
same  predicates have the same semantic and prototype in all of the hyperalerts.
For  example,  if  HasService  has a prototype like "HasService(ip_addr, port)",
then   all    the  hyperalerts  should  follow  this  prototype,  otherwise  the
matching    would   fail.   Any  new  predicates  can  be  defined  as  well  in
hyperalerts,      provided     that     it     respects     this     constraint.


===========================
6. Additional documentation
===========================

The additional documentation over the code, functions and data structures can
be automatically generated by Doxygen by typing `make doc', and installed  in
SNORT_DIR/doc then typing `make doc-install'.