Cover V09, I09
Article
Figure 1
Figure 2

sep2000.tar


Snort — A Look Inside an Intrusion Detection System

Kristy Westphal

As evidenced by the daily news headlines, catching wily hackers is becoming even tougher. Every bit of sensible security you can add to your network may help, especially if the tool you are using is free, portable, and easy to install. In the case of Intrusion Detection Systems (IDS’s), there are many good commercial versions. What isn’t as widely advertised are the freeware IDS’s. These programs are not only good products by themselves, but are also excellent supplements to these commercial systems.

Snort (written by Martin Roesch) is one such tool. Snort is a rules-based, “lightweight” Intrusion Detection System that is based on libpcap, and runs on UNIX operating systems. Snort can perform content searches on IP packets, then, through logging, let the security administrator know if unusual activity has occurred. It is the type of IDS that lets you dig down into the packet via the tcpdump format, or simply a decoded format through a directory structure based upon the IP address of the source address. The administrator has the flexibility to set up filters based on IP addresses and the ability to close connections when a rule for a hostile probe or possible attack is found.

This article explores setting up Snort, how to use the various plugins, how to interpret the output of packet captures from Snort, and how it can compliment other IDS’s.

Setting Up Snort: Where to Start, and What You’ll Need

Snort runs on almost every flavor of UNIX, including: Linux, OpenBSD, FreeBSD, Solaris, HP-UX, and AIX. It runs on various hardware platforms (x86, Sparc, and Alpha), as well. Check the hardware matrix listed in the documentation to make sure that the OS/hardware combination you prefer is available. The examples in this article are all based on an x86, Solaris 2.7 installation, using the 1.6.1 beta3 source code of Snort.

Usually, Snort can be found at the main Snort homepage: http://www.clark.net/~roesch/security.html, but the author is currently looking for a new home. In the meantime, you can download the Snort source code from one of the various mirror sites. (Check out http://www.whitehats.com, under their Free Tools, Intrusion Detection, NIDS section. Not only does this site store Snort, but it has arachnids, which is a database of known attack signatures that may come in handy when you start writing your own IDS rules.)

In addition to the Snort source code, you need various tools to compile Snort: a C compiler (the gcc version from sunfreeware.com works well), and the libpcap library (download from ftp://ftp.ee.lbl.gov/libpcap.tar.Z).

libpcap

What is libpcap? libpcap is “a portable framework for low-level network monitoring”. It is system independent and allows a lot of flexibility, especially for an Intrusion Detection System. To install it, untar the source code in a temporary directory. (Note: you will also need Flex and Bison to successfully compile libpcap. I downloaded versions 2.5.4 and 1.2.8, respectively, from http://sunfreeware.com.) While still in that directory, check the makefile.in file for any path changes that need to be made, then run:

./configure
make
make install
make install-incl
make install-man
You only need to run the last two commands if you want to have the include and man files. This installation is straightforward and went without issue on my system.

Back to Installing Snort

Once your C compiler and libpcap are in place, you are ready to compile Snort. Untar it in a temporary directory. If you want to install the basic Snort, you can run the following while still in the directory you untarred it in:

./configure
make
make install
The install will put the binaries in /usr/local/bin. There are also several options you can use while compiling the source code. For example, if you have special system variables that need to be used while compiling, you can run the configure option like this:

CFLAGS=-O2 LIBS=-lposix ./configure
You can also compile Snort for more than one type of OS at the same time, but you must have a version of make that supports the VPATH variable in order to place the object files for each type in different directories.

An interesting option you can use while compiling is the -enable-smbalerts option, which can be a security issue because it opens a popen() call that runs with root privileges. The best idea is not to use SMB alerting, however, if you want this functionality, it might be best to have Snort running by itself on a machine with minimal services so that if it is ever compromised, nothing else is jeopardized.

Another option is -enable-flexresp. When you compile with this option, your code will allow you to cancel hostile connections when you get a rule match. Note that in order to use this option, you will need another library — libnet. libnet can be found at: https://www.packetfactory.net/libnet. There are more details on this option in the README.FLEXRESP file that comes with the source code.

When I compiled Snort on my Solaris system, I did the basic install, and it compiled without any problems. Once the code is compiled, it is time to start setting up your sensors.

A Side Discussion on IDS Sensors

It can be diffficult deciding where to place your IDS sensors on your network. I have heard a lot of discussion about where to place sensors: outside the firewall monitoring incoming traffic, inside the firewall monitoring outgoing traffic, or in the DMZ of your network. It mostly depends on two factors: 1) how much flexibility with money and resources that you have with implementing your IDS, and 2) how paranoid you are. Attacks can come from all sides, and my theory is — the more sensors the better. Naturally, along with more comes the problem of support.

If you have numerous sensors, but no one to monitor them, then it becomes a fruitless process. However, if your organization is one that needs to keep a record of everything whether it is analyzed or not, then you may be required to store the logs away as they come in, reading only the incoming traffic logs as time allows. The notion to keep in mind is that IDS alone cannot be depended upon to save your network from would-be attackers. It can play a vital role, along with other tools such as your firewall and routers, to protecting your network, but only if it is used as it was intended.

