Welcome to Linux Support and Sun Help
Search LinuxSupport
From: Subject: Writing Snort Rules Date: Wed, 4 Jul 2001 10:27:48 +0100 MIME-Version: 1.0 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Location: http://www.snort.org/writing_snort_rules.htm X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2919.6600 Writing Snort Rules  =20
Writing Snort=20 Rules
How To=20 write Snort rules and keep your = sanity=20
Current as of version=20 1.7
by=20 Martin=20 = Roesch


The=20 = Basics
Snort uses a simple, lightweight rules description language = that=20 is flexible and quite powerful.  There are a number of simple = guidelines=20 to remember when developing Snort rules.=20

The first is that Snort rules must be completely contained on a = single=20 line, the Snort rule parser doesn't know how to handle rules on = multiple=20 lines.=20

Snort rules are divided into two logical sections, the rule header = and the=20 rule options.  The rule header contains the rule's action, = protocol,=20 source and destination IP addresses and netmasks, and the source and=20 destination ports information.  The rule option section contains = alert=20 messages and information on which parts of the packet should be = inspected to=20 determine if the rule action should be taken.=20

Here is an example rule:=20

alert tcp any any -> 111 = (content:"|00 01=20 86 a5|"; msg: "mountd=20 access";)
Figure 1 - Sample Snort Rule

The text up to the first parenthesis is the rule header and = the=20 section enclosed in parenthesis is the rule options.  The = words=20 before the colons in the rule options section are called option=20 keywords.  Note that the rule options section is not = specifically=20 required by any rule, they are just used for the sake of making = tighter=20 definitions of packets to collect or alert on (or drop, for that=20 matter).  All of the elements in that make up a rule must be true = for the=20 indicated rule action to be taken.  When taken together, the = elements can=20 be considered to form a logical AND statement.  At the same time, = the=20 various rules in a Snort rules library file can be considered to form = a large=20 logical OR statement.  Let's begin by talking about the rule = header=20 section.


The include keyword allows other rule files to be included = within=20 the rules file indicated on the Snort command line.  It works = much like=20 an "#include" from the C programming language, reading the contents of = the=20 named file and putting them in place in the file in the place where = the=20 include appears.=20


include: <include file=20 path/name>
Note that there is no semicolon at = the end=20 of this line.  Included files will substitute any predefined = variable=20 values into their own variable references.  See the Variables = section for=20 more information on defining and using variables in Snort rule files.=20


Variables may be defined in Snort.  These are simple = substitution=20 variables set with the var keyword as in Figure 2.=20


var: <name> <value>

var MY_NET [,]=20

alert tcp any any -> $MY_NET any (flags: S; msg: "SYN=20 packet";)

Figure 2 - Example of Variable Definition and Usage

The rule variable names can be modified in several ways.  You = can=20 define meta-variables using the "$" operator.  These can = be used=20 with the variable modifier operators, "?" and "-".=20

See Figure 3 for = an example=20 of these rules modifiers in action.

