One type of tool that’s come to the forefront in network security in recent years is the network intrusion detection system (NIDS). These systems can be deployed on your network and monitor the traffic until they detect suspicious behavior, when they spring into action and notify you of what is going on. They are excellent tools to use in addition to your logs, since a network IDS can often spot an attack before it reaches the intended target or has a chance to end up in your logs.
Currently, there are two main types of NIDS. The first type detects intrusions by monitoring network traffic for specific byte patterns that are similar to known attacks. A NIDS that operates in this manner is known as a signature-based intrusion detection system. The other type of network IDS is a statistical monitor. These systems also monitor the traffic on the network, but instead of looking for a particular pattern or signature, they maintain a statistical history of the packets that pass through the network and report when they see a packet that falls outside of the normal network traffic pattern. NIDSs that employ this method are known as anomaly-based intrusion detection systems.
In this chapter, you’ll learn how to set up Snort, a signature-based IDS. You’ll also learn how to set up Snort with SPADE, which adds anomaly-detection capabilities to Snort, giving you the best of both worlds. This chapter also demonstrates how to set up several different applications that can help you to monitor and manage your NIDS once you have it deployed. In addition, you’ll learn how to leverage Snort and ClamAV to scan your network traffic for viruses and prevent them from propagating.
Finally, you’ll see how to set up a system that appears vulnerable to attackers, but is actually quietly waiting and monitoring everything it sees. These systems are called honeypots. The last few hacks will show you how to quickly and easily get a honeypot up and running, and how to monitor intruders that have been fooled and trapped by it.
Use one of the most powerful (and free) network intrusion detection systems available to keep an eye on your network.
Monitoring your logs can take you only so far in detecting intrusions. If the logs are being generated by a service that has been compromised, welcome to one of the security admin’s worst nightmares: you can no longer trust your logs. This is where network intrusion detection systems come into play: they can alert you to intrusion attempts, or even intrusions in progress.
The undisputed champion of open source NIDSs is Snort (http://www.snort.org
). Some of the features that make Snort so powerful are its signature-based rule engine and its easy extensibility through plug-ins and preprocessors. These features allow you to extend Snort in any direction you need. Consequently, you don’t have to depend on anyone else to provide you with rules when a new exploit comes to your attention: with a basic knowledge of TCP/IP, you can write your own rules quickly and easily. This is probably Snort’s most important feature, since new attacks are invented and reported all the time. Additionally, Snort has a very flexible reporting mechanism that allows you to send alerts to a syslogd, flat files, or even a database.
To compile and install a plain-vanilla version of Snort, download the latest version and unpack it. Run the configure script and then make
:
$ ./configure && make
Then become root and run:
# make install
Note that all the headers and libraries for
libpcap (http://www.tcpdump.org
) and PCRE (http://www.pcre.org
) must be installed before you start building Snort; otherwise, compilation will fail. Additionally, you might need to make use of the --with-libpcap-includes
, --with-libpcre-includes
, --with-libpcap-libraries
, or --with-libpcre-libraries
configure script options to tell the compiler where it can find the libraries and headers. However, you should need to do this only if you have installed the libraries and headers in a nonstandard location (i.e., somewhere other than the /usr or /usr/local hierarchy).
For example, if you have installed libpcap within the /opt hierarchy, you would use this:
$./configure --with-libpcap-includes=/opt/include \
--with-libpcap-libraries=/opt/lib
Snort is capable of flexible response: the ability to respond to the host that has triggered one of its rules. To enable this functionality, you’ll also need to use the --enable-flexresp
option, which requires the
libnet packet injection library (http://www.packetfactory.net/projects/libnet/
). After ensuring that this package is installed on your system, you can use the --with-libnet-includes
and --with-libnet-libraries
switches to specify its location.
If you want to include support for sending alerts to a database, you will need to make use of either the --with-mysql
, --with-postgresql
, or --with-oracle
option. To see the full list of configure script options, type ./configure --help
.
After you have installed Snort, test it out by using it in sniffer mode. You should immediately see some traffic:
# snort -evi eth0
Running in packet dump mode
Initializing Network Interface eth0
--== Initializing Snort ==--
Initializing Output Plugins!
Decoding Ethernet on interface eth0
--== Initialization Complete ==--
,,_ -*> Snort! <*-
o" )~ Version 2.4.4 (Build 28)
'''' By Martin Roesch & The Snort Team: http://www.snort.org/team.html
(C) Copyright 1998-2005 Sourcefire Inc., et al.
NOTE: Snort's default output has changed in version 2.4.1!
The default logging mode is now PCAP, use "-K ascii" to activate
the old default logging mode.
05/06-14:16:13.214265 0:C:29:C3:C8:3B -> 0:A:95:F5:F1:A5 type:0x800 len:0x92
192.168.0.43:22 -> 192.168.0.60:63126 TCP TTL:64 TOS:0x10 ID:29515 IpLen:20 DgmLen:132 DF
***AP*** Seq: 0x7FCD85CF Ack: 0xA75EBFF2 Win: 0x9E8 TcpLen: 32
TCP Options (3) => NOP NOP TS: 486412346 1797431762
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
05/06-14:16:13.252177 0:A:95:F5:F1:A5 -> 0:C:29:C3:C8:3B type:0x800 len:0x42
192.168.0.60:63126 -> 192.168.0.43:22 TCP TTL:64 TOS:0x10 ID:38015 IpLen:20 DgmLen:52 DF
***A**** Seq: 0xA75EBFF2 Ack: 0x7FCD861F Win: 0xFFFF TcpLen: 32
TCP Options (3) => NOP NOP TS: 1797431762 486412307
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
The Snort source distribution provides some configuration files in the etc directory, but they are not installed when running make install
. You can create a directory to hold these in /etc or /usr/local/etc and copy the pertinent files to it by running something similar to this:
# mkdir /usr/local/etc/snort && cp etc/[^Makefile]* /usr/local/etc/snort
You’ll probably want to copy the
rules directory to that location as well. Note that, as of Version 2.4.0, rules are not distributed with the source but can be downloaded from http://www.snort.org/rules/
. Unregistered users have access to rulesets that are updated only with every major version release (e.g., 2.4.0, 2.5.0, etc.), whereas registered users can receive rulesets that trail the current rules offered to paying subscribers by five days. In addition, you can download community rules that are contributed by the OSS community to the Snort team.
Now, you need to edit the snort.conf file. Snort’s sample snort.conf file lists a number of variables. Some are defined with default values, and all are accompanied by comments that make this section mostly self-explanatory. Of particular note, however, are these two variables:
var HOME_NET any var EXTERNAL_NET any
HOME_NET
specifies which IP address spaces should be considered local. The default is set so that any IP address is included as part of the home network. Networks can be specified using CIDR notation (i.e., xxx
.
xxx
.
xxx
.
xxx
/
yy
). You can also specify multiple subnets and IP addresses by enclosing them in brackets and separating them with commas:
var HOME_NET [10.1.1.0/24,192.168.1.0/24]
To automatically set HOME_NET
to the network address of a particular interface, set the variable to $eth0_ADDRESS
. In this particular case, $eth0_ADDRESS
sets it to the network address of eth0.
The EXTERNAL_NET
variable allows you to explicitly specify IP addresses and networks that are not part of HOME_NET
. Unless a subset of HOME_NET
is considered hostile, you can just keep the default value, which is any
.
The rest of the variables that deal with IP addresses or network ranges— DNS_SERVERS
, SMTP_SERVERS
, HTTP_SERVERS
, SQL_SERVERS
, and TELNET_SERVERS
—are set to $HOME_NET
by default. These variables are used within the ruleset that comes with the Snort distribution and can be used to fine-tune a rule’s behavior. For instance, rules that deal with SMTP-related attack signatures use the SMTP_SERVERS
variable to filter out traffic that isn’t actually related to those rules. Fine-tuning with these variables leads not only to more relevant alerts and fewer false positives, but also to higher performance.
Another important variable is
RULE_PATH
, which is used later in the configuration file to include rulesets. The sample configuration file sets it to ../rules
, but to be compatible with the previous examples you should change it to ./rules
, since snort.conf and the rules directory are both in /usr/local/etc/snort.
The next section in the configuration file allows you to configure Snort’s built-in preprocessors. These do anything from reassembling fragmented packets to decoding HTTP traffic to detecting port scans. For most situations, the default configuration is sufficient. However, if you need to tweak any of these settings, the configuration file is fully documented with each preprocessor’s options.
If you’ve compiled in database support, you’ll probably want to enable the database output plug-in, which will cause Snort to store any alerts that it generates in your database. Enable this plug-in by putting lines similar to these in your configuration file:
output database: log, mysql, user=snort password=snortpass dbname=SNORT \ host=dbserver output database: alert mysql, user=snort password=snortpass dbname=SNORT \ host=dbserver
The first line configures Snort to send any information generated by rules that specify the log
action to the database. Likewise, the second line tells Snort to send any information generated by rules that specify the
alert
action to the database. For more information on the difference between the log
and alert
actions, see “Write Your Own Snort Rules” [Hack #110].
If you’re going to use a database with Snort, you’ll need to create a new database, and possibly a new database user account. The Snort source code’s schemas directory includes scripts to create databases of the supported types: create_mssql, create_mysql, create_oracle.sql, and create_postgresql.
If you are using MySQL, you can create a database and then create the proper tables by running a command like this:
# mysql SNORT -p < ./schemas/create_mysql
This lets you easily organize your alerts and logs and enables you to take advantage of user-friendly systems that can be used to monitor your IDS, such as BASE [Hack #107].
The rest of the configuration file deals mostly with the rule signatures Snort will use when monitoring network traffic for intrusions. These rules are categorized and stored in separate files and are activated by using the include
directive. For testing purposes (or on networks with light traffic) the default configuration is sufficient, but you should look over the rules and decide which rule categories you really need and which ones you don’t.
Now that all of the hard configuration and setup work is out of the way, you should test your snort.conf file. You can do this by running something similar to the following command:
# snort -T -c /usr/local/etc/snort/snort.conf
Snort will report any errors that it finds and then exit. If there aren’t any errors, run Snort with a command similar to this:
# snort -Dd -c /usr/local/etc/snort/snort.conf
Two of these flags, -d
and -c
, were used previously (to tell Snort to decode packet data and to use the specified configuration file, respectively). The -D
flag tells Snort to print out some startup messages and then fork into the background.
Some other useful options are -u
and -g
, which let Snort drop its privileges and run under the user and group that you specify. These are especially useful with the -t
option, which will chroot()
Snort to the directory that you specify.
Now you should start to see logs appearing in /var/log/snort, if you’re not logging to a database. The alerts file is a text file that contains human-readable alerts generated by Snort. The snort.log files are tcpdump capture files containing the packets that triggered the alerts.
Chapter 11, “Simple Intrusion Detection Techniques,” in Building Secure Servers with Linux, by Michael D. Bauer (O’Reilly)