Installing Snort and Barnyard2

Installing Snort and Barnyard2

Date: 2015-10-05 14:19:27

Snort is a widely used packet sniffer and IDS. The Installation of the Snort IDS from sources is quite straight forward with only minor obstacles however the configuration might need a little more effort.

Of course it is possible to use the Snort packages from distributions such as Debian or Ubuntu, however that's often not the latest version, and we want to get our pork as fresh as possible.

Installation of Snort

To compile Snort from source, which is the best method to get the latest copy, we will be using either a Debian system, which of course needs all the tools to configure, compile and install stuff, or Arch-Linux where the following are included in the base-devel package and usually installed already with the system.

[root@debian ~]# apt-get update [root@debian ~]# apt-get install gcc automake build-essential libtool

Additionally, we need some more stuff in order to compile everything, so we install that too from the official repository.

[root@debian ~]# apt-get install bison flex libpcap-dev

For Arch-Linux, bison and flex should be installed with base-devel, libpcap-dev is included in libpcap-Package

[root@arch ~]# pacman -S libpcap

Snort needs daq, so we download this one first.

[root@debian ~]# wget

Then Snort itself...

[root@debian ~]# wget

... which we unpack.

[root@debian ~]# tar xvzf daq-2.0.6.tar.gz [root@debian ~]# tar xvzf snort-

Next change into daq's directory to compile it...

[root@debian ~]# cd daq-2.0.6 [root@debian daq-2.0.6]# ./configure [root@debian daq-2.0.6]# make && make install [root@debian daq-2.0.6]# cd .. [root@debian ~]# ldconfig

After daq is successfully installed, we can proceed with Snort. Snort itself needs more libraries, so let's get those too.

[root@debian ~]# apt-get install libpcre3-dev zlib1g-dev

We also need libdnet1 (not the "libdnet" from the official debian repository, this is not the libdnet we need) which can be installed using:

[root@debian ~]# apt-get install libdumbnet-dev

Or on Arch-Linux we use libdnet:

[root@arch ~]# pacman -S libdnet

Then change into Snort's directory, configure and compile. This configuration works with most setups. If you are using a non-ethernet interface (some Virtual Machines may have this), Snort might complain with an "ERROR: Cannot decode data link type 113". In this case, add --enable-non-ether-decoders to your configure options.

[root@debian ~]# cd snort- [root@debian snort-]# ./configure [root@debian snort-]# make && make install

Now we can test whether the piggy runs:

[root@debian ~]# snort -i eth0

When we start Snort like above, it basically runs like tcpdump -i eth0 -; just sniffing packets and displaying them without any rule processing. For processing rules we need a proper configuration file which we setup later.

Installing Barnyard2

Barnyard2 is a dedicated spooler for Snort unified2 binary file format. It relieves Snort from the task of writing and processing their alerts so it can focus on its main task: Sniffing the network for suspicious activities without bothering a connection to a database or similar.

Barnyard2 monitors Snort's log directory and catches alerts from the spool file as they appear and send them somewhere else, in our case a MySQL database.

Barnyard2 can be obtained from its git repository, so we install git quickly if we haven't done it before...

Since we use MySQL as our alert database, we need to install the required packages in the same run.

Note: The setup of your MySQL server might vary on different distributions and will not be covered here. This tutorial only explains the creation of a user for barnyard2 and the required tables. Please refer to your MySQL documentation if you need help installing the server.

[root@debian ~]# apt-get install git mysql-server libmysqlclient-dev mysql-client

Or for Arch-Linux

[root@debian ~]# pacman -S git mysql libmysqlclient

We clone barnyard2 to our local harddrive and change into its dicrectory.

[root@debian ~]# git clone [root@debian ~]# cd barnyard2/

To compile Barnyard2 with MySQL support, we first need to locate the libmysqlclient libraries and use this information to configure our makefile.

[root@debian barnyard2]# ldconfig -p | grep mysql (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/ (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/ [root@debian barnyard2]# ./ [root@debian barnyard2]# ./configure --with-mysql --with-mysql-libraries=/usr/lib/x86_64-linux-gnu [root@debian barnyard2]# make && make install

Configuring Snort so it can be read by Barnyard2

As said above, Barnyard2 reads Snort's unified2 output (and only in the unified2 format). Therefore we have to get Snort using u2 as its log output.

We use the example configuration of Snort, which we can get from the official site or simply copy from the source directory.

[root@debian ~]# mkdir /etc/snort [root@debian ~]# cp snort-*.conf* snort-*.map /etc/snort

Furthermore we create a directory in /var/log for Snort to write its log files.

[root@debian ~]# mkdir /var/log/snort

We also create directories and files for the rules.

[root@debian ~]# mkdir /etc/snort/rules /etc/snort/so_rules /etc/snort/preproc_rules /usr/local/lib/snort_dynamicrules [root@debian ~]# touch /etc/snort/rules/local.rules /etc/snort/rules/white_list.rules /etc/snort/rules/black_list.rules /etc/snort/

The example configuration comes with a list of includes to various rule files. We donĀ“t use them here so we comment them out and just leave our local.rules in the includes.

