Snort rules are powerful, flexible and relatively easy to write. It's best to start with the VRT (Sourcefire Vulnerability Research Team) Certified rules because they are the best written, but there are other sources for rules. Once you've downloaded existing IDS rules, you can modify them to suit your needs.
To get started, review the FAQ at Snort.org, and while you're there, download the latest VRT rules. (See How to decipher the Oinkcode.) Read the rules, modify them and try them (in a test environment, of course). If there is a Snort rule that doesn't work quite the way you want it to, you can change it. Here's how.
All Snort rules follow a very simple format that is worth examining. But first a note about SID and Rev (revision). The SID is the Snort rule ID (a.k.a. Signature ID). Snort.org has reserved any number less than 1 million for the "official" rules, and Bleeding Snort uses SIDs starting at 2 million. If you modify a rule, just add 1 million to the SID so you can keep track of the original. If you create a new rule, use a SID starting at 9 million. Increment the revision whenever you make a change and rule change control is complete.
Some Snort.org rule sets come with an empty local.rules file. Don't use it or your custom IDS rules may be overwritten by the empty file the next time you install new rules. Create one or two other files such as company_prod.rules and company_test.rules, and add an include statement in your snort.conf file. You can run more than one instance of Snort on a single machine and interface, which can be useful for testing rules, but it may be easier and safer to run a test Snort on an old PC in parallel with your production box.
Here is a simple Snort rule:
alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"ICMP PING NMAP"; dsize:0; itype:8; reference:arachnids,162; classtype:attempted-recon; sid:469; rev:3;)
This code means: Send an alert if you see an ICMP packet from whatever the $EXTERNAL_NET is defined as (default = any) to whatever the $HOME_NET is defined as (default = any), if the data size (dsize) is zero and the ICMP type (itype) is 8 (which is echo (request)). (See also: http://www.snort.org/pub-bin/sigs.cgi?sid=469.) Other actions beside "alert" include, but are not limited to, log and pass. The protocol in this case is ICMP, but IP, TCP and UDP are also supported. Variables are defined in the configuration file and prefixed with a dollar sign.
SID 469 is not a very good rule. It causes a lot of false positives, because it's rather "loose." Other applications beside NMAP send echo request packets with no payload, and there are no other criteria to make the rule "tighter" or more specific. A better rule is:
alert udp $EXTERNAL_NET any -> $SQL_SERVERS any (msg:"MS-SQL probe response overflow attempt"; content:"|05|"; depth:1; byte_test:2,>,512,1; content:"|3B|"; distance:0; isdataat:512,relative; content:!"|3B|"; within:512; reference:bugtraq,9407; reference:cve,2003-0903; reference:url,www.microsoft.com/technet/security/bulletin/MS04-003.mspx; classtype:attempted-user; sid:2329; rev:6;)
Due to space constraints I can't examine each detail of this rule, but you can see just from looking at it that it is much more specific. You may also have noticed that these examples include references to external sources. See the "reference.config" file in your Snort "etc" directory for the urls, or look up the SID on the Snort site for rule documentation including links to these references.
Snort v2.1.0 introduced PCRE (Perl Compatible Regular Expressions), thresholding and suppression, all of which are critical for proper tuning. PCRE allows the use of Regular Expressions in rules, so you can be very specific about what you are searching for. The three kinds of thresholding allow you to limit the number of alerts sent for "noisy" rules in various ways and may be written into custom rules or placed in a separate configuration file such as threshold.conf. In particular, you can use such an external file to "tune" the official Snort.org rules without having to actually modify those rules, which makes updating them much easier. Suppression commands allow you to be very granular and specific about which devices will and will not trigger alerts. For example, if you have a network management station at 10.1.1.54 that polls SNMP devices using a community string of "public" (you know that's really bad, right?) you can suppress it using a rule like:
suppress gen_id 1, sig_id 1411, track by_src, ip 10.1.1.54
We've only scratched the surface here. For more comprehensive information see the Snort Users' Manual and FAQ at Snort.org, and get current rules from Snort.org and BleedingSnort.com. The "readme" files are included with the Snort source code, which you can download and examine to learn more. If you don't want to download the source code tarball you can access all of Snort's source code, documentation and obsolete rules on the Web the Snort CVS Repository. Note the rules in the public CVS repository are not being maintained as of April 2005, though there is discussion about that and it may change. You can also read the archive or join the Snort Sigs mailing list at Snort.org.
SNORT INTRUSION DETECTION AND PREVENTION GUIDE
Why Snort makes IDS worth the time and effort
How to identify and monitor network ports
How to handle network design with switches and segments
Where to place IDS network sensors
Finding an OS for Snort IDS sensors
How to determine network interface cards for IDS sensors
Modifying and writing custom Snort IDS rules
How to configure Snort variables
Where to find Snort IDS rules
How to automatically update Snort rules
How to decipher the Oinkcode for Snort's VRT rules
Using IDS rules to test Snort
ABOUT THE AUTHOR:
|JP Vossen, CISSP, is a Senior Security Engineer for Counterpane Internet Security. He is involved with various open source projects including Snort, and has previously worked as an information security consultant and systems engineer.|