var MY_NET $(MY_NET:- =20

log tcp any any -> $(MY_NET:?MY_NET is undefined!) = 23 =20

Figure 3 - Advanced Variable Usage Example

<= /TBODY>
Rule=20 = Headers
Rule Actions:=20

The rule header contains the information that defines the "who, = where,=20 and what" of a packet, as well as what to do in the event that a = packet with=20 all the attributes indicated in the rule should show up.  The = first=20 item in a rule is the rule action.  The rule action = tells Snort=20 what to do when it finds a packet that matches the rule = criteria. =20 There are five available default actions in Snort, alert, log, pass, = activate, and dynamic.=20

  • alert - generate an alert using the selected alert method, and = then=20 log the packet=20
  • log - log the packet=20
  • pass - ignore the packet=20
  • activate - alert and then turn on another dynamic rule=20
  • dynamic - remain idle until activated by an activate = rule, then=20 act as a log rule
You can also define your own = rule types=20 and associate one or more output=20 plugins with them.  You can then use the rule types as = actions in=20 Snort rules.=20

This example will create a type that will log to just tcpdump:=20

ruletype suspicious
    type log=20
    output log_tcpdump: suspicious.log

This example will create a rule type that will log to syslog and = a mysql=20 database:=20

ruletype redalert
    type alert=20
    output alert_syslog: LOG_AUTH LOG_ALERT=20
    output database: log, mysql, user=snort = dbname=snort=20 host=localhost


The next field in a rule is the protocol.  There are three = IP=20 protocols that Snort currently analyzes for suspicious behavior, = tcp, udp,=20 and icmp.  In the future there may be more, such as ARP, IGRP, = GRE,=20 OSPF, RIP, IPX, etc.

  • tcp=20
  • udp=20
  • icmp
IP Addresses: =

The next portion of the rule header deals with the IP address and = port=20 information for a given rule.  The keyword "any" may be used to = define=20 any address.  Snort does not have a mechanism to provide host = name=20 lookup for the IP address fields in the rules file.  The = addresses are=20 formed by a straight numeric IP address and a CIDR = block. =20 The CIDR block indicates the netmask that should be applied to the = rule's=20 address and any incoming packets that are tested against the = rule.  A=20 CIDR block mask of /24 indicates a Class C network, /16 a Class B = network,=20 and /32 indicates a specific machine address.  For example, the = address/CIDR combination would signify the block of = addresses=20 from to  Any rule that used this = designation=20 for, say, the destination address would match on any address in that = range.  The CIDR designations give us a nice short-hand way to=20 designate large address spaces with just a few characters.=20

In Figur= e=20 1, the source IP address was set to match for any computer = talking, and=20 the destination address was set to match on the Class C = network.=20

There is an operator that can be applied to IP addresses, the = negation=20 operator.  This operator tells Snort to match any IP = address=20 except the one indicated by the listed IP = address.  The=20 negation operator is indicated with a "!".  For example, an = easy=20 modification to the initial example is to make it alert on any = traffic that=20 originates outside of the local net with the negation operator as = shown in=20 Figure 4.=20

alert tcp ! any -> = 111=20 (content: "|00 01 86 a5|"; msg: "external mountd=20 access";)
Figure 4 - Example IP Address Negation Rule

This rule's IP addresses indicate "any tcp packet with a source = IP=20 address not originating from the internal network and = a=20 destination address  on the internal network".=20

You may also specify lists of IP addresses. An IP list is=20 specified by enclosing a comma separated list of IP addresses and = CIDR=20 blocks within square brackets. For the time being, the IP list may = not=20 include spaces between the addresses. See Figure 3 for an example of = an IP=20 list in action.=20

alert tcp ![,] any ->=20 [,] 111 (content: "|00 01 86 a5|"; = msg:=20 "external mountd = access";)

Port Numbers=20

Port numbers may be specified in a number of ways, including = "any" ports,=20 static port definitions, ranges, and by negation.  "Any" ports = are a=20 wildcard value, meaning literally any port.  Static ports are = indicated=20 by a single port number, such as 111 for portmapper, 23 for telnet, = or 80=20 for http, etc.  Port ranges are indicated with the range = operator=20 ":".  The range operator may be applied in a number of ways to = take on=20 different meanings, such as in Figure 5.

log udp any any -> = 1:1024 =20
log udp traffic coming from any port and destination = ports=20 ranging from 1 to 1024
log tcp any any -> = :6000 =20
log tcp traffic from any port going to ports less than = or equal=20 to 6000
log tcp any :1024 -> = 500: =20
log tcp traffic from priveleged ports less than or = equal to=20 1024 going to ports greater than or equal to=20 500
Figure 5 - Port Range Examples

Port negation is indicated by using the negation operator = "!".  The=20 negation operator may be applied against any of the other rule types = (except=20 any, which would translate to none, how Zen...).  For example, = if for=20 some twisted reason you wanted to log everything except the X = Windows ports,=20 you could do something like the rule in Figure 6.

log tcp any any -> !6000:6010
Figure 6 - Example of Port Negation

The Direction Operator=20

The direction operator "->" indicates the orientation, = or=20 "direction", of the traffic that the rule applies to.  The IP = address=20 and port numbers on the left side of the direction operator is = considered to=20 be the traffic coming from the source host, and the address and port = information on the right side of the operator is the destination = host. =20 There is also a bidirectional operator, which is indicated = with a=20 "<>" symbol.  This tells Snort to consider the = address/port pairs=20 in either the source or destination orientation.  This is handy = for=20 recording/analyzing both sides of a conversation, such as telnet or = POP3=20 sessions.  An example of the bidirectional operator being used = to=20 record both sides of a telnet session is shown in Figure 7. =

log ! any <> 23
Figure 7 - Snort rules using the Bidirectional = Operator

Activate/Dynamic Rules=20

Activate/dynamic rule pairs give Snort a powerful = capability.  You=20 can now have one rule activate another when it's action is performed = for a=20 set number of packets.  This is very useful if you want to set = Snort up=20 to perform follow on recording when a specific rule "goes = off". =20 Activate rules act  just like alert rules, except they have a=20 *required* option field:  "activates". Dynamic rules act just = like log=20 rules, but they have a  different option field: "activated_by". = Dynamic=20 rules have a second  required field as well, "count".  = When the=20 "activate" rule goes off, it turns on the dynamic rule it is  = linked to=20 (indicated by the activates/activated_by option numbers) for  = "count"=20 number of packets (50 in this case).=20

Put 'em together and they look like  this:

activate tcp !$HOME_NET any -> $HOME_NET 143 = (flags: PA;=20 content:  "|E8C0FFFFFF|\bin|; activates: 1; msg: "IMAP = buffer=20 overflow!";) =20

 dynamic tcp !$HOME_NET any -> $HOME_NET 143 = (activated_by:=20 1; count:  = 50;) 

Figure 8 - Activate/Dynamic rule example

These rules tell Snort to alert when it detects an IMAP buffer = overflow=20 and collect the next 50 packets headed for port 143 coming from = outside=20 $HOME_NET headed to $HOME_NET.  If the buffer overflow happened = and was=20 successful, there's a very good possibility that useful data will be = contained within the next 50 (or whatever) packets going to that = same=20 service port on the network, so there's value in collecting those = packets=20 for later analysis.

<= /TBODY>
Rule=20 = Options
Rule options form the heart of Snort's intrusion detection = engine, combining ease of use with power and flexibility.  All = Snort=20 rule options are separated from each other using the semicolon ";"=20 character.  Rule option keywords are separated from their = arguments=20 with a colon ":" character. As of this writing, there are fifteen = rule=20 option keywords  available for Snort:
  • msg=20 - prints a message in alerts and packet logs=20
  • logto -=20 log the packet to a user specified filename instead of the = standard=20 output file=20
  • ttl=20 - test the IP header's TTL field value=20
  • tos=20 - test the IP header's TOS field value=20
  • id -=20 test the IP header's fragment ID field for a specific value=20
  • ipoption=20 - watch the IP option fields for specific codes=20
  • fragbits=20 - test the fragmentation bits of the IP header=20
  • dsize -=20 test the packet's payload size against a value=20
  • flags -=20 test the TCP flags for certain values=20
  • seq=20 - test the TCP sequence number field for a specific value=20
  • ack=20 - test the TCP acknowledgement field for a specific value=20
  • itype -=20 test the ICMP type field against a specific value=20
  • icode -=20 test the ICMP code field against a specific value=20
  • icmp_id= =20 - test the ICMP ECHO ID field against a specific value=20
  • icmp_seq=20 - test the ICMP ECHO sequence number against a specific value=20
  • content= =20 - search for a pattern in the  packet's payload=20
  • conten= t-list=20 - search for a set of patterns in the packet's payload=20
  • offset=20 - modifier for the content option, sets the offset to begin = attempting=20 a pattern match=20
  • depth -=20 modifier for the content option, sets the maximum search depth = for a=20 pattern match attempt=20
  • nocase=20 - match the preceeding content string with case insensitivity=20
  • session= =20 - dumps the application layer information for a given session=20
  • rpc=20 - watch RPC services for specific application/proceedure calls =
  • resp -=20 active response (knock down connections, etc)=20
  • react -=20 active response (block web sites) =
  • Msg

    The msg rule option tells the logging and alerting engine = the=20 message to print along with a packet dump or to an alert.  It = is a=20 simple text string that utilizes the "\" as an escape character to = indicate=20 a discrete character that might otherwise confuse Snort's rules = parser (such=20 as the semi-colon ";" character).=20


    msg: "<message = text>";
    <= /TBODY>

    The logto option tells Snort to log all packets that = trigger this=20 rule to a special output log file.  This is especially handy = for=20 combining data from things like NMAP activity, HTTP CGI scans, = etc.  It=20 should be noted that this option does not work when Snort is in = binary=20 logging mode.=20


    logto: "<filename>";

    This rule option is used to set a specific time-to-live value to = test=20 against.  The test it performs is only sucessful on an exact=20 match.  This option keyword was intended for use in the = detection of=20 traceroute attempts.=20


    ttl: "<number>";

    The "tos" keyword allows you to check the IP header TOS field for = a=20 specific value.  The test it performs is only sucessful on an = exact=20 match.=20


    tos: "<number>";

    This option keyword is used to test for an exact match in the IP = header=20 fragment ID field.  Some hacking tools (and other programs) set = this=20 field specifically for various purposes, for example the value 31337 = is very=20 popular with some hackers.  This can be turned against them by = putting=20 a simple rule in place to test for this and some other "hacker = numbers".=20


    id: "<number>";


    If IP options are present in a packet, this option will search = for a=20 specific option in use, such as source routing. Valid arguments to = this=20 option are:=20

    • rr - Record route=20
    • eol - End of list=20
    • nop - No op=20
    • ts - Time Stamp=20
    • sec - IP security option=20
    • lsrr - Loose source routing=20
    • ssrr - Strict source routing=20
    • satid - Stream identifier
    The most frequently = watched for IP=20 options are strict and loose source routing which aren't used in any = widespread internet applications. Only a single option may be = specified per=20 rule.=20


    ipopts: <option>;

    This rule inspects the fragment and reserved bits in the IP=20 header.   There are three bits that can be checked, the = Reserved=20 Bit (RB), More Fragments (MF) bit, and the Dont Fragment (DF) = bit. =20 These bits can be checked in a variety of combinations. Use the = following=20 values to indicate specific bits:=20

    • R - Reserved Bit=20
    • D - DF bit=20
    • M - MF bit
    You can also use modifiers to indicate = logical=20 match criteria for the specified bits:=20
    • + - ALL flag, match on specified bits plus any others=20
    • * - ANY flag, match if any of the specified bits are = set=20
    • ! - NOT flag, match if the specified bits are not set=20
    fragbits: <bit=20 values>;

    alert tcp !$HOME_NET any -> $HOME_NET any = (fragbits: R+;=20 msg: "Reserved IP bit=20 set!";)
    Figure 9 - Example of fragbits detection usage

    <= /TBODY>

    The dsize option is used to test the packet payload size.  = It may be=20 set to any value, plus use the greater than/less than signs to = indicate=20 ranges and limits.  For example, if you know that a certain = service has=20 a buffer of a certain size, you can set this option to watch for = attempted=20 buffer overflows.  It has the added advantage of being a much = faster=20 way to test for a buffer overflow than a payload content check.=20


    dsize: [>|<] = <number>;=20
    Note: The > and < operators are = optional!


    The content keyword is one of the more important features of = Snort. =20 It allows the user to set rules that search for specific content in = the=20 packet payload and trigger response based on that data.  = Whenever a=20 content option pattern match is performed, the Boyer-Moore pattern = match=20 function is called and the (rather computationally expensive) test = is=20 performed against the packet contents.  If data exactly = matching the=20 argument data string os contained anywhere within the packet's = payload, the=20 test is successful and the remainder of the rule option tests are=20 performed.  Be aware that this test is case sensitive.=20

    The option data for the content keyword is somewhat complex; it = can=20 contain mixed text and binary data.  The binary data is = generally=20 enclosed within the pipe ("|") character and represented as=20 bytecode.  Bytecode represents binary data as = hexidecimal=20 numbers and is a good shorthand method for describing complex binary = data.  Figure 7 contains an example of mixed text and binary = data in a=20 Snort rule.

    alert tcp any any -> 143 = (content: "|90C8=20 C0FF FFFF|/bin/sh"; msg: "IMAP buffer=20 overflow!";)
    Figure 10 - Mixed Binary Bytecode and Text in a Content Rule = Option


    content: "<content = string>";


    The offset rule option is used as a modifier to rules using the = content=20 option keyword.  This keyword modifies the starting search = position for=20 the pattern match function from the beginning of the packet = payload. =20 It is very useful for things like CGI scan detection rules where the = content=20 search string is never found in the first four bytes of the = payload. =20 Care should be taken against setting the offset value too "tightly" = and=20 potentially missing an attack!  This rule option keyword cannot = be used=20 without also specifying a content rule option.=20


    offset: <number>;

    <= /TBODY>

    Depth is another content rule option modifier.  This sets = the=20 maximum search depth for the content pattern match function to = search from=20 the beginning of its search region.  It is useful for limiting = the=20 pattern match function from performing inefficient searches once the = possible search region for a given set of content has been = exceeded. =20 (Which is to say, if you're searching for "cgi-bin/phf" in a = web-bound=20 packet, you probably don't need to waste time searching the payload = beyond=20 the first 20 bytes!)  See Figure 8 for an example of a combined = content, offset, and depth search rule.=20


    depth: = <number>;

    alert tcp any any -> 80 (content: = "cgi-bin/phf"; offset: 3; depth: 22; msg: "CGI-PHF=20 access";)
    Figure 11 - Combined Content, Offset and Depth Rule


    The nocase option is used to deactivate case sensitivity in a = "content"=20 rule.  It is specified alone within a rule and any ASCII = characters=20 that are compared to the packet payload are treated as though they = are=20 either upper of lower case.=20



    alert tcp any any -> 21 (content: = "USER=20 root"; nocase; msg: "FTP root user access=20 attempt";)
    Figure 12 - Content rule with nocase modifier

    <= /TBODY>

    This rule tests the TCP flags for a match.  There are = actually 8=20 flags variables available in Snort:=20

    • F - FIN (LSB in TCP Flags byte)=20
    • S - SYN=20
    • R - RST=20
    • P - PSH=20
    • A - ACK=20
    • U - URG=20
    • 2 - Reserved bit 2=20
    • 1 - Reserved bit 1 (MSB in TCP Flags byte)
    There are = also=20 logical operators that can be used to specify matching criteria for = the=20 indicated flags:=20
    • + - ALL flag, match on all specified flags plus any = others=20
    • * - ANY flag, match on any of the specified flags=20
    • ! - NOT flag, match if the specified flags aren't set = in the=20 packet
    The reserved bits can be used to detect unusual = behavior,=20 such as IP stack fingerprinting attempts or other suspicious = activity. =20 Figure 13 shows a SYN-FIN scan detection rule.=20


    flags: <flag = values>;

    alert any any -> any (flags: SF; = msg:=20 "Possible SYN FIN = scan";)
    Figure 13 - Sample TCP Flags Specification


    This rule option refers to the TCP sequence number.  = Essentially, it=20 detects if the packet has a static sequence number set, and is = therefore=20 pretty much unused.  It was included for the sake of = completeness.=20


    seq: <number>;


    The ack rule option keyword refers to the TCP header's = acknowledge=20 field.  This rule has one practical purpose so far: = detecting  NMAP TCP pings.  A NMAP = TCP ping=20 sets this field to zero and sends a packet with the TCP ACK flag set = to=20 determine if a network host is active.  The rule to detect this = activity is shown in Figure 14.=20


    ack: = <number>;

    alert any any -> any (flags: A; = ack: 0;=20 msg: "NMAP TCP = ping";)
    Figure 14 - TCP ACK Field Usage

    <= /TBODY>

    This rule tests the value of the ICMP type field.  It is set = using=20 the numeric value of this field.  For a list of the = available=20 values, look in the decode.h file included with Snort or in any ICMP = reference.  It should be noted that the values can be set out = of range=20 to detect invalid ICMP type values that are sometimes used in denial = of=20 service and flooding attacks.=20


    itype: <number>;

    <= /TBODY>

    The icode rule option keyword is pretty much identical to the = itype rule,=20 just set a numeric value in here and Snort will detect any traffic = using=20 that ICMP code value.  Out of range values can also be set to = detect=20 suspicious traffic.=20


    icode: <number>;


    The session keyword is brand new as of version and is = used to=20 extract the user data from TCP sessions.  It is extremely = useful for=20 seeing what users are typing in telnet, rlogin, ftp, or even web=20 sessions.  There are two available argument keywords for the = session=20 rule option, printable or all.  The = printable=20 keyword only prints out data that the user would normally see or be = able to=20 type.  The all keyword substitutes non-printable = characters with=20 their hexadecimal equivalents.  This function can slow Snort = down=20 considerably, so it shouldn't be used in heavy load situations, and = is=20 probably best suited for post-processing binary (tcpdump format) log = files.  See Figure 15 for a good example of a telnet session = logging=20 rule.=20


    session: = [printable|all];

    log tcp any any <> 23 = (session:=20 printable;)
    Figure 15 - Logging Printable Telnet Session Data


    The icmp_id option examines an ICMP ECHO packet's ICMP ID number = for a=20 specific value. This is useful because some cover= t=20 channel programs use static ICMP fields when they communicate. = This=20 particular plugin was developed to enable the stacheldraht detection = rules=20 written by Max Vision, but = it is=20 certainly useful for detection of a number of potential attacks.=20


    icmp_id: <number>;


    The icmp_id option examines an ICMP ECHO packet's ICMP sequence = field for=20 a specific value. This is useful because some cover= t=20 channel programs use static ICMP fields when they communicate. = This=20 particular plugin was developed to enable the stacheldraht detection = rules=20 written by Max Vision, but = it is=20 certainly useful for detection of a number of potential attacks. = (And yes, I=20 know the info for this field is almost identical to the icmp_id = description,=20 it's practically the same damn thing!)=20


    icmp_seq: <number>;


    This option looks at RPC requests and automatically decodes the=20 application, procedure, and program version, indicating success when = all=20 three variables are matched. The format of the option call is = "application,=20 procedure, version". Wildcards are valid for both the procedure and = version=20 numbers and are indicated with a "*".=20


    rpc: <number, [number|*],=20 [number|*]>;

    alert tcp any any -> 111 (rpc:=20 100000,*,3; msg:"RPC getport (TCP)";)
    alert udp any any -> 111 (rpc:=20 100000,*,3; msg:"RPC getport (UDP)";)
    alert udp any any -> 111 (rpc:=20 100083,*,*; msg:"RPC ttdb";)
    alert udp any any -> 111 (rpc:=20 100232,10,*; msg:"RPC=20 sadmin";)
    Figure 16 - Various RPC Call Alerts


    The resp keyword implements flexible reponse (FlexResp) to = traffic that=20 matches a Snort rule.  The FlexResp code allows Snort to = actively close=20 offending connections.  The following arguments are valid for = this=20 module:=20

    • rst_snd - send TCP-RST packets to the sending socket=20
    • rst_rcv - send TCP-RST packets to the receiving socket=20
    • rst_all - send TCP_RST packets in both directions=20
    • icmp_net - send a ICMP_NET_UNREACH to the sender=20
    • icmp_host - send a ICMP_HOST_UNREACH to the sender=20
    • icmp_port - send a ICMP_PORT_UNREACH to the sender=20
    • icmp_all - send all above ICMP packets to the sender =
    These=20 options can be combined to send multiple responses to the target = host. =20 Multiple arguments are separated by a comma.=20


    resp: <resp_modifier[,=20 resp_modifier...]>;
    alert tcp any any -> = 1524=20 (flags: S; resp: rst_all; msg: "Root shell backdoor=20 attempt";)
    alert udp any any -> 31 = (resp:=20 icmp_port,icmp_host; msg: "Hacker's Paradise access=20 attempt";)
    Figure 17 - FlexResp Usage Examples


    The content-list keyword allows multiple content strings to be = specified=20 in the place of a single content option. The patterns to be searched = for=20 must each be on a single line of content-list file as shown in = Figure 1, but=20 they are treated otherwise identically to content strings specified = as an=20 argument to a standard content directive. This option is the = basis=20 for the react keyword.=20

      # adult sites
      hard core =
      # ... 
      Figure 18 - Content-list "adults" file = example
        content-list: "<file_name>";
    <= /TBODY>

    The react keyword based on flexible response (Flex Resp) = implements=20 flexible reaction to traffic that matches a Snort rule. The basic = reaction=20 is blocking interesting sites users want to access: New York Times,=20 slashdot, or something really important - napster and porn sites. = The Flex=20 Resp code allows Snort to actively close offending connections = and/or send a=20 visible notice to the browser (warn modifier available soon). The = notice may=20 include your own comment. The following arguments (basic = modifiers)=20 are valid for this option:

    • block - close connection and send the visible notice=20
    • warn - send the visible, warning notice (will be available=20 soon)
      The basic argument may be combined with the = following=20 arguments (additional modifiers):=20
    • msg - include the msg option text into the blocking visible = notice=20
    • proxy: <port_nr> - use the proxy port to send the = visible=20 notice (will be available soon)
    Multiple = additional=20 arguments are separated by a comma. The react keyword should be = placed as=20 the last one in the option list.
        react: <react_basic_modifier[,=20 react_additional_modifier...]>;
      alert tcp any any <> = 80=20 (content-list: "adults"; msg: "Not for children!"; react: = block,=20 msg;)
      alert tcp any any <> = any=20 (content-list: "adults"; msg: "Adults list access attempt"; = react:=20 block;)
      Figure 19 - React Usage = Examples
    Preprocessor = Overview=20

    Preprocessors were introduced in version 1.5 of Snort.  They = allow=20 the functionality of Snort to be extended by allowing users and = programmers=20 to drop modular "plugins" into Snort fairly easily.  = Preprocessor code=20 is run before the detection engine is called, but after the packet = has been=20 decoded.  The packet can be modified or analyzed in an "out of = band"=20 manner through this mechanism.=20

    Preprocessors are loaded and configured using the = preprocessor=20 keyword.  The format of the preprocessor directive in the Snort = rules=20 file is:=20

    preprocessor <name>: = <options>
    preprocessor minfrag:=20 128
    Figure 20 - Preprocessor Directive Format Example

    Available Preprocessor Modules=20


    The minfrag preprocessor examines fragmented packets for a = specified=20 size threshold.  When packets are fragmented, it is generally = caused=20 by routers between the source and destination.  Generally = speaking,=20 there is no piece of commercial network equipment that fragments = packets=20 in sizes smaller than 512 bytes, so we can use this fact to enable = traffic=20 to be monitored for tiny fragments that are generally indicative = of=20 someone trying to hide their traffic behind fragmentation.=20


    minfrag: <threshold = number>
    HTTP=20 = Decode

    HTTP Decode is used to process HTTP URI strings and convert = their data=20 to non-obfuscated ASCII strings.  This is done to defeat = evasive web=20 URL scanners and hostile attackers that could otherwise elude the = content=20 analysis strings used to examine HTTP traffic for suspicious=20 activity.  The preprocessor module takes HTTP port numbers = (separated=20 by spaces) to be normalized as its arguments (typically 80 and = 8080).=20


    http_decode: <port = list>
    preprocessor http_decode: 80=20 8080
    Figure 21 - HTTP Decode Directive Format Example

    Portscan=20 = Detector

    The Snort Portscan Preprocessor is developed by Patrick Mullen = and=20 (much) more information is available at his web = page.=20

    What the Snort Portscan Preprocessor does:=20

    Log the start and end of portscans from a single source IP to = the=20 standard logging facility.=20

    If a log file is specified, logs the destination IPs and ports = scanned=20 as well as the type of scan.=20

    A portscan is defined as TCP connection attempts to more than P = ports=20 in T seconds or UDP packets sent to more than P ports in T = seconds. =20 Ports can be spread across any number of destination IP addresses, = and may=20 all be the same port if spread across multiple IPs. This version = does=20 single->single and single->many portscans.  The next = full=20 release will do distributed portscans (multiple->single or=20 multiple->multiple).  A portscan is also defined as a = single=20 "stealth scan" packet, such as NULL, FIN, SYNFIN, XMAS, etc.  = This=20 means that from scan-lib in the standard distribution of snort you = should=20 comment out the section for stealth scan packets.  The = benefit is=20 with the portscan module these alerts would only show once per = scan,=20 rather than once for each packet.  If you use the external = logging=20 feature you can look at the technique and type in the log file.=20

    The arguments to this module are:=20

    • network to monitor - The network/CIDR block to monitor for = portscans=20
    • number of ports - number of ports accessed in the detection = period=20
    • detection period - number of seconds to count that the port = access=20 threshold is considered for=20
    • logdir/filename - the directory/filename to place alerts in. = Alerts=20 are also written to the standard alert file
    portscan: <network to monitor> <number = of=20 ports> <detection period>=20 <logdir/filename>
    preprocessor portscan: 5 = 7=20 /var/log/portscan.log
    Figure 22 - Portscan Module Configuration Example

    Portscan=20 = Ignorehosts

    Another module from Patrick Mullen that modifies the portscan = detection=20 system's operation.  If you have servers which tend to trip = off the=20 portscan detector (such as NTP, NFS, and DNS servers), you can = tell=20 portscan to ignore TCP SYN and UDP portscans from certain=20 hosts.   The arguments to this module are a list of = IPs/CIDR=20 blocks to be ignored.=20


    portscan-ignorehosts: <host=20 list>
    preprocessor portscan-ignorehosts:=20 =
    Figure 23 - Portscan Ignorehosts Module Configuration=20 Example


    The=20 defrag module (from Dragos Ruiu) allows Snort to perform full = blown IP=20 defragmentation, making it more difficult for hackers to simply = circumvent=20 the detection capabilities of the system.  It is very simple = in its=20 usage, merely requiring the addition of a preprocessor directive = to the=20 configuration file with no arguments.  This module generall=20 supercedes the functionality of the minfrag module (i.e. you don't = need to=20 use minfrag if you're using defrag).=20


    preprocessor=20 defrag
    Figure 24 - Defrag preprocessor configuration=20 example


    Thi= s=20 module is still in BETA testing, use with caution!=20

    The stream plugin provides TCP stream reassembly functionality = to=20 Snort.  TCP streams on the configured ports with small = segments will=20 be reassembled into a stream of data that Snort can properly = evaluate for=20 suspicious activity.  This plugin takes a number of = arguments:=20

    • timeout - the max time in seconds for which a stream will be = kept=20 alive if we haven't seen a packet for it=20
    • port - a server port to monitor.  we don't want to = monitor all=20 tcp streams (do we?)=20
    • maxbytes - maximum bytes in our reconstructed packets=20
    stream: timeout <timeout>, ports=20 <ports>, maxbytes = <maxbytes>
    preprocessor stream: timeout 5, ports 21 = 23 80=20 8080, maxbytes 16384
    Figure 25 - TCP stream reassembler configuration = example

    Spade: the Statistical = Packet=20 Anomaly Detection=20 = Engine

    In the interest of timeliness and sanity, I'd suggest checking = out the=20 README.Spade in the Snort distrbution as well as checking out http://www.silicondefense.c= om/spice/=20

    This module allows Snort to be able to perform statistical = anomaly=20 detection on your network, and it's essentially an entire new = detection=20 engine for Snort.  If you're interested in this kind of = capability,=20 you should definitely read the documentation in the Snort = distribution as=20 well as that on the SiliconDefense site.=20

    <= /TBODY>
    Output=20 = Modules
    Output Module Overview=20

    Output modules are new as of version 1.6.  They allow Snort = to be=20 much more flexible in the formatting and presentation of output to = its=20 users.  The output modules are run when the alert or logging = subsystems=20 of Snort are called, after the preprocessors and detection engine. = The=20 format of the directives in the rules file is very similar to that = of the=20 preprocessors.=20

    Multiple output plugins may be specified in the Snort = configuration=20 file.  When multiple plugins of the same type (log, alert) are=20 specified, they are "stacked" and called in sequence when an event=20 occurs.  As with the standard logging and alerting systems, = output=20 plugins send their data to /var/log/snort by default or to a user = directed=20 directory (using the "-l" command line switch).=20

    Output modules are loaded at runtime by specifying the = output=20 keyword in the rules file:=20

    output <name>: <options>
    output alert_syslog: LOG_AUTH=20 LOG_ALERT
    Figure 26 - Output Module Configuration Example

    Available Output Modules=20


    This module sends alerts to the syslog facility (much like the = -s=20 command line switch).  This module also allows the user to = specify=20 the logging facility and priority within the Snort rules file, = giving=20 users greater flexibility in logging alerts.=20

    Available keywords:=20

    • Options=20
      • LOG_CONS=20
      • LOG_NDELAY=20
      • LOG_PERROR=20
      • LOG_PID
    • Facilities=20
      • LOG_AUTH=20
      • LOG_AUTHPRIV=20
      • LOG_DAEMON=20
      • LOG_LOCAL0=20
      • LOG_LOCAL1=20
      • LOG_LOCAL2=20
      • LOG_LOCAL3=20
      • LOG_LOCAL4=20
      • LOG_LOCAL5=20
      • LOG_LOCAL6=20
      • LOG_LOCAL7=20
      • LOG_USER
    • Priorities=20
      • LOG_EMERG=20
      • LOG_ALERT=20
      • LOG_CRIT=20
      • LOG_ERR=20
      • LOG_WARNING=20
      • LOG_NOTICE=20
      • LOG_INFO=20
      • LOG_DEBUG
    alert_syslog: <facility> <priority>=20 <options>
    <= /TR>

    This will print Snort alerts in a quick one line format to a = specified=20 output file.  It is a faster alerting method than full = alerts=20 because it doesn't need to print all of the packet headers to the = output=20 file=20


    alert_fast: <output = filename>
    output alert_fast:=20 alert.fast
    Figure 27 - Fast alert configuration

    <= /TR>

    Print Snort alert messages with full packet headers.  This = alerting facility is generall pretty slow because it requires that = the=20 program do a whole lot of data parsing to format the data to be=20 printed.  The alerts will be written in the default logging = directory=20 (/var/log/snort) or in the logging directory specified at the = command=20 line.=20


    alert_full: <output = filename>
    output alert_full:=20 alert.full
    Figure 28 - Fast alert configuration


    This plugin sends WinPopup alert messages to the NETBIOS named = machines=20 indicated within the file specified as an argument to this output=20 plugin.  It should be noted that use of this plugin is = not=20 encouraged as it executes an external executable binary = (smbclient) at the=20 same privilege level as Snort, commonly root.  The format of = the=20 workstation file is a list of the NETBIOS names of the hosts that = wish to=20 receive alerts, one per line in the file.=20


    alert_smb: <alert workstation=20 filename>
    output alert_smb:=20 workstation.list
    Figure 29 - SMB alert configuration


    Sets up a UNIX domain socket and sends alert reports to = it. =20 External programs/processes can listen in on this socket and = receive Snort=20 alert and packet data in real time.  This is currently an=20 experimental interface.=20


    output=20 alert_unixsock
    Figure 30 - UnixSock alert configuration


    The log_tcpdump module logs packets to a tcpdump-formatted = file. This=20 is useful for performing post process analysis on collected = traffic with=20 the vast number of tools that are avialable for examining tcpdump=20 formatted files.  This module only takes a single argument, = the name=20 of the output file.=20


    log_tcpdump: <output=20 filename>
    output log_tcpdump:=20 snort.log
    Figure 31 - Tcpdump Output Module Configuration = Example


    The XML plug-in enables snort to log in SNML - simple network = markup=20 language aka (snort markup language) to a file or over a = network. =20 The DTD is available in the contrib directory of the snort = distribution=20 and at: http://www.cert.org/DTD/snml-1.0.dtd. You can use this = plug-in=20 with on one or more snort sensors to log to a central database and = create=20 highly configurable intrusion detection infrastructures within = your=20 network. The plugin will also enable you to automatically report = alerts to=20 the CERT Coordination Center, your response team, or your =
    managed IDS=20 provider.=20

    This plugin was developed by Jed Pickel and Roman Danyliw at = the CERT=20 Coordination Center as part of the AIRCERT project.=20

    Be aware that the SNML DTD is in its early phases of = development and is=20 likely to be modified as it undergoes public scrutiny.=20

    See http://www.cert.org/kb/snortxml for the most up to date = information=20 and documentation about this plugin.=20

    The configuration line will be of the following format:=20

       output xml: [log | alert], [parameter list] =


    [log | alert ] - specify log or alert to = connect the=20 xml plugin to the log or alert facility.=20

    [parameter list] - The parameter list consists of key = value=20 pairs. The proper format is a list of key=value pairs each = separated a=20 space.

    file when this is the only parameter it will log to a file on = the=20 local machine.  Otherwise, if http or https is = employed (see=20 protocol), this is the script which is to be executed on = the=20 remote host.
    protocol The possible values for this field are =20
    http  - send a POST over HTTP to a = webserver=20 (required: a [file] parameter)
    https - just like = http but=20 ssl encrypted and mutually authenticated.  = (required: a=20 [file], [cert], [key] parameter)
    tcp   - A = simple=20 tcp connection. You need to use some sort of listener = (required:=20 a [port] parameter) 
    iap   - An=20 implementation of the Intrusion Alert Protocol (This = does not=20 work yet)
    host remote host where the logs are to be sent
    port The port number to connect to (default ports are)=20
    http  80
    https 443 =
    tcp   9000=20
    iap   9000
    cert the client X.509 certificate to use with https (PEM=20 formatted)
    key the client private key to use with https (PEM = formatted)
    ca the CA certificate used to validate the https server's=20 certificate (PEM formatted)
    server the file containing a list of valid servers with which = to=20 communicate. It is used so that Snort canauthenticate the = peer=20 server. Each server is identified by a string formed by=20 concatenating the subject of the server's X.509 = certificate. =20 This string can be created by:
    % openssl x509 -subject -in <server=20 certificate>.

    Typically only someone deploying the HTTPS will = have to=20 perform this task (since they have access to the server=20 certificate). This entitity should publish this subject = string for=20 configuration inside each snort sensor.

    sanatize The argument is a a network/netmask combination for an = IP=20 range you wish to be sanitized. Any IP address within the = range=20 you specify will be represented as "xxx.xxx.xxx.xxx". = Also, for=20 sanitized alerts, no packet payload will be logged. You = can use=20 the sanitize parameter multiple times to represent = multiple IP=20 ranges.
    encoding Packet payload and option data is binary and there is = not one=20 standard way to represent it as ASCII text. You can choose = the=20 binary encoding option that is best suited for your=20 environment.  Each has its own advantages and = disadvantages:=20
    hex: (default) Represent binary data as a hex=20 string.
    storage requirements - 2x the size of the = binary=20
    searchability....... - very good
    human = readability... -=20 not readable unless you are a true geek requires post = processing=20

    base64: Represent binary data as a base64 string. =
    storage=20 requirements - ~1.3x the size of the binary=20
    searchability....... - impossible without post = processing=20
    human readability... - not readable requires post = processing=20

    ascii: Represent binary data as an ascii string. This = is the=20 only option where you will actually loose data.  = Non ascii=20 data is represented as a ".". If you choose this option = then=20 data for ip and tcp options will still be represented as = "hex"=20 because it does not make any sense for that data to be = ascii.=20
    storage requirements - Slightly larger than the = binary=20 because some characters are escaped (&,<,>)=20
    searchability....... - very good for searching for a = text=20 string impossible if you want to search for binary =
    human=20 readability... - very good

    detail How much detailed data do you want to store? The options = are:=20
    full: (default) log all details of a packet = that=20 caused an alert (including ip/tcp options and the = payload)=20

    fast: log only a minimum amount of data. You severely = limit=20 the potential of some analysis applications if you = choose this=20 option, but this is still the best choice for some = applications.=20 The following fields are logged- (timestamp, signature, = source=20 ip, destination ip, source port, destination port, tcp = flags,=20 and=20 = protocol)

    xml: <output = facility>
    output xml: log,  =20 file=output
    output xml: log,   protocol=https = host=air.cert.org=20 file=alert.snort cert=mycert.crt key=mykey.pem = ca=ca.crt=20 server=srv_list.lst
    Figure 32 - XML output plugin setup examples


    This module from Jed Pickel sends Snort data to a variety of = SQL=20 databases.  More information on installing and configuring = this=20 module can be found on the Incident.org web = page. =20 The arguments to this plugin are the name of the database to be = logged to=20 and a parameter list.  Parameters are specified with the = format=20 parameter = argument.  The following parameters are = available:=20

    host Host to connect to. If a non-zero-length string is = specified,=20 TCP/IP communication is used. Without a host name, it will = connect=20 using a local Unix domain socket. 
    port Port number to connect to at the server host, or socket = filename=20 extension for Unix-domain connections.
    dbname Database name
    user Database username for authentication
    password Password used if the database demands password=20 authentication
    sensor_name Specify your own name for this snort sensor. If you do not = specify a name one will be generated automatically
    encoding Because the packet payload and option data is binary, = there is=20 no one simple and portable way to store it in a database. = BLOBS are=20 not used because they are not portable across databases. So = I leave=20 the encoding option to you. You can choose from the = following=20 options. Each has its own advantages and disadvantages:=20
    hex: (default) Represent binary data as a hex = string.=20
    storage requirements - 2x the size of the = binary=20
    searchability....... - very good
    human = readability... -=20 not readable unless you are a true geek requires post=20 processing
    base64: Represent binary data as a base64 = string.=20
    storage requirements - ~1.3x the size of the = binary=20
    searchability....... - impossible without post = processing=20
    human readability... - not readable requires post=20 processing
    ascii: Represent binary data as an ascii string. = This=20 is the only option where you will actually loose = data.  Non=20 ascii data is represented as a ".". If you choose this = option then=20 data for ip and tcp options will still be represented as = "hex"=20 because it does not make any sense for that data to be=20 ascii. =20
    storage requirements - Slightly larger than = the=20 binary because some characters are escaped = (&,<,>)=20
    searchability....... - very good for searching for a = text=20 string impossible if you want to search for binary =
    human=20 readability... - very = good
    detail How much detailed data do you want to store? The options = are:=20
    full: (default) log all details of a packet that = caused an alert (including ip/tcp options and the=20 payload)
    fast: log only a minimum amount of data. You = severely=20 limit the potential of some analysis applications if you = choose=20 this option, but this is still the best choice for some=20 applications. The following fields are logged - = (timestamp,=20 signature, source ip, destination ip, source port, = destination=20 port, tcp flags, and=20 protocol)

    Furthermore, there is a logging method and database type that = must be=20 defined.  There are two logging types available, log = and=20 alert.  Setting the type to log attaches the database logging = functionality to the log facility within the program.  If you = set the=20 type to log, the plugin will be called on the log output=20 chain.  Setting the type to alert attaches the plugin = to the=20 alert output chain within the program.=20

    There are four database types available in the current version = of the=20 plugin are MySQL, PostgreSQL, Oracle, and unixODBC compliant=20 databases.  Set the type to match the database you are using. =


    database: <log | alert>, <database = type>,=20 <parameter list>
    output database: log, mysql,  dbname=snort = user=snort host=localhost=20 password=xyz
    Figure 33 - Database output plugin=20 configuration
    Building Good=20 = Rules
    There are some general concepts to keep in mind when = developing=20 Snort rules to maximize efficiency and speed.  I will add to = this=20 section as my muse wills. :)=20

    Content Rules are Case Sensitive = (unless=20 you use the "nocase" option)=20

    Don't forget that content rules are case sensitive and that many = programs=20 typically use uppercase letters to indicate commands.  FTP is a = good=20 example of this.  Consider the following two rules:=20

    alert tcp any any -> 21 (content: "user = root"; msg:=20 "FTP root login";)=20

    alert tcp any any -> 21 (content: "USER = root"; msg:=20 "FTP root login";)

    The second of those two rules will catch most every automated = root login=20 attempt, but none that use lower case characters for "user".=20

    Speeding Up Rules That Have = Content=20 Options=20

    The order that rules are tested by the detection engine is = completely=20 independent of the order that they are written in a rule.  The = last=20 rule test that is done (when necessary) is always the content rule=20 option.  Take advantage of this fact by using other faster rule = options=20 that can detect whether or not the content needs to be checked at = all. =20 For instance, most of the time when data is sent from client to = server after=20 a TCP session is established, the PSH and ACK TCP flags are set on = the=20 packet containing the data.  This fact can be taken advantage = of by=20 rules that need to test payload content coming from the client to = the sever=20 with a simple TCP flag test that is far less computationally = expensive than=20 the pattern match algorithm.  Knowing this, a simple way to = speed up=20 rules that use content options is to also perform a flag test, as in = Figure=20 23.  The basic idea is that if the PSH and ACK flags aren't = set,=20 there's no need to test the packet payload for the given rule.  = If the=20 flags are set, the additional computing power required to perform = the test=20 is negligible.

    alert tcp any any -> 80 (content: = "cgi-bin/phf"; flags: PA; msg: "CGI-PHF=20 probe";)
    Figure 34 - Using TCP Flag Tests to Hasten Content = Rules

    Version 1.2, All rights reserved, =A9 Copyright 1999-2001 Martin=20 Roesch
    Valid HTML 4.01! Valid CSS!