[root@debian ~]# sed -i 's/include \$RULE\_PATH/#include \$RULE\_PATH/' /etc/snort/snort.conf

Using vim or any other text editor, we finally edit snort.conf and set the correct paths and files and also set the $HOME_NET variable to your local network (which we want to protect), assuming we are sitting in a

[root@debian ~]# vim /etc/snort/snort.conf In line :45 set HOME_NET to our local network ipvar HOME_NET In line :104 set the following variables accordingly var RULE_PATH rules var SO_RULE_PATH so_rules var PREPROC_RULE_PATH preproc_rules var WHITE_LIST_PATH rules var BLACK_LIST_PATH rules In line :541 uncomment local.rules include $RULE_PATH/local.rules In line :516 define unified2 as the log format output unified2: filename snort.u2, limit 128, nostamp, mpls_event_types, vlan_event_types

Now we have configured Snort to report in a format that can be read by Barnyard2.

To test if there are any typos in snort.conf or included files, Snort comes with a handy option -T which Tests the config and quits without further packet processing.

[root@debian ~]# snort -T -c /etc/snort/snort.conf Running in Test mode --== Initializing Snort ==-- Initializing Output Plugins! Initializing Preprocessors! Initializing Plug-ins! Parsing Rules file "/etc/snort/snort.conf" [ ... various blablas where Snort tells us stuff about its config we are not interested in now ... ] --== Initialization Complete ==-- ,,_ -*> Snort! <*- o" )~ Version GRE (Build 262) '''' By Martin Roesch & The Snort Team: Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved. Copyright (C) 1998-2013 Sourcefire, Inc., et al. Using libpcap version 1.7.4 Using PCRE version: 8.37 2015-04-28 Using ZLIB version: 1.2.8 Rules Engine: SF_SNORT_DETECTION_ENGINE Version 2.4 Preprocessor Object: SF_SMTP Version 1.1 Preprocessor Object: SF_REPUTATION Version 1.1 Preprocessor Object: SF_SIP Version 1.1 Preprocessor Object: SF_FTPTELNET Version 1.2 Preprocessor Object: SF_DNP3 Version 1.1 Preprocessor Object: SF_POP Version 1.0 Preprocessor Object: SF_SDF Version 1.1 Preprocessor Object: SF_IMAP Version 1.0 Preprocessor Object: SF_MODBUS Version 1.1 Preprocessor Object: SF_SSH Version 1.1 Preprocessor Object: SF_SSLPP Version 1.1 Preprocessor Object: SF_DNS Version 1.1 Preprocessor Object: SF_GTP Version 1.1 Preprocessor Object: SF_DCERPC2 Version 1.0 Snort successfully validated the configuration! Snort exiting

Finally we create a user and a group for Snort to run as and set the file permissions:

[root@debian ~]# groupadd snort [root@debian ~]# useradd snort -r -s /sbin/nologin -g snort [root@debian ~]# chown -R snort:snort /etc/snort /var/log/snort/ /usr/local/lib/snort_dynamicrules [root@debian ~]# chmod -R 5775 /etc/snort /var/log/snort/ /usr/local/lib/snort_dynamicrules

In a next step we tell Barnyard2 where it can find the spool u2-files to report alerts.

For that purpose, we copy the Barynard2 default config, which comes with handy examples, into a suitable place of our choice and edit it. In the same run, we will also create a directory for Barnyard2 logs.

[root@debian ~]# mkdir /etc/barnyard2 /var/log/barnyard2 [root@debian ~]# cp barnyard2/etc/barnyard2.conf /etc/barnyard2 [root@debian ~]# vim /etc/barnyard2/barnyard2.conf In line :54 uncomment/edit config logdir: /var/log/barnyard2 In line :141 uncomment/edit the following line config waldo_file: /tmp/barnyard2.waldo In line :348 uncomment the following and fill in the appropriate login details output database: log, mysql, user=barnyard2 password=BARNIES_PASSWORD dbname=snort host=localhost

You can have the database running on a different system, centralize it, having a WebGUI for monitoring (Snorby, BASE or similar) or use other output plugins like syslog or Sguil. But let's stick with MySQL for this tutorial.

Setting up the MySQL database

In this step we create the database for Barnyard2 and the user that we specified in the barnyard2.conf.

[root@debian ~]# echo "create database snort;" | mysql -u root -p Enter password: [root@debian ~]# mysql -u root -p -D snort < /tmp/barnyard2/schemas/create_mysql Enter password: [root@debian ~]# echo "grant create, insert, select, delete, update on snort.* to barnyard2@localhost identified by 'BARNIES_PASSWORD'" | mysql -u root -p Enter password:

Now we can test if everything looks cosy in our barnyard with the following command:

