Snort Cookbook/Rules and Signatures

From WikiContent

< Snort Cookbook
Revision as of 17:56, 26 August 2009 by Docbook2Wiki (Talk)
(diff) ←Older revision | Current revision (diff) | Newer revision→ (diff)
Jump to: navigation, search
Snort Cookbook



The ability to customize Snort through the use of rules is one of the program's greatest advantages. This chapter will show you how to build rules that aid Snort in seeking out things specific to your needs. The chapter includes some examples of specific uses of the rules language. The trick to writing effective rules lies in a few tips:

ol lidivLook for something that's repeated every time the condition occurs. Like ttGET //tt or ttPOST //tt in a web connection. /div/li

lidivTry not to make your trigger so general that it fires on every connection.

alert tcp any any - any 80 (msg:"port 80 connection!!!"; 
flow: stateless; rev:1;)


lidivYou can use multiple conditions in a single rule for more accurate detection. For example, the following rule looks for a successful compromise of a wu-ftpd server (one of the most common Unix FTP servers that has been known to be plagued by exploits). The rule looks for the client sending the command ttuname/tt, along with some reference to a /bin directory.

alert tcp $HOME_NET any - any 21 (msg:"FTP compromise - success 
w00t"; content:"uname"; content:"\/bin"; flow:from_client, 
established; rev:1;)



Now let's look at some specific examples of the rules engine and its power in helping defend your network.

How to Build Rules


I see all these examples. Now, how do I create my own rules?


This is a rough example of the Snort rule language and its capabilities. We'll take some generic rules from the official Snort rules so that you can look them up later when you want to try them on your network. These examples will demonstrate a simple protocol identifier, port usage, and finally, packet details for application data.

Protocol rules

Snort can detect when an IP protocol is in use on the network. For example, Snort Identification (SID) number 2187—from the official Snort rules—detects when protocol 55 (IP Mobility) is in use on the network.

alert ip any any - any any (msg:"Bad-traffic IP Proto 55 IP 
Mobility"; ip_proto:55; reference:bugtraq,8211; reference:cve,
2003-0567; classtype:non-standard-protocol; sid:2187; rev:3;)

This official signature from also uses of one of the other keywords from the Snort language: ttreference/tt. This keyword can link to a URL for information, bugtraq, CVE, ARCHNIDS, the MacAfee virus database, and even a file on the system. However, this will alert on any packet traveling over protocol 55, no matter what its source or destination is. This rule has undergone three revisions to get to the current point.

Port rules

This example looks for a particular port in use on the network. In this example, we don't care what the payload is in the packet; we just care about the protocol and the port in use. One word of caution: be very careful about using this type of rule. It can flood Snort when used for a common port. However, this rule would be good for a policy-based IDS infrastructure in which a given port should never be used on the network and you want to be notified when client machines try to use it. This example detects IRC connections over the default port of 6667/tcp from our network.

Alert tcp $HOME_NET any - any 6667 (msg:"IRC port in use"; 
flow:from_client,stateless; sid:10550; rev:1;)

One problem is that IRC can use more than one port. 6667-7001/tcp is its default range. So let's change that rule to detect when any of these ports are in use on the network.

First, add a variable to the snort.conf file:

var IRC_PORTS 6667:70001

Then rewrite the rule to reflect the change.

Alert tcp $HOME_NET any - any $IRC_PORTS (msg:"IRC ports in use"; 
flow:from_client,stateless; sid:10550; rev:2;)

Application rules

Sometimes you'll want to detect when something happens inside of an application or protocol such as when a Microsoft IIS server has been exploited successfully. This example again pulls from the official Snort rules for SID number 2123. This rule shows some of the power of the Snort engine and rules language in filtering out traffic. It also shows how much detail it can extract from a packet.

Alert tcp $HOME_NET !21:23 - $EXTERNAL_NET any (msg:"ATTACK-RESPONSES 
Microsoft cmd.exe banner"; flow:from_server,established; content:
"Microsoft Windows"; content:"|28|C|29| Copyright 1985-"; distance:0; 
content:"Microsoft Corp."; distance:0; reference:nessus,11633; 
classtype:successful-admin; sid:2123; rev:2;)

This rule says to ignore any traffic coming back on ports 21-23/tcp and to get very specific packet details. For example, it uses the ttcontent/tt keyword that locates either ASCII text in the packet payload (ttcontent:"Microsoft Corp./tt") or raw binary values in the packet (ttcontent:"|28|C|29|/tt"). The binary data is broken up by the pipe (tt|/tt) character and represents the HEX value of the binary data. This rule also uses the ttdistance/tt keyword to skip down bytes into the packet for analysis. If the packets you're looking for are large and common, this can help in finding the "bad" packets in a stream of good connections.

Finally, this rule uses the ttflow/tt keyword. This keyword marks that the rule only runs on packets that are:

  • Part of an established connection. (The TCP three-way handshake has been completed.)
  • Part of a stream that's returning from the server. If we are recording full TCP sessions, our previous packet was most likely some kind of exploit packet, and it was successful given this rule being fired.


Having seen the previous examples, you should realize that the rules language is rich with options to use for detecting traffic on your network. One caveat is that any encrypted traffic—such as HTTPS traffic—can't be unencrypted with Snort. You can work around this if you encrypt the connections to the border of your network but keep the link to the web servers inside the network unencrypted. This could be accomplished through use of a secure proxy or SSL accelerator card. This might also make it easier to determine the cause of issues with any of your web-based applications. You might be thinking that rules can get quite complicated. One of the nice things about a tool as popular as Snort is that there is a large community of people willing to help answer questions and problems. Local Snort user groups and the Snort-sigs mailing list are just a few of the possible sources of help.

The Snort rules have a basic format that expands for more specific needs.

