Understanding IDS for Linux

Pedro discusses the different types of intrusion detection systems and shows how to create signatures to identify attacks.

Snort was created by Marty Roesch and currently has over 1,000 rules used to detect attacks like simple port scans and even new attacks such as the SSH CRC32 exploit [see “Snort: Planning IDS for Your Enterprise” by Nalneesh Guar on the LJ web site at /article/4668]. One of the greatest advantages of Snort is its flexibility to create new rules on demand. Whereas with some IDS vendors you have to wait until they release new packages, you may customize and create signatures as soon as the attacks are exposed. One good example was the wu-ftpd exploit in mid-December 2001. Just a few hours after the release of the exploit, the Snort filter was released on security mailing lists. Snort also has the capability to interact with firewalls, i.e., Check Point FireWall-1, using the OPSEC feature or using other plugins to interact with Linux's iptables. Besides the fact that Snort has a large signature database and is mainly based on the misuse model, it offers a beta feature to introduce it to the anomaly model. This feature, called SPADE, does a statistical analysis of the data it gathers and tries to find out what the ordinary behavior is. As with many open-source applications, Snort has a lot of additional applications that you may want to use together.

One nice application from Silicon Defense is SnortSnarf, which creates HTML reports based on the data gathered by Snort.

Snort also works perfectly well with just one network interface card (NIC). Instead of other NIDSes, which need two NICs, one to gather the data and other to be used by the administration interface, Snort can work with one NIC in the promiscuous mode and also can be used to administrate it, inserting new rules or upgrading it.


More recently, another concept of IDS is becoming popular. It is the hybrid intrusion detection system. Marcus Ranum, founder of NFR (Network Flight Recorder, Inc.), wrote that “The shim-type hybrid IDSes are an interesting blend of the strengths and weakness of HBIDSes and NIDSes.” This means that it has most of the features of the NIDS but on a per-host basis. This has a lot of advantages, as it will try to detect attacks to the host exclusively, and the traffic that it will analyze will be only packets with the host destination IP address. The disadvantage of this kind of IDS is that it needs to be deployed in every host.


Prelude is an example of a hybrid-IDS. It is divided into two different parts: the sensor, called Prelude NID, that is responsible for the packet capture and analysis, and the report server, used by the sensor to report an intrusion attempt. Prelude has an interesting feature that deserves some comments: the capability to read rules from Snort IDS. In other words, it has a complete rule set ready to use. From its web site, it is also capable of reading rules from any NIDS. Prelude was built with the cluster concept in mind. This explains the idea of deploying information into a different machine called a report server, which has the job of translating all the information received into a user-friendly format, such as HTML.

Understanding and Creating Signatures

As we learned before, signatures are attack patterns. It's important to understand how they work, so we can create them on-demand or when a new exploit is discovered. In our examples, we will see how Snort handles its signatures. In the second half of 2001 we observed new and powerful worms on the Net, such as Code Red, Code Red II and Nimda. When these attacks started to happen, Linux users (and I was one of them) felt very lucky because the worms mainly were attached to Microsoft's IIS (Internet Information Server). These worms had some particular patterns, for example, trying to access the cmd.exe file through Microsoft's IIS. By knowing this, we easily could create a Nimda Snort rule as mentioned in the section “IDS types and Models”:

alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS 80
  (msg:"WEB-IIS cmd.exe access"; flags: A+;
  content:"cmd.exe"; nocase;
  classtype:web-application-attack; sid:1002; rev:2;)

Okay, but what does it mean? Snort rules are nothing more than sequential parameters divided in two sections that we use to inform Snort of what we want it to pay attention to. The first section is called rule header and includes everything before the first brackets. The first parameter in this header tells Snort what to do when the packet matches this rule—in this case, “alert” indicates that Snort will generate an alarm and then log the packet. The second parameter tells Snort what kind of protocol we want—in this case, just TCP. The next five parameters indicate the source IP address and port, direction of the packet, destination IP address and port. In this way, we know that a packet from any address outside of our network, with any source port, going to an IP address in our internal network at port 80 (usually web servers listen to this port) will be checked by the internal parameters of the rule, called rule options. The rule option section contains alert messages and information about which parts will be checked in the packet, and then with the result of this inspection, the appropriate action will be taken.

Rule options in our example:

  • msg: “WEB-IIS cmd.exe access”—description of the alert.

  • flags: A+—logical operator (+) to test all flags in the packet.

  • content: “cmd.exe”—sets the specific content (cmd.exe) in the packet payload.

  • nocase—will match the specified string with case-insensitivity.

  • classtype: web-application-attack—classification of the alert.

  • sid:1002—Snort rule ID.

  • rev:2—rule revision number.

In the Snort Users Manual you can find more than 30 rule options that you can use to satisfy your needs. Too complicated? No, it is not! Let's try to create a simple rule to alert any porn web access attempt from your network using the few rule options above:

alert tcp $INTERNAL_NET any -> $EXTERNAL_NET  80
  (msg: "Web Porn Access Attempt"; content:"Free porn";
   nocase; flags:A+);