[root@debian ~]# barnyard2 -T -c /etc/barnyard2/barnyard2.conf -d /var/log/snort -f snort.u2 Running in Test mode --== Initializing Barnyard2 ==-- Initializing Input Plugins! Initializing Output Plugins! Parsing config file "/etc/barnyard2/barnyard2.conf" +[ Signature Suppress list ]+ ---------------------------- +[No entry in Signature Suppress List]+ ---------------------------- +[ Signature Suppress list ]+ Barnyard2 spooler: Event cache size set to [2048] INFO database: Defaulting Reconnect/Transaction Error limit to 10 INFO database: Defaulting Reconnect sleep time to 5 second [CacheSynchronize()],INFO: No system was found in cache (from signature map file), will not process or synchronize informations found in the database database: compiled support for (mysql) database: configured to use mysql database: schema version = 107 database: host = localhost database: user = barnyard2 database: database name = snort database: sensor name = localhost:NULL database: sensor id = 1 database: sensor cid = 4 database: data encoding = hex database: detail level = full database: ignore_bpf = no database: using the "log" facility --== Initialization Complete ==-- ______ -*> Barnyard2 <*- / ,,_ \ Version 2.1.14 (Build 336) |o" )~| By Ian Firns (SecurixLive): + '''' + (C) Copyright 2008-2013 Ian Firns Barnyard2 successfully loaded configuration file! Barnyard2 exiting database: Closing connection to database "snort"

No serious complains and our Barnyard2 seems ready to run. It is possible that barnyard2 complains about a missing or truncated waldo file in the first run, however, this is no big concern since Barnyard2 will simply create the file once alerts occur.

If you are bothered about the sensor name of "localhost:NULL", you can edit the config in the following lines to your personal needs. This comes in handy when you are collecting events from multiple sensors on one server and want some organisation in your database:

[root@debian ~]# vim /etc/barnyard2/barnyard2.config In line :70 uncomment/edit config hostname: office config interface: eth0


To test our installation as a whole, we now create a test rule to see if Snort notices it so we can see it appearing in our database.

Snort rules basically follow this pattern:

type proto from_ip from_port -> to_ip to_port (rule_options;)

To test our installation, we create a rule that applies when a packet with a certain content was send to an Ip number on a HTTP port in our internal network. The content of the packet shall be "donoevil" and the IP number of the attacked can be any server in our HOME_NET while the attacker can sit everywhere, outside or inside.

So we open /etc/snort/rules/local.rules and edit it:

[root@debian ~]# vim /etc/snort/rules/local.rules alert tcp any any -> any any (msg:"Something doing no evil"; content:"donoevil"; nocase; sid:1000001; rev:1; priority:1;)

This will rise an alert of the highest priority as soon as Snort spots a packet containing the string "donoevil" (not case sensitive) sent to any Ip on any port. For simplicity we just use any to any. The "sid:" gives our alert a unique ID. It is conventional to use a high number like sid:1000001 for custom rules, even if you have no third party rules in the directory.

Barnyard2 reads the file we created before to map sids to messages about the attack. This file is normally generated by a script that keeps the rules up to date. For this test case we could leave the file blank or create one for the single rule. If we leave it blank, barnyard2 will only report the sid but won't display any custom messages. This might be enough for a test case but doesn't look very beautiful. For our test rule the following entry in shall be enough:

[root@debian ~]# vim /etc/snort/ 1000001 || Something doing no evil

Now lets start Snort and Barnyard2 as daemons before we test the setup. Please note that the interface you specify with the -i option must be able to "hear" the packets in promiscuous mode. So if the pig is running on a dedicated box on a switch and not directly on the router you might need to use a network tap, a switch with a monitor port or in the simplest case a dumb hub, because in a switched network your sniffer might not get all the traffic that's not directed to its MAC address.

For this test run, we will run Snort with the option -A console, that outputs all alerts on console.

[root@debian ~]# snort -d -A console -c /etc/snort/snort.conf -i eth0 [root@debian ~]# barnyard2 -D -c /etc/barnyard2/barnyard2.conf -d /var/log/snort -f snort.u2

To test our rule, we can use nc to connect to a HTTP server and request a string containing our trigger phrase. As the victim HTTP server of our mocked attack, we can simply use our router's WebGUI, as long as it is in our protected $HOME_NET.

[root@debian ~]# nc 80 GET donoevil HTTP/1.1 [hit return key twice]

Snort should now give an output similar to this:

01/01-14:30:10.315345 [**] [1:10000001:0] Something doing no evil [**] {TCP} ->

And if everything works with Barnyard2, select * from data; in our snort database something like this should show up:

+-----+-----+----------------------------------------------+ | sid | cid | data_payload | +-----+-----+----------------------------------------------+ | 1 | 1 | 47455420646F6E6F6576696C20485454502F312E310A | +-----+-----+----------------------------------------------+ 1 row in set (0.00 sec)

This is a hex representation of the packet payload data "GET donoevil HTTP/1.1" that went over the network. Snort catched it up and Barnyard2 sent it into our MySQL database.

Since we have seen that our rule works, we can now stop Snort with ^C and start it in daemon mode using -D instead of -A console.

Snort knows many more sophisticated options to detect malicious packets however for this tutorial this simple rule should be enough to test if our setup works at all. It is advised to subscribe to Snort, to get an Oinkcode and to use something like pulledpork to get at least the latest community rule compilation for your IDS.

The setup of pulledpork will be issued in a later article.