snort action protocol src IP src PORT direction dst IP 
dst port (msg:"Tell the user what I'm tracking"; optional 
classtype ;optional snort ID (sid); optional revision (rev) 

This can be broken down and identified as shown in Table 3-1.

div id="snortckbk-CHP-3-TABLE-1" Table 3-1. Snort rule language keywords

Part Information
Snort action This can be one of three keywords. alert sends an alarm on this signature. log doesn't create an alarm, it just log this alarm (to a file, for example). pass is used mostly for policy based IDS. It tells the Snort engine to pass only packets that match the signature, no matter what else is in the packet(s).
Protocol This keyword tells Snort what protocol to monitor. It can be one of the more common protocols like tcp, udp, and icmp. Or it can be IP in general to monitor another IP protocol. However, with IP, you need to add the keyword ip_proto, followed by the number of the protocol, in your /etc/protocols file on Unix systems. You can find a complete list of IANA protocols at
Source IP This is the host or group of IP addresses from which Snort will be looking for the connection to originate.
Source ports This is the originating port from which Snort will be looking for the connection to start. For most connections, the ports are dynamic, and as a result, pass Snort the keyword any, and the source port will not matter.
Direction This tells Snort whether to look for the connection to start from your source IP or from your destination IP. This can be in the form of - for source-to-destination, - for destination-to-source, or - for bidirectional traffic.
Destination IP This is the destination IP or group of IP addresses where Snort will look for the connection to end.
Destination port This is the destination port of the traffic that we are looking for: 80 for HTTP, 21 for FTP, and 23 for Telnet connections, just to name a few.
Message This is the comment field of a Snort alarm. This information is displayed to an alarm manager such as ACID or syslog.
Class type This is a priority helper. If you're using a tool like Barnyard to prioritize alarms into those that need to be looked at immediately or those that can wait until a slower time during the shift/day/etc., this is the way to mark them. For example, attempted-admin is one name while network-scan is another. For the full list of classes, check out the Snort source code manual.
Snort Identification (SID) number This is the "unique" number assigned to your rule. If you create your own rule, the convention is to number it starting above 10,000. This makes an obvious distinction between the official Snort rules and your creations.
Revision number This is an optional keyword, but you will find it useful once you start creating multiple rules. It can also be useful if you have to keep track of rule changes for an entire IDS team.


Table 3-1 lists only a core set of keywords. There are more language keywords that allow for a much more granular level of analysis and detection into network traffic.

See Also

Snort user groups


Snort users' mailing lists

Snort documentation for the most current rule language changes

Keeping the Rules Up to Date


In the current Snort build, there are about 3,500 rules. How do I make sure I have the most current rules to protect my network?


The defacto Snort rule updater is Oinkmaster (). It allows for scripted and automatic rule updates. This runs as a command-line tool for ease of scripting, but it does have an add-on component for GUI management. The recommended way to use Oinkmaster is to determine when rules have changed, without having it automatically update your rules. If you allow Oinkmaster to update your rules automatically, you open up a big can of trouble for change management and rule management within a security team. However, it's useful if you just want to have a daily comparison between your currently running rules and the rules on

Download Oinkmaster:

mkdir /opt/oinkmaster 
mkdir /opt/oinkmaster/CURRENT_RULES
mkdir /opt/oinkmaster/NEW

Copy your currently running rules to CURRENT_RULES and compare them with the official rules:

perl -o /opt/oinkmaster/CURRENT_RULES -c -C 

As you might have noticed, you don't see the results as they scroll by, so from a Bourne shell, try the following:

# shperl -o /opt/oinkmaster/CURRENT_RULES \ 
 -c -C oinkmaster.conf  OINK_Report.txt 21

For those readers who might convert this to a daily report to show any changes in the official rules, the following script should work:

# Checks daily for changes to the currently running Snort rule set 
# Runs from cron every 24 hours 
# * 23 * * * /bin/sh /opt/ 
# Variables 
# Date of the report 
mydate='date "+%c"' 
# Run oinkmaster Capturing all of the output 
perl /opt/oinkmaster -o /opt/oinkmaster/CURRENT_RULES -c 
-C /opt/oinkmaster/oinkmaster.conf  /opt/oinmaster/OINK_Report.txt 
# Create a function report 
echo " Snort Rule Change Report "  /opt/oinkmaster/Daily_report.txt
echo " "  /opt/oinkmaster/Daily_report.txt
echo "   For Date: $mydate "  /opt/oinkmaster/Daily_report.txt 
echo " "  /opt/oinkmaster/Daily_report.txt 
cat /opt/oinkmaster/OINK_Report.txt  
# Use mutt to send our emails 
mutt -s "Daily Snort Changes" IDS_TEAM@organization  /opt/oinkmaster/OINK_Report.txt
# Push to web server for a web portal ?
# Future? 
# Other ideas ? 
# Done !! 


You can configure several options in the oinkmaster.conf file to enable OinkMaster to change your rule sets. With the oinkmaster.conf file, you can specify such things as:

  • Push the rules to other hosts via SSH's secure copy (scp) once they're downloaded and updated.
  • Edit the oinkmaster.conf file to compare only your rules files.
# find the line in the conf file 
# titled "update_files = \.rules$|\.config$|\.conf$|\.txt$|\.map$"
# then change it to 
"update_files = \.rules$
  • This then tells Oinkmaster to compare only rules and not other files such as your snort.conf file
  • Edit the oinkmaster.conf file to ignore certain rules files. For example, a good idea is to only add or change rules in the local.rules file, and then leave the official rules alone. If you follow that guideline, you'll find that rule management becomes a whole lot easier.
# find the line in the conf file 
# titled "skipfile=local.rules" 
# If you are following the above statement then uncomment 
# This line by removing the "#"
  • If, however, you are making changes to other files and want to keep them, just make a new line in the config file with a comment as to why you are skipping the rule file. (This is a good habit to start, especially in larger security teams.) Then create a ttskipfile=rule_file_name.rule/tt line for that ruleset.
  • Edit the oinkmaster.conf file to change, modify, and even enable and disable Snort rules based on SID number. Each Snort rule has a unique number assigned to it. The ones from are numbered up to about 3,500. Custom rules made by individuals and organizations should be numbered above 10,000.

For example, to modify one or more Snort rules, edit the oinkmaster.conf file. You will need to specify the rule number and the change you want to make such as in the following example, which would be a good reference.

# modifysid 1378 "^alert" | "pass"

This changes Snort rule number 1378 from an alerting rule to a pass rule that will ignore the traffic.

If, however, you want to forcibly enable or disable specific rules, that's possible as well. Use the ttenablesid/tt and ttdisablesid/tt commands in the oinkmaster.conf file.

To enable a specific rule that was disabled in the official distribution, you would use something like the following:

# enablesid 1325

You can also disable a specific rule that was enabled by's distribution. For example, you could disable a rule that, on your network, is quite noisy with false positives with the following:

# disablesid 1325

So as you can see, Oinkmaster offers quite a bit of functionality for an organization's IDS team.

Finally, if you want a functional GUI for Oinkmaster, an file comes with the Oinkmaster distribution under the contrib directory. However, to run this under *nix systems, you will need to have Perl/Tk installed.

To install a new Perl module on a system, if you have root access, download Tk from this site, as found in the Oinkmaster documentation.

Once downloaded, the simplest way to install a new Perl module is to extract and compile the source code into your local Perl library.

# EXAMPLE tk800.024 
perl Makefile.PL 
make test 
make install

If you are on a windows system and want to use the GUI, just download and install the ActivePerl Windows distribution. This build comes with all the components necessary to run the GUI.

  1. Run the GUI


Once in the GUI, you will need to specify the location of several key components, such as the following:

Path to your Oinkmaster.conf file: 
Path to your file 
your output directory 

For an example of GUI, see Figure 3-1, as you might find it easier to use than editing the config file itself.

div id="snortckbk-CHP-3-FIG-1" Figure 3-1. Oinkmaster GUI examples

Oinkmaster GUI examples /div

See Also

Oinkmaster mailing list

Basic Rules You Shouldn't Leave Home Without


With so much flexibility and so many predefined rules, how do I choose? Are there any rules that an organization should always have in its toolbox?


This is largely a matter of preference for each organization's IDS team personnel, but a few rules are accurate indicators of potential problems on a network and well worth keeping around.

The most noticeable of these rules would be cmd.exe, which detects the automated Unicode and nimda-style attacks.

(msg:"WEB-IIS cmd.exe access"; flow:to_server,established; 
content:"cmd.exe"; nocase; classtype:web-application-attack; 
sid:1002; rev:6;)

Another one for helping find the virus/Trojan of the week is a custom rule that triggers on client machines acting as mail servers. We have found this rule very effective.

alert tcp !$SMTP_SERVERS any - !$SMTP_SERVERS 25 (msg:"Possible 
virus Mailing";flags:A+;classtype:policy-violation;sid:11111; 

This rule triggers on mail not sent from our mail servers to outside mail servers. However, with the most recent mydoom family of viruses (a family of viruses that spread via email rapidly), we have one word of advice: use the threshold.conf for this rule unless you want to have a flooded database. :) As this rule will be fired for every packet on port 25/tcp that wasn't sent or received by your list of mail servers, it has the potential to generate lots of alarms. For organizations plagued by Instant Messenger, this might be helpful.

alert tcp $HOME_NET any - $AIM_SERVERS any (msg:"CHAT AIM login"; 
flow:to_server,established; content:"*|01|"; depth:2; 
classtype:policy-violation; sid:1631; rev:6;)

This will trigger a lot if you have IM users on your network. However, when combined with session logging and other tools, you will have a nice evidence log of a clear policy violation. This is also helpful in the case of a financial organization, which, according to SEC mandate, must log and analyze all IM communications with external investment banking clients so they may detect potential securities trading violations.

The following triggers an alarm of the IE browser exploit from the MS04-013 vulnerability for the ms-its sub-protocol.

alert tcp any any - any any (msg:"Possible browser hijacking"; 
content:"ms-its\:mhtml\:file"; content:"chm"; flags:A+; 
classtype:bad-unknown; rev:4;)

This will capture a user browsing or getting through email the exploit for this vulnerability. The file is hidden from IE by using a Microsoft compiled help (.chm) file to load. However, it is actually loading an .exe file that IE will helpfully execute locally on a user's machine.

The following rule, which triggers on 403 errors coming back from your web servers, can be invaluable, especially if you are dropped into a new network as a consultant.

(msg:"ATTACK-RESPONSES 403 Forbidden"; flow:from_server,
established; content:"HTTP/1.1 403"; depth:12; 
classtype:attempted-recon; sid:1201; rev:7;)

This can help you identify what kind of traffic is affecting a client's web servers. For example, if you walk into an organization and turn on this rule to get something like:

HTTP/1.0 403 Access denied to webserver_IP../../../winnt/system32

It would tell you that either the organization's web server is still vulnerable to the directory traversal attack or that outside attackers are trying to exploit the system.


Hopefully, you will realize that there is no silver bullet set of rules to use in any organization. But this discussion should give you an idea of where to start and the broad scope of the rules.

If you are just coming into an organization, you can turn on the default Snort rules and tune down to a more manageable ruleset as you have time. Another option would be to tune out the default rules you know are useless.

Finally, if you want to tempt fate, you can get a copy of the rules at the following site: . They are as close to zero-day rules as we can get, though a BIG word of caution goes out to people who are going to try to run them straight on a core or border sensor.

See also

Recipe 3.6

Snort-sigs mailing list

Dynamic Rules


I need to analyze a connection to verify whether it's an attack or normal traffic. How can Snort help?


Snort has a couple of answers to your question. First, there is a keyword ttactivate/tt and its complementary keyword ttdynamic/tt. When a rule marked ttactivate/tt is triggered, it turns on a corresponding ttdynamic/tt rule to capture the exploit, log the next couple of packets, etc.

activate tcp $EXTERNAL_NET any - any 23 (msg:"Solaris TTYPROMPT 
flow:to_server,established;sid:10555;reference:url:; rev:1; activates:1;) 
dynamic tcp $EXTERNAL_NET any - any 23 (activated_by: 1; count:50;)

For example, the previous rule will trigger on a single exploit packet such as most Snort rules. However, this rule then calls its ttdynamic/tt partner to log the next 50 packets to port 23 tcp, which is useful in capturing the results of a successful exploit of a victim system.

However, as you might have realized that this could get unmanageable with only a few rules. It's also not very scalable. So Snort is slowly replacing those keywords with the tttagging/tt keyword. This provides a much simpler method to log attack responses. Here is the same rule changed to the new keywords.

alert tcp $EXTERNAL_NET any - any 23 (msg:"Solaris TTYPROMPT expoit"; 
content:"TTYPROMPT"; depth:17; content:"|20|63|"; flow:to_server,
established; sid:10555;
telnet.c; rev:1; tag:session:50,packets;)

This example captures the same event as the ttactivate/tt rules with only one rule. This example uses the tttag/tt keyword to capture the next 50 packets over port 23 tcp with one addition, accuracy. The tttag/tt keyword tells Snort to log the next 50 packets in the same session between attacker and victim, ignoring other port 23 traffic on the network.


There are several options to the tttagging/tt keyword that might be more helpful to some organizations. For example, the ability to log only the attacker side of the connection or to limit the log based on time or number of packets.

This modification of the same rule is going to log only the next 50 packets to our victim machine using some of the options for the tttag/tt keyword. The options to the tttag/tt keyword are used to create a more accurate and filtered logfile. For example, if you only want to see one side of an attack as in the following, record only one side of the connections.

Alert tcp $EXTERNAL_NET any - any 23 (msg:"Solaris TTYPROMPT 
exploit"; content:"TTYPROMPT"; depth:17; content:"|20|63|"; flow:to_server,
established; sid:105556; reference:url,; rev:1; tag:host:50,

This modification of the same rule logs only the next 50 seconds to our victim machine, using some more options to the tttag/tt keyword. The following example uses the opposite ttsub/tt keywords to the previous example to capture only the next 50 packets heading back to the attacker.

Alert tcp $EXTERNAL_NET any - any 23 (msg:"Solaris TTYPROMPT 
exploit"; content:"TTYPROMPT"; depth:17; content:"|20|63|"; flow:to_server,
established; sid:105556; reference:url,; rev:1; tag:host:50,seconds,

As you can see, this keyword provides a much easier method for event logging. It also provides a level of granularity and flexibility not found with the ttactivate/tt and ttdynamic/tt keywords. When combined with the ttlogto/tt keyword, this can help when working with law enforcement and outside agencies/teams. The ttlogto/tt keyword specifies the name of the file to which to write the results of the alert. For this example, we want the traffic related to this specific event to be placed into a file called telnet_exploit.log. This will create and fill a file in the Snort logging directory when this event is seen, while also creating a session log for the tttag/tt keyword. These files can then be turned over to law enforcement as both the cause and effect of an attack, where the cause is seen in a full packet dump by the ttlogto/tt keyword file as well as the effect from the tttag/tt keywords' file.

See Also

Snort official documentation ()

Snort-sigs mailing list

Detecting Binary Content


How can I detect when binary content is being used and downloaded on my network(s)?


The ttcontent/tt keyword can detect when binary data is traveling over your network. The ttcontent/tt keyword matches both ASCII text and HEX-encoded raw packet data.

For example, this rule triggers when the Napster client application is downloaded:

alert tcp $EXTERNAL_NET any - $HOME_NET 8888 (msg:"P2P napster 
download attempt"; flow:to_server,established; content:"|00 CB 00|"; 
depth:3; offset:1; classtype:policy-violation; sid:551; rev:7;)

For some organizations, going to the Napster site may be allowed as long as files aren't downloaded. Snort can detect when the policy is actually broken. The following rule triggers on the attempted download of the file itself and its ASCII name:

alert tcp $HOME_NET any - $EXTERNAL_NET $HTTP_PORTS (msg:"P2P Napster
client installer"; flow:established; content:"NapsterSetup.exe"; 
classtype:policy-violation; sid:15543; rev:1;)


While rules that detect ACSII content are easier to write, they're open to all kinds of IDS evasion attacks such as character encoding, extra spacing, and even other languages. It is in the best interest of the rule writer to try to find a HEX string in the binary content of the packets for accuracy. Not only are HEX strings faster to detect—as Snort doesn't need to perform ASCII translation on the packet—but they are also more accurate alarms.

Finally, if you need some examples of rules that fire for HEX content with explanations, check out the archives of the Snort-sigs list. The list is a good resource for community-created rules and for help, if you're having trouble creating rules or detecting traffic.

See Also

P2P rules at

Detecting Malware


My company is overrun by malware. How can we track users who have malware and where it's installed?


There is not easy way to detect all malware. However, you can use several methods to try to identify the traffic.

There are several methods with which to track these types of connections.

ul lidivTrack all DNS queries from your network and look for known spyware domains like,, etc. This tracks all A records and pointer records from hosts on your network to your DNS servers. If you allow your users to access external DNS servers, you might want to change ttDNS_SERVERS/tt to ttany/tt.

log $HOME_NET any - $DNS_SERVERS 53 (msg:"DNS query"; content:"A "; 
content:"PTR "; logto: dnsqueries.log;  sid:10501; rev:1;)



ul lidivRecord the web browsers in use on the network. Each browser has a unique name that it uses to identify itself to web servers. For example, if you look in your web server logs, you might see Microsoft Internet Explorer (MSIE) as the vast majority of connections. So record all the user agents but the most common.

Log $HOME_NET any - any $HTTP_PORTS (msg:"HTTP USER AGENT LOG"; flow:
from_client; content:"user-agent"; logto:useragents.log; classtype: 
recon; sid:10502; rev:1;)



ul lidivCertain pieces of spyware—such as Gator—make it easy to determine some important information, such as:

ul lidivWhen an installation occurs. Installation of Gator is done over the Web through ActiveX components or such simple requests as a "GET gatorinst.exe" that the user will just click and install. For example, the following rule detects a Gator install over http:

Alert tcp $HOME_NET any - $EXTERNAL_NET $HTTP_PORTS (msg:" Gator 
Spyware Download"; uricontent:"/gatorcme/"; nocase; classtype:
bad-unknown; sid:10556; rev:1;)



ul lidivThe following rule detects the use of the Gator software once it's installed. Gator communicates using its own name for its ttbrowser/tt.

alert tcp $HOME_NET any - $EXTERNAL_NET $HTTP_PORTS (msg:"Gator 
browser in use"; content:"User-agent\:"; content:"Gator"; nocase; 
flow:from_client,established;  classtype:bad-unknown; sid:10557; 



ul lidivWhen installed, spyware communicates with known spyware company networks. The following rule comes from the Snort-sigs mailing list. It detects general Gator traffic on the network. I've modified the original signature to use the ttflow/tt keyword instead of the old ttflags/tt keyword.

Alert tcp $HOME_NET any - $EXTERNAL_NET $HTTP_PORTS (msg:"Gator 
client usage"; content:"Host\:"; flow:
to_server, established; classtype: bad-unknown; sid:10558; rev:1;)


/ul /div/li



Gator is only one piece of malware that might be running across your networks. The key to detecting and identifying malware is the same as with other types of traffic. Find some common feature of the traffic, such as a word or phrase, or even the HEX of the packets. Then zero in on that and determine some specifics of the traffic that you can repeat with as much accuracy as possible. The other key is to watch your web traffic very closely. User-agent or browser identification is a great method for searching through the logs to find strange connections from your network. Another suggestion is to use some of Snort's other tools to find hosts that are generating more traffic than normal or simply talkative hosts. Talkative hosts are usually an indication of a problem, unless they are servers.

Another suggestion is to use the malware ruleset from . This entire ruleset just targets malware on a network. These rules—though you use them at your own risk—may help you figure out just how much of your total network traffic is used by malware/adware/spyware software. Finally, detecting this type of traffic is really a job for your web proxy server and your DNS server. When you use blocks or denies to hamper this type of traffic, you'll have a more secure network and visibly better performance.

See Also

for the ideas about blocking malware
for some malware rules

Detecting Viruses


How can I use Snort to detect viruses, Trojans, and worms?


One way to detect viruses is to use the following rule from 3.x Rules. This will detect when a box has been infected with a virus that spreads via a new email server.

alert tcp !$SMTP_SERVERS any - !$SMTP_SERVERS 25 (msg:"Possible 
virus Mailing";flags:A+;classtype:policy-violation;sid:11111; rev:1;)

Another rule that helps detect when email messages come through your mail server with "bad" attachments would be this one from the 2.2.0 ruleset. This rule detects 25 attachment types at once!

alert tcp $HOME_NET any - $EXTERNAL_NET 25 (msg:"VIRUS OUTBOUND bad 
file attachment"; flow:to_server,established; content:"Content-
Disposition|3A|"; nocase; pcre:"/filename\s*=\s*.*?\.(?=[abcdehijlmnoprsvwx])
"; classtype:suspicious-filename-detect; sid:721; rev:8;)


Officially, the ruleset carries the previous rule only for detecting viruses. This is because they are more worried about other threats to a network. The other consideration is that there's no need to detect this type of traffic given the speed and scale of such devices as email gateway virus scanners, and also workstation and server antivirus products that even sweep running memory.

See Also

open-source antivirus software

Chapter 7

Detecting IM


We have a problem with users chatting over Instant Messenger networks. How can we detect when they are using the applications so that we can catch them in the act?


The following few examples track AOL IM, Yahoo! IM, and MSN IM usage on the network.


While AOL IM is one of the most aggressive IM clients, it must be able to communicate with a specific server, However, oscar uses quite a bit of IP space when traversing corporate networks. So the snort.conf default variable ttAIM_SERVERS/tt catches the AIM protocol in use when connecting to the known servers. Feel free to submit IP addresses back to Snort as you find more AIM servers.

# This will detect when the client is logging into AOL 
Alert tcp $HOME_NET any - $AIM_SERVERS any (msg:"Chat AIM login"; flow:to_
server,established; content:"*01|"; depth:2; classtype:
policy-violation; sid:1632; rev:1;)

The following rule logs all traffic between AIM clients. If you have AIM users, you'll soon be flooded with alarms, but it may at least yield some interesting results.

Alert tcp $HOME_NET any - $AIM_SERVERS any (msg:"Chat AIM Message"; 
Flow:from_client,established; content:"*|02|"; depth:2; content:"|00 
04 00 06|"; depth:4; offset:6; classtype: policy-violation; sid:1633;

You can also detect and block port 5190/tcp, as this is the default port AIM uses to communicate.

Yahoo! IM (YIM)

Next is Yahoo! IM (YIM). While YIM is not quite as aggressive in its determination to get out, it does have one feature that will drive you nuts. It's crazy about keeping proper time. On one network, we have a YIM event about every 30 seconds when someone is using it! So our rule to detect YIM is again looking for the protocol even when trying to avoid the default port of 5050/tcp.

# This rule will fire on the binary data from the YIM client itself
alert tcp $HOME_NET any - $EXTERNAL_NET any (msg:"Chat Yahoo IM 
login"; flow:from_client,established; content:"|70 61 74 83 d2 f3 b2 
06 46 f6 d6 61 9e 3d 2e|"; classtype:policy-violation; sid:10570; 

While this example tracked the application protocol, the following rule is looking for an actual conversation in the flow. This rule will filter out packets that have a TCP payload of less than 52 bytes to help reduce false positives. The snort keyword dsize allows us to filter packets based on a byte size of the TCP payload data

alert tcp $HOME_NET any - any any (msg:"Chat Yahoo IM Message"; flow:to_
server,established; content:"YMSG"; dsize:52; content:
"TYPING"; sid:10571; rev:1;)


This client is very hard to identify on the network. Since MS integrates its IM client with the clients for users' Hotmail and MSN Mail accounts and uses the unified passport login system, distinguishing IM traffic from normal MSN traffic is a problem. Your only defense is to look for MSN traffic over the default port of 1863/tcp, and then try to determine if the traffic is a result of chat or mail connections.

Alert tcp $HOME_NET any  $EXTERNAL_NET 1863 (msg:"Chat MSN IM 
message"; flow:established; content:"MSG"; depth:4; content:
"Content-Type|3A|"; distance:0; nocase; content:"text/plain"; 
distance:1; classtype:policy-violation; sid:540; rev:11;)

The following rule looks for a file transferred over the MSN IM protocol. This is one way for viruses to appear on workstation machines, even though you have no record of them passing through email or file servers.

alert tcp $HOME_NET an  $EXTERNAL_NET 1863 (msg:"Chat MSN IM file 
transfer accept";flow:established; content:"MSG"; depth:4; 
content:"Content-Type|3A|"; nocase; content:"text/x-msmsgsinvite"; 
distance:0; content:"Invitation-Command|3A|"; content:"ACCEPT"; 
distance:1; classtype: policy-violation; sid:1988; rev:3;)


Instant Messenger is a part of the normal work flow for some organizations. For example, in the financial world, IM is allowed, provided all communications are logged for SEC records. However, for other corporations, IM is just another way that people avoid work and possibly steal corporate information. It can be threat to your network since new viruses and Trojans have exploits through IM to bypass strict border security measures.

Another threat is that most of the IM services have Java or web clients that require no installation and run entirely from the browser. This makes them much harder to identify. Sites like may send chills down your spine if you're concerned about IM security. Some sites allow encrypted access using SSL and anonymous chatting over a web interface. A determined user could use these via a number of proxies to bypass your security measures.

The best hope an organization has for this type of traffic is to use other countermeasures to block it, such as content-based web proxies, DNS blocks of known IM and IM-supporting sites, and perimeter blocking of known IP space for IM servers.

See Also

Snort-sigs mailing list

Detecting P2P


How can I detect when users on my network(s) are using peer-to-peer (P2P) applications, possibly putting our company on the RIAA's radar for investigation?


Much like the IM problem, P2P applications are hard to detect on your network. Users can choose from dozens of networks and just as many clients. One ideal solution would be to have a default policy of deny first on your firewall's outbound traffic. However, in the real world of politics, corporate networking policies, and management exceptions, the ideal solution is rarely possible. So, we'll just try to track the most popular networks: Kazaa, BitTorrent, and Gnutella.


The Kazaa network is actually a mini HTTP protocol for sending files and browsing other user's shared files. It sets up the client to communicate on port 1214/tcp. The following rule detects outbound connections on the Kazaa port:

Alert tcp $HOME_NET any - $EXTERNAL_NET 1214 (msg:"Kazaa port in 
use"; flow:to_server;established; sid:10503; rev:1;)

The next example narrows the rule to detect when one of your users actually has the Kazaa client installed.

Alert tcp $HOME_NET any - $EXTERNAL_NET 1214 (msg:"Kazaa client 
activity"; flow:from_client,established;  content:"GET"; content:
"KazaaClient"; classtype:policy-violation; sid:10561; rev:1;)

While there are some other ways to detect Kazaa traffic, these should get you started.


BitTorrent has legitimate uses. Certain Linux distributions use it to help people get new versions of their software. However, the vast majority of these connections are used to share pirated software and movies. According to the official BitTorrent site: "Prior to version 3.2, BitTorrent by default uses ports in the range of 6881-6889. As of 3.2 and later, the range has been extended to 6881-6999. (These are all TCP ports, BitTorrent does not use UDP.)" However, BitTorrent has been known to use HTTP ports for communication as well.

One method of detecting BitTorrent is to track when it's installed on a client machine. The following rule detects when a user downloads the Windows version of the BitTorrent client:

Alert tcp $HOME_NET any - any $HTTP_PORTS (msg:Bit Torrent Client 
download"; uricontent:"BitTorrent"; uricontent:"\.exe"; classtype: 
bad-unknown; sid:10559; rev:1;)

Another method is to determine whether the client is already installed on a workstation and when it is being used. This signature detects when an installed client is communicating with another BitTorrent server.

Alert tcp $HOME_NET any - $EXTERNAL_NET any (msg:"Bit Torrent client 
usage"; content:"|00 00 40 09 07 00 00 00|"; offset:0; depth:4; 
classtype: policy-violation; reference:url,; sid:10560; rev:1;)


Gnutella is another popular file-sharing application. This application, like Kazaa, has a default port (6346/tcp) that opens up on the client machine, as well as the port used for communicating with the Gnutella network. The following rule fires when the client is communicating on your network. This rule comes from the official Snort rules, number 557.

alert tcp $HOME_NET any - $EXTERNAL_NET any (msg:"p2p Gnutella client 
request"; flow:to_server,established; content:"GNUTELLA OK"; depth:40; 
classtype:policy-violation; sid:557; rev:6;)

The following rule determines when an installed client is actually downloading files.

Alert tcp $HOME_NET any - $EXTERNAL_NET any (msg:"p2p Gnutella client 
file connection"; flow:from_client,established; content:"X-Gnutel"; 
classtype:policy-violation; sid:10566; rev:1;)


These few specific rules should give you some idea of the range and flexibility of P2P clients to surf your network. More clients and more networks are available to your users. Several options can help you detect and defend against these applications.

Policy solutions:

  • Restrict access and block networks that are known to have these clients.
  • Set workstation host profiles that deny user access to install these clients.
  • Scan your network for common ports at odd times to find the clients when active.

Snort solutions:

  • Find more effective rules to detect a broader scope of P2P clients.
  • Use the stream4 preprocessor to enable the keyword ttkeepstats machine/tt. This records session information about your network. Then use a manual process such as:
cat session.log | awk '{ print $12 }' | sort | uniq -c | sort -nr 
  • This gives us a count of the top ports in use on the network. Then I would look for talkative hosts on the network with the following commands:
cat session.log | awk '{ print $19 }' | sort | uniq -c | sort -nr  

Immediately mark out known server, and you are left with your top talking hosts. With a little scripting, you can determine with what ports and to whom your talk workstation has been communicating.

One feature of all P2P users on a network is that they will have lots of connections both in and out of your network. So keeping a count of network usage plays a large part in detection, especially on larger networks.

See Also

Snort rules and mailing lists ()

Detecting IDS Evasion


I have these great rules, but I went to Defcon and saw H.D. Moore (available here: ) use IDS evasion to bypass Snort's rules. How can I defend against that?


Snort is a signature-based IDS. Most of the methods of evading signature-based IDS systems rely on disguising the attack in a way that doesn't match the standard signature. There will always be someone who writes some great evasion technology to bypass your signature-based IDS. However, all hope is not lost; Snort has several preprocessors that will help normalize the traffic.

  • If the attacker is using multiple small packets to disguise the attack, use the stream4 preprocessor.
  • If the attacker is attempting to disguise the attack by breaking a packet up into small fragments, use the frag2 preprocessor.
  • If the attacker is attempting to use arpspoofing to gain access, use the arpspoof preprocessor.
  • If the attacker is attempting to use an alternative method of writing a path (/etc/passwd or /home/simon/../../etc/passwd, for example), use the http_inspect preprocessor.


Preprocessors are plug-ins to Snort that take data off the network and reassemble it in a similar format to the way it finally reaches the target. There are a number of ways to attempt to evade a signature-based IDS, and they all rely on making the packets fail to match the signature. Snort has several preprocessors and components that will help detect or ignore several types of IDS evasion tactics. For example, the http_inspect preprocessor can be very useful in fighting attacks that try to obfuscate the attack by hiding in Unicode or other character sets. Snort can also use its stream4 preprocessor to help rebuild packets that try to hide in a flood of seemingly nonessential packets. The frag2 preprocessor attempts to reassemble fragmented packets and detect when they have state problems. The following sections include detailed information on using preprocessors to protect against IDS evasion techniques.


The stream4 preprocessor reassembles a number of packets to interpret the payload. If we assume for a moment that the string "open sesame" will activate a trap door letting in an attacker, we would write a Snort rule that detects "open sesame" as a string. If the attacker then breaks the string up into smaller packets, say "o," "p," "e," "n," etc., the string wouldn't match. However, when the smaller packets were reassembled by the target machine, the string would still exist. stream4 does this reassembly for Snort and allows you to write a rule to detect the attack string, regardless of the number of packets in which it is sent.

preprocessor stream4: options

Stream4 is included by adding the previous line to your snort.conf file. Table 3-2 lists configuration options for the stream4 preprocessor:

div id="snortckbk-CHP-3-TABLE-2" Table 3-2. Configuration options for the stream4 preprocessor

Option Action
This option sets stream4 to detect port scans that are not using the standard TCP handshake as the scan method.
This option sets stream4 to detect problems with the way the TCP stream is keeping state. This could indicate a number of hijacking attacks.
This option disables the alerts given by stream4 relating to attempts to evade the IDS using packet stream related attacks. It should be disabled only if you are getting a large number of false positives.
This option sets the maximum difference that will be allowed in the routing lengths of different packets in the same session. Generally, packets should have very similar time-to-live fields, and large discrepancies are typical of an attempt to hijack a session.
This option keeps statistics on each session that stream4 deals with. These statistics are written out to a file either in machine format, which is plain text, or binary, which is the standard Snort unified output.
This turns off stream reassembly for all ports except those explicitly specified.
This sets the time that stream4 will cease to watch a session that has ceased to be active.
This option makes stream4 log the packet that it has reassembled when it creates an alert.
This sets the maximum amount of memory that stream4 can consume in keeping track of the state of sessions.
clientonly / serveronly / both
This option specifies which parts of the session should be reassembled.
This specifies which ports should be reassembled if you set the ttnoinspect/tt option.



The frag2 preprocessor reassembles fragmented packets. An attack using fragmented packets is similar to one using multiple packets; it makes use of the ability to reduce a packet into smaller packets within an IP network. This allows packets to traverse networks with a smaller maximum transmission unit (MTU) size. The process is similar to breaking up a string, although the break point need not necessarily send complete characters. In addition, this type of attack would be used with tools like Snot and Sneeze to try and flood the IDS sensors with bad data. However, using the frag2 preprocessor and running Snort with a tt-z/tt flag will help defend against this type of attack. This is due to the fact that the tt-z/tt option tells Snort to only alert on streams that have established a three-way handshake. While this will defend against stateless attack tools like Snot and Sneeze, it does ignore some attacks that don't need an established connection, such as several new DDoS tools that use a single Syn-flagged TCP packet for their commands. One solution to this problem is to enable tt-z/tt only on certain sensors. On others, set rules for stateless detection.

Frag2 is included using the following line in your snort.conf file:

preprocessor frag2: option

Frag2 takes the options listed in Table 3-3.

div id="snortckbk-CHP-3-TABLE-3" Table 3-3. Configuration options for the frag2 preprocessor

Option Action
This option tells frag2 to drop a fragment, if it hasn't received the following fragment within the timeout.
This option specifies how much memory frag2 can use to keep track of fragmented packets.
This option specifies the minimum time-to-live that a packet must have before Snort bothers with it: if the IDS is n hops away from the target and the ttl is n - 1 hops, it can be immediately discounted.
This option sets the maximum difference that will be allowed in the routing lengths of different packets in the same session. Generally, packets should have very similar time-to-live fields, and large discrepancies are typical of an attempt to hijack a session.
This option detects errors in the state of the fragment stream—for example, two or more fragments of the same number.



The arpspoof preprocessor detects Address Resolution Protocol (ARP) spoofing attacks. These attacks convince machines that they should send network traffic for a certain host or hosts to the attacker's machine instead of the correct destination. Used properly, this also allows eavesdroppers to listen in on a switched network, where normally they would receive nothing. On the down side, there is very little that is automatic about this rule. You need to specify each host individually along with the correct ARP address. You do this by inserting the following lines into your snort.conf file:

preprocessor arpspoof
preprocessor arpspoof_detect_host: 00:09:5B:3B:CE:E6

The arpspoof preprocessor can also detect unicast ARP requests (ARP is normally broadcast). You turn on unicast alerting by using the tt-unicast/tt option on the arpspoof preprocessor line in snort.conf.

preprocessor arpspoof: -unicast


What if the attack came over HTTP? The http_decode preprocessor normalizes HTTP requests. This means that it translates the many ways of writing a URL into one single format that you can more easily scan for a specific string. If an attacker sends Code Red with Unicode encoding tagged to the packet:

GET / HTTP/1.0

with the help of the http_inspect preprocessor, that's turned into the attack of:

GET /default.ida HTTP/1.0

You can add the http_decode preprocessor to your snort.conf with the following line:

preprocessor http_decode

This monitors all traffic to port 80 by default. If you wish to monitor other ports, you need to specify these as a list on the preprocessor line, as follows:

preprocessor http_decode: 80 8080 8000

After this list, you can specify any of the options listed in Table 3-4.

div id="snortckbk-CHP-3-TABLE-4" Table 3-4. Configuration options for the http_decode preprocessor

Option Action
Decodes Unicode to normal ASCII text.
Decodes Unicode from the alternative IIS representation. Use if you have IIS servers.
Decodes strings that have been encoded in HEX twice. For example, an attacker sends a URL with %255c in it. The %25 decodes as the % sign, so this will decode as %5c, which in turn decodes as /.
This changes all slashes to lean the right way. So all \ are changed to /.
This translates tab characters to spaces. This is an attack targeted at Apache, which translates all tabs to spaces, so a string with spaces can be obfuscated by use of tab characters.
This ceases processing if http_decode detects an invalid hex character (e.g., %GG). This is advisable if you are running Apache servers, which will also drop any requests with incorrect hex.
This drops everything after the parameter marker in a string. So in a GET method form, it ignores everything after the ?.
This detects certain abnormal conditions. For example, any HTTP command over 10 characters long is flagged, because the longest normal HTTP request is only seven characters long.


Used in combination, these preprocessors should cover you for most of the possible evasion methods that are likely to be put forward by 99 percent of your attackers. You should bear in mind, though, that new attacks appear daily (or even hourly), so keeping Snort up to date is vital. All the previously discussed preprocessors (with the exception of fnord) are in active development and have regular updates. Using all these preprocessors and keeping evasion in mind when writing rules should help prevent attacks from sneaking past your Snort sensors. For more information on preprocessors, see Chapter 4.

See Also

H.D. Moore's metasploit framework () for some tools to test evasion techniques

Snort Users Manual

Countermeasures from Rules


My web/FTP/SMTP server(s) are logging attack attempts that look like they should be detected by the Snort rules, but Snort isn't seeing them. What is happening?


This is especially common when detecting HTTP traffic. With the liberal use of utf-8, Unicode, and even FrontPage HTTP extensions, it is child's play to avoid detection by some rules. For example, the evasion attack in the previous recipe would never have been detected by the default Snort rule without the http_inspect preprocessor.


The preprocessors play an important role in allowing the rules engine to correctly identify attack traffic. Another suggestion, especially for encoded traffic, is to detect variations on an attack using the new rule keyword ttpcre/tt (Perl-compatible regular expressions). For more information on creating and using regular expressions, check out Mastering Regular Expressions (O'Reilly). This will not only give you several good reference examples, but also devotes several chapters to the use of regular expressions in Perl. The following rule from detects most variants of Windows shell access:

(msg:"BLEEDING-EDGE Attempt to access SHELL\:"; pcre:"/
[\:]/i"; classtype:web-application-attack; sid:2001100; rev:1;)

Even using regular expressions, an attacker could still send a packet with tt%115%104%101%108%108/tt instead of ttshell/tt to get past this rule. You can work around this by tuning the Snort sensor beyond the default http_inspect parameters to convert hex to ASCII normalization.

See Also

H.D. Moore's metasploit framework () for some tools to test evasion techniques

Koziol, Jack, et al. The Shellcoder's Handbook. New York: Wiley, 2004.

Snort-sigs mailing list

Friedl, Jeffrey E. F. Mastering Regular Expressions. Sebastopol, CA: O'Reilly, 2002.

Testing Rules


I have new rules and ideas for rules I want to test without causing problems for the production deployment. How can I use Snort to test itself?


There are actually a couple of answers to this question.

  • Using the Snort command-line tt-T/tt option is best for quick changes to production sensors. This option is usually placed as the last option at runtime to test a snort.conf file. For example, you finish reading this book and you want to ensure that you've set up Snort to output to a database.
snort -c /path/to/my/snort.conf -i Sniff_interface -l 
/log/snort/path -T
  • With this in place, Snort makes a dry run of the parts of Snort and the enabled/disabled components of the conf file. If for example a rule had an error in it, an output module didn't have support enabled, or even if Snort couldn't log to the log directory, it would show up here. If there is a problem with the rule you wrote, Snort will warn you with a tt^/tt at the closest point to the error. This is great if you are just getting into writing your own rules. It's also useful for experienced Snort users and administrators, because even the experts make mistakes sometimes.
  • Out-of-band testing is the preferred method of testing Snort rules. Build a system with a similar setup to your production sensors to run Snort through a testing process before being deployed. This is great for testing what has changed between Snort versions, and even builds if you are customizing Snort source code.
  • In-band testing requires you to set up an extra sensor on your production network. This way, when you want to test either rules or builds of Snort, you can test in the actual environment of your production network. If you feel like living on the edge, this is for you.


For a full discussion of how to set up a testing infrastructure for Snort, check out the chapter on keeping Snort up to date in the Snort 2.1 book (Syngress). Solutions for a testing infrastructure for large and small organizations will differ with size, cost, and necessity.

See Also

Beale, Jay. Snort 2.1 Intrusion Detection. Rockland, MA: Syngress, 2004.

Open Source Testing Methodology ()

Optimizing Rules


How can I speed up my rules to perform better and identify attacks faster?


Snort rules use several recursion loops to detect possible evasion attempts. The trick to optimizing rules is to make them specific enough that they can detect matches with as few passes as possible.

One possible solution is to use several discrete or single hit keywords at the beginning of your rules to help limit the times through the engine. For example, as mentioned before, if you can write your signatures to use the HEX values of the packets rather than the ASCII translations. Then Snort need only run the packet through the engine once the first time through without having to run the packet through the ASCII translation engine, and then pass it back through the rules engine.


We'll start with a rule to detect the MS-ITS subprotocol exploit, and then optimize it.

alert tcp any any - any any (msg:"Possible browser hijacking"; 
content:"ms-its\:mhtml\:file"; content:"chm"; flags:A+; classtype:
bad-unknown; rev:4;)

First, add a filter to the rule so it only examines packets with a large enough payload size. A window of greater than 64-bytes long should only display packets that have a TCP payload.

Alert tcp any any - any any (msg:"Possible browser hijacking"; 
dsize64; content:"ms-its\:mhtml\:file"; content:"chm"; flags:A+; 
classtype: attempted-admin; rev:5;)

Then make the payload a little more accurate, by ssing the keyword ttwithin/tt.

Alert tcp any any - any any (msg:"Possible browser hijacking"; 
dsize64; content:"ms-its\:mhtml\:file"; content:"chm"; within:10; 
flags:A+; classtype: attempted-admin; rev:6;)

Now pull the rule over the ttflow/tt keyword for one last bit of accuracy.

Alert tcp any any - any any (msg:"Possible browser hijacking"; 
dsize64; content:"ms-its\:mhtml\:file"; content:"chm"; within:10;
flow:established,to_server; classtype: attempted-admin; rev:7;)

Now this rule has several very specific parameters that have to be met on the first pass through the engine, or else the alarm will fail, thus dropping out of the several pass sequence.

Keep in mind when creating rules that the more specific your rules, the faster they will process through the Snort engine and the less load on the Snort engine they will place. If you place less of a load on the Snort engine, it's less likely to drop connections and logs.

See Also

Beale, Jay. Snort 2.1 Intrusion Detection. Rockland, MA: Syngress, 2004.

Snort-sigs mailing list and posts by Brian Caswell

Blocking Attacks in Real Time


You want to block an attack in real time.


There are two possible solutions. If you wish to terminate a particular connection, you should use the session termination as described in the Recipe 2.27 recipe. If, however, you wish to prevent the attacker from trying again, you should use the inline IDS described in the Recipe 7.4 recipe.


Active response, or intrusion prevention, varies in popularity. You should seriously consider the potential implications of its use, as it can be turned against you to produce a denial of service attack.

A malicious attacker can easily spoof an attack from what would normally be a legitimate IP address—for example, that of a regular customer. This would then be automatically excluded by the firewall, cutting off the legitimate user. This feature, while potentially very useful, can also be very dangerous. Please use with care.

See Also

Recipe 7.9

Beale, Jay. Snort 2.1 Intrusion Detection. Rockland, MA: Syngress, 2004.

Suppressing Rules


You want to suppress a rule without permanently removing it from the ruleset.


Use the ttsuppress/tt command to suppress a rule.

suppress gen_id gen_id, sid_id sid-id


Suppression allows you to deactivate a rule completely. The options are ttgen_id/tt and ttsig_id/tt. ttGen_id/tt is the generator ID, and ttsig_id/tt is the Snort signature ID.

To suppress an event entirely:

suppress gen_id 1, sig_id 1234

See Also

Snort User Manual

Recipe 3.17

Thresholding Alerts


Noisy logs are the bane of every administrator's existence! How do you reduce the size of your haystack to help find that all-important needle?


Use the ttthreshold/tt keyword:

threshold: type limit:threshold:both,  track by_src:by_dst, count 
n, seconds n;


Thresholding is a useful way of thinning down your logs. It also allows you to monitor for other unusual behavior. If you suddenly see a lot of NFS errors—as opposed to one or two every minute—you certainly have a problem, but you won't want to be alerted for every single NFS error.

To alert the first n times that an event happens during a time interval, use ttlimit/tt. To alert every nth occurrence during the time interval, use ttthreshold/tt.

There is also the combination type of ttboth/tt, which alerts once after n instances of the event.

The tttrack/tt keyword is used to monitor traffic either by source IP address or destination IP address. It provides a method for grouping events to enable thresholding. Tracking is done either by source or destination IP address only; there is no tracking done on ports or any other criteria. The ttcount/tt is the number of events for the ttthreshold/tt and ttboth/tt types, and the number of alerts for the ttlimit/tt type. The ttseconds/tt option sets the time during which the events should be counted, and, funnily enough, is in seconds.

So to set the threshold of an alert on every ten occurrences of a rule within a five second period from the source for the rule, use the following:

threshold: type threshold, track by_src, count 10, seconds 5;

See Also

Snort User Manual

Recipe 2.25

Excluding from Logging


You need to log everything except . . .


Use the ttsuppress/tt keyword, as described in "Suppressing Rules," but use the additional options to qualify the suppression better.

suppress gen_id gen_id, sig_id sig_id, track by_src|by_dst, ip 


To be a little more selective with ttsuppress/tt, use the tttrack/tt and ttip/tt options. The tttrack/tt option specifies whether you are interested in packets coming or going, and ttip/tt specifies either a single IP address or a range.

To suppress an event from a specific IP:

suppress gen_id 1, sig_id 1234, track by_src, ip

To suppress an event going to a subnet:

suppress gen_id 1, sig_id 1234, track by_dst, ip

See Also

Beale, Jay. Snort 2.1 Intrusion Detection. Rockland, MA: Syngress, 2004.

Recipe 3.15

Recipe 3.17

Carrying Out Statistical Analysis


You want Snort to alert you to behavior on your network that isn't normal.


Use the Spade preprocessor S plug-in.

Download a copy of Spade. Its original creators are no longer around, but as it has been released under the GNU Public License, it is still available and is now being maintained again. Download a copy here: .

In the top level of your Snort distribution, uncompress and unpack the Spade distribution by typing the following:

tar xzvf Spade-040223.1.tgz

Change into the Spade distribution directory and make the distribution by typing the following:

cd Spade-040223.1

Compile Snort as normal according to Recipe 1.n.

To get started quickly, copy the lines included in the spade.conf file into your file snort.conf to enable the preprocessor.


Plenty of tools allow you to do statistical analysis of alerts you've already collected. Spade creates an overview of the "normal" behavior of the network based upon observed history. The fewer times a packet of a certain type is seen, the higher its anomaly score. This will very quickly balance out to show the normal behavior of your network (you can also configure Spade to show you what the normal behavior of your network is, which is very useful for capacity planning) and will flash up any "odd" packets. Spade is bright enough not only to spot unusual source and destination ports and IP addresses but also oddly "shaped" packets with odd configurations of flags.

Once you have carried out the installation instructions, you will need to edit your snort.conf file. An example of all the requisite lines for enabling Spade is included in the spade.conf file in the distribution directory.

The following should be added to snort.conf:

preprocessor spade: {optionname=value}

You can add any of the options listed in Table 3-5.

div id="snortckbk-CHP-3-TABLE-5" Table 3-5. Configuration options for the Spade preprocessor

Option Action
Specifies the logging file for Spade; if - is specified, stdout is used.
Specifies the state file and stores the probability table between runs. If this file exists, Spade starts from scratch again to build the tables.
Specifies how often the state file is updated with the current state. The file will be updated every n times the state changes. The default is 50,000 changes before the file is written.
This specifies the destination of the messages from Spade. It can be alert, log, or both.
This specifies the location to which messages regarding the updates of the probabilities should be sent. If this isn't specified, the messages go to the source specified in Dest.


You then need to give Spade a bit of an idea about the location of the Snort sensor within the network. You do this by inserting the following line:

preprocessor spade-homenet: [network,network,...]

You'll need to specify your network using CIDR notation (e.g.,, a specific IP address (e.g.,, or ttany/tt (which means everything). The ttany/tt setting is the default if no other line is specified. The ttspade-homenet/tt setting is unrelated to any Snort options about the home network.

You'll now need to set up some detectors. Detectors are the bits that do the work, somewhat like rules, and allow you to create more targeted statistical analysis of your traffic. The format of a detector line is as follows:

preprocessor spade-detect: {optionname=value}

You can use any combination of the options listed in Table 3-6.

div id="snortckbk-CHP-3-TABLE-6" Table 3-6. Configuration options for Spade detectors

Option Action
Indicates the detector type. You can choose from closed-dport, dead-dest, odd_dport, or odd-typecode.
Sets the direction of traffic: home is traffic with destinations in the earlier specified homenet, nothome is everything else, and any is both directions.
Is the same as To, except for the source rather than the destination.
Specifies which protocol the detector is for; can be tcp, udp, or icmp.
Specifies flags that are set for TCP packets. Possible values are synonly, synack, setup, established, teardown, or "weird".
Specifies the type of ICMP packet to look for; can be "err", "noterr", or "all".
Is the initial threshold for packets to be reported based upon their anomaly score.
Are minimum observations: how many packets need to be observed before alerts are sent. This covers the startup of the system, when all packets look like anomalies.
Is the number of seconds that a message is held in the waiting queue before timing out.
Exclude reports from this detector about certain destination IP addresses.
Exclude reports from this detector about certain destination ports.
Xsips Exclude reports from this detector about certain source addresses.
Exclude reports from this detector about certain source ports.
Is a label for the detector; must start with a letter, and can contain only alphanumeric characters,- and _.
Causes the conditions for the detection to be reversed, if response waiting is enabled for this detector.
Is how often in minutes the existing observations are decayed in favor of newer observations.
Is the relative weight that should be given to old data at each scalefreq reweighing.
Helps to attain a certain half life for the weight of an item of traffic. It can be created through scalefreq and scalefactor, but is easier to specify as an exact time in seconds.
Is the point below which an item of traffic will be removed from the active dataset.


Each detector type makes use of the other options in slightly different ways; some options are inappropriate for use with a specific detector type.


This detector type looks at TCP and UDP traffic for attempts to connect to closed ports. This is common behavior for port scanners, which attempt to connect to all ports to determine what is open. There is an option to wait for the rejection of the packet before issuing an alert to see whether the port was open, which removes alerts caused through the use of passive FTP. This will create one of three types of alert. Without the response wait option enabled, it gives ttRare dest port used/tt. If response waiting is enabled and a RST or ICMP unreachable response is sent, it gives ttClosed/tt ttdest port used/tt. Finally, if response waiting is enabled and the port is open, it gives ttRare but open dest port used/tt. The normal options are in Table 3-7.

div id="snortckbk-CHP-3-TABLE-7" Table 3-7. Configuration options for the closed-dport detector

Option Action
As normal
tcp or udp only
synonly, synack, established, teardown, and weird available
How long to wait for the response packet
Wait for response



This detector type scans for traffic that is being sent to IP addresses that are not in use. This will detect the typical behavior of network scanners and worms that are unaware of the internal layout of your network. The alert given is ttNon-live dest/tt ttused/tt. The normal options are listed in Table 3-8.

div id="snortckbk-CHP-3-TABLE-8" Table 3-8. Configuration options for the dead-dest detector

Option Action
As normal
synonly, synack, established, teardown, and weird available
As normal



This detector type looks for use of ports that differ from the normal usage patterns. This is often a symptom of a compromised host running something new. This can be applied to local or remote sources, and is reported with an alert of ttSource used odd/tt ttdest port/tt. The normal options are listed in Table 3-9.

div id="snortckbk-CHP-3-TABLE-9" Table 3-9. Configuration options for the odd-dport detector

Option Action
from, id
As normal
tcp or udp only
How long to wait for a response packet if you specify revwaitrpt
Wait for a response before alerting



This detector looks for anomalous behavior in the way of connections being made to normal ports on unusual machines. For example, if email usually goes to a specific host and this changes suddenly, it may be that the host has been compromised in some way. The alert given is ttSource used odd dest for port/tt. The normal options are listed in Table 3-10.

div id="snortckbk-CHP-3-TABLE-10" Table 3-10. Configuration options for the odd-port-dest detector

Option Action
from, id
As normal.
tttcp/tt and ttudp/tt only.
This is a measure of the variation that should be expected for the destination IP of a given port. 0 indicates that there should be only one port expected, and increasingly higher numbers indicate an increasingly higher variation.



This detector reports odd ICMP packets on the network. The alert given is ttOdd ICMP/tt tttype/code found/tt. The normal options are listed in Table 3-11.

div id="snortckbk-CHP-3-TABLE-11" Table 3-11. Configuration options for the odd-typecode detector

Option Action
To, id
As normal
As normal; defaults to any


The Spade documentation goes into a great deal of depth, both as to the exact options and the mathematics beyond the plug-in. The example cases that are given, spade.conf and spade.more.conf, are well written and clear as to the way that you should make use of Spade.

See Also

Spade User Manual

Personal tools