Intrusion Detection Systems were meant to capture traffic on your network for analysis of suspicious behavior. Depending on what type of system it is, an IDS can only analyze so far. With today’s technology, the real payoff in an IDS is the analyst who can investigate the analogous pattern until resolution is satisfactory. This analyst has to go way beyond the traffic on the network to figure out what a pattern could mean.

Placing sensors carefully and meaningfully throughout your network will not only help get the maximum benefit out of the IDS itself, but will also help the diligent analyst who is trying to understand what it all means. If you have the opportunity to add only one sensor to your network, then I recommend putting it between the Internet and your firewall. The ideal situation is to have two sensors at every gateway: one watching incoming traffic, and one watching outgoing traffic. Outgoing traffic can be just as malicious as incoming traffic due to the large number of attacks that happen from the inside of organizations.

Running Snort

Now that you have carefully considered where to put your sensors, you are ready to actually run Snort. Snort comes with several basic rule sets, including:

web-lib — For Web-based attacks on applications like Cold Fusion and Frontpage
scan-lib — Looks for port scans, traceroutes, and the like
overflow-lib — For buffer overflow exploits
backdoor-lib — For backdoor type of attacks like Back Orifice
misc-lib — A library for miscellaneous rules called
snort-lib — References all of the other rules

These rules are standard with the source code, but are updated frequently by the author. Updated versions can be found on the Snort homepage. See Figure 1 for an example of the overflow-lib rules file.

The format of the rule is broken into two parts: the header and the options. However, each individual rule must be within one line or the parser does not understand it. The header contains the following format: action, protocol, source and destination IP addresses and their netmasks, as well as the source and destination ports information. The rules option section actually contains the alert message and the pattern or signature for which you are inspecting a packet. Examine the last rule in the overflow-lib ruleset as an example. The header consists of:

alert tcp any any -> $HOME_NET 21
The action portion of the header can mean one of three things: alert (a match for your rule has been found, now follow the designated action), log (log this particular packet), or pass (drop the packet). The types of alerts currently available are: full, fast, or none. The full alert writes a fairly complete log entry in your log file, whereas fast simply writes the timestamp, message, IP address, and port numbers to the log file. None turns off alerting altogether.

The alerting of Snort was kept simple to enable the system to 1) run efficiently and 2) keep security tight. The author of Snort recommends using the excellent freeware third-party tools already available to do any type of fancy alerting, like paging or email. In order to keep the performance of your Snort system running well, I recommend storing your logs on another server that can scan them and alert accordingly.

The second field is the protocol field. Snort currently can filter tcp, udp, and icmp protocols, with the author’s intention of adding more protocols as time allows. The first “any” in this particular header stands for the IP address range, in this case the source address, as it is the left side of the arrow. IP addresses can be in two formats in the header — either with a CIDR block mask to indicate the netmask, or with the use of negation. A CIDR block mask in the format of /24 designates a Class C network, /16 is Class B network, and /32 designates a particular machine address. For negation, an exclamation mark in front of the address indicates that anything but that address should be considered. The second “any” in the header relates to the port number for the source IP.

Below is an example of a header that is scanning for traffic coming from ports less than or equal to 1024 on the 192.168.1.0 network, to ports greater than or equal to 100 on the 10.1.1.0 network:

alert tcp 192.168.1.0/24 :1024  \
   -> 10.1.1.0/24 100:
On the destination side of the header, the variable $HOME_NET stands for the destination network for which the packet is addressed. 21 is the certain port to be monitored. Notice that $HOME_NET is an environment variable versus an IP address range. Variables were added to the later versions of Snort as a feature, and can be set in the rules file with the following syntax: var HOME_NET xxx.xxx.xxx.xxx/24. Another advanced rule setting is Include, which allows you to include other rules files that are not mentioned when running Snort at the command line.

Currently, there are 15 rule option keywords that can be utilized for rules files. Some of the recognized options are: content, flags, seq, icmp_id, and ipoption. The content rule looks for a particular pattern in the packet’s payload. The flags keyword searches for the TCP flags for certain settings, whereas seq looks at the TCP sequence number field. icmp_id looks for a certain value in the ICMP ECHO ID field, and ipoption examines the IP option fields for certain values. Rule options are separated from each other with a semi-colon, whereas keywords are separated from their corresponding arguments with a colon. Rule options are distinguished by parentheses. Look at the option section of the rule header we already examined:

(msg:"FTP buffer overflow1!";  \
   content:"|5057 440A 2F69|";)
This option prints the message: FTP buffer overflow! in the alert and log file when the content of |5057 440A 2F69| is found in the tcp packets that are destined for port 21 on your home network.

The Precompiled Plugins

To make Snort even more flexible, plugin functionality was created in later versions. With this capability, willing contributors can write modules that can act as plugins or preprocessors, running before the detection engine runs, but after the packet has already been examined. The main difference between the two types of available plugins is that the plugin can be called numerous times with different criteria during the examination of a single packet, whereas the preprocessors are used once per packet to perform a single function. Generally, the plugins are called out of the main rules file (snort-lib). The format to use a preprocessor in a rules file is:

preprocessor <name>:<options>
Several plugins have already been written including: Portscan Detector and Minfrag. The Portscan Detector (written by Patrick Mullen) looks for TCP or UDP packets sent so many times during a specified time period, which you can designate yourself. Running this preprocessor is very flexible and can be used in conjunction with the scan-lib ruleset. The Minfrag preprocessor looks at fragmented packets of a particular size.

It is also painless to add new plugins that you may write by simply updating the plugbase.h and plugbase.c files, adding them to the makefile, and recompiling. Don’t forget to update the snort-lib rules file to reference your new plugin, too!

What Does a Packet Capture Look Like?

You have compiled your code, configured your rules, and decided where your sensors will go. Now you are finally ready to run Snort! Keep in mind when first using Snort that you may want to adjust the settings to ensure that you are getting the desired traffic. Snort is so flexible that you may end up sniffing for nothing at all!

When you run Snort, designate a location to log the packets it is filtering if your Snort directory doesn’t have a lot of room. When you do so, Snort starts to log by network ID. For instance, if your IP address is 10.x.x.x, then it will make a directory under the designated log directory called 10.x.x.x, and start logging by traffic type. When I ran:

snort -v -l /logpath
at the command line, a log file called ICMP_ECHO_REPLY, was written in my log directory under my workstation’s IP address. The output of the file looked like:

05/23-18:57:59.513554 172.x.x.x \
   -> 172.x.x.y
ICMP TTL:255 TOS:0x0 ID:37055  DF
ID:256   Seq:4608  ECHO REPLY
This way of running Snort simply gives you the packet’s protocol header information. In this example, the date and time are given, then the source address, then the destination address. The protocol type is next, then the packet’s time-to-live value, the type of service, the IP Header identification field, the “do not fragment” flag, the ICMP packet identification field, the sequence number of the packet, then the ICMP flag, ECHO REPLY.

If you run Snort with the additional -d flag, you will see packet data, in addition to the header. An example of this output is shown below:

05/23-19:04:47.034777 172.x.x.y:1953 \
   -> 172.x.x.x:23
TCP TTL:128 TOS:0x0 ID:53377  DF
*****PA* Seq: 0x2F10B2B5    \
   Ack: 0x502E6B3B   Win: 0x2229
FF FC 1F FF FC 23 FF FC 27 FF FC \
   24 9E 3F EE C2  .....#..'..$.?..
In this case, we are looking at the same information as before, except that this is a TCP packet. This time we can see the TCP flags that are set (Push and Ack), as well as part of the data that is being pushed over to the host during this attempted telnet session.

You can see even more data by running Snort with the -e option (Figure 2). This example shows everybody’s favorite type of traffic — good ol’ netbios. In this case, we are looking at a UDP packet, as well as much of the payload that comes with those annoying broadcast packets we so often having floating around the network.

Why It Is Good to Use Alone or with Other IDS’s

Snort is touted as a lightweight IDS. This is an understatement at best, but then again, it cannot do everything. Snort can be a wonderful companion to a commercial IDS when you need to dig down into the packet and monitor for signatures that are seen nowhere but in the payload of the packet. However, if you don’t already have an IDS, then Snort can be used in conjunction with other freeware (such as Shadow) to make a powerful combination for any network.

Shadow, developed by a team at the Naval Surface Warfare Center (http://www.nswc.navy.mil/ISSEC/CID) analyzes datagram headers, as opposed to the content of packets. Used together, these two IDS’s can be great allies as they cover more ground. How you design your network will depend upon how you will want to use these two tools.

More Information

Snort is a well documented freeware tool but, even after reading this article and the documentation, you may have some questions. In addition to the forum hosted at www.whitehats.com under Security Forum, you can join the Snort mailing list by sending a mail message to: majordomo@bofh.kyrnet.kg, with “subscribe snort” (minus the quotes) in the subject line. You can also sign up for the “snort-announce” or “snort-digest” lists using the same method. You can also email the author directly at: roesch@hiverworld.com.

Snort also has quite a following, which has resulted in some cool tools being developed by the Snort community. Two of these add-on tools are snortlog (a logging tool written in Perl by Angelos Karageorgiou) and snort_stat.pl (a great stats tool for Snort, also in Perl and with output in html, written by Yen-Ming Chen).

Summary

Snort is a “lightweight” Intrusion Detection System that can stand on its own, or fit in nicely with other IDS’s on your network. Snort has numerous features, which seem to grow frequently, and can be customized to be as specific for your network as you need it to be. Easy to set up and easy to use, Snort is a smart addition to the security engineer’s toolkit.

References

• Snort readme files — Much of the material in this article is from the readme files included with the Snort source code, as well as the Snort homepage. Thanks to Martin Roesch for starting such a great thing!

libpcap readme files

About the Author

Kristy Westphal is a versatile network administrator, skilled in troubleshooting and process analysis. Her 6+ years of experience in the IS field have allowed her to become knowledgeable in UNIX and NT, as well as project management and security/disaster recovery planning. She can be reached at: cpwkaw@primenet.com.