The scalable and efficient Snort open-source Network Intrusion Detection System (NIDS) uses a series of well-defined rules to detect anomalous packets on your network. Maintaining these rule sets dramatically improves the system's effectiveness. A few rule-management techniques can help you maintain your Snort IDS. First, you can prevent an alert overload by tightening variable definitions and grooming your Snort rules. You can also persist your custom rules across rule-set upgrades. Finally, you can deconstruct a rule to understand how to customize rules for your environment.
By default, Snort contains more than 1900 stock rules within a series of nearly 50 text files organized by type, as Figure 1 shows. These rules define response triggers to many known vulnerability exploits pertaining to Windows, UNIX, and widely used applications such as Microsoft IIS, Apache, Microsoft SQL Server, and Oracle SQL. The rules also help Snort provide reconnaissance data and possible configuration warnings to alert you of network scans or of a machine that's broadcasting an SNMP default community string, for example. As you might imagine, Snort can generate a tremendous number of alerts. To reduce the noise of the stock rules, the default Snort configuration enables only about 1300 of the rules by default and disables entire rule types, such as policy, chat, and virus, by default. (A rule type is typically contained within its own text file, so rules of type virus are contained in the file virus.rules.) Review any disabled rule groups and enable any that might apply to your environment.
Prune Your Rules
Even with the many rules that Snort disables by default, your Snort IDS system likely will generate many alerts. Trudging through all these alerts might dull your senses to truly suspicious traffic. After you install Snort in your environment, prune the rules to remove those that don't pertain to your environment or that don't concern you. For example, if you don't have the HTML embedded scripting language PHP: Hypertext Preprocessor (PHP) installed in your environment, you can disable the web-php.rules rules file. When deciding which rules to disable, however, consider users who might have various software on their machines. For example, one of your Snort sensors might pick up suspicious packets from a compromised home machine over a VPN connection. So, continuing the previous example, even if you don't have PHP installed on any of your corporate computers, one of your end users might have installed it at home. If that home computer were compromised through a PHP vulnerability, the attacker might be able to access your corporate network while the compromised computer is remotely connected to the corporate network (such as over a VPN).
Most alerting and reporting systems display the name and SID for each rule for easy reference. To further trim your list of enabled rules, monitor your systems, jot down extraneous rules' names or SIDs, then disable those rules. To manually disable a Snort rule, open the rule file and insert a pound sign (#) in front of the rule. To disable an entire class of rules, add a pound sign in front of the rule filename in the Snort configuration file. You must restart Snort to load the modified rules.
Revisiting your rules regularly and continuing to eliminate those that don't apply to your network will dramatically decrease the number of alerts that Snort generates, thereby making it easier to spot and identify truly suspicious packets. And remember to reenable rules as necessary when you introduce new technology that currently disabled rules would protect.
Keep Rules Current
Snort.org hosts two versions of Snort rules: snortrules-stable and snortrules-current, which work with Snort 2.0x and Snort 1.9x, respectively. The newer rules contain additional signatures and updates to existing rules to make use of expanded variables. For example, the version 2.0.0 rules define variables that specifically describe certain machine functions (e.g., the variables HTTP_SERVERS and HTTP_PORTS characterize computers that run Web services and might be prone to Web service attacks). These new variables work in the new rules to further screen incoming attacks. An old rule might alert you to a suspicious HTTP request destined for any computer on your network, but the new rule looks for the same attack only when it's destined for a Web server that the HTTP_SERVERS variable defines. This classification process helps reduce false alarms.
Snort.org updates the rule sets frequently to stay up-to-date with new exploit discoveries. To stay current, regularly check for, download, and apply new rules that would be useful in your environment. However, note that whenever you download a set of new rules, the text files containing the new rules overwrite those containing the old rules. You'll quickly find that commenting out all your unused rules every time you update your rule files is burdensome.
Oinkmaster to the Rescue
Fortunately, several open-source tools can help you overcome this problem. A Perl script program called Oinkmaster, which you can download from http://www.algonet.se/~nitzer/oinkmaster, automates the download of new rules and manages disabled or modified rules. Tailored for UNIX systems, the Perl script uses the wget, tar, and gzip tools to fetch and expand new rules whenever the script runs. Most of these tools come installed on UNIX systems, but you can download the tools for Windows. Remember that open-source solutions have limited dedicated support (if any), so look online for solutions to any problems or questions you might have. The open-source software (OSS) community abounds with useful information. A good place to start is by subscribing to one of the Snort mailing lists, which you can sign up for at http://www.snort.org/lists.html.
Be sure to consult the README file for detailed installation instructions for your platform. The basic Oinkmaster installation procedure consists of expanding the oinkmaster.pl and oinkmaster.conf files into your Snort directory (or a directory you specify), then using oinkmaster.conf to configure Oinkmaster.
Open oinkmaster.conf and follow the inline comments to configure the tool. First, confirm the location of the updated rules as a Web address (e.g., http://www.snort.org/dl/signatures/snortrules.tar.gz). Be sure to point Oinkmaster to a trusted and reputable site, especially if you choose to download and install the rules automatically. Otherwise, you run the risk of downloading corrupted (or worse, tampered) rules that could compromise your IDS.
Next, specify the files to skip, modify, and disable. By default, Oinkmaster doesn't process (i.e., it skips) local.rules and snort.conf.
The script's modifysid feature lets you modify newly downloaded rules; think of modifysid as a Search and Replace feature for a specific rule that you identify by SID. With this command, you can modify the text of a specific rule. For example, you can use modifysid to enable a rule that's disabled by default. To do this, add a new modifysid command identifying the rule that you want to enable and instruct it to remove the comment character (#). Anytime a new rule set is downloaded, this comment character will be removed when Oinkmaster parses that rule. You can also use modifysid to elevate a rule's action type. For example, the command
modifysid 2003 "alert" | "sev1"
elevates the alert with a SID of 2003 to a custom action type of sev1. Oinkmaster does this by searching for "alert" and replacing it with "sev1". And yes, it will make multiple substitutions, so use it with care.
The final and most popular Oinkmaster feature, disablesid, lets you disable selected rules. Specify the SIDs of all rules that you want to keep disabled. For example, to disable alerting on network scans, you might start with an entry similar to
disablesid 469, 615, 618, 620
After downloading and parsing a new set of rules, Oinkmaster looks for the specified SIDs and comments out the rules. As long as Oinkmaster manages your rules, the rules will remain disabled, even across rule-set updates.
Manually execute the script whenever you want to update your rules. If you feel bold, schedule the script to run and update the rules on a recurring basis. Oinkmaster will fetch the rules, expand them, and copy them into your sensor's rules directory. As with most OSS, use Oinkmaster with discretion and first learn what it does and how it will affect your environment. For example, test a new set of rules by running Snort in the self-test mode (by using snort -T plus your other parameters) before deploying the rules into your production environment.
Oinkmaster lets you avoid the risks of downloading dubious updates by giving you the option of backing up old rules and by delivering a log of its actions to the console. Review this output, which shows removed rules, modified active rules, nonrule revisions, and new files, to confirm that Oinkmaster successfully completed its tasks and to confirm the rules that Oinkmaster modified. If you choose to schedule Oinkmaster to run automatically, consider emailing the results to facilitate review, as Figure 2 shows. The following example shows how to schedule Oinkmaster to run daily at 6:15 a.m. by using the Linux crontab command (crontab lets you schedule jobs in Linux):
15 6 * * * /home/snort/ oinkmaster.pl -o /home/snort/ rules -b /home/snort/backup 2>&1 | mail -s "Oinkmaster" [email protected]
The Oinkmaster parameters specify the rule directory (-o), the backup rule directory (-b), and a command to email the results to the owner. The command 2>&1 sends the StdErr output to StdOut (the console) before sending it to the email application.
Looking at a Snort Rule
In addition to disabling or making basic modifications to the stock rules, you can create your own rules and further tailor the Snort rules directly to your environment. For example, consider a sensor deployment that monitors traffic inside and outside your firewall. Although knowing how many worm attacks your firewall repels might interest you, knowing whether any of those attacks originated from within your network will probably interest you even more. Recently, Snort rules have included "tuned" rules like the above example, but many others remain that you might want to customize similarly. Listing 1 shows a standard rule that alerts you when it detects the SQL Slammer (aka Sapphire) worm. Let's quickly deconstruct this rule. (For detailed information about all available parameters that define the rules, refer to the thorough Snort rules documentation at http://www.snort.org/docs/writing_rules/chap2.html#tth_sec2.3.26.)
All rules must reside on one line and begin with a rule action, which in this case is
The rule action defines how Snort responds to the rule if triggered. You can modify the rule type (e.g., to a string such as 'sev1') to provide custom handling—for example, to escalate the action in case of a match. This step is different from the previous example, in which we used Oinkmaster to change the alert type of an existing rule; in this example, we're creating a new rule using an existing rule as a template.
The set of parameters
udp $EXTERNAL_NET any -> $HOME_NET 1434
provides the protocol, IP address, port information, and traffic direction for the rule. This rule tells Snort to find any UDP packet from a network source (which the variable $EXTERNAL_NET defines) attempting to go to the variable $HOME_NET on port 1434. Most default rules primarily use the variables $EXTERNAL_NET and $HOME_NET. However, some rules use more specific variables. For example, the rules that pertain to DNS servers (in the dns.rules file) use the variable $DNS_SERVERS. Define these variables in the Snort configuration file (typically snort.conf). Optionally, create your own variables to reflect your topology (e.g., $MAIL_SERVERS) and for use in custom rules. Define a variable by using its name (e.g., var MAIL_SERVERS= 192.168.0.20/30), then reference the variable by prefixing it with a dollar sign ($—e.g., $MAIL_SERVERS). The rule action and these parameters make up the rule header.
The rule options further refine the rule so that a suspect packet (and only a suspect packet) will trigger a response. As you might guess, these signatures can become quite detailed and extend far beyond simple port matching. For example, imagine the false positives that would result if this Slammer rule simply alerted you to any UDP port 1434 traffic.
The msg option
msg:"MS-SQL Worm propagation attempt"
provides a simple description of the alert for use in alerting and reporting activities. The content option
content:"|04|"; depth:1; content:"|81 F1 03 01 04 9B 81 F1 01|"; content:"sock"; content:"send";
contains the case-sensitive payload pattern matching string, in either ASCII or hexadecimal values (enclose hex values with the pipe character—|). You can specify multiple content options. The depth option follows each content option and specifies how many bytes into the payload you want to search for the specified content. In this example, a packet will trigger a response if it contains the hex value 04 in the first byte or the remaining content anywhere in the payload.
Downloaded rules often contain references to detailed information about the suspect exploit or reason behind the creation of the rule. Some reporting systems support the reference option by providing direct links to this information:
reference:bugtraq,5310; reference:bugtraq,5311; reference:url,vil.nai.com/vil/content/v_99992.htm;
Snort assigns rules to classes and assigns these classes a priority of high, medium, or low. Currently, more than 30 classifications exist, including attempted-admin, trojan-activity, attempted denial of service, and network-scan. In our example, the classification is
Snort records the response priority for detected intrusions. You can use an external tool or script to further parse this priority and take action with your reporting application.
In the final segment
sid represents a unique Snort rule, and rev denotes the revision number. These properties uniquely identify the rule.
Tailoring the Rule
Let's examine how to modify this rule to provide an escalated alert when it detects internal infected hosts. Because we're dealing with the same exploit as the original rule, the content definition of the rule remains the same. We need to modify only the IP addresses and traffic direction. Let's change the source IP address to $HOME_NET, as follows:
udp $HOME_NET any -> $EXTERNAL_NET 1434
Snort.conf defines $EXTERNAL_NET as "any," so this rule will still catch corrupt packets that target internal hosts (as would the original rule). However, now that we have a dedicated rule that tracks only internal source IP addresses, we can change the action type to a custom action type that triggers an escalated alert.
The current Snort rules include this outbound Slammer worm detection rule in the default rule set. However, when a new worm, virus, or other exploit begins to spread, consider creating new rules that highlight specific intrusions.
Making Your Rules
In addition to existing or custom rules that you can modify or create, you might want to include rules you get from another source. For example, when news of a new worm spreads across the Internet, security sites and newsgroups are quick to publish one-off Snort rules that can detect the new worm. Paste these new rules into the local.rules file, then restart Snort for the new rules to take effect.
Snort provides the framework for an inexpensive and customizable IDS. Buoyed by a community-supported rule set, Snort remains a flexible and effective system. Keeping your rules current will increase your vigilance and lower the noise that results from ineffective alerts. As with any open-source project, taking the time to understand how it works and familiarizing yourself with its community-developed add-ons will dramatically improve your comfort with the system and increase its effectiveness